summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2022-08-09 13:09:16 -0400
committerDonald Sharp <sharpd@nvidia.com>2022-08-10 07:14:43 -0400
commita310ebc114af2f211e493ec29817b3debab2561a (patch)
treefda48a45b2f41316b48488affe0e515f32417efa /zebra/zebra_rib.c
parent57a552457855deb005ab5b5f6b2a2ddfe7e3d7ec (diff)
zebra: Combine meta_queue_free and meta_queue_vrf_free functions
These functions essentially do the same thing. Combine them for the goodness of mankind. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c158
1 files changed, 68 insertions, 90 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 2651eab164..79eb99ddf9 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2958,64 +2958,103 @@ 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;
+ struct route_node *rnode;
+ struct listnode *node, *nnode;
- new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
+ for (ALL_LIST_ELEMENTS(l, node, nnode, rnode)) {
+ rib_dest_t *dest = rib_dest_from_rnode(rnode);
- for (i = 0; i < MQ_SIZE; i++) {
- new->subq[i] = list_new();
- assert(new->subq[i]);
- }
+ if (dest && rib_dest_vrf(dest) != zvrf)
+ continue;
- return new;
+ route_unlock_node(rnode);
+ node->data = NULL;
+ list_delete_node(l, node);
+ mq->size--;
+ }
}
-void meta_queue_free(struct meta_queue *mq)
+
+void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
{
enum meta_queue_indexes i;
@@ -3023,10 +3062,10 @@ void meta_queue_free(struct meta_queue *mq)
/* Some subqueues may need cleanup - nhgs for example */
switch (i) {
case META_QUEUE_NHG:
- nhg_meta_queue_free(mq->subq[i]);
+ nhg_meta_queue_free(mq, mq->subq[i], zvrf);
break;
case META_QUEUE_EVPN:
- evpn_meta_queue_free(mq->subq[i]);
+ evpn_meta_queue_free(mq, mq->subq[i], zvrf);
break;
case META_QUEUE_CONNECTED:
case META_QUEUE_KERNEL:
@@ -3034,76 +3073,15 @@ void meta_queue_free(struct meta_queue *mq)
case META_QUEUE_NOTBGP:
case META_QUEUE_BGP:
case META_QUEUE_OTHER:
+ rib_meta_queue_free(mq, mq->subq[i], zvrf);
break;
}
- list_delete(&mq->subq[i]);
+ if (!zvrf)
+ list_delete(&mq->subq[i]);
}
- XFREE(MTYPE_WORK_QUEUE, mq);
-}
-
-void rib_meta_queue_free_vrf(struct meta_queue *mq, struct zebra_vrf *zvrf)
-{
- vrf_id_t vrf_id = zvrf->vrf->vrf_id;
- 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;
-
- switch (i) {
- case META_QUEUE_EVPN: {
- struct wq_evpn_wrapper *w = data;
-
- if (w->vrf_id == vrf_id) {
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- }
- break;
- }
- case META_QUEUE_NHG: {
- 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;
- }
- 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: {
- 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;
- }
- break;
- }
- }
-
- if (del) {
- list_delete_node(mq->subq[i], lnode);
- mq->size--;
- }
- }
- }
+ if (!zvrf)
+ XFREE(MTYPE_WORK_QUEUE, mq);
}
/* initialise zebra rib work queue */