gnrc/nib: consolidate prefix removal code in _nib_offl_remove_prefix()

This commit is contained in:
Benjamin Valentin 2021-08-13 17:01:11 +02:00
parent 1fd645ebcd
commit 10887ebb19
6 changed files with 82 additions and 18 deletions

View File

@ -679,6 +679,38 @@ void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
#endif /* CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C */
}
void _nib_offl_remove_prefix(_nib_offl_entry_t *pfx)
{
gnrc_netif_t *netif;
/* remove prefix timer */
evtimer_del(&_nib_evtimer, &pfx->pfx_timeout.event);
/* get interface associated with prefix */
netif = gnrc_netif_get_by_pid(_nib_onl_get_if(pfx->next_hop));
if (netif != NULL) {
uint8_t best_match_len = pfx->pfx_len;
ipv6_addr_t *best_match = NULL;
/* remove address associated with prefix */
for (int i = 0; i < CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
if (ipv6_addr_match_prefix(&netif->ipv6.addrs[i],
&pfx->pfx) >= best_match_len) {
best_match_len = pfx->pfx_len;
best_match = &netif->ipv6.addrs[i];
}
}
if (best_match != NULL) {
gnrc_netif_ipv6_addr_remove_internal(netif,
best_match);
}
}
/* remove prefix */
_nib_pl_remove(pfx);
}
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C)
_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr)
{

View File

@ -683,6 +683,16 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface,
*/
void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
/**
* @brief Removes a prefix from the prefix list as well as the addresses
* associated with the prefix.
*
* @param[in,out] nib_offl An entry.
*
* Corresponding on-link entry is removed, too.
*/
void _nib_offl_remove_prefix(_nib_offl_entry_t *pfx);
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || DOXYGEN
/**
* @brief Creates or gets an existing forwarding table entry by its prefix

View File

@ -269,6 +269,24 @@ void _set_rtr_adv(gnrc_netif_t *netif)
_handle_snd_mc_ra(netif);
}
void _snd_rtr_advs_drop_pfx(gnrc_netif_t *netif, const ipv6_addr_t *dst,
_nib_offl_entry_t *pfx)
{
gnrc_pktsnip_t *ext_opts = NULL;
uint32_t now = evtimer_now_msec();
DEBUG("nib: broadcasting removal of %s/%u from %u\n",
ipv6_addr_to_str(addr_str, &pfx->pfx, sizeof(addr_str)),
pfx->pfx_len, netif->pid
);
pfx->pref_until = now + 10; /* add some safety margin */
pfx->valid_until = now + 10; /* will be rounded to sec */
ext_opts = _offl_to_pio(pfx, ext_opts);
gnrc_ndp_rtr_adv_send(netif, NULL, dst, false, ext_opts);
}
static void _snd_ra(gnrc_netif_t *netif, const ipv6_addr_t *dst,
bool final, _nib_abr_entry_t *abr)
{

View File

@ -118,6 +118,16 @@ void _set_rtr_adv(gnrc_netif_t *netif);
*/
void _snd_rtr_advs(gnrc_netif_t *netif, const ipv6_addr_t *dst,
bool final);
/**
* @brief Send router advertisements to remove a prefix
*
* @param[in] netif The interface to send the router advertisement over.
* @param[in] dst Destination address for the router advertisement.
* @param[in] pfx Off-link entry of the prefix that should be removed.
*
*/
void _snd_rtr_advs_drop_pfx(gnrc_netif_t *netif, const ipv6_addr_t *dst,
_nib_offl_entry_t *pfx);
#else /* CONFIG_GNRC_IPV6_NIB_ROUTER */
#define _init_iface_router(netif) (void)netif
#define _call_route_info_cb(netif, type, ctx_addr, ctx) (void)netif; \
@ -130,6 +140,9 @@ void _snd_rtr_advs(gnrc_netif_t *netif, const ipv6_addr_t *dst,
#define _snd_rtr_advs(netif, dst, final) (void)netif; \
(void)dst; \
(void)final
#define _snd_rtr_advs_drop_pfx(netif, dst, pfx) (void)netif; \
(void)dst; \
(void)pfx;
#endif /* CONFIG_GNRC_IPV6_NIB_ROUTER */
#ifdef __cplusplus

View File

@ -1331,16 +1331,7 @@ static void _handle_pfx_timeout(_nib_offl_entry_t *pfx)
gnrc_netif_acquire(netif);
if (now >= pfx->valid_until) {
evtimer_del(&_nib_evtimer, &pfx->pfx_timeout.event);
for (int i = 0; i < CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
if (ipv6_addr_match_prefix(&netif->ipv6.addrs[i],
&pfx->pfx) >= pfx->pfx_len) {
gnrc_netif_ipv6_addr_remove_internal(netif,
&netif->ipv6.addrs[i]);
}
}
pfx->mode &= ~_PL;
_nib_offl_clear(pfx);
_nib_offl_remove_prefix(pfx);
}
else if (now >= pfx->pref_until) {
for (int i = 0; i < CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
@ -1495,10 +1486,9 @@ static void _remove_prefix(const ipv6_addr_t *pfx, unsigned pfx_len)
if ((offl->mode & _PL) &&
(offl->pfx_len == pfx_len) &&
(ipv6_addr_match_prefix(&offl->pfx, pfx) >= pfx_len)) {
_nib_pl_remove(offl);
_nib_offl_remove_prefix(offl);
}
}
return;
}
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C)

View File

@ -104,17 +104,18 @@ void gnrc_ipv6_nib_pl_del(unsigned iface,
if ((pfx_len == dst->pfx_len) &&
((iface == 0) || (iface == _nib_onl_get_if(dst->next_hop))) &&
(ipv6_addr_match_prefix(pfx, &dst->pfx) >= pfx_len)) {
_nib_pl_remove(dst);
_nib_release();
/* notify downstream nodes about the prefix removal */
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface);
if (netif) {
/* update prefixes down-stream */
_handle_snd_mc_ra(netif);
if (netif && (netif->flags & GNRC_NETIF_FLAGS_IPV6_RTR_ADV)) {
_snd_rtr_advs_drop_pfx(netif, &ipv6_addr_all_nodes_link_local, dst);
}
#endif
return;
/* remove the prefix & associated address*/
_nib_offl_remove_prefix(dst);
break;
}
}
_nib_release();