Index: sys/netinet6/nd6.h =================================================================== --- sys/netinet6/nd6.h +++ sys/netinet6/nd6.h @@ -216,6 +216,7 @@ /* Prefix status */ #define NDPRF_ONLINK 0x1 #define NDPRF_DETACHED 0x2 +#define NDPRF_DYING 0x4 /* protocol constants */ #define MAX_RTR_SOLICITATION_DELAY 1 /* 1sec */ Index: sys/netinet6/nd6_rtr.c =================================================================== --- sys/netinet6/nd6_rtr.c +++ sys/netinet6/nd6_rtr.c @@ -1136,7 +1136,8 @@ ND6_UNLOCK_ASSERT(); ND6_RLOCK(); - if (pfxrtr_lookup(pr, dr) != NULL) { + if (pfxrtr_lookup(pr, dr) != NULL && + (pr->ndpr_stateflags & NDPRF_DYING) == 0) { ND6_RUNLOCK(); return; } @@ -1149,7 +1150,8 @@ new->router = dr; ND6_WLOCK(); - if (pfxrtr_lookup(pr, dr) == NULL) { + if (pfxrtr_lookup(pr, dr) == NULL && + (pr->ndpr_stateflags & NDPRF_DYING) == 0) { LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry); update = true; } else { @@ -1217,6 +1219,8 @@ { if (refcount_release(&pr->ndpr_refcnt)) { + KASSERT(pr->ndpr_stateflags & NDPRF_DYING, + ("prefix %p not marked as dying", pr)); KASSERT(LIST_EMPTY(&pr->ndpr_advrtrs), ("prefix %p has advertising routers", pr)); free(pr, M_IP6NDP); @@ -1295,6 +1299,7 @@ ND6_WLOCK_ASSERT(); LIST_REMOVE(pr, ndpr_entry); + pr->ndpr_stateflags |= NDPRF_DYING; V_nd6_list_genid++; if (list != NULL) LIST_INSERT_HEAD(list, pr, ndpr_entry);