summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/6lowpan.c
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2015-10-13 07:42:55 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-10-20 18:49:24 -0400
commitcefdb801c80736017b5a0d97a4a9f816d5a98fc4 (patch)
treeb24038cd412000fafe0e31dcb01a0166572c641f /net/bluetooth/6lowpan.c
parent71cd2aa53dbf9eb8cb954fc9e65de8dab774b7f6 (diff)
bluetooth: 6lowpan: use lowpan dispatch helpers
This patch adds a check if the dataroom of skb contains a dispatch value by checking if skb->len != 0. This patch also change the dispatch evaluation by the recently introduced helpers for checking the common 6LoWPAN dispatch values for IPv6 and IPHC header. There was also a forgotten else branch which should drop the packet if no matching dispatch is available. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/6lowpan.c')
-rw-r--r--net/bluetooth/6lowpan.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index db73b8a1433f..665bf38bd03b 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -314,15 +314,17 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
314 if (!netif_running(dev)) 314 if (!netif_running(dev))
315 goto drop; 315 goto drop;
316 316
317 if (dev->type != ARPHRD_6LOWPAN) 317 if (dev->type != ARPHRD_6LOWPAN || !skb->len)
318 goto drop; 318 goto drop;
319 319
320 skb_reset_network_header(skb);
321
320 skb = skb_share_check(skb, GFP_ATOMIC); 322 skb = skb_share_check(skb, GFP_ATOMIC);
321 if (!skb) 323 if (!skb)
322 goto drop; 324 goto drop;
323 325
324 /* check that it's our buffer */ 326 /* check that it's our buffer */
325 if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { 327 if (lowpan_is_ipv6(*skb_network_header(skb))) {
326 /* Copy the packet so that the IPv6 header is 328 /* Copy the packet so that the IPv6 header is
327 * properly aligned. 329 * properly aligned.
328 */ 330 */
@@ -334,7 +336,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
334 local_skb->protocol = htons(ETH_P_IPV6); 336 local_skb->protocol = htons(ETH_P_IPV6);
335 local_skb->pkt_type = PACKET_HOST; 337 local_skb->pkt_type = PACKET_HOST;
336 338
337 skb_reset_network_header(local_skb);
338 skb_set_transport_header(local_skb, sizeof(struct ipv6hdr)); 339 skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
339 340
340 if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) { 341 if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) {
@@ -347,38 +348,34 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
347 348
348 consume_skb(local_skb); 349 consume_skb(local_skb);
349 consume_skb(skb); 350 consume_skb(skb);
350 } else { 351 } else if (lowpan_is_iphc(*skb_network_header(skb))) {
351 switch (skb->data[0] & 0xe0) { 352 local_skb = skb_clone(skb, GFP_ATOMIC);
352 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 353 if (!local_skb)
353 local_skb = skb_clone(skb, GFP_ATOMIC); 354 goto drop;
354 if (!local_skb)
355 goto drop;
356 355
357 ret = iphc_decompress(local_skb, dev, chan); 356 ret = iphc_decompress(local_skb, dev, chan);
358 if (ret < 0) { 357 if (ret < 0) {
359 kfree_skb(local_skb); 358 kfree_skb(local_skb);
360 goto drop; 359 goto drop;
361 } 360 }
362 361
363 local_skb->protocol = htons(ETH_P_IPV6); 362 local_skb->protocol = htons(ETH_P_IPV6);
364 local_skb->pkt_type = PACKET_HOST; 363 local_skb->pkt_type = PACKET_HOST;
365 local_skb->dev = dev; 364 local_skb->dev = dev;
366 365
367 if (give_skb_to_upper(local_skb, dev) 366 if (give_skb_to_upper(local_skb, dev)
368 != NET_RX_SUCCESS) { 367 != NET_RX_SUCCESS) {
369 kfree_skb(local_skb); 368 kfree_skb(local_skb);
370 goto drop; 369 goto drop;
371 } 370 }
372 371
373 dev->stats.rx_bytes += skb->len; 372 dev->stats.rx_bytes += skb->len;
374 dev->stats.rx_packets++; 373 dev->stats.rx_packets++;
375 374
376 consume_skb(local_skb); 375 consume_skb(local_skb);
377 consume_skb(skb); 376 consume_skb(skb);
378 break; 377 } else {
379 default: 378 goto drop;
380 break;
381 }
382 } 379 }
383 380
384 return NET_RX_SUCCESS; 381 return NET_RX_SUCCESS;