From a290fc1ba078d676a5237b635545e6ca5481300e Mon Sep 17 00:00:00 2001 From: Alexander Skorichenko Date: Wed, 28 Feb 2024 20:34:06 +0100 Subject: [PATCH] zebra: fix route deletion during zebra shutdown 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 --- lib/vrf.c | 28 ++++++++++++++++++++++++++++ lib/vrf.h | 3 +++ zebra/main.c | 2 ++ 3 files changed, 33 insertions(+) diff --git a/lib/vrf.c b/lib/vrf.c index 9f4c5cdddc4b..cd0439c407d5 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -326,6 +326,34 @@ void vrf_disable(struct vrf *vrf) (*vrf_master.vrf_disable_hook)(vrf); } +/* Disable VRF module. */ +void vrf_disable_all(void) +{ + struct vrf *vrf, *tmp; + + if (debug_vrf) + zlog_debug("%s: vrf subsystem", __func__); + + RB_FOREACH_SAFE (vrf, vrf_id_head, &vrfs_by_id, tmp) { + if (vrf->vrf_id == VRF_DEFAULT) + continue; + + vrf_disable(vrf); + } + + RB_FOREACH_SAFE (vrf, vrf_name_head, &vrfs_by_name, tmp) { + if (vrf->vrf_id == VRF_DEFAULT) + continue; + + vrf_disable(vrf); + } + + /* Finally disable default VRF */ + vrf = vrf_lookup_by_id(VRF_DEFAULT); + if (vrf) + vrf_disable(vrf); +} + const char *vrf_id_to_name(vrf_id_t vrf_id) { struct vrf *vrf; diff --git a/lib/vrf.h b/lib/vrf.h index 4277a51bb1b8..00e10690a6b5 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -203,8 +203,11 @@ extern void vrf_init(int (*create)(struct vrf *vrf), /* * Call vrf_terminate when the protocol is being shutdown + * it implements disable() and destroy() hooks + * vrf_disable_all does disable() only */ extern void vrf_terminate(void); +extern void vrf_disable_all(void); /* * Utilities to create networks objects, diff --git a/zebra/main.c b/zebra/main.c index 27e98ed999f1..0ac0a1284fd3 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -205,6 +205,8 @@ static void sigint(void) list_delete(&zrouter.client_list); list_delete(&zrouter.stale_client_list); + vrf_disable_all(); + /* Indicate that all new dplane work has been enqueued. When that * work is complete, the dataplane will enqueue an event * with the 'finalize' function.