From 68ea1450ee9de6ecf3b14137085801a991841af5 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Thu, 10 Jun 2021 16:52:35 -0400 Subject: [PATCH] lib: terminate default vrf last Always terminate default VRF last during FRR shutdown. On shutdown we were simply looping over the RB tree and terminating VRFs from the ROOT. This is not guaranteed to be the default last ever. Instead switch to RB_SAFE and skip the default VRF till the very end. Signed-off-by: Stephen Worley --- lib/vrf.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index de29f45f8f..a04f2ddeb7 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -582,29 +582,38 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *), cmd_variable_handler_register(vrf_var_handlers); } +static void vrf_terminate_single(struct vrf *vrf) +{ + /* Clear configured flag and invoke delete. */ + UNSET_FLAG(vrf->status, VRF_CONFIGURED); + vrf_delete(vrf); +} + /* Terminate VRF module. */ void vrf_terminate(void) { - struct vrf *vrf; + struct vrf *vrf, *tmp; if (debug_vrf) zlog_debug("%s: Shutting down vrf subsystem", __func__); - while (!RB_EMPTY(vrf_id_head, &vrfs_by_id)) { - vrf = RB_ROOT(vrf_id_head, &vrfs_by_id); + RB_FOREACH_SAFE (vrf, vrf_id_head, &vrfs_by_id, tmp) { + if (vrf->vrf_id == VRF_DEFAULT) + continue; - /* Clear configured flag and invoke delete. */ - UNSET_FLAG(vrf->status, VRF_CONFIGURED); - vrf_delete(vrf); + vrf_terminate_single(vrf); } - while (!RB_EMPTY(vrf_name_head, &vrfs_by_name)) { - vrf = RB_ROOT(vrf_name_head, &vrfs_by_name); + RB_FOREACH_SAFE (vrf, vrf_name_head, &vrfs_by_name, tmp) { + if (vrf->vrf_id == VRF_DEFAULT) + continue; - /* Clear configured flag and invoke delete. */ - UNSET_FLAG(vrf->status, VRF_CONFIGURED); - vrf_delete(vrf); + vrf_terminate_single(vrf); } + + /* Finally terminate default VRF */ + vrf = vrf_lookup_by_id(VRF_DEFAULT); + vrf_terminate_single(vrf); } int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id, -- 2.39.5