diff --git a/net/core/dev.c b/net/core/dev.c index 0dd54a6..9244373 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2720,6 +2720,17 @@ static inline int deliver_skb(struct sk_buff *skb, return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); } +static inline int deliver_skb_clone(struct sk_buff *skb, + struct packet_type *pt_prev, + struct net_device *orig_dev) +{ + struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); + + if (!nskb) + return 0; + return pt_prev->func(nskb, nskb->dev, pt_prev, orig_dev); +} + #if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \ (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)) /* This hook is defined here for ATM LANE */ @@ -2950,7 +2961,7 @@ static int __netif_receive_skb(struct sk_buff *skb) if (ptype->dev == null_or_orig || ptype->dev == skb->dev || ptype->dev == orig_dev) { if (pt_prev) - ret = deliver_skb(skb, pt_prev, orig_dev); + ret = deliver_skb_clone(skb, pt_prev, orig_dev); pt_prev = ptype; } } @@ -2976,7 +2987,7 @@ ncls: if (vlan_tx_tag_present(skb)) { if (pt_prev) { - ret = deliver_skb(skb, pt_prev, orig_dev); + ret = deliver_skb_clone(skb, pt_prev, orig_dev); pt_prev = NULL; } if (vlan_hwaccel_do_receive(&skb)) {