6lowpan: Make a copy of skb's delivered to 6lowpan
authorAlan Ott <alan@signal11.us>
Sat, 1 Sep 2012 05:57:06 +0000 (05:57 +0000)
committerDavid S. Miller <davem@tempietto.lan>
Sun, 2 Sep 2012 02:48:01 +0000 (22:48 -0400)
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>
net/ieee802154/6lowpan.c

index 6a095225148e929bc5e3b8d7de2731229cc5f53c..b28ec790c7c845af81752f7bb4afef02fd74c60d 100644 (file)
@@ -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;