aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/6lowpan/iphc.c32
-rw-r--r--net/bluetooth/6lowpan.c14
-rw-r--r--net/ieee802154/6lowpan_rtnl.c41
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
174static 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 };
327int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, 304int 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;
499drop: 479drop:
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
295drop: 295drop:
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
196drop: 203drop:
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;
569drop_skb: 580drop_skb:
570 kfree_skb(skb); 581 kfree_skb(skb);
571drop: 582drop: