diff options
author | alex.bluesman.smirnov@gmail.com <alex.bluesman.smirnov@gmail.com> | 2011-08-31 23:55:15 -0400 |
---|---|---|
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 f0d15365722a..19d6aefe97d4 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) | |||
479 | int stat = NET_RX_SUCCESS; | 479 | int stat = NET_RX_SUCCESS; |
480 | 480 | ||
481 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), | 481 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), |
482 | GFP_KERNEL); | 482 | GFP_ATOMIC); |
483 | kfree_skb(skb); | 483 | kfree_skb(skb); |
484 | 484 | ||
485 | if (NULL == new) | 485 | if (!new) |
486 | return -ENOMEM; | 486 | return -ENOMEM; |
487 | 487 | ||
488 | skb_push(new, sizeof(struct ipv6hdr)); | 488 | skb_push(new, sizeof(struct ipv6hdr)); |
@@ -495,13 +495,14 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) | |||
495 | rcu_read_lock(); | 495 | rcu_read_lock(); |
496 | list_for_each_entry_rcu(entry, &lowpan_devices, list) | 496 | list_for_each_entry_rcu(entry, &lowpan_devices, list) |
497 | if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) { | 497 | if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) { |
498 | skb = skb_copy(new, GFP_KERNEL); | 498 | skb = skb_copy(new, GFP_ATOMIC); |
499 | skb->dev = entry->ldev; | 499 | if (!skb) { |
500 | stat = -ENOMEM; | ||
501 | break; | ||
502 | } | ||
500 | 503 | ||
501 | if (in_interrupt()) | 504 | skb->dev = entry->ldev; |
502 | stat = netif_rx(skb); | 505 | stat = netif_rx(skb); |
503 | else | ||
504 | stat = netif_rx_ni(skb); | ||
505 | } | 506 | } |
506 | rcu_read_unlock(); | 507 | rcu_read_unlock(); |
507 | 508 | ||