diff options
Diffstat (limited to 'drivers/net/can/vxcan.c')
| -rw-r--r-- | drivers/net/can/vxcan.c | 15 |
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; |
