RIOT+ULAs: no router entry

Hi everyone,

I'm testing COAP between RIOT on Phytec pba-d-01-kw2x and Linux on RasPi+Openlabs using ULA IP addresses.

On the Pi I run a 'radvd' to advertise a ULA prefix to RIOT, which works: - RIOT sends RS after boot - the Pi answers with RA containing ULA prefix - RIOT configures ULA IP on 6lo iface

COAP (or communication in general) via ULA IP works, as long as RIOT has the Pi in its routers cache. However, sometimes RIOT _forgets_ or does not set a routers entry for the Pi at all. In that case communication is not possible via ULAs, using link-local IPs works all the time. The issue seems be with the RS+RA processing. I found that sometimes RIOT does not create a routers entry on reception of a RA - though it does configure the ULA prefix correctly.

I just had the case that RIOT configures the ULA _and_ sets a routers entry, hence communication was working. At least for about 15min, but then RIOT send another RS, Pi answers with RA, RIOT still has ULA IP configured -- BUT the routers entry for the Pi is gone and communication fails. Again: using link-local IPs still works.

Btw. even when communication via ULAs is working, RIOT never creates a ncache entry for ULA IP of the Pi but it did create an ncache entry for link-local IP of the Pi. I thought the latter is not required/allowed in 6lo but for ULAs it should create an entry?

Has somebody else observed this behavior or any hints how to resolve this?

Thanks, best   Sebastian

Hi,

Hey,

That sounds like the problem described in this issue [1]. The current master / release candidate version should include a "workaround" fix for that.

Cheers, Cenk

[1] https://github.com/RIOT-OS/RIOT/issues/5122

Hi,

this may be.

In any case, the erroneous behavior described by smlng should not depend on the use of ULAs.

Proposal to smlng: Please use global unicast addresses and confirm the misbehavior. Strip off ULA from the discussion thereafter.

Cheers,   Thomas

Hi Alex, and all,

my radvd.conf is the following:

---snip---

interface lowpan0 {     AdvSendAdvert on;     UnicastOnly on;     AdvCurHopLimit 255;     AdvSourceLLAddress on;

    MinRtrAdvInterval 3;     MaxRtrAdvInterval 10;

    AdvDefaultPreference low;

    prefix fd4b:c597:5df5:0::/64     {         AdvOnLink off;         AdvAutonomous on;         AdvRouterAddr on;     };

    abro fe80::1ac0:ffee:1ac0:ffee     {         AdvVersionLow 10;         AdvVersionHigh 2;         AdvValidLifeTime 2;     }; };

---snap---

btw. I use your/linux-wpan fork of radvd. Again: RIOT does receive the RA from radvd AND configures an IP with the provided prefix. Thus, the processing of RS+RA up this point seems to be correct, what's missing is the routers entry in RIOT. Further, RIOT does receive the COAP requests but it cannot send any reply, as it does not know the LLaddr for the destination (ULA) IP. As far as I remember my last digging into RIOTs NDP processing, RIOT does the following:

1. if DST_IP is link-local: extract LLaddr 2. else if neighbor cache entry exist, use it 3. if no ncache: query (default) router for LLaddr 4. if no router: abort

I think I'm running into case 4, where no entry exists what so ever and thus no COAP reply is send.

@Alex as you joined the discussion: I also have a question regarding the Linux side. I currently use Raspbian with shipped Linux-Kernel 4.1.19. I observed that Linux still does NS for link-local address via the nodes scoped multicast address, instead of using 6lo 'shortcut' by extracting LL/MAC-address from the link-local IP. Is this fixed in some recent version?

Regards,   Sebastian

Hi Cenk, and all,

I'm running my tests with latest master and 2016.04-branch, same behavior. Minus the fact, that the router entry in RIOT is created or missing in a somewhat 'non-deterministic' fashion.

Best,   Sebastian

Hi all,

I stripped down my 'radvd.conf' to a minimal of:

---snip--- interface lowpan0 {     AdvSendAdvert on;     MinRtrAdvInterval 3;     MaxRtrAdvInterval 10;     AdvDefaultPreference low;

    prefix fd4b:c597:5df5:0::/64     {         AdvOnLink off;         AdvAutonomous on;         AdvRouterAddr on;     }; }; ---snap---

same behavior with RIOT. It still consistently configures an (ULA) IP with provided prefix, but the routers entry is missing most of the time - sometimes it's there for a couple of seconds -> until the next RS/RA round.

Best,   Sebastian

mhhh,

With MaxRtrAdvInterval 10 then the:

AdvDefaultLifetime

will be 3 * 10 = 30 seconds. Don't know if this is anything related to it. It should be send another RA messages in the interval of 3-10, so far I know. In this interval the route (on RIOT side) should be updated, or?

I think in my setup I used a high value (9000) for this to make anything working. :slight_smile: I can imagine this parameter will not fix this issue, so it happens later only.

"Must be either zero or between MaxRtrAdvInterval and 9000 seconds." see [0].

Hi,

Hi all,

I stripped down my 'radvd.conf' to a minimal of:

---snip--- interface lowpan0 {     AdvSendAdvert on;     MinRtrAdvInterval 3;     MaxRtrAdvInterval 10;     AdvDefaultPreference low;

    prefix fd4b:c597:5df5:0::/64     {         AdvOnLink off;         AdvAutonomous on;         AdvRouterAddr on;     }; }; ---snap---

same behavior with RIOT. It still consistently configures an (ULA) IP with provided prefix, but the routers entry is missing most of the time - sometimes it's there for a couple of seconds -> until the next RS/RA round.

so far I know ABRO MUST BE there. radvd/6lowpan doesn't do anything with that option it's a dummy only, but otherwise 6LoWPAN stacks will drop it, see [0].

But it's "when RAs are used to propagate information between routers" only. Not sure right now. :slight_smile:

- Alex

[0] RFC 6775 - Neighbor Discovery Optimization for IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs)

Hi,

...

> > @Alex as you joined the discussion: I also have a question regarding the Linux side. I currently use Raspbian with shipped Linux-Kernel 4.1.19. I observed that Linux still does NS for link-local address via the nodes scoped multicast address, instead of using 6lo 'shortcut' by extracting LL/MAC-address from the link-local IP. Is this fixed in some recent version? >

There are currently pending patches for introducing neigh_ops, which is a callback strucuture for send/recv NS/NA. After this is mainline it should be easily to change this behaviour, or? What do you think? See [3] - function "lowpan_ndisc_send_ns".

I think, I know what you mean. There is some NS with src as unspecified addr "::" and dest is some "multicast node scope".

RFC 6775 says [0]:

An unspecified source address MUST NOT be used in NS messages.

Additional to the pending patches I added:

diff --git a/net/6lowpan/ndisc.c b/net/6lowpan/ndisc.c index d088295..c6207cd 100644 --- a/net/6lowpan/ndisc.c +++ b/net/6lowpan/ndisc.c @@ -386,8 +386,11 @@ static void lowpan_ndisc_send_ns(struct net_device *dev,                 saddr = &addr_buf;         }

+ /* RFC6775: + * An unspecified source address MUST NOT be used in NS messages. + */         if (ipv6_addr_any(saddr)) - inc_opt = false; + return;         if (inc_opt) {                 optlen += ndisc_opt_addr_space(dev, dev->addr_len);                 optlen += lowpan_ndisc_802154_short_addr_space(dev);

This will not sending NS with "::" addresses as source address.

However, it's a little bit ugly we should prevent to calling this callback when source address is "::".

This patch should be fine at first but can maybe optimized in future.

Hi,

Hi,

... > > > > @Alex as you joined the discussion: I also have a question regarding the Linux side. I currently use Raspbian with shipped Linux-Kernel 4.1.19. I observed that Linux still does NS for link-local address via the nodes scoped multicast address, instead of using 6lo 'shortcut' by extracting LL/MAC-address from the link-local IP. Is this fixed in some recent version? > > > > There are currently pending patches for introducing neigh_ops, which is > a callback strucuture for send/recv NS/NA. After this is mainline it > should be easily to change this behaviour, or? What do you think? > See [3] - function "lowpan_ndisc_send_ns". >

I think, I know what you mean. There is some NS with src as unspecified addr "::" and dest is some "multicast node scope".

RFC 6775 says [0]:

An unspecified source address MUST NOT be used in NS messages.

Additional to the pending patches I added:

diff --git a/net/6lowpan/ndisc.c b/net/6lowpan/ndisc.c index d088295..c6207cd 100644 --- a/net/6lowpan/ndisc.c +++ b/net/6lowpan/ndisc.c @@ -386,8 +386,11 @@ static void lowpan_ndisc_send_ns(struct net_device *dev,                 saddr = &addr_buf;         }

+ /* RFC6775: + * An unspecified source address MUST NOT be used in NS messages. + */         if (ipv6_addr_any(saddr)) - inc_opt = false; + return;

Question would here also, if we really wants to drop it or use ?link-local? saddr then.

        if (inc_opt) {                 optlen += ndisc_opt_addr_space(dev, dev->addr_len);                 optlen += lowpan_ndisc_802154_short_addr_space(dev);

This will not sending NS with "::" addresses as source address.

However, it's a little bit ugly we should prevent to calling this callback when source address is "::".

This patch should be fine at first but can maybe optimized in future.

I think what you ask is the complete ARO stuff support and I can't follow the:

"by extracting LL/MAC-address from the link-local IP." in case of destination address and sending NS. What I found is the "Sending NS" section of rfc6775 [0], which doesn't say anything about different destination address.

Also I found a bootstrapping example in case of 6LN -> 6LR, [1]. But they meant there the GP64 and link-local is defined as LL64.

...

I think I need to look deeper into that to say something related to 6LoWPAN-ND. :slight_smile:

- Alex

[0] RFC 6775 - Neighbor Discovery Optimization for IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs) [1] RFC 6775 - Neighbor Discovery Optimization for IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs)

Hi Alex, hi all,

over the last days I did some more extensive tests and enabled/added some debug output in RIOT, and I got close to the root cause of the problem.

TL;DR: - Linux does not set the router flag in its NAs - but it should when `radvd` is running (or `radvd` should enable it). - RIOT behaves correctly, according to RFC-4861 7.2.4.

Hi Alex, hi all,

over the last days I did some more extensive tests and enabled/added some debug output in RIOT, and I got close to the root cause of the problem.

TL;DR: - Linux does not set the router flag in its NAs - but it should when `radvd` is running (or `radvd` should enable it). - RIOT behaves correctly, according to RFC-4861 7.2.4.

----

Now the slightly longer version; I quickly recap my setup:

- a RasPi with OpenLabs transceiver, and `radvd` (linux-wpan version from github) - Atmel samr21-xpro running RIOT with `gnrc_networking` example (2016.04-branch) - `radvd` announces a ULA-prefix (though ULA doesn't matter, could global as well)

I observed the following behavior:

- RIOT send RS on boot, `radvd` on RasPi replies with RA (incl. PIO, ABRO, SLLAO) - RIOT parse RA, generates IP from prefix, adds NCE for router with router flag set - RIOT send NS for RasPi/routers link-local address -> RasPi replies with NA - RIOT parses NA, but router flag not set -> unset router flag in NCE of router - hence no more router in cache -> no ping or data transfer via non-link-local (e.g. ULA) IPs

so my question @alex and @linux-wpan: can I manually set/enable the routers flag for NAs in Linux Kernel? Or somehow _convince_ `radvd` to do so on startup?

Routers are indicated by the "forwarding" setting. radvd silent warns about that if this isn't set for interfaces with RA advert is on, so far I know you need to increase the debug level for that.

I simple set:

echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

this will set forwarding for all interfaces.

Some code explaining:

See http://lxr.free-electrons.com/source/net/ipv6/ndisc.c#L838

this is at function when NS is received, the routeri flag will be set when forwarding is enabled.

Maybe this solves all your current issues. :slight_smile:

I'm running latest Raspbian with Kernel 'Linux raspberrypi 4.1.19+' and wpan-tools from github on the RasPi.

I would better use bluetooth-next, if possible. With all recent patches you could also try to use 6CO in radvd.

btw: the radvd wants to accept my patches for 6lowpan 6CO stuff, but basic 6LoWPAN-ND (first short address support for NA/NS) will be added and short-address handling will not work with RIOT, but that's another issue...

- Alex

Hi Alex, and all,

Routers are indicated by the "forwarding" setting. radvd silent warns about that if this isn't set for interfaces with RA advert is on, so far I know you need to increase the debug level for that.

I simple set:

echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

this will set forwarding for all interfaces.

Some code explaining:

See http://lxr.free-electrons.com/source/net/ipv6/ndisc.c#L838

this is at function when NS is received, the routeri flag will be set when forwarding is enabled.

Maybe this solves all your current issues. :slight_smile:

Yep, thanks - that did the trick.

I wonder why it isn't sufficient to set 'echo 1 > /proc/sys/net/ipv6/conf/lowpan0/forwarding' on that specific lowpan interface? I tried it, but `radvd` still complains (debug level 5) that forwarding is 0. However, it works by enabling it for all IPv6 interfaces as you suggested.

I'm running latest Raspbian with Kernel 'Linux raspberrypi 4.1.19+' and wpan-tools from github on the RasPi.

I would better use bluetooth-next, if possible. With all recent patches you could also try to use 6CO in radvd.

mhm, I'm using default Raspbian with RPI-Linux+DTS-overlay 'at86rf233' as it is cause a fast and easy setup - and until now, this was sufficient for my test cases ...

Best, Sebastian

[mail]: s@mlng.net [code]: smlng (Sebastian Meiling) · GitHub