]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: fix route deletion during zebra shutdown 15569/head
authorAlexander Skorichenko <askorichenko@netgate.com>
Wed, 28 Feb 2024 19:34:06 +0000 (20:34 +0100)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Mon, 18 Mar 2024 11:45:05 +0000 (11:45 +0000)
Split zebra's vrf_terminate() into disable() and delete() stages.
The former enqueues all events for the dplane thread.
Memory freeing is performed in the second stage.

Signed-off-by: Alexander Skorichenko <askorichenko@netgate.com>
(cherry picked from commit 444ce317b2af491b5cdc321286772627a5d4c8ea)

lib/vrf.c
lib/vrf.h
zebra/main.c

index 9f4c5cdddc4b1c43d7a776026db6531ac72d42ee..e907626bae59d9ea463f3ac145111cc5f2bab9bc 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -326,6 +326,33 @@ void vrf_disable(struct vrf *vrf)
                (*vrf_master.vrf_disable_hook)(vrf);
 }
 
+void vrf_iterate(vrf_iter_func fnc)
+{
+       struct vrf *vrf, *tmp;
+
+       if (debug_vrf)
+               zlog_debug("%s:  vrf subsystem iteration", __func__);
+
+       RB_FOREACH_SAFE (vrf, vrf_id_head, &vrfs_by_id, tmp) {
+               if (vrf->vrf_id == VRF_DEFAULT)
+                       continue;
+
+               fnc(vrf);
+       }
+
+       RB_FOREACH_SAFE (vrf, vrf_name_head, &vrfs_by_name, tmp) {
+               if (vrf->vrf_id == VRF_DEFAULT)
+                       continue;
+
+               fnc(vrf);
+       }
+
+       /* Finally process default VRF */
+       vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       if (vrf)
+               fnc(vrf);
+}
+
 const char *vrf_id_to_name(vrf_id_t vrf_id)
 {
        struct vrf *vrf;
@@ -542,32 +569,12 @@ static void vrf_terminate_single(struct vrf *vrf)
        vrf_delete(vrf);
 }
 
-/* Terminate VRF module. */
 void vrf_terminate(void)
 {
-       struct vrf *vrf, *tmp;
-
        if (debug_vrf)
                zlog_debug("%s: Shutting down vrf subsystem", __func__);
 
-       RB_FOREACH_SAFE (vrf, vrf_id_head, &vrfs_by_id, tmp) {
-               if (vrf->vrf_id == VRF_DEFAULT)
-                       continue;
-
-               vrf_terminate_single(vrf);
-       }
-
-       RB_FOREACH_SAFE (vrf, vrf_name_head, &vrfs_by_name, tmp) {
-               if (vrf->vrf_id == VRF_DEFAULT)
-                       continue;
-
-               vrf_terminate_single(vrf);
-       }
-
-       /* Finally terminate default VRF */
-       vrf = vrf_lookup_by_id(VRF_DEFAULT);
-       if (vrf)
-               vrf_terminate_single(vrf);
+       vrf_iterate(vrf_terminate_single);
 }
 
 int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
index 4277a51bb1b8be863f23535f6d0770462cfe0397..3ebb6ddf53712bbf5f5283178b483c63c65db33e 100644 (file)
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -201,6 +201,12 @@ extern void vrf_init(int (*create)(struct vrf *vrf),
                     int (*disable)(struct vrf *vrf),
                     int (*destroy)(struct vrf *vrf));
 
+/*
+ * Iterate over custom VRFs and round up by processing the default VRF.
+ */
+typedef void (*vrf_iter_func)(struct vrf *vrf);
+extern void vrf_iterate(vrf_iter_func fnc);
+
 /*
  * Call vrf_terminate when the protocol is being shutdown
  */
index 606ecc72796463bfb4387b79667fdf91d5d51cbb..27e05e7335f310eee6f153cf645b9b1da5bbc9c5 100644 (file)
@@ -204,6 +204,12 @@ static void sigint(void)
 
        list_delete(&zrouter.client_list);
 
+       /*
+        * Besides other clean-ups zebra's vrf_disable() also enqueues installed
+        * routes for removal from the kernel, unless ZEBRA_VRF_RETAIN is set.
+        */
+       vrf_iterate(vrf_disable);
+
        /* Indicate that all new dplane work has been enqueued. When that
         * work is complete, the dataplane will enqueue an event
         * with the 'finalize' function.