tass-belgium / picotcp

PicoTCP is a free TCP/IP stack implementation
Other
1.16k stars 216 forks source link

RFC6775: Sleep mode for loWPAN communication and ND Optimization for 6LoWPANs #217

Open danielinux opened 9 years ago

danielinux commented 9 years ago
jelledevleeschouwer commented 8 years ago

To get a better view on the development of 6LoWPAN, briefly document the module I'll note down a small status-update, some design thoughts and a TODO-list.

Adaption Layer

The 6LoWPAN adaption-layer on itself should be ready. It should be able to communicate with any IEEE802.15.4 PHY driver (written by the implementer) by means of the generic _ieee_radio_-structure. It supports giving the interface a 16-bit short link-layer address as well as a 64-bit EUI-64 address. It doesn't support IPv4-forwarding through NALP-messages (as noted in #215) yet, but maybe an update should be given if this is still required? The adaption-layer supports the 6LoWPAN-frame format and dispatch headers as per RFC4944 §5. The adaption layer also translates IPv6 link-local multicast and on-link unicast addresses to IEEE802.15.4 link layer addresses as per RFC4944. These notes are associated with #215.

Compression

As the compression scheme as per RFC4944 is deprecated, IPv6 header compression is implemented as per RFC6282. Although, only _stateless compression is implemented_, not _stateful_. Stateless means that no context information (information about the local link and frequently used addresses) is disseminated throughout the PAN by the 6LoWPAN Border Router (6LBR). Stateful compression is thus capable of compressing the IPv6-header even further. This could be an enhancement in the future. But then again, does the compression ratio weigh against the effort needed to maintain context information, keeping it up-to-date and disseminate it throughout the network? If you have a lossy network, better compression won't help you better with this. Next to IPv6 header compression _UDP-header compression_ is implemented as wel as per RFC6282. These notes concern issue #215 as well.

Fragmentation

If a frame, after compression, is still too big to fit inside a single 6LoWPAN-frame the frame is fragmented as per RFC4944. While a fragmented frame is being transmitted on the network the 6LoWPAN-interface doesn't accept any other frames from the stack. On reception of fragmented a frame the frames are reassembled and decompressed. Here, a reassembly timeout should still be implemented.

Broadcasting & Mesh networking

This is were the fun starts. I'll note my thoughts on the mesh and broadcast mechanism of the 6LoWPAN implementation. Please interrupt my if my logic is wrong anywhere :smile:

Every node has a 6LoWPAN routing table in which it stores routes to other nodes on the network with the amount of hops in between. Imagine the stack wants to send a frame through the 6LoWPAN-interface. The node is fresh on the network so it has no clue about wat's going on and has no entries in it's routing table. In this case, we still want to make sure the frame arrives at the destination, right? So the device sends the frame through broadcast, and in this manner, the network will get flooded with the frame and eventually arrive at the destination. Question: Should it be better if the device probes the network first, before he transmits the frame, to find out if the destination is even reachable? In this case the node can maybe cache the frame to transmit it later on.

When this sent broadcast-frame is received by any host on the network, that receiving host can determine if the sending host is either a neighbour (1 hop away) or multiple hops away. When the sending host is a neighbour, the origin address is the same as the link-layer source-address. An entry will immediately be added to the routing table. When the sending host is multiple hops away, the receiving host sends sort of a ping-request to the origin through the last hop it received the frame from, to determine the amount of hops in between. On reception of this ping request the originator of the sent frame _elicits a ping-request itself_ for the originator of the ping-request. Okay, now it gets quite confusing.. This should be updated, since it can derive the amount of hops already from the ping-request, so it shouldn't elicit another ping-request. By sending the first frame through broadcast, every other node on the network can already determine a route to a new host joining the network. And the new host eventually has routes to every host on the network when joining.

So my idea then was, to not periodically check for stale routing-table entries. Especially not for addresses it doesn't even care about. When it has no entry for the destination in it's routing table it just sends it through broadcast. When it has an entry with a valid lifetime, it uses the route. And when the node has an entry but that entry is not longer valid (it lifetime has expired), then and only then it sends a ping-request to reconfirm if the route is still valid or not. This would allow the host to sleep (if it has this capability) for longer periods and reduce the amount of traffic on the network. This is refactored recently in f2b04b2f025d5838a00fe03651d7eb68f5aaced7, but I still think this is a good idea, so I should check if this mechanism is still possible and without spewning a lot of timers. But if this is not a good idea, we should still check if there's a periodic check for stale entries. Because I don't think it's periodic ATM.

Duplicate frame suppression

The 6LoWPAN-device uses the most simplest of queues (since a couple of days ago, 76d6641297caf738f64751c0b94ee1ea613f85e1) to suppress duplicates. The queue is 4 places deep and every unique _forward_ is enqueued by means of inserting the origin & final link layer address and sequence number. For a broadcast frame the sequence number of the broadcast dispatch header is used, instead of the sequence number of the IEEE802.15.4-frame. When a frame is to be forwarded, the above items are first looked for in the queue and if an entry is found, the frame is not forwarded on the network again.

IPv6 Neighbour Discovery Optimisations

Because of the mesh-under topology (link-layer forwarding) of the 6LoWPAN-implementation, the amount of Neighbour Discovery Optimisations are minimised. 6LoWPAN-devices can be configured as a 6LBR (see compression) and a network IPv6-prefix can be set. When a host joins the PAN, it will sent router solicitations to configure a default router. The 6LBR sends router advertisements as per RFC6775 with the IPv6-prefix with which the 6LoWPAN nodes (6LN) can configure a unicast address with. When they've done this, they sent an address registration option with their configured unicast address in a neighbour solicitation to the 6LBR for duplicate address detection and to register the address in the 6LBR-cache. Only an unicast address may be configured based on the EUI-64 of the IEEE802.15.4 PHY.

So this is the status of 6LoWPAN, it is indeed almost there, especially if the unit tests are in place. So now a small TODO-list,

TODO

Future enhancements

frederikvs commented 8 years ago

It might be interesting if the design thoughts from @jelledevleeschouwer 's extensive post would make their way to our wiki eventually. No rush, I just don't want to lose this documentation :-)

phalox commented 8 years ago

The https://en.wikipedia.org/wiki/Bus_factor is high in this man.

(sorry for the clutter :-) )