diff options
author | alex.bluesman.smirnov@gmail.com <alex.bluesman.smirnov@gmail.com> | 2011-09-01 03:55:15 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-15 15:36:35 -0400 |
commit | dcef1151804257684f65c779fc1c19836ee0196a (patch) | |
tree | e0371cd545ecc0afa191249aab06db64e2e0742b /net/ieee802154/6lowpan.c | |
parent | fa3df928e0878350ab0ddd1453bb85b056c726da (diff) |
6LoWPAN: fix skb_copy call
This patch fixes 2 issues in lowpan_skb_deliver function:
1. Check for return status of skb_copy call;
2. Use skb_copy with proper GFP flag, drop check for non-interrupt
context.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154/6lowpan.c')
-rw-r--r-- | net/ieee802154/6lowpan.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index f0d15365722..19d6aefe97d 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -479,10 +479,10 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) int stat = NET_RX_SUCCESS; new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), - GFP_KERNEL); + GFP_ATOMIC); kfree_skb(skb); - if (NULL == new) + if (!new) return -ENOMEM; skb_push(new, sizeof(struct ipv6hdr)); @@ -495,13 +495,14 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) rcu_read_lock(); list_for_each_entry_rcu(entry, &lowpan_devices, list) if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) { - skb = skb_copy(new, GFP_KERNEL); - skb->dev = entry->ldev; + skb = skb_copy(new, GFP_ATOMIC); + if (!skb) { + stat = -ENOMEM; + break; + } - if (in_interrupt()) - stat = netif_rx(skb); - else - stat = netif_rx_ni(skb); + skb->dev = entry->ldev; + stat = netif_rx(skb); } rcu_read_unlock(); |