On 24/07/14 17:22, Alexander Aring wrote: > 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. Maybe they mean to cover further application headers that can be compressed. Look at the draft GHC spec for instance. > >> 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? Not sure, what about ipv6 options?? again maybe they are future proofing for future compression algorithms like GHC. > > 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. I have a patch already which refactors lowpan_rcv to be more rfc compliant (and renames process_data :) ) but it relies on an earlier patch which hasn't been accepted yet. I'm away until Monday now so I'll send it then if everyone is ok that this is the way to go. > 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
- Martin ------------------------------------------------------------------------------ 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