]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: fix fpm crash 12003/head
authoranlan_cs <vic.lan@pica8.com>
Sat, 24 Sep 2022 23:00:14 +0000 (19:00 -0400)
committeranlan_cs <vic.lan@pica8.com>
Sat, 24 Sep 2022 23:39:58 +0000 (19:39 -0400)
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>
zebra/rib.h
zebra/zebra_fpm.c
zebra/zebra_rib.c

index dec5b2b8d6d62ca1fd64731e2b04ac927f1c4d8a..99f52bcd4e434070c3ea20ddad4a1a39645df2c7 100644 (file)
@@ -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
index 21acaa823c6231908035600ab2d37894acbb8805..1b2753377b1dac792aa4c4a3e6f30c490a630a0f 100644 (file)
@@ -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);
index bd7e8bbbd0938d5fae79331d2b04d77bf002b7e7..fceaaaa9f02633a1dd24433841dc22bdb962a1e0 100644 (file)
@@ -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);
        }