}
 
 static struct lowpan_fragment *
-lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag)
+lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag)
 {
        struct lowpan_fragment *frame;
 
 
        INIT_LIST_HEAD(&frame->list);
 
-       frame->length = (iphc0 & 7) | (len << 3);
+       frame->length = len;
        frame->tag = tag;
 
        /* allocate buffer for frame assembling */
        case LOWPAN_DISPATCH_FRAGN:
        {
                struct lowpan_fragment *frame;
-               u8 len, offset;
-               u16 tag;
+               /* slen stores the rightmost 8 bits of the 11 bits length */
+               u8 slen, offset;
+               u16 len, tag;
                bool found = false;
 
-               if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */
+               if (lowpan_fetch_skb_u8(skb, &slen) || /* frame length */
                    lowpan_fetch_skb_u16(skb, &tag))  /* fragment tag */
                        goto drop;
 
+               /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */
+               len = ((iphc0 & 7) << 8) | slen;
+
                /*
                 * check if frame assembling with the same tag is
                 * already in progress
 
                /* alloc new frame structure */
                if (!found) {
-                       frame = lowpan_alloc_new_frame(skb, iphc0, len, tag);
+                       frame = lowpan_alloc_new_frame(skb, len, tag);
                        if (!frame)
                                goto unlock_and_drop;
                }
        tag = fragment_tag++;
 
        /* first fragment header */
-       head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7);
-       head[1] = (payload_length >> 3) & 0xff;
+       head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7);
+       head[1] = payload_length & 0xff;
        head[2] = tag >> 8;
        head[3] = tag & 0xff;