summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Stapp <mjs.ietf@gmail.com>2024-03-18 13:06:18 -0400
committerGitHub <noreply@github.com>2024-03-18 13:06:18 -0400
commit2437d09b0dabedc114c48d89dedee57269a911a5 (patch)
tree44ecf8d44f20b1d8e67dfbc9bba8bf70996222df
parenta0153fff1849c146279cc7555eb28ab6e1fef620 (diff)
parente5e564a4217697aa13148cfc4dccd773dd7c5fc5 (diff)
Merge pull request #15569 from FRRouting/mergify/bp/dev/10.0/pr-15424
zebra: fix route deletion during zebra shutdown (backport #15424)
-rw-r--r--lib/vrf.c49
-rw-r--r--lib/vrf.h6
-rw-r--r--zebra/main.c6
3 files changed, 40 insertions, 21 deletions
diff --git a/lib/vrf.c b/lib/vrf.c
index 9f4c5cdddc..e907626bae 100644
--- 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,
diff --git a/lib/vrf.h b/lib/vrf.h
index 4277a51bb1..3ebb6ddf53 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -202,6 +202,12 @@ extern void vrf_init(int (*create)(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
*/
extern void vrf_terminate(void);
diff --git a/zebra/main.c b/zebra/main.c
index 606ecc7279..27e05e7335 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -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.