diff options
| author | anlan_cs <vic.lan@pica8.com> | 2022-09-24 19:00:14 -0400 |
|---|---|---|
| committer | anlan_cs <vic.lan@pica8.com> | 2022-09-24 19:39:58 -0400 |
| commit | 0d0f516c76eef90d2f9e0e5c4d1472b78b24991c (patch) | |
| tree | 16a74d5de482d5c9b9067df26f2295a275c5e57e /zebra/zebra_fpm.c | |
| parent | 344d81ceedd37702503baceece3acb1cde788018 (diff) | |
zebra: fix fpm crash
Fix issue#11996.
When removing VRF ( all routes of this VRF), zebra mistakenly forgot to check
whether its routes are in update queue of FPM. So FPM module will crash during
its dealing with these routes, which are already freed.
Add a new HOOK `rib_shutdown()`, `zebra_rtable_node_cleanup()` will use it
to remove these routes from update queue of FPM module before freeing them.
Signed-off-by: anlan_cs <vic.lan@pica8.com>
Diffstat (limited to 'zebra/zebra_fpm.c')
| -rw-r--r-- | zebra/zebra_fpm.c | 27 |
1 files changed, 27 insertions, 0 deletions
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 @@ -1478,6 +1478,32 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason) } /* + * 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 */ static unsigned int zfpm_mac_info_hash_keymake(const void *p) @@ -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); |
