Merge pull request #1258 from joakimeriksson/multiple-reassembly-fix

6LoWPAN - multiple reassembly fix and cleanup
This commit is contained in:
Adam Dunkels 2016-01-22 07:15:18 +01:00
commit 7128a6a178
3 changed files with 403 additions and 537 deletions

File diff suppressed because it is too large Load Diff

View File

@ -38,10 +38,10 @@ ArchRock and Sensinode implementations.
We do not implement mesh under related features, as we target route over We do not implement mesh under related features, as we target route over
techniques. techniques.
\subsection hc01 draft-hui-6lowpan-hc-01 \subsection RFC 6282
draft-hui-6lowpan-hc-01 defines a stateful header compression mechanism RFC6282 defines a stateful header compression mechanism
which should soon deprecate the stateless header compression mechanism which deprecate the stateless header compression mechanism
defined in RFC4944. It is much more powerfull and flexible, in defined in RFC4944. It is much more powerfull and flexible, in
particular it allows compression of some multicast addresses and of all particular it allows compression of some multicast addresses and of all
global unicast addresses. global unicast addresses.
@ -110,8 +110,8 @@ the link-layer address. The dependency is reflected in the
\subsection io Packet Input/Output \subsection io Packet Input/Output
At initialization, the #input function in sicslowpan.c is set as the At initialization, the input function in sicslowpan.c is set as the
function to be called by the MAC upon packet reception. The #output function to be called by the MAC upon packet reception. The output
function is set as the tcpip_output function.<br> function is set as the tcpip_output function.<br>
At packet reception, the link-layer copies the 802.15.4 payload in the At packet reception, the link-layer copies the 802.15.4 payload in the
rime buffer, and sets its length. It also stores the source and rime buffer, and sets its length. It also stores the source and
@ -122,19 +122,19 @@ packetbuf_set_datalen(rx_frame.payload_length);
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)&rx_frame.dest_addr); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)&rx_frame.dest_addr);
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)&rx_frame.src_addr); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)&rx_frame.src_addr);
\endcode \endcode
It then calls the sicslowpan #input function. Similarly, when the IPv6 layer It then calls the sicslowpan input function. Similarly, when the IPv6 layer
has a packet to send over the radio, it puts the packet in uip_buf, has a packet to send over the radio, it puts the packet in uip_buf,
sets uip_len and calls the sicslowpan #output function. sets uip_len and calls the sicslowpan output function.
\subsection frag Fragmentation \subsection frag Fragmentation
\li #output function: When an IP packet, after header compression, is \li output function: When an IP packet, after header compression, is
too big to fit in a 802.15.4 frame, it is fragmented in several packets too big to fit in a 802.15.4 frame, it is fragmented in several packets
which are sent successively over the radio. The packets are formatted which are sent successively over the radio. The packets are formatted
as defined in RFC 4944. Only the first fragment contains the IP/UDP as defined in RFC 4944. Only the first fragment contains the IP/UDP
compressed or uncompressed header fields. compressed or uncompressed header fields.
\li #input function: This function takes care of fragment \li input function: This function takes care of fragment
reassembly. We do not assume that the fragments are received in order. reassembly. We do not assume that the fragments are received in order.
When reassembly of a packet is ongoing, we discard any non fragmented When reassembly of a packet is ongoing, we discard any non fragmented
packet or fragment from another packet. Reassembly times out after packet or fragment from another packet. Reassembly times out after
@ -143,8 +143,9 @@ packet or fragment from another packet. Reassembly times out after
\note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG \note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG
compilation option. compilation option.
\note As we do not support complex buffer allocation mechanism, for now \note In order to make it possible to reassemble multiple packets at
we define a new 1280 bytes buffer (#sicslowpan_buf) to reassemble packets. the same time we have a mechanism for storing each fragment per sender
and tag until it is fully reassembled or the reassemly times out.
At reception, once all the fragments are received, we copy the packet At reception, once all the fragments are received, we copy the packet
to #uip_buf, set #uip_len, and call #tcpip_input. to #uip_buf, set #uip_len, and call #tcpip_input.
@ -157,49 +158,35 @@ the header 25 bytes long).
<b>Compression schemes</b><br> <b>Compression schemes</b><br>
The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the
compression scheme supported. We support HC1, HC06, and IPv6 compression. compression scheme supported. We support IPHC, and IPv6 compression.
HC1 and IPv6 compression are defined in RFC4944, HC06 in IPv6 compression are defined in RFC4944, IPHC in RFC6282.
draft-hui-6lowpan-hc-06. What we call IPv6 compression means sending packets What we call IPv6 compression means sending packets
with no compression, and adding the IPv6 dispatch before the IPv6 header.<br> with no compression, and adding the IPv6 dispatch before the IPv6 header.<br>
If at compile time IPv6 "compression" is chosen, packets sent will never If at compile time IPv6 "compression" is chosen, packets sent will never
be compressed, and compressed packets will not be processed at reception.<br> be compressed, and compressed packets will not be processed at reception.<br>
If at compile time either HC1 or HC06 are chosen, we will try to compress
If at compile time IPHC is chosen, we will try to compress
all fields at sending, and will accept packets compressed with the all fields at sending, and will accept packets compressed with the
chosen scheme, as well as uncompressed packets.<br> chosen scheme, as well as uncompressed packets.<br>.
Note that HC1 and HC06 supports are mutually exclusive. HC06 should soon
deprecate HC1.
<b>Compression related functions</b><br> <b>Compression related functions</b><br>
When a packet is received, the #input function is called. Fragmentation When a packet is received, the input function is called. Fragmentation
issues are handled, then we check the dispatch byte: if it is IPv6, we issues are handled, then we check the dispatch byte: if it is IPv6, we
treat the packet inline. If it is HC1 or HC06, the corresponding treat the packet inline. If it is IPHC, the decompression function
decompression function (#uncompress_hdr_hc1 or #uncompress_hdr_hc06) (uncompress_hdr_iphc) is called.<br>
is called.<br>
When a packet needs to be sent, we try to compress it. If only the IPv6 When a packet needs to be sent, we try to compress it. If only the IPv6
compression support is enabled, we just add the IPv6 dispatch before the compression support is enabled, we just add the IPv6 dispatch before the
802.15.4 payload. If HC1 or HC06 support is enabled, we call the 802.15.4 payload. If IPHC support is enabled, we call the
corresponding compression function (#compress_hdr_hc1 or #compress_hdr_hc06) corresponding compression function (compress_hdr_iphc)
to compress the packet as much as possible. to compress the packet as much as possible.
<b>HC1 comments</b><br> <b>IPHC comments</b><br>
In HC1, if the IPv6 flow label is not compressed, we would need to copy IPHC uses address contexts to enable compression of global unicast
the fields after the flow label starting in the middle of a byte (the
flow label is 20 bits long). To avoid this, we compress the packets only
if all fields can be compressed. If we cannot, we use the IPv6 dispatch
and send all headers fields inline. This behavior is the one defined in
draft-hui-6lowpan-interop-00.<br>
In the same way, if the packet is an UDP packet, we compress the UDP
header only if all fields can be compressed.<br>
Note that HC1 can only compress unicast link local addresses. For this
reason, we recommend using HC01.
<b>HC01 comments</b><br>
HC01 uses address contexts to enable compression of global unicast
addresses. All nodes must share context (namely the global prefixes in addresses. All nodes must share context (namely the global prefixes in
use) to compress and uncompress such addresses successfully. The context use) to compress and uncompress such addresses successfully. The context
number is defined by 2 bits. Context 00 is reserved for the link local number is defined by 4 bits. Context 00 is reserved for the link local
context. Other contexts have to be distributed within the LoWPAN context. Other contexts have to be distributed within the LoWPAN
dynamically, by means of ND extensions yet to be defined.<br> dynamically, by means of ND extensions yet to be implemented.<br>
Until then, if you want to test global address compression, you need Until then, if you want to test global address compression, you need
to configure the global contexts manually. to configure the global contexts manually.

View File

@ -145,6 +145,7 @@
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
#ifndef SICSLOWPAN_CONF_FRAG #ifndef SICSLOWPAN_CONF_FRAG
#define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_FRAG 1
#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 4
#define SICSLOWPAN_CONF_MAXAGE 8 #define SICSLOWPAN_CONF_MAXAGE 8
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2