Skip to content

Commit

Permalink
gnrc_ipv6_nib: only route to prefix list entry if on-link
Browse files Browse the repository at this point in the history
In 06aa65e (RIOT-OS#10627) a new behavior was
introduced in IPv6 route resolution to try address resolution only at
interfaces that have the prefix of the address to be resolved configured
in the prefix list. This however only makes sense, if the prefix
configured is [on-link], otherwise there is small likelihood of the
address to be resolved being on that link.

For the error case presented for 06aa65e (circular routing at the border
router) this made sense, however within a 6LoWPAN, due to the prefix
being valid for the entire mesh, this leads to the nodes always trying
classic address resolution for in-network addresses instead of just
routing to the default route.
Classic address resolution however fails, as 6LoWPAN hosts typically
[don't join the solicited-node multicast address of their unicast
addresses][6LN-iface-init], resulting in in-network addresses not being
reachable.

As such, to prevent both error cases

- the fallback to address resolution by prefix list must only be used
  when the prefix is on-link,
- the prefix configured by DHCPv6/UHCP at the 6LoWPAN border router
  must be configured as on-link, but
- the prefix must not be advertised as on-link within the 6LoWPAN to
  still be [in line with RFC 6775][RFC-6775-forbidden]

With this change these cases are covered.

[on-link]: https://tools.ietf.org/html/rfc4861#page-6
[RFC 6775]: https://tools.ietf.org/html/rfc6775
[6LN-iface-init]: https://tools.ietf.org/html/rfc6775#section-5.2
[RFC-6775-forbidden]: https://tools.ietf.org/html/rfc6775#section-6.1
  • Loading branch information
miri64 committed Mar 25, 2020
1 parent a62abe0 commit 1474a6b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
4 changes: 3 additions & 1 deletion sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,9 @@ int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *pkt,
(void *)pkt);
_nib_offl_entry_t *offl = _nib_offl_get_match(dst);

if (offl == NULL) {
if ((offl == NULL) ||
/* give default route precedence over off-link PLEs */
((offl->mode == _PL) && !(offl->flags & _PFX_ON_LINK))) {
_nib_dr_entry_t *router = _nib_drl_get_dr();

if ((router == NULL) && (offl == NULL)) {
Expand Down
9 changes: 8 additions & 1 deletion sys/net/gnrc/network_layer/ipv6/nib/_nib-router.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ static gnrc_pktsnip_t *_offl_to_pio(_nib_offl_entry_t *offl,
{
uint32_t now = (xtimer_now_usec64() / US_PER_MS) & UINT32_MAX;
gnrc_pktsnip_t *pio;
gnrc_netif_t *netif = gnrc_netif_get_by_pid(
_nib_onl_get_if(offl->next_hop)
);
uint8_t flags = 0;
uint32_t valid_ltime = (offl->valid_until == UINT32_MAX) ? UINT32_MAX :
((offl->valid_until - now) / MS_PER_SEC);
Expand All @@ -111,7 +114,11 @@ static gnrc_pktsnip_t *_offl_to_pio(_nib_offl_entry_t *offl,
DEBUG("nib: Build PIO for %s/%u\n",
ipv6_addr_to_str(addr_str, &offl->pfx, sizeof(addr_str)),
offl->pfx_len);
if (offl->flags & _PFX_ON_LINK) {
/* do not advertise as on-link if 6LN
* https://tools.ietf.org/html/rfc6775#section-6.1 otherwise the PIO will be
* ignored by other nodes (https://tools.ietf.org/html/rfc6775#section-5.4)
*/
if ((offl->flags & _PFX_ON_LINK) && !gnrc_netif_is_6ln(netif)) {
flags |= NDP_OPT_PI_FLAGS_L;
}
if (offl->flags & _PFX_SLAAC) {
Expand Down
7 changes: 6 additions & 1 deletion sys/net/gnrc/network_layer/ipv6/nib/nib_pl.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ int gnrc_ipv6_nib_pl_set(unsigned iface,
return 0;
}
gnrc_netif_acquire(netif);
if (!gnrc_netif_is_6ln(netif) &&
/* prefixes within a 6Lo-ND-performing are typically off-link, the
* border router however should configure the prefix as on-link to only do
* address resolution towards the LoWPAN and not the upstream interface
* See https:/RIOT-OS/RIOT/pull/10627 and follow-ups
*/
if ((!gnrc_netif_is_6ln(netif) || gnrc_netif_is_6lbr(netif)) &&
((idx = gnrc_netif_ipv6_addr_match(netif, pfx)) >= 0) &&
(ipv6_addr_match_prefix(&netif->ipv6.addrs[idx], pfx) >= pfx_len)) {
dst->flags |= _PFX_ON_LINK;
Expand Down

0 comments on commit 1474a6b

Please sign in to comment.