diff options
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/6lowpan.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index f651da60f161..1714cfab1220 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -594,10 +594,32 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
594 | } | 594 | } |
595 | } | 595 | } |
596 | 596 | ||
597 | static int lowpan_give_skb_to_devices(struct sk_buff *skb) | ||
598 | { | ||
599 | struct lowpan_dev_record *entry; | ||
600 | struct sk_buff *skb_cp; | ||
601 | int stat = NET_RX_SUCCESS; | ||
602 | |||
603 | rcu_read_lock(); | ||
604 | list_for_each_entry_rcu(entry, &lowpan_devices, list) | ||
605 | if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { | ||
606 | skb_cp = skb_copy(skb, GFP_ATOMIC); | ||
607 | if (!skb_cp) { | ||
608 | stat = -ENOMEM; | ||
609 | break; | ||
610 | } | ||
611 | |||
612 | skb_cp->dev = entry->ldev; | ||
613 | stat = netif_rx(skb_cp); | ||
614 | } | ||
615 | rcu_read_unlock(); | ||
616 | |||
617 | return stat; | ||
618 | } | ||
619 | |||
597 | static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) | 620 | static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) |
598 | { | 621 | { |
599 | struct sk_buff *new; | 622 | struct sk_buff *new; |
600 | struct lowpan_dev_record *entry; | ||
601 | int stat = NET_RX_SUCCESS; | 623 | int stat = NET_RX_SUCCESS; |
602 | 624 | ||
603 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), | 625 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), |
@@ -614,19 +636,7 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) | |||
614 | new->protocol = htons(ETH_P_IPV6); | 636 | new->protocol = htons(ETH_P_IPV6); |
615 | new->pkt_type = PACKET_HOST; | 637 | new->pkt_type = PACKET_HOST; |
616 | 638 | ||
617 | rcu_read_lock(); | 639 | stat = lowpan_give_skb_to_devices(new); |
618 | list_for_each_entry_rcu(entry, &lowpan_devices, list) | ||
619 | if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) { | ||
620 | skb = skb_copy(new, GFP_ATOMIC); | ||
621 | if (!skb) { | ||
622 | stat = -ENOMEM; | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | skb->dev = entry->ldev; | ||
627 | stat = netif_rx(skb); | ||
628 | } | ||
629 | rcu_read_unlock(); | ||
630 | 640 | ||
631 | kfree_skb(new); | 641 | kfree_skb(new); |
632 | 642 | ||