Sunday 13 April 2014

IPv6-in-IPv6 + HBHO Extension Headers: The answer to the ultimate question of RFC compliance, the universe, and everything

So there is this person with whom I've been discussing Contiki/6LoWPAN-related topics for ages. However, due to the fact that he's based in the other side of the Atlantic, we'd not had a chance to meet in person before. IETF 89 took place in London this year, he was attending, it was an excellent opportunity to meet in person and I jumped on a train without hesitation.

Himself, a bunch of other (IETF) IoT / Contiki enthusiasts and I met after the IETF and we went for dinner and a few drinks. Among them, a key player in IETF's ROLL WG. Naturally, lots of the conversation was on Contiki-related topics, and at some point we started discussing ROLL's protocols.

Among other topics, we spoke about RPL (some pronounce it 'ripple') and MPL (some pronounce it 'mipple'). I emphatically recommended that, for obvious pronunciation-related reasons, they should refrain from using the acronym NPL for any of their subsequent protocols...

Moving swiftly on...

A little background


Now that Contiki features its shiny support for 6LoWPAN multicast, I've been spending some of my spare time implementing the most recent version of the MPL ID (currently v08).

Simple scenario: A 6LoWPAN connected to the rest of the Internet. For simplicity's (and my own sanity's) sake, let's for a second assume that the world suddenly woke up one day and IPv6 had been deployed globally. A host somewhere in the Internet sends a multicast datagram to a Global-Scope IPv6 address, and some nodes inside the 6LoWPAN are interested in this multicast group. Shimples!

Or maybe it's not that simple. You see, MPL defines an IPv6 HBHO header, called the 'MPL Option', present in all MPL Data Messages. Why is that a problem? Well, it's a problem cause MPL only operates inside the 6LoWPAN, so if a multicast datagram originates from somewhere outside it, it won't have an MPL Option.

Let's try to visualise this from a network layer perspective (omitting layer 2 and UDP headers for clarity). Observe how a multicast datagram originating at an Internet host will not have an MPL Option extension header in it (right). However, inside the 6LoWPAN, the MPL Option must be there (left).



In the MPL draft, there is also a discussion about the Realm-Local multicast scope. This is a new scope, currently emerging as part of draft-ietf-6man-multicast-scopes (currently at v04). The relevance of the Realm-Local scope is not immediately obvious. Please bear with me...

An example of a perfectly smooth conversation


So there we were, eating dinner and generally having a blast, till I decided to mention the Realm-Local scope, which was when then things started going south... The conversation below was predominantly between myself and a person very active within IETF's ROLL WG. Let's call him "Him", to preserve anonymity, privacy etc.

Me: Is Realm-Local moving forward? I'm planning to add support for it in Contiki since MPL uses it.
Him: Yes, it's moving forward.
Me: In practical terms, what's the difference between Realm-Local and... <blah blah>?
Him: <Explanation>

(so far so good)...

An example of a conversation NOT to continue, cause it stops being perfectly smooth...


Him (continues): Thus, when a multicast datagram enters the 6LoWPAN, the LBR is going to send it as Realm-Local.
Me (dazed and confused):  Do you mean a datagram with a Global-Scope destination?
Him: Yes.
Me (dazed and confused): Eeeerm. What? Why would we change the destination address? Why not just forward it inside the 6LoWPAN with the same destination?
Him: No no, you're not changing it. But the datagram doesn't have an MPL option.

(Remember the image earlier. No MPL Option in the original datagram)

Me: Why not just add the MPL option? (I should have known the answer but I didn't)
Him: NO! You may not add extension headers en-route!
Me: OK. Then what?
Him: You encapsulate with IPv6-in-IPv6. The inner header stays as-is, the outer one uses Realm-Local destination.

That was shock number one. Now to give credit where credit's due, the MPL ID is quite explicit about this scenario: "IPv6-in-IPv6 encapsulation MUST be used, hence the "I should have known" comment above.

Let's try to expand the previous diagram to explain what I was thinking (top structure of network headers) and what "Him" was explaining (bottom).


Fair enough, at the end of the day, as discussed in a previous post, Contiki currently doesn't implement either, so if we're gonna do it, we can always do it correctly right from the start... Or can we?

But then I just had this Eureka moment: Haaaang on a minute. Wait wait wait. RPL also defines its own HBHO [RFC 6553] and the situation with incoming unicast datagrams is identical: They are not carrying the RPL HBHO.

Therefore, I simply had to insist


Me: Let's totally forget about multicast for a moment. Plain old unicast datagram sent from the internet. When the datagram is entering the 6LoWPAN, it needs the RPL HBHO and the border router adds it.
Him: Noooope. You must do IPv6-in-IPv6

Houston, we have a problem!


Simply put, "Him" just told me we're not RFC-compliant... Once again, let's have a look at the usual diagram, this time modified for a unicast datagram entering the RPL network. Observe how I've replaced the MPL Option with the RPL Option.



Despite the comedy value of the conversation, this last bit is an even more serious problem than the situation with MPL's HBHO. You see, we (Contiki) don't currently support incoming multicast datagrams, but we sure as hell support unicasts entering a RPL network. In a sense, it's better to not support a spec, than to support it in a non-compliant fashion. I like to think of Contiki as THE operating system for the IoT. Due to the embedded, super optimized way its TCP/IP stack has been implemented, I fear it would take a very considerable effort to implement IPv6-in-IPv6. Not to mention the code size and complexity increase.

Me: Well, sorry, but IPv6-in-IPv6 with Contiki ain't gonna happen any time soon.

I know that the people I was talking to can't be wrong about those things. Originally, I was hoping that they misunderstood the use-case I was trying to describe, or that I misunderstood what they were trying to explain to me.

Nevertheless, the discussion prompted me to re-visit RFC 6553 (RPL Option), as well as draft-ietf-roll-trickle-mcast-08 (MPL's spec, including MPL Option). Having done so, it appears, dear reader, that they understood the question perfectly well and that I understood the answer perfectly well too...

In other words, we just found out that Contiki is not as RFC Compliant as we might have liked it to be. If that's the case, we should probably open a bug in the issue tracker...

Now blogs are about personal opinions are they not? Well, I know that this one is. Well, even though I'm a lot wiser now (thanks, "Him"), my personal opinion is not a lot different to what I said during the dinner in question:

Me: Well, sorry, but IPv6-in-IPv6 with Contiki ain't gonna happen any time soon.

The entire situation is a little bit of a mess. I can see why the RPL Option is useful. What I can't see is the need to over-complicate a spec that targets constrained environments, therefore also constrained nodes. RPL is becoming the de-facto standard for 6LoWPANs, and it's already complex enough. What I can't see is the need to harm it by introducing serious implications to its implementability for something that's no huge benefit.

Happy coding!

Saturday 12 April 2014

Upstream Contiki goes multicast... More or less...

After a fair bit of patience, my 6LoWPAN multicast implementation for Contiki has now been merged upstream. This is super cool, and I must admit I'm well chuffed!

This means that now you can have a Contiki node join an IPv6 multicast group. You can then send a datagram to this multicast address from somewhere in the Internet, and the Contiki node will receive it. Right? Well, I'm afraid the answer is "No, not quite".

You see, as I documented right from the start in Contiki's Pull Request #364, we currently only support multicast for traffic originating inside a 6LoWPAN and with a destination in the same 6LoWPAN. Multicast traffic cannot traverse the network's boundary in either direction.

Within the 6LoWPAN, we currently have two options:
  1. Multicast group management with RPL in MOP3. Forwarding with SMRF (pronounced "Smurf"!) [1, 2]
  2. All multicast functionality with Trickle Multicast [3] (there is no group management as such). This is currently based on an old version of the MPL Internet Draft, which is why I'm intentionally using the name "Trickle Multicast" and not MPL.
Thus, things inside the 6LoWPAN are pretty much sorted out. In order to be able to extend this functionality across the 6LoWPAN's boundary, we need a couple more components:
  • Some sort of mechanism to notify the outside world about group subscriptions of nodes inside the LoWPAN. This, in my humble opinion, can and should be done with MLD. As a Contiki contributor demonstrated recently, an embedded implementation of MLD won't be trouble in terms of code size and complexity.
  • The network's border router should be able to forward multicast traffic from the outside world to the 6LoWPAN and vice-versa. For reasons that I'm explaining in a separate post, this is not as straightforward as it may initially sound, and it's certainly more complex than simply forwarding an IPv6 datagram.
  • The network's border router should be able to conduct multicast routing on its internet-facing interfaces (in other words, outside the 6LoWPAN). The discussion of what protocols and mechanisms could be used for that is a wider topic on IPv6 multicasting and therefore out of scope of this post.
I'll try to visualise this. Everything inside the dashed 6LoWPAN box is what we already have (points 1 and 2 above). We need more functionality on the BR in order to achieve the right-hand side of the figure, plus functionality to cross the 6LoWPANs boundary.
R: A router somewhere in the Internet. BR: Our border router


Naturally, all of the above is under the assumption of an IPv6-enabled Internet. But let's not discuss this right now.

Thus, milestone achieved, but not quite there yet. Next up (in no particular order):
  • MPL implementation. This will update and eventually obsolete the current "Trickle Multicast" implementation.
  • Better forwarding in RPL MOP3 instances (I'm planning to publish this, so I'm not telling you how!)
  • MLD support
Stay tuned

References

[1] G. Oikonomou, I. Phillips, T. Tryfonas, "IPv6 Multicast Forwarding in RPL-Based Wireless Sensor Networks", Wireless Personal Communications, Springer US, 73(3), pp. 1089-1116, 2013 [ doi ]
[2] G. Oikonomou, I. Phillips, "Stateless Multicast Forwarding with RPL in 6LoWPAN Sensor Networks", in Proc. 2012 IEEE International Conference on Pervasive Computing and Communications Workshops (PERCOM Workshops), Lugano, Switzerland, pp. 272-277, 2012 [ doi ]
[3] J. Hui, R. Kelsey, "Multicast Forwarding Using Trickle", IETF Internet Draft (version 01) [ url ]