diff --git a/lib/vrf.c b/lib/vrf.c index cd0439c407d5..e907626bae59 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -326,32 +326,31 @@ void vrf_disable(struct vrf *vrf) (*vrf_master.vrf_disable_hook)(vrf); } -/* Disable VRF module. */ -void vrf_disable_all(void) +void vrf_iterate(vrf_iter_func fnc) { struct vrf *vrf, *tmp; if (debug_vrf) - zlog_debug("%s: vrf subsystem", __func__); + 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; - vrf_disable(vrf); + fnc(vrf); } RB_FOREACH_SAFE (vrf, vrf_name_head, &vrfs_by_name, tmp) { if (vrf->vrf_id == VRF_DEFAULT) continue; - vrf_disable(vrf); + fnc(vrf); } - /* Finally disable default VRF */ + /* Finally process default VRF */ vrf = vrf_lookup_by_id(VRF_DEFAULT); if (vrf) - vrf_disable(vrf); + fnc(vrf); } const char *vrf_id_to_name(vrf_id_t vrf_id) @@ -570,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 00e10690a6b5..3ebb6ddf5371 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -201,13 +201,16 @@ 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 - * 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 0ac0a1284fd3..d83f1d0491bf 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -205,7 +205,11 @@ static void sigint(void) list_delete(&zrouter.client_list); list_delete(&zrouter.stale_client_list); - vrf_disable_all(); + /* + * 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