From 0ef6eacc95c82014c04f13be3b641ff3983040ca Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Sun, 23 Jan 2022 20:22:42 +0300 Subject: 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 --- zebra/zebra_vrf.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) (limited to 'zebra/zebra_vrf.c') 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); -- cgit v1.2.3