diff --git a/sys/include/net/gnrc/ipv6/nib/ft.h b/sys/include/net/gnrc/ipv6/nib/ft.h index 817c5a394e..0d8182ce58 100644 --- a/sys/include/net/gnrc/ipv6/nib/ft.h +++ b/sys/include/net/gnrc/ipv6/nib/ft.h @@ -112,7 +112,8 @@ void gnrc_ipv6_nib_ft_del(const ipv6_addr_t *dst, unsigned dst_len); * * The iteration over all forwarding table entries in the NIB includes all * entries added via @p gnrc_ipv6_nib_ft_add() and entries that are currently - * in the Destination Cache, in the Prefix List, and in the Default Router List. + * in the Destination Cache, in the Prefix List (only if they're on-link), + * and in the Default Router List. * * Usage example: * diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib_ft.c b/sys/net/gnrc/network_layer/ipv6/nib/nib_ft.c index f739de1df1..2aecb5cdf1 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib_ft.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib_ft.c @@ -132,14 +132,26 @@ bool gnrc_ipv6_nib_ft_iter(const ipv6_addr_t *next_hop, unsigned iface, while ((offl = _nib_offl_iter(offl))) { assert(offl->mode != 0); - if ((offl->next_hop != NULL) && - ((iface == 0) || (iface == _nib_onl_get_if(offl->next_hop))) && - ((next_hop == NULL) || ipv6_addr_equal(&offl->next_hop->ipv6, - next_hop))) { - _nib_ft_get(offl, fte); - *state = offl; - return true; + if (offl->next_hop == NULL) { + /* 'holey' NIB / dangling reference. + * there is no next hop (not even an interface) */ + continue; } + if (offl->mode == _PL && !(offl->flags & _PFX_ON_LINK)) { + /* prefix list entry is off-link */ + continue; + } + if (iface && iface != _nib_onl_get_if(offl->next_hop)) { + /* interface does not match */ + continue; + } + if (next_hop && !ipv6_addr_equal(&offl->next_hop->ipv6, next_hop)) { + /* next hop does not match */ + continue; + } + _nib_ft_get(offl, fte); + *state = offl; + return true; } *state = NULL; }