diff options
Diffstat (limited to 'net/ieee802154/6lowpan.c')
-rw-r--r-- | net/ieee802154/6lowpan.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 536c6e21b20e..6a095225148e 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -645,7 +645,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr) | |||
645 | } | 645 | } |
646 | 646 | ||
647 | static struct lowpan_fragment * | 647 | static struct lowpan_fragment * |
648 | lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag) | 648 | lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag) |
649 | { | 649 | { |
650 | struct lowpan_fragment *frame; | 650 | struct lowpan_fragment *frame; |
651 | 651 | ||
@@ -656,7 +656,7 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag) | |||
656 | 656 | ||
657 | INIT_LIST_HEAD(&frame->list); | 657 | INIT_LIST_HEAD(&frame->list); |
658 | 658 | ||
659 | frame->length = (iphc0 & 7) | (len << 3); | 659 | frame->length = len; |
660 | frame->tag = tag; | 660 | frame->tag = tag; |
661 | 661 | ||
662 | /* allocate buffer for frame assembling */ | 662 | /* allocate buffer for frame assembling */ |
@@ -714,14 +714,18 @@ lowpan_process_data(struct sk_buff *skb) | |||
714 | case LOWPAN_DISPATCH_FRAGN: | 714 | case LOWPAN_DISPATCH_FRAGN: |
715 | { | 715 | { |
716 | struct lowpan_fragment *frame; | 716 | struct lowpan_fragment *frame; |
717 | u8 len, offset; | 717 | /* slen stores the rightmost 8 bits of the 11 bits length */ |
718 | u16 tag; | 718 | u8 slen, offset; |
719 | u16 len, tag; | ||
719 | bool found = false; | 720 | bool found = false; |
720 | 721 | ||
721 | if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ | 722 | if (lowpan_fetch_skb_u8(skb, &slen) || /* frame length */ |
722 | lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ | 723 | lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ |
723 | goto drop; | 724 | goto drop; |
724 | 725 | ||
726 | /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */ | ||
727 | len = ((iphc0 & 7) << 8) | slen; | ||
728 | |||
725 | /* | 729 | /* |
726 | * check if frame assembling with the same tag is | 730 | * check if frame assembling with the same tag is |
727 | * already in progress | 731 | * already in progress |
@@ -736,7 +740,7 @@ lowpan_process_data(struct sk_buff *skb) | |||
736 | 740 | ||
737 | /* alloc new frame structure */ | 741 | /* alloc new frame structure */ |
738 | if (!found) { | 742 | if (!found) { |
739 | frame = lowpan_alloc_new_frame(skb, iphc0, len, tag); | 743 | frame = lowpan_alloc_new_frame(skb, len, tag); |
740 | if (!frame) | 744 | if (!frame) |
741 | goto unlock_and_drop; | 745 | goto unlock_and_drop; |
742 | } | 746 | } |
@@ -1004,8 +1008,8 @@ lowpan_skb_fragmentation(struct sk_buff *skb) | |||
1004 | tag = fragment_tag++; | 1008 | tag = fragment_tag++; |
1005 | 1009 | ||
1006 | /* first fragment header */ | 1010 | /* first fragment header */ |
1007 | head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7); | 1011 | head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7); |
1008 | head[1] = (payload_length >> 3) & 0xff; | 1012 | head[1] = payload_length & 0xff; |
1009 | head[2] = tag >> 8; | 1013 | head[2] = tag >> 8; |
1010 | head[3] = tag & 0xff; | 1014 | head[3] = tag & 0xff; |
1011 | 1015 | ||