summaryrefslogtreecommitdiff
path: root/drivers/net/can/vxcan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/vxcan.c')
-rw-r--r--drivers/net/can/vxcan.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index f14c6f02b662..e882250180ef 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -21,6 +21,7 @@
#include <linux/can/vxcan.h>
#include <linux/can/can-ml.h>
#include <linux/slab.h>
+#include <net/can.h>
#include <net/rtnetlink.h>
#define DRV_NAME "vxcan"
@@ -39,6 +40,7 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
struct vxcan_priv *priv = netdev_priv(dev);
struct net_device *peer;
struct net_device_stats *peerstats, *srcstats = &dev->stats;
+ struct can_skb_ext *csx;
struct sk_buff *skb;
unsigned int len;
@@ -63,8 +65,19 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
goto out_unlock;
}
+ /* the cloned skb points to the skb extension of the already cloned
+ * oskb with an increased refcount. skb_ext_add() creates a copy to
+ * separate the skb extension data which is needed to start with a
+ * fresh can_gw_hops counter in the other namespace.
+ */
+ csx = skb_ext_add(skb, SKB_EXT_CAN);
+ if (!csx) {
+ kfree_skb(skb);
+ goto out_unlock;
+ }
+
/* reset CAN GW hop counter */
- skb->csum_start = 0;
+ csx->can_gw_hops = 0;
skb->pkt_type = PACKET_BROADCAST;
skb->dev = peer;
skb->ip_summed = CHECKSUM_UNNECESSARY;