diff options
author | Igor Ryzhov <iryzhov@nfware.com> | 2022-01-23 18:22:42 +0100 |
---|---|---|
committer | Igor Ryzhov <iryzhov@nfware.com> | 2022-02-01 16:20:30 +0100 |
commit | 0ef6eacc95c82014c04f13be3b641ff3983040ca (patch) | |
tree | ffbd3d6951c5baa1a955beba32891a610b5ceb1a /zebra/zebra_vrf.c | |
parent | Merge pull request #10408 from idryzhov/no-opaque-by-default (diff) | |
download | frr-0ef6eacc95c82014c04f13be3b641ff3983040ca.tar.xz frr-0ef6eacc95c82014c04f13be3b641ff3983040ca.zip |
zebra: fix cleanup of meta queues on vrf disable
Current code treats all metaqueues as lists of route_node structures.
However, some queues contain other structures that need to be cleaned up
differently. Casting the elements of those queues to struct route_node
and dereferencing them leads to a crash. The crash may be seen when
executing bgp_multi_vrf_topo2.
Fix the code by using the proper list element types.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'zebra/zebra_vrf.c')
-rw-r--r-- | zebra/zebra_vrf.c | 34 |
1 files changed, 2 insertions, 32 deletions
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 842dc3f57..f88a65d95 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -177,7 +177,6 @@ static int zebra_vrf_disable(struct vrf *vrf) struct interface *ifp; afi_t afi; safi_t safi; - unsigned i; assert(zvrf); if (IS_ZEBRA_DEBUG_EVENT) @@ -222,21 +221,7 @@ static int zebra_vrf_disable(struct vrf *vrf) if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); /* clean-up work queues */ - for (i = 0; i < MQ_SIZE; i++) { - struct listnode *lnode, *nnode; - struct route_node *rnode; - rib_dest_t *dest; - - for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode, - rnode)) { - dest = rib_dest_from_rnode(rnode); - if (dest && rib_dest_vrf(dest) == zvrf) { - route_unlock_node(rnode); - list_delete_node(zrouter.mq->subq[i], lnode); - zrouter.mq->size--; - } - } - } + rib_meta_queue_free_vrf(zrouter.mq, zvrf); /* Cleanup (free) routing tables and NHT tables. */ for (afi = AFI_IP; afi <= AFI_IP6; afi++) { @@ -262,7 +247,6 @@ static int zebra_vrf_delete(struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; struct other_route_table *otable; - unsigned i; assert(zvrf); if (IS_ZEBRA_DEBUG_EVENT) @@ -272,21 +256,7 @@ static int zebra_vrf_delete(struct vrf *vrf) table_manager_disable(zvrf); /* clean-up work queues */ - for (i = 0; i < MQ_SIZE; i++) { - struct listnode *lnode, *nnode; - struct route_node *rnode; - rib_dest_t *dest; - - for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode, - rnode)) { - dest = rib_dest_from_rnode(rnode); - if (dest && rib_dest_vrf(dest) == zvrf) { - route_unlock_node(rnode); - list_delete_node(zrouter.mq->subq[i], lnode); - zrouter.mq->size--; - } - } - } + rib_meta_queue_free_vrf(zrouter.mq, zvrf); /* Free Vxlan and MPLS. */ zebra_vxlan_close_tables(zvrf); |