diff options
| author | Mark Stapp <mjs.ietf@gmail.com> | 2024-03-18 13:06:18 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-18 13:06:18 -0400 | 
| commit | 2437d09b0dabedc114c48d89dedee57269a911a5 (patch) | |
| tree | 44ecf8d44f20b1d8e67dfbc9bba8bf70996222df | |
| parent | a0153fff1849c146279cc7555eb28ab6e1fef620 (diff) | |
| parent | e5e564a4217697aa13148cfc4dccd773dd7c5fc5 (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.c | 49 | ||||
| -rw-r--r-- | lib/vrf.h | 6 | ||||
| -rw-r--r-- | zebra/main.c | 6 | 
3 files changed, 40 insertions, 21 deletions
@@ -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, @@ -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.  | 
