gnrc_ipv6_nib: consider largest prefix match when deciding if host on-link#16557
gnrc_ipv6_nib: consider largest prefix match when deciding if host on-link#16557miri64 merged 1 commit intoRIOT-OS:masterfrom
Conversation
No, appart from prefix list and the default router list (which are a sub-view of the FIB), the FIB is not filled by NDP. That's the job of a routing protocol. |
|
I may have some pull to get @cgundogan or @PeterKietzmann to review. Bug fixes before the release are always nice. |
@MrKevinWeiss where you able to use your "pull" :) |
d95c014 to
76a2617
Compare
|
Seems like not really, I will try again next time I see them in the office. |
|
@miri64 what's your 2¢ on this? |
|
TBH I am not quite sure why the distinction for the FIB is needed. If the prefix is not in the prefix list or if it is not marked as on-link (which is your true condition for |
| continue; | ||
| } | ||
|
|
||
| *iface = _nib_onl_get_if(entry->next_hop); |
There was a problem hiding this comment.
BTW there might be an (unrelated) bug here. As for 6Lo-ND only link-local addresses are on-link, best_pfx should only be set if *iface is not a 6LN interface (this case is checked above, but only when *iface was initialized before the call.
There was a problem hiding this comment.
Huh, if the WPAN got a prefix from the border router, all addresses with that prefix should be on-link too, no?
There was a problem hiding this comment.
Ah I just remembered: No the prefix should not be advertised as on-link in the first place: https://datatracker.ietf.org/doc/html/rfc6775#section-5.4
There was a problem hiding this comment.
| #endif /* CONFIG_GNRC_IPV6_NIB_6LN */ | ||
| while ((entry = _nib_offl_iter(entry))) { | ||
| if ((entry->mode & _PL) && (entry->flags & _PFX_ON_LINK) && | ||
| (ipv6_addr_match_prefix(dst, &entry->pfx) >= entry->pfx_len) && |
There was a problem hiding this comment.
Maybe the problem is that this should rather be a == or <= and that is why you get the wrong prefixes reported as on-link?
|
This is for the cascading subnets use-case (#16536): Here Now addresses like That's why when the router created the subnet, it also sent a router advertisement with a RIO for the new prefix (#16568). This ends up creating a forwarding table entry that looks like (I'm only using global addresses in the example for simplicity's sake). Now with this patch node A will see that the fib entry for |
Mhh this sounds to me more like the matching algorithm is wrong here. Maybe the way to go would here to first find the best matching entry in the prefix list (read |
|
So are you suggesting something like this? static bool _on_link(const ipv6_addr_t *dst, unsigned *iface)
{
_nib_offl_entry_t *entry = NULL;
_nib_offl_entry_t *match = NULL;
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LN)
if (*iface != 0) {
if (gnrc_netif_is_6ln(gnrc_netif_get_by_pid(*iface))) {
return ipv6_addr_is_link_local(dst);
}
}
#endif /* CONFIG_GNRC_IPV6_NIB_6LN */
while ((entry = _nib_offl_iter(entry))) {
if ((ipv6_addr_match_prefix(dst, &entry->pfx) >= entry->pfx_len) &&
((match == NULL) || (entry->pfx_len > match->pfx_len))) {
match = entry;
}
}
if (match) {
*iface = _nib_onl_get_if(match->next_hop);
return match->flags & _PFX_ON_LINK;
}
return ipv6_addr_is_link_local(dst);
}And since we are always checking for link-local in the end, why not do it first? static bool _on_link(const ipv6_addr_t *dst, unsigned *iface)
{
_nib_offl_entry_t *entry = NULL;
_nib_offl_entry_t *match = NULL;
if (ipv6_addr_is_link_local(dst)) {
return true;
}
while ((entry = _nib_offl_iter(entry))) {
if ((ipv6_addr_match_prefix(dst, &entry->pfx) >= entry->pfx_len) &&
((match == NULL) || (entry->pfx_len > match->pfx_len))) {
match = entry;
}
}
if (match) {
*iface = _nib_onl_get_if(match->next_hop);
return match->flags & _PFX_ON_LINK;
}
return false;
} |
Yepp, that looks good. |
Ah wait, the check if the entry is in the prefix list should stay. Not sure, if the flags are cleared, when |
|
Does it fix the problem you encountered? |
|
Yes with this #16536 is working (I discovered a minor bug in |
miri64
left a comment
There was a problem hiding this comment.
The change looks sensible now and I trust your testing. Please squash (and change the commit message to reflect the changed directive of the PR).
…-link If the fib contains a route to a subnet via another host, it can not be on-link. Consider fib entries when deciding whether an address is on-link. If a route via another host is a stronger match than an on-link prefix, the address must be off-link.
cbb1d7b to
452500b
Compare

Contribution description
If the fib contains a route to a subnet via another host, it can not be on-link.
Consider fib entries when deciding whether an address is on-link.
If a route via another host is a stronger match than an on-link prefix, the address must be off-link.
Testing procedure
see #8823 (comment)
this required manually adding a routing entry for the next hop via
nib route add 5 2001:16b8:45b5:9afa::/63 fe80::5884:3bff:fe4f:a903(is it possible to use NDP for this?yes, see #16568)Here packets for the
2001:16b8:45b5:9afa::/63network should be routed throughfe80::5884:3bff:fe4f:a903.On master hosts in this network are considered on-link as
2001:16b8:45b5:9af8::/62is already a match. A neighbor solicitation on interface #5 for any host in2001:16b8:45b5:9afa::/63will however not yield any results as those are behind another hop. Sending fails with a host unreachable message.Issues/PRs references
#8823 (comment)