diff options
Diffstat (limited to 'net/ieee802154/6lowpan/6lowpan_rtnl.c')
-rw-r--r-- | net/ieee802154/6lowpan/6lowpan_rtnl.c | 169 |
1 files changed, 3 insertions, 166 deletions
diff --git a/net/ieee802154/6lowpan/6lowpan_rtnl.c b/net/ieee802154/6lowpan/6lowpan_rtnl.c index 1918c43499ce..9dce20e7f6a0 100644 --- a/net/ieee802154/6lowpan/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan/6lowpan_rtnl.c @@ -57,21 +57,9 @@ #include "6lowpan_i.h" -static LIST_HEAD(lowpan_devices); +LIST_HEAD(lowpan_devices); static int lowpan_open_count; -/* private device info */ -struct lowpan_dev_info { - struct net_device *real_dev; /* real WPAN device ptr */ - struct mutex dev_list_mtx; /* mutex for list ops */ - u16 fragment_tag; -}; - -struct lowpan_dev_record { - struct net_device *ldev; - struct list_head list; -}; - /* don't save pan id, it's intra pan */ struct lowpan_addr { u8 mode; @@ -88,12 +76,6 @@ struct lowpan_addr_info { }; static inline struct -lowpan_dev_info *lowpan_dev_info(const struct net_device *dev) -{ - return netdev_priv(dev); -} - -static inline struct lowpan_addr_info *lowpan_skb_priv(const struct sk_buff *skb) { WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct lowpan_addr_info)); @@ -134,74 +116,6 @@ static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev, return 0; } -static int lowpan_give_skb_to_devices(struct sk_buff *skb, - struct net_device *dev) -{ - struct lowpan_dev_record *entry; - struct sk_buff *skb_cp; - int stat = NET_RX_SUCCESS; - - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - - rcu_read_lock(); - list_for_each_entry_rcu(entry, &lowpan_devices, list) - if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { - skb_cp = skb_copy(skb, GFP_ATOMIC); - if (!skb_cp) { - kfree_skb(skb); - rcu_read_unlock(); - return NET_RX_DROP; - } - - skb_cp->dev = entry->ldev; - stat = netif_rx(skb_cp); - if (stat == NET_RX_DROP) - break; - } - rcu_read_unlock(); - - consume_skb(skb); - - return stat; -} - -static int -iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) -{ - u8 iphc0, iphc1; - struct ieee802154_addr_sa sa, da; - void *sap, *dap; - - raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); - /* at least two bytes will be used for the encoding */ - if (skb->len < 2) - return -EINVAL; - - if (lowpan_fetch_skb_u8(skb, &iphc0)) - return -EINVAL; - - if (lowpan_fetch_skb_u8(skb, &iphc1)) - return -EINVAL; - - ieee802154_addr_to_sa(&sa, &hdr->source); - ieee802154_addr_to_sa(&da, &hdr->dest); - - if (sa.addr_type == IEEE802154_ADDR_SHORT) - sap = &sa.short_addr; - else - sap = &sa.hwaddr; - - if (da.addr_type == IEEE802154_ADDR_SHORT) - dap = &da.short_addr; - else - dap = &da.hwaddr; - - return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, - IEEE802154_ADDR_LEN, dap, da.addr_type, - IEEE802154_ADDR_LEN, iphc0, iphc1); -} - static struct sk_buff* lowpan_alloc_frag(struct sk_buff *skb, int size, const struct ieee802154_hdr *master_hdr) @@ -485,83 +399,6 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } -static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct ieee802154_hdr hdr; - int ret; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (!skb) - goto drop; - - if (!netif_running(dev)) - goto drop_skb; - - if (skb->pkt_type == PACKET_OTHERHOST) - goto drop_skb; - - if (dev->type != ARPHRD_IEEE802154) - goto drop_skb; - - if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) - goto drop_skb; - - /* check that it's our buffer */ - if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { - /* Pull off the 1-byte of 6lowpan header. */ - skb_pull(skb, 1); - return lowpan_give_skb_to_devices(skb, NULL); - } else { - switch (skb->data[0] & 0xe0) { - case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ - ret = iphc_decompress(skb, &hdr); - if (ret < 0) - goto drop_skb; - - return lowpan_give_skb_to_devices(skb, NULL); - case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ - ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); - if (ret == 1) { - ret = iphc_decompress(skb, &hdr); - if (ret < 0) - goto drop_skb; - - return lowpan_give_skb_to_devices(skb, NULL); - } else if (ret == -1) { - return NET_RX_DROP; - } else { - return NET_RX_SUCCESS; - } - case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ - ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); - if (ret == 1) { - ret = iphc_decompress(skb, &hdr); - if (ret < 0) - goto drop_skb; - - return lowpan_give_skb_to_devices(skb, NULL); - } else if (ret == -1) { - return NET_RX_DROP; - } else { - return NET_RX_SUCCESS; - } - default: - break; - } - } - -drop_skb: - kfree_skb(skb); -drop: - return NET_RX_DROP; -} - -static struct packet_type lowpan_packet_type = { - .type = htons(ETH_P_IEEE802154), - .func = lowpan_rcv, -}; - static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -607,7 +444,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, ret = register_netdevice(dev); if (ret >= 0) { if (!lowpan_open_count) - dev_add_pack(&lowpan_packet_type); + lowpan_rx_init(); lowpan_open_count++; } @@ -624,7 +461,7 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) lowpan_open_count--; if (!lowpan_open_count) - dev_remove_pack(&lowpan_packet_type); + lowpan_rx_exit(); mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { |