summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2022-08-10 16:32:12 +0300
committerGitHub <noreply@github.com>2022-08-10 16:32:12 +0300
commit03efa836c6f778173849724a14f48ad6a41b834f (patch)
tree5dbb6f2a636dd2ebf0728e4e826ec199d9faec5f
parent9ad7e387be7d4745e8c12ab7ae73934d141828f8 (diff)
parent1548fbbc449583c6db859982d86fa2d30e6f66a4 (diff)
Merge pull request #11774 from donaldsharp/zebra_meta_q_shakeups
Zebra meta q shakeups
-rw-r--r--zebra/rib.h4
-rw-r--r--zebra/zapi_msg.c16
-rw-r--r--zebra/zebra_mpls.c20
-rw-r--r--zebra/zebra_mpls.h10
-rw-r--r--zebra/zebra_rib.c292
-rw-r--r--zebra/zebra_router.c2
-rw-r--r--zebra/zebra_vrf.c4
7 files changed, 177 insertions, 171 deletions
diff --git a/zebra/rib.h b/zebra/rib.h
index 60092c9632..a40843e27f 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -454,9 +454,7 @@ int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
struct in_addr vtep_ip);
-extern void meta_queue_free(struct meta_queue *mq);
-extern void rib_meta_queue_free_vrf(struct meta_queue *mq,
- struct zebra_vrf *zvrf);
+extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf);
extern int zebra_rib_labeled_unicast(struct route_entry *re);
extern struct route_table *rib_table_ipv6;
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 9895943016..a578395ef8 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2492,7 +2492,6 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
{
struct stream *s;
struct zapi_labels zl;
- int ret;
/* Get input stream. */
s = msg;
@@ -2510,12 +2509,7 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
if (zapi_labels_validate(&zl) < 0)
return;
- ret = mpls_zapi_labels_process(true, zvrf, &zl);
- if (ret < 0) {
- if (IS_ZEBRA_DEBUG_RECV)
- zlog_debug("%s: Error processing zapi request",
- __func__);
- }
+ mpls_zapi_labels_process(true, zvrf, &zl);
}
/*
@@ -2532,7 +2526,6 @@ static void zread_mpls_labels_delete(ZAPI_HANDLER_ARGS)
{
struct stream *s;
struct zapi_labels zl;
- int ret;
/* Get input stream. */
s = msg;
@@ -2547,12 +2540,7 @@ static void zread_mpls_labels_delete(ZAPI_HANDLER_ARGS)
return;
if (zl.nexthop_num > 0) {
- ret = mpls_zapi_labels_process(false /*delete*/, zvrf, &zl);
- if (ret < 0) {
- if (IS_ZEBRA_DEBUG_RECV)
- zlog_debug("%s: Error processing zapi request",
- __func__);
- }
+ mpls_zapi_labels_process(false /*delete*/, zvrf, &zl);
} else {
mpls_lsp_uninstall_all_vrf(zvrf, zl.type, zl.local_label);
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index ade381e27f..3010a516b9 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -2747,9 +2747,9 @@ static bool ftn_update_nexthop(bool add_p, struct nexthop *nexthop,
return true;
}
-int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, uint8_t route_type,
- unsigned short route_instance)
+void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, uint8_t route_type,
+ unsigned short route_instance)
{
struct route_table *table;
struct route_node *rn;
@@ -2761,7 +2761,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
/* Lookup table. */
table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
if (!table)
- return -1;
+ return;
/* Lookup existing route */
rn = route_node_get(table, prefix);
@@ -2772,7 +2772,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
break;
}
if (re == NULL)
- return -1;
+ return;
/*
* Nexthops are now shared by multiple routes, so we have to make
@@ -2801,8 +2801,6 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
zebra_nhg_free(new_nhe);
rib_queue_add(rn);
-
- return 0;
}
/*
@@ -2884,8 +2882,8 @@ static bool ftn_update_znh(bool add_p, enum lsp_types_t type,
* There are several changes that need to be made, in several zebra
* data structures, so we want to do all the work required at once.
*/
-int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
- const struct zapi_labels *zl)
+void mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
+ const struct zapi_labels *zl)
{
int i, counter, ret = 0;
char buf[NEXTHOP_STRLEN];
@@ -2906,7 +2904,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
/* Lookup table. */
lsp_table = zvrf->lsp_table;
if (!lsp_table)
- return -1;
+ return;
/* Find or create LSP object */
tmp_ile.in_label = zl->local_label;
@@ -3070,8 +3068,6 @@ znh_done:
if (new_nhe)
zebra_nhg_free(new_nhe);
-
- return ret;
}
/*
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index a7a955a80b..a114f01339 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -261,15 +261,15 @@ void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
* Handle zapi request to install/uninstall LSP and
* (optionally) FEC-To-NHLFE (FTN) bindings.
*/
-int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
- const struct zapi_labels *zl);
+void mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
+ const struct zapi_labels *zl);
/*
* Uninstall all NHLFEs bound to a single FEC.
*/
-int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, uint8_t route_type,
- unsigned short route_instance);
+void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, uint8_t route_type,
+ unsigned short route_instance);
/*
* Install/update a NHLFE for an LSP in the forwarding table. This may be
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d0babbb9e4..79eb99ddf9 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -77,51 +77,65 @@ static struct dplane_ctx_q rib_dplane_q;
DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
(rn, reason));
+/* Meta Q's specific names */
+enum meta_queue_indexes {
+ META_QUEUE_NHG,
+ META_QUEUE_EVPN,
+ META_QUEUE_CONNECTED,
+ META_QUEUE_KERNEL,
+ META_QUEUE_STATIC,
+ META_QUEUE_NOTBGP,
+ META_QUEUE_BGP,
+ META_QUEUE_OTHER,
+};
+
/* Each route type's string and default distance value. */
static const struct {
int key;
uint8_t distance;
- uint8_t meta_q_map;
+ enum meta_queue_indexes meta_q_map;
} route_info[ZEBRA_ROUTE_MAX] = {
- [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */, 0},
- [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 7},
- [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 3},
- [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 2},
- [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 4},
- [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 5},
- [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 5},
- [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 5},
- [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 5},
- [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 5},
- [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 6},
- [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 7},
- [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 5},
- [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 5},
- [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 7},
- [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 7},
- [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 4},
- [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 7},
- [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 6},
- [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 6},
- [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 6},
- [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 6},
- [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 6},
- [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 5},
- [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 7},
- [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 7},
- [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 7},
- [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 5},
- [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 7},
- [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 7},
- [ZEBRA_ROUTE_ALL] = {ZEBRA_ROUTE_ALL, 255, 7},
+ [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */,
+ META_QUEUE_NHG},
+ [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, META_QUEUE_KERNEL},
+ [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, META_QUEUE_KERNEL},
+ [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, META_QUEUE_CONNECTED},
+ [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, META_QUEUE_STATIC},
+ [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, META_QUEUE_STATIC},
+ [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115,
+ META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_ALL] = {ZEBRA_ROUTE_ALL, 255, META_QUEUE_OTHER},
/* Any new route type added to zebra, should be mirrored here */
/* no entry/default: 150 */
};
-/* EVPN/VXLAN subqueue is number 1 */
-#define META_QUEUE_EVPN 1
-
/* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
* from the OS, and an 'nhe' is a nhe update.
*/
@@ -164,24 +178,24 @@ struct wq_evpn_wrapper {
#pragma FRR printfrr_ext "%pZN" (struct route_node *)
#endif
-static const char *subqueue2str(uint8_t index)
+static const char *subqueue2str(enum meta_queue_indexes index)
{
switch (index) {
- case 0:
+ case META_QUEUE_NHG:
return "NHG Objects";
- case 1:
+ case META_QUEUE_EVPN:
return "EVPN/VxLan Objects";
- case 2:
+ case META_QUEUE_CONNECTED:
return "Connected Routes";
- case 3:
+ case META_QUEUE_KERNEL:
return "Kernel Routes";
- case 4:
+ case META_QUEUE_STATIC:
return "Static Routes";
- case 5:
+ case META_QUEUE_NOTBGP:
return "RIP/OSPF/ISIS/EIGRP/NHRP Routes";
- case 6:
+ case META_QUEUE_BGP:
return "BGP Routes";
- case 7:
+ case META_QUEUE_OTHER:
return "Other Routes";
}
@@ -2407,7 +2421,7 @@ static void process_subq_nhg(struct listnode *lnode)
struct nhg_ctx *ctx;
struct nhg_hash_entry *nhe, *newnhe;
struct wq_nhg_wrapper *w;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
w = listgetdata(lnode);
@@ -2496,19 +2510,30 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
* Examine the specified subqueue; process one entry and return 1 if
* there is a node, return 0 otherwise.
*/
-static unsigned int process_subq(struct list *subq, uint8_t qindex)
+static unsigned int process_subq(struct list *subq,
+ enum meta_queue_indexes qindex)
{
struct listnode *lnode = listhead(subq);
if (!lnode)
return 0;
- if (qindex == META_QUEUE_EVPN)
+ switch (qindex) {
+ case META_QUEUE_EVPN:
process_subq_evpn(lnode);
- else if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
+ break;
+ case META_QUEUE_NHG:
process_subq_nhg(lnode);
- else
+ break;
+ case META_QUEUE_CONNECTED:
+ case META_QUEUE_KERNEL:
+ case META_QUEUE_STATIC:
+ case META_QUEUE_NOTBGP:
+ case META_QUEUE_BGP:
+ case META_QUEUE_OTHER:
process_subq_route(lnode, qindex);
+ break;
+ }
list_delete_node(subq, lnode);
@@ -2613,7 +2638,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
{
struct nhg_ctx *ctx = NULL;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
ctx = (struct nhg_ctx *)data;
@@ -2639,7 +2664,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data)
{
struct nhg_hash_entry *nhe = NULL;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
nhe = (struct nhg_hash_entry *)data;
@@ -2933,131 +2958,130 @@ int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
return mq_add_handler(w, rib_meta_queue_evpn_add);
}
+
+/* Create new meta queue.
+ A destructor function doesn't seem to be necessary here.
+ */
+static struct meta_queue *meta_queue_new(void)
+{
+ struct meta_queue *new;
+ unsigned i;
+
+ new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
+
+ for (i = 0; i < MQ_SIZE; i++) {
+ new->subq[i] = list_new();
+ assert(new->subq[i]);
+ }
+
+ return new;
+}
+
/* Clean up the EVPN meta-queue list */
-static void evpn_meta_queue_free(struct list *l)
+static void evpn_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
- struct listnode *node;
+ struct listnode *node, *nnode;
struct wq_evpn_wrapper *w;
/* Free the node wrapper object, and the struct it wraps */
- while ((node = listhead(l)) != NULL) {
- w = node->data;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
+ if (zvrf) {
+ vrf_id_t vrf_id = zvrf->vrf->vrf_id;
+
+ if (w->vrf_id != vrf_id)
+ continue;
+ }
+
node->data = NULL;
XFREE(MTYPE_WQ_WRAPPER, w);
list_delete_node(l, node);
+ mq->size--;
}
}
/* Clean up the nhg meta-queue list */
-static void nhg_meta_queue_free(struct list *l)
+static void nhg_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
struct wq_nhg_wrapper *w;
- struct listnode *node;
+ struct listnode *node, *nnode;
/* Free the node wrapper object, and the struct it wraps */
- while ((node = listhead(l)) != NULL) {
- w = node->data;
- node->data = NULL;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
+ if (zvrf) {
+ vrf_id_t vrf_id = zvrf->vrf->vrf_id;
+ if (w->type == WQ_NHG_WRAPPER_TYPE_CTX &&
+ w->u.ctx->vrf_id != vrf_id)
+ continue;
+ else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG &&
+ w->u.nhe->vrf_id != vrf_id)
+ continue;
+ }
if (w->type == WQ_NHG_WRAPPER_TYPE_CTX)
nhg_ctx_free(&w->u.ctx);
else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG)
zebra_nhg_free(w->u.nhe);
+ node->data = NULL;
XFREE(MTYPE_WQ_WRAPPER, w);
list_delete_node(l, node);
+ mq->size--;
}
}
-/* Create new meta queue.
- A destructor function doesn't seem to be necessary here.
- */
-static struct meta_queue *meta_queue_new(void)
+static void rib_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
- struct meta_queue *new;
- unsigned i;
-
- new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
-
- for (i = 0; i < MQ_SIZE; i++) {
- new->subq[i] = list_new();
- assert(new->subq[i]);
- }
+ struct route_node *rnode;
+ struct listnode *node, *nnode;
- return new;
-}
-
-void meta_queue_free(struct meta_queue *mq)
-{
- unsigned i;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, rnode)) {
+ rib_dest_t *dest = rib_dest_from_rnode(rnode);
- for (i = 0; i < MQ_SIZE; i++) {
- /* Some subqueues may need cleanup - nhgs for example */
- if (i == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
- nhg_meta_queue_free(mq->subq[i]);
- else if (i == META_QUEUE_EVPN)
- evpn_meta_queue_free(mq->subq[i]);
+ if (dest && rib_dest_vrf(dest) != zvrf)
+ continue;
- list_delete(&mq->subq[i]);
+ route_unlock_node(rnode);
+ node->data = NULL;
+ list_delete_node(l, node);
+ mq->size--;
}
-
- XFREE(MTYPE_WORK_QUEUE, mq);
}
-void rib_meta_queue_free_vrf(struct meta_queue *mq, struct zebra_vrf *zvrf)
+
+void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
{
- vrf_id_t vrf_id = zvrf->vrf->vrf_id;
- unsigned int i;
+ enum meta_queue_indexes i;
for (i = 0; i < MQ_SIZE; i++) {
- struct listnode *lnode, *nnode;
- void *data;
- bool del;
-
- for (ALL_LIST_ELEMENTS(mq->subq[i], lnode, nnode, data)) {
- del = false;
-
- if (i == META_QUEUE_EVPN) {
- struct wq_evpn_wrapper *w = data;
-
- if (w->vrf_id == vrf_id) {
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- }
- } else if (i ==
- route_info[ZEBRA_ROUTE_NHG].meta_q_map) {
- struct wq_nhg_wrapper *w = data;
-
- if (w->type == WQ_NHG_WRAPPER_TYPE_CTX &&
- w->u.ctx->vrf_id == vrf_id) {
- nhg_ctx_free(&w->u.ctx);
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- } else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG &&
- w->u.nhe->vrf_id == vrf_id) {
- zebra_nhg_free(w->u.nhe);
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- }
- } else {
- struct route_node *rnode = data;
- rib_dest_t *dest = rib_dest_from_rnode(rnode);
-
- if (dest && rib_dest_vrf(dest) == zvrf) {
- route_unlock_node(rnode);
- del = true;
- }
- }
-
- if (del) {
- list_delete_node(mq->subq[i], lnode);
- mq->size--;
- }
+ /* Some subqueues may need cleanup - nhgs for example */
+ switch (i) {
+ case META_QUEUE_NHG:
+ nhg_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
+ case META_QUEUE_EVPN:
+ evpn_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
+ case META_QUEUE_CONNECTED:
+ case META_QUEUE_KERNEL:
+ case META_QUEUE_STATIC:
+ case META_QUEUE_NOTBGP:
+ case META_QUEUE_BGP:
+ case META_QUEUE_OTHER:
+ rib_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
}
+ if (!zvrf)
+ list_delete(&mq->subq[i]);
}
+
+ if (!zvrf)
+ XFREE(MTYPE_WORK_QUEUE, mq);
}
/* initialise zebra rib work queue */
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 24e71b4a8b..c66849863e 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -239,7 +239,7 @@ void zebra_router_terminate(void)
zebra_router_free_table(zrt);
work_queue_free_and_null(&zrouter.ribq);
- meta_queue_free(zrouter.mq);
+ meta_queue_free(zrouter.mq, NULL);
zebra_vxlan_disable();
zebra_mlag_terminate();
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 553864d089..6624f0beb9 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -218,7 +218,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
/* clean-up work queues */
- rib_meta_queue_free_vrf(zrouter.mq, zvrf);
+ meta_queue_free(zrouter.mq, zvrf);
/* Cleanup (free) routing tables and NHT tables. */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
@@ -253,7 +253,7 @@ static int zebra_vrf_delete(struct vrf *vrf)
table_manager_disable(zvrf);
/* clean-up work queues */
- rib_meta_queue_free_vrf(zrouter.mq, zvrf);
+ meta_queue_free(zrouter.mq, zvrf);
/* Free Vxlan and MPLS. */
zebra_vxlan_close_tables(zvrf);