Index: sys/net/route.c =================================================================== --- sys/net/route.c +++ sys/net/route.c @@ -348,7 +348,7 @@ nhops_init_rib(rh); /* Init subscription system */ - CK_STAILQ_INIT(&rh->rnh_subscribers); + rib_init_subscriptions(rh); /* Finally, set base callbacks */ rh->rnh_addaddr = rn_addroute; @@ -382,6 +382,8 @@ rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head); nhops_destroy_rib(rh); + + rib_destroy_subscriptions(rh); /* Assume table is already empty */ RIB_LOCK_DESTROY(rh); Index: sys/net/route/route_ctl.c =================================================================== --- sys/net/route/route_ctl.c +++ sys/net/route/route_ctl.c @@ -847,3 +847,29 @@ free(rs, M_RTABLE); } + +void +rib_init_subscriptions(struct rib_head *rnh) +{ + + CK_STAILQ_INIT(&rnh->rnh_subscribers); +} + +void +rib_destroy_subscriptions(struct rib_head *rnh) +{ + struct rib_subscription *rs; + struct epoch_tracker et; + + NET_EPOCH_ENTER(et); + RIB_WLOCK(rnh); + while ((rs = CK_STAILQ_FIRST(&rnh->rnh_subscribers)) != NULL) { + CK_STAILQ_REMOVE_HEAD(&rnh->rnh_subscribers, next); + epoch_call(net_epoch_preempt, destroy_subscription_epoch, + &rs->epoch_ctx); + } + RIB_WUNLOCK(rnh); + NET_EPOCH_EXIT(et); +} + + Index: sys/net/route/shared.h =================================================================== --- sys/net/route/shared.h +++ sys/net/route/shared.h @@ -67,6 +67,10 @@ void nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu); int nhops_dump_sysctl(struct rib_head *rh, struct sysctl_req *w); +/* subscriptions */ +void rib_init_subscriptions(struct rib_head *rnh); +void rib_destroy_subscriptions(struct rib_head *rnh); + /* route */ VNET_DECLARE(uma_zone_t, rtzone); /* Routing table UMA zone. */ #define V_rtzone VNET(rtzone)