diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index 955b1df9029..6b0869196d1 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -1407,13 +1407,31 @@ rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg NET_EPOCH_ENTER(et); RIB_WLOCK(rnh); - CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next); + CK_STAILQ_INSERT_HEAD(&rnh->rnh_subscribers, rs, next); RIB_WUNLOCK(rnh); NET_EPOCH_EXIT(et); return (rs); } +struct rib_subscription * +rib_subscribe_locked(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg, + enum rib_subscription_type type) +{ + struct rib_subscription *rs; + + NET_EPOCH_ASSERT(); + RIB_WLOCK_ASSERT(rnh); + + if ((rs = allocate_subscription(f, arg, type, false)) == NULL) + return (NULL); + rs->rnh = rnh; + + CK_STAILQ_INSERT_HEAD(&rnh->rnh_subscribers, rs, next); + + return (rs); +} + /* * Remove rtable subscription @rs from the routing table. * Needs to be run in network epoch. @@ -1433,6 +1451,20 @@ rib_unsibscribe(struct rib_subscription *rs) &rs->epoch_ctx); } +void +rib_unsibscribe_locked(struct rib_subscription *rs) +{ + struct rib_head *rnh = rs->rnh; + + NET_EPOCH_ASSERT(); + RIB_WLOCK_ASSERT(rnh); + + CK_STAILQ_REMOVE(&rnh->rnh_subscribers, rs, rib_subscription, next); + + epoch_call(net_epoch_preempt, destroy_subscription_epoch, + &rs->epoch_ctx); +} + /* * Epoch callback indicating subscription is safe to destroy */ diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h index ecbc9ee91dc..bd256e9f083 100644 --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -144,6 +144,9 @@ struct rib_subscription *rib_subscribe(uint32_t fibnum, int family, struct rib_subscription *rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type, bool waitok); +struct rib_subscription *rib_subscribe_locked(struct rib_head *rnh, + rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type); void rib_unsibscribe(struct rib_subscription *rs); +void rib_unsibscribe_locked(struct rib_subscription *rs); #endif