The first fragment, FRAG1, must contain some payload according to the
specs. However, as it is currently written, the first fragment will
remain empty and only contain the 6lowpan headers.

This patch also extract the transport layer information from the first
fragment. This information is later on use when uncompressing UDP
header.

Signed-off-by: Tony Cheneau <tony.chen...@amnesiak.org>
---
 net/ieee802154/6lowpan.c |   54 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 8a2ee95..38cecaf 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -654,7 +654,7 @@ static void lowpan_fragment_timer_expired(unsigned long 
entry_addr)
 }
 
 static struct lowpan_fragment *
-lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag)
+lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag)
 {
        struct lowpan_fragment *frame;
 
@@ -735,6 +735,18 @@ lowpan_process_data(struct sk_buff *skb)
                /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */
                len = ((iphc0 & 7) << 8) | slen;
 
+               if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) {
+                       pr_debug("%s received a FRAG1 packet (tag: %d, "
+                                "size of the entire IP packet: %d)"
+                                , __func__, tag, len);
+               } else { /* FRAGN */
+                       if (lowpan_fetch_skb_u8(skb, &offset))
+                               goto unlock_and_drop;
+                       pr_debug("%s received a FRAGN packet (tag: %d, "
+                                "size of the entire IP packet: %d, "
+                                "offset: %d)", __func__, tag, len, offset * 8);
+               }
+
                /*
                 * check if frame assembling with the same tag is
                 * already in progress
@@ -749,17 +761,13 @@ lowpan_process_data(struct sk_buff *skb)
 
                /* alloc new frame structure */
                if (!found) {
+                       pr_debug("%s first fragment received for tag %d, "
+                                "begin packet reassembly", __func__, tag);
                        frame = lowpan_alloc_new_frame(skb, len, tag);
                        if (!frame)
                                goto unlock_and_drop;
                }
 
-               if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1)
-                       goto unlock_and_drop;
-
-               if (lowpan_fetch_skb_u8(skb, &offset)) /* fetch offset */
-                       goto unlock_and_drop;
-
                /* if payload fits buffer, copy it */
                if (likely((offset * 8 + skb->len) <= frame->length))
                        skb_copy_to_linear_data_offset(frame->skb, offset * 8,
@@ -777,6 +785,10 @@ lowpan_process_data(struct sk_buff *skb)
                        list_del(&frame->list);
                        spin_unlock_bh(&flist_lock);
 
+                       pr_debug("%s successfully reassembled fragment "
+                                "(tag %d)", __func__, tag);
+
+
                        dev_kfree_skb(skb);
                        skb = frame->skb;
                        kfree(frame);
@@ -976,13 +988,13 @@ static int lowpan_get_mac_header_length(struct sk_buff 
*skb)
 
 static int
 lowpan_fragment_xmit(struct sk_buff *skb, u8 *head,
-                       int mlen, int plen, int offset)
+                       int mlen, int plen, int offset, int type)
 {
        struct sk_buff *frag;
        int hlen, ret;
 
-       /* if payload length is zero, therefore it's a first fragment */
-       hlen = (plen == 0 ? LOWPAN_FRAG1_HEAD_SIZE :  LOWPAN_FRAGN_HEAD_SIZE);
+       hlen = (type == LOWPAN_DISPATCH_FRAG1 ? LOWPAN_FRAG1_HEAD_SIZE :
+                       LOWPAN_FRAGN_HEAD_SIZE);
 
        lowpan_raw_dump_inline(__func__, "6lowpan fragment header", head, hlen);
 
@@ -1025,7 +1037,18 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
        head[2] = tag >> 8;
        head[3] = tag & 0xff;
 
-       err = lowpan_fragment_xmit(skb, head, header_length, 0, 0);
+       err = lowpan_fragment_xmit(skb, head, header_length, LOWPAN_FRAG_SIZE,
+                                  0, LOWPAN_DISPATCH_FRAG1);
+
+       if (err) {
+#if DEBUG
+               pr_debug("%s unable to send FRAG1 packet (tag: %d)",
+                        __func__, tag);
+#endif /* DEBUG */
+               goto exit;
+       }
+
+       offset = LOWPAN_FRAG_SIZE;
 
        /* next fragment header */
        head[0] &= ~LOWPAN_DISPATCH_FRAG1;
@@ -1040,10 +1063,17 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
                        len = payload_length - offset;
 
                err = lowpan_fragment_xmit(skb, head, header_length,
-                                                       len, offset);
+                                          len, offset, LOWPAN_DISPATCH_FRAGN);
+               if (err) {
+                       pr_debug("%s unable to send a subsequent FRAGN packet "
+                                "(tag: %d, offset: %d", __func__, tag, offset);
+                       goto exit;
+               }
+
                offset += len;
        }
 
+exit:
        return err;
 }
 
-- 
1.7.8.6


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to