diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/6lowpan/iphc.c | 32 | ||||
-rw-r--r-- | net/bluetooth/6lowpan.c | 14 | ||||
-rw-r--r-- | net/ieee802154/6lowpan_rtnl.c | 41 |
3 files changed, 44 insertions, 43 deletions
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 747b3ccfc4f8..45714fe885f0 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c | |||
@@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb, | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, | ||
175 | struct net_device *dev, skb_delivery_cb deliver_skb) | ||
176 | { | ||
177 | int stat; | ||
178 | |||
179 | skb_push(skb, sizeof(struct ipv6hdr)); | ||
180 | skb_reset_network_header(skb); | ||
181 | skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr)); | ||
182 | |||
183 | skb->protocol = htons(ETH_P_IPV6); | ||
184 | skb->pkt_type = PACKET_HOST; | ||
185 | skb->dev = dev; | ||
186 | |||
187 | raw_dump_table(__func__, "raw skb data dump before receiving", | ||
188 | skb->data, skb->len); | ||
189 | |||
190 | stat = deliver_skb(skb, dev); | ||
191 | |||
192 | consume_skb(skb); | ||
193 | |||
194 | return stat; | ||
195 | } | ||
196 | |||
197 | /* Uncompress function for multicast destination address, | 174 | /* Uncompress function for multicast destination address, |
198 | * when M bit is set. | 175 | * when M bit is set. |
199 | */ | 176 | */ |
@@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; | |||
327 | int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, | 304 | int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, |
328 | const u8 *saddr, const u8 saddr_type, const u8 saddr_len, | 305 | const u8 *saddr, const u8 saddr_type, const u8 saddr_len, |
329 | const u8 *daddr, const u8 daddr_type, const u8 daddr_len, | 306 | const u8 *daddr, const u8 daddr_type, const u8 daddr_len, |
330 | u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb) | 307 | u8 iphc0, u8 iphc1) |
331 | { | 308 | { |
332 | struct ipv6hdr hdr = {}; | 309 | struct ipv6hdr hdr = {}; |
333 | u8 tmp, num_context = 0; | 310 | u8 tmp, num_context = 0; |
@@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, | |||
492 | hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, | 469 | hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, |
493 | hdr.hop_limit, &hdr.daddr); | 470 | hdr.hop_limit, &hdr.daddr); |
494 | 471 | ||
495 | raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); | 472 | skb_push(skb, sizeof(hdr)); |
473 | skb_reset_network_header(skb); | ||
474 | skb_copy_to_linear_data(skb, &hdr, sizeof(hdr)); | ||
496 | 475 | ||
497 | return skb_deliver(skb, &hdr, dev, deliver_skb); | 476 | raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); |
498 | 477 | ||
478 | return 0; | ||
499 | drop: | 479 | drop: |
500 | kfree_skb(skb); | 480 | kfree_skb(skb); |
501 | return -EINVAL; | 481 | return -EINVAL; |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 6c5c2eff45bd..45d9a9fef634 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -252,7 +252,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) | |||
252 | 252 | ||
253 | skb_cp = skb_copy(skb, GFP_ATOMIC); | 253 | skb_cp = skb_copy(skb, GFP_ATOMIC); |
254 | if (!skb_cp) | 254 | if (!skb_cp) |
255 | return -ENOMEM; | 255 | return NET_RX_DROP; |
256 | 256 | ||
257 | return netif_rx(skb_cp); | 257 | return netif_rx(skb_cp); |
258 | } | 258 | } |
@@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev, | |||
290 | return lowpan_process_data(skb, netdev, | 290 | return lowpan_process_data(skb, netdev, |
291 | saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, | 291 | saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, |
292 | daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, | 292 | daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, |
293 | iphc0, iphc1, give_skb_to_upper); | 293 | iphc0, iphc1); |
294 | 294 | ||
295 | drop: | 295 | drop: |
296 | kfree_skb(skb); | 296 | kfree_skb(skb); |
@@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | |||
350 | if (ret != NET_RX_SUCCESS) | 350 | if (ret != NET_RX_SUCCESS) |
351 | goto drop; | 351 | goto drop; |
352 | 352 | ||
353 | local_skb->protocol = htons(ETH_P_IPV6); | ||
354 | local_skb->pkt_type = PACKET_HOST; | ||
355 | local_skb->dev = dev; | ||
356 | |||
357 | if (give_skb_to_upper(local_skb, dev) | ||
358 | != NET_RX_SUCCESS) { | ||
359 | kfree_skb(local_skb); | ||
360 | goto drop; | ||
361 | } | ||
362 | |||
353 | dev->stats.rx_bytes += skb->len; | 363 | dev->stats.rx_bytes += skb->len; |
354 | dev->stats.rx_packets++; | 364 | dev->stats.rx_packets++; |
355 | 365 | ||
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 1779a08d110a..15c7717c5e06 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c | |||
@@ -141,20 +141,28 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb, | |||
141 | struct sk_buff *skb_cp; | 141 | struct sk_buff *skb_cp; |
142 | int stat = NET_RX_SUCCESS; | 142 | int stat = NET_RX_SUCCESS; |
143 | 143 | ||
144 | skb->protocol = htons(ETH_P_IPV6); | ||
145 | skb->pkt_type = PACKET_HOST; | ||
146 | |||
144 | rcu_read_lock(); | 147 | rcu_read_lock(); |
145 | list_for_each_entry_rcu(entry, &lowpan_devices, list) | 148 | list_for_each_entry_rcu(entry, &lowpan_devices, list) |
146 | if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { | 149 | if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { |
147 | skb_cp = skb_copy(skb, GFP_ATOMIC); | 150 | skb_cp = skb_copy(skb, GFP_ATOMIC); |
148 | if (!skb_cp) { | 151 | if (!skb_cp) { |
149 | stat = -ENOMEM; | 152 | kfree_skb(skb); |
150 | break; | 153 | rcu_read_unlock(); |
154 | return NET_RX_DROP; | ||
151 | } | 155 | } |
152 | 156 | ||
153 | skb_cp->dev = entry->ldev; | 157 | skb_cp->dev = entry->ldev; |
154 | stat = netif_rx(skb_cp); | 158 | stat = netif_rx(skb_cp); |
159 | if (stat == NET_RX_DROP) | ||
160 | break; | ||
155 | } | 161 | } |
156 | rcu_read_unlock(); | 162 | rcu_read_unlock(); |
157 | 163 | ||
164 | consume_skb(skb); | ||
165 | |||
158 | return stat; | 166 | return stat; |
159 | } | 167 | } |
160 | 168 | ||
@@ -190,8 +198,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) | |||
190 | 198 | ||
191 | return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, | 199 | return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, |
192 | IEEE802154_ADDR_LEN, dap, da.addr_type, | 200 | IEEE802154_ADDR_LEN, dap, da.addr_type, |
193 | IEEE802154_ADDR_LEN, iphc0, iphc1, | 201 | IEEE802154_ADDR_LEN, iphc0, iphc1); |
194 | lowpan_give_skb_to_devices); | ||
195 | 202 | ||
196 | drop: | 203 | drop: |
197 | kfree_skb(skb); | 204 | kfree_skb(skb); |
@@ -528,44 +535,48 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, | |||
528 | 535 | ||
529 | /* check that it's our buffer */ | 536 | /* check that it's our buffer */ |
530 | if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { | 537 | if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { |
531 | skb->protocol = htons(ETH_P_IPV6); | ||
532 | skb->pkt_type = PACKET_HOST; | ||
533 | |||
534 | /* Pull off the 1-byte of 6lowpan header. */ | 538 | /* Pull off the 1-byte of 6lowpan header. */ |
535 | skb_pull(skb, 1); | 539 | skb_pull(skb, 1); |
536 | 540 | return lowpan_give_skb_to_devices(skb, NULL); | |
537 | ret = lowpan_give_skb_to_devices(skb, NULL); | ||
538 | if (ret == NET_RX_DROP) | ||
539 | goto drop; | ||
540 | } else { | 541 | } else { |
541 | switch (skb->data[0] & 0xe0) { | 542 | switch (skb->data[0] & 0xe0) { |
542 | case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ | 543 | case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ |
543 | ret = process_data(skb, &hdr); | 544 | ret = process_data(skb, &hdr); |
544 | if (ret == NET_RX_DROP) | 545 | if (ret == NET_RX_DROP) |
545 | goto drop; | 546 | goto drop; |
546 | break; | 547 | |
548 | return lowpan_give_skb_to_devices(skb, NULL); | ||
547 | case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ | 549 | case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ |
548 | ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); | 550 | ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); |
549 | if (ret == 1) { | 551 | if (ret == 1) { |
550 | ret = process_data(skb, &hdr); | 552 | ret = process_data(skb, &hdr); |
551 | if (ret == NET_RX_DROP) | 553 | if (ret == NET_RX_DROP) |
552 | goto drop; | 554 | goto drop; |
555 | |||
556 | return lowpan_give_skb_to_devices(skb, NULL); | ||
557 | } else if (ret == -1) { | ||
558 | return NET_RX_DROP; | ||
559 | } else { | ||
560 | return NET_RX_SUCCESS; | ||
553 | } | 561 | } |
554 | break; | ||
555 | case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ | 562 | case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ |
556 | ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); | 563 | ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); |
557 | if (ret == 1) { | 564 | if (ret == 1) { |
558 | ret = process_data(skb, &hdr); | 565 | ret = process_data(skb, &hdr); |
559 | if (ret == NET_RX_DROP) | 566 | if (ret == NET_RX_DROP) |
560 | goto drop; | 567 | goto drop; |
568 | |||
569 | return lowpan_give_skb_to_devices(skb, NULL); | ||
570 | } else if (ret == -1) { | ||
571 | return NET_RX_DROP; | ||
572 | } else { | ||
573 | return NET_RX_SUCCESS; | ||
561 | } | 574 | } |
562 | break; | ||
563 | default: | 575 | default: |
564 | break; | 576 | break; |
565 | } | 577 | } |
566 | } | 578 | } |
567 | 579 | ||
568 | return NET_RX_SUCCESS; | ||
569 | drop_skb: | 580 | drop_skb: |
570 | kfree_skb(skb); | 581 | kfree_skb(skb); |
571 | drop: | 582 | drop: |