]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: terminate default vrf last 8844/head
authorStephen Worley <sworley@nvidia.com>
Thu, 10 Jun 2021 20:52:35 +0000 (16:52 -0400)
committerStephen Worley <sworley@nvidia.com>
Fri, 11 Jun 2021 15:48:23 +0000 (11:48 -0400)
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 <sworley@nvidia.com>
lib/vrf.c

index de29f45f8f1377c72a99e1ef4bf1319e71735d3b..a04f2ddeb78843b53cc716823426b507d9c9c6dd 100644 (file)
--- 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,