diff options
author | Alan Ott <alan@signal11.us> | 2012-09-01 09:57:06 +0400 |
---|---|---|
committer | David S. Miller <davem@tempietto.lan> | 2012-09-02 06:48:01 +0400 |
commit | a437d2744b0a4e5f405f6b9be284eb9e0a2d7741 (patch) | |
tree | 9d83ef2dcca22e73cb0638ccf6512a884f3878b5 /net/ieee802154 | |
parent | 1bed966cc3bd4042110129f0fc51aeeb59c5b200 (diff) | |
download | linux-a437d2744b0a4e5f405f6b9be284eb9e0a2d7741.tar.xz |
6lowpan: Make a copy of skb's delivered to 6lowpan
Since lowpan_process_data() modifies the skb (by calling skb_pull()), we
need our own copy so that it doesn't affect the data received by other
protcols (in this case, af_ieee802154).
Signed-off-by: Alan Ott <alan@signal11.us>
Signed-off-by: David S. Miller <davem@tempietto.lan>
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/6lowpan.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 6a095225148e..b28ec790c7c8 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -1133,6 +1133,8 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { + struct sk_buff *local_skb; + if (!netif_running(dev)) goto drop; @@ -1144,7 +1146,12 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ - lowpan_process_data(skb); + local_skb = skb_clone(skb, GFP_ATOMIC); + if (!local_skb) + goto drop; + lowpan_process_data(local_skb); + + kfree_skb(skb); break; default: break; |