On Thu, Jul 24, 2014 at 04:59:33PM +0100, Martin Townsend wrote:
> On 24/07/14 16:52, Alexander Aring wrote:
> >On Thu, Jul 24, 2014 at 01:59:21PM +0100, Martin Townsend wrote:
> >>Looking at contiki code [0], line 1582 onwards it looks to me like they 
> >>process fragmentation headers first and then could potentially process an 
> >>uncompressed IPv6 header.
> >>
> >>[0] 
> >>https://github.com/contiki-os/contiki/blob/master/core/net/ipv6/sicslowpan.c
> >>
> >>Also I've just read in RFC 6282 on page 5 that
> >>"
> >>
> >>Section 5.3 of [RFC4944] <http://tools.ietf.org/html/rfc4944#section-5.3> 
> >>also defines how to fragment compressed IPv6
> >>    datagrams that do not fit within a single link frame.  Section 5.3 of
> >>    [RFC4944] <http://tools.ietf.org/html/rfc4944#section-5.3> defines the 
> >> fragment header's datagram_size and
> >>    datagram_offset values as the size and offset of the IPv6 datagram
> >>    before compression.  As a result, all fragment payload outside the
> >>    first fragment must carry their respective portions of the IPv6
> >>    datagram before compression.  This document does not change that
> >>    requirement.  When using the fragmentation mechanism described in
> >>    Section 5.3 of [RFC4944] 
> >> <http://tools.ietf.org/html/rfc4944#section-5.3>, any header that cannot 
> >> fit within the first
> >>    fragment MUST NOT be compressed.
> >>
> >>"
> >>
> >>my reading of this is that on tx if at the point of compressing the IPv6 
> >>header it doesn't fit into 127 bytes then we should send the packet as 
> >>uncompressed IPv6 and then on receive we should process uncompressed IPv6 
> >>packets using 6LoWPAN fragmentation mechanism, or am I wrong in this?
> >>
> >mhhh, that's interesting. It seems we should really not send compressed
> >fragmentation 6lowpan packets.
> >
> >This part updates the Section of 5.3 which means we should do what
> >rfc6282 for section 5.3 of rfc4944 says.
> >
> >Now, I wonder myself why my contiki device sends compressed fragmented
> >packets, but it should not do that. We should not compress the ipv6 header
> >and set the dispatch value "IPv6" instead IPHC and followed by the ipv6
> >packet. Then we should do the fragmentation mechanism.
> >
> >But on the receiving side we should evaluate if it's "IPHC" or "IPv6"
> >after reassembly. Contiki sends me compressed headers while fragmentation,
> >but it should not do this. Also wireshark does accept and decode the IPHC
> >format without malformed information.
> >
> >
> >On sending part we need to hope that contiki/tinyos or others 6LoWPAN
> >stack, can accept uncompressed IPv6 packets.
> >
> >On receiving part we should really check if it's a IPHC dispatch value
> >and add a comment to this for compatibility with others stacks. What do
> >you think about this? Did you see any stacks that sends uncompressed
> >6lowpan packets while fragmentation?
> >
> >
> >Thanks Martin for pointing this out.
> >
> >- Alex
> My understanding is that you can send compressed packets with fragmentation
> and should always strive to compress the IPv6 header. The only situation
> that you should send an uncompressed IPv6 header is when all the headers
> including the compressed IPv6 header do not fit into the first fragment, ie

ok. You mean part:

When using the fragmentation mechanism described in
Section 5.3 of [RFC4944], any header that cannot fit within the first
fragment MUST NOT be compressed.


Any header == sum of headers.

> are more than the MTU of the device sending the packet, for us 127 MTU of
> the 802.15.4 device.  ie  the sum of all the MAC headers/6 LoWPAN headers
> and the compressed IPv6 header > 127.

Okay, I agree. That makes more sense, but when could happen this?

Worst case in our supported:

 802.15.4 MAC dataframe:        39 (fc + seq + address + sec + fcs)
 6LoWPAN Header :               43 (IPv6(40) + NHC(1) + IPHC(2))
 UDP Header :                    8 (like normal udp)

 Total :                        90

So in worst case we have 90 bytes at the moment. But we should handle
the receiving part correctly, if we receive some kind of this packets.

If you look at [0] we always assume that a fragmented packet is
compressed and run process_data function (ugly name for this). and we
doesn't evaluate the DISPATCH value after fragmentation, which we should
do because a non compressed fragmented header has a dispatch value of
LOWPAN_DISPATCH_IPV6 which means it's not a compressed packet.





I hacked a solution for this but need more error handling etc... it's
only a draw for a possible solution:

We simple run lowpan_rcv if the packet is reassembled. This function
evaluate the dispatch value then.

diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 016b77e..547b786 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -495,20 +497,10 @@ static int lowpan_rcv(struct sk_buff *skb, struct 
net_device *dev,
                                goto drop;
                        break;
                case LOWPAN_DISPATCH_FRAG1:     /* first fragment header */
-                       ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
-                       if (ret == 1) {
-                               ret = process_data(skb, &hdr);
-                               if (ret == NET_RX_DROP)
-                                       goto drop;
-                       }
+                       lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
                        break;
                case LOWPAN_DISPATCH_FRAGN:     /* next fragments headers */
-                       ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
-                       if (ret == 1) {
-                               ret = process_data(skb, &hdr);
-                               if (ret == NET_RX_DROP)
-                                       goto drop;
-                       }
+                       lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
                        break;
                default:
                        break;
@@ -522,6 +514,12 @@ drop:
        return NET_RX_DROP;
 }
 
+int lowpan_do_rcv(struct sk_buff *skb, struct net_device *dev)
+{
+       return lowpan_rcv(skb, dev, NULL, NULL);
+}
+EXPORT_SYMBOL(lowpan_do_rcv);
+
 static int lowpan_newlink(struct net *src_net, struct net_device *dev,
                          struct nlattr *tb[], struct nlattr *data[])
 {
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index 4122cdf..abca6d2 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -230,6 +230,8 @@ err:
        return -1;
 }
 
+int lowpan_do_rcv(struct sk_buff *skb, struct net_device *dev);
+
 /*     Check if this packet is complete.
  *     Returns NULL on failure by any reason, and pointer
  *     to current nexthdr field in reassembled frame.
@@ -323,6 +325,8 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, 
struct sk_buff *prev,
        fq->q.fragments = NULL;
        fq->q.fragments_tail = NULL;
 
+       lowpan_do_rcv(head, dev);
+
        return 1;
 out_oom:
        net_dbg_ratelimited("lowpan_frag_reasm: no memory for reassembly\n");

[0] 
https://github.com/linux-wpan/linux-wpan-next/blob/master/net/ieee802154/6lowpan_rtnl.c#L497

------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to