diff --git a/zebra/rib.h b/zebra/rib.h index dec5b2b8d6..99f52bcd4e 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -585,6 +585,7 @@ static inline void rib_tables_iter_cleanup(rib_tables_iter_t *iter) DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason), (rn, reason)); +DECLARE_HOOK(rib_shutdown, (struct route_node * rn), (rn)); /* * Access installed/fib nexthops, which may be a subset of the diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 21acaa823c..1b2753377b 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -1477,6 +1477,32 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason) return 0; } +/* + * zfpm_trigger_remove + * + * The zebra code invokes this function to indicate that we should + * send an remove to the FPM about the given route_node. + */ + +static int zfpm_trigger_remove(struct route_node *rn) +{ + rib_dest_t *dest; + + if (!zfpm_conn_is_up()) + return 0; + + dest = rib_dest_from_rnode(rn); + if (!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)) + return 0; + + zfpm_debug("%pRN Removing from update queue shutting down", rn); + + UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM); + TAILQ_REMOVE(&zfpm_g->dest_q, dest, fpm_q_entries); + + return 0; +} + /* * Generate Key for FPM MAC info hash entry */ @@ -2036,6 +2062,7 @@ static int zfpm_fini(void) static int zebra_fpm_module_init(void) { hook_register(rib_update, zfpm_trigger_update); + hook_register(rib_shutdown, zfpm_trigger_remove); hook_register(zebra_rmac_update, zfpm_trigger_rmac_update); hook_register(frr_late_init, zfpm_init); hook_register(frr_early_fini, zfpm_fini); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index bd7e8bbbd0..fceaaaa9f0 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -76,6 +76,8 @@ static struct dplane_ctx_q rib_dplane_q; DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), (rn, reason)); +DEFINE_HOOK(rib_shutdown, (struct route_node * rn), (rn)); + /* Meta Q's specific names */ enum meta_queue_indexes { @@ -944,6 +946,9 @@ void zebra_rtable_node_cleanup(struct route_table *table, if (node->info) { rib_dest_t *dest = node->info; + /* Remove from update queue of FPM module */ + hook_call(rib_shutdown, node); + rnh_list_fini(&dest->nht); XFREE(MTYPE_RIB_DEST, node->info); }