Skip to content

Commit

Permalink
zebra: fix route deletion during zebra shutdown
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
askorichenko committed Mar 12, 2024
1 parent 1942951 commit 14ec95a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 21 deletions.
49 changes: 28 additions & 21 deletions lib/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions lib/vrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ 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
*/
Expand Down
6 changes: 6 additions & 0 deletions zebra/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ static void sigint(void)
list_delete(&zrouter.client_list);
list_delete(&zrouter.stale_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.
Expand Down

0 comments on commit 14ec95a

Please sign in to comment.