]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: dataplane context reset and init apis
authorMark Stapp <mjs@voltanet.io>
Tue, 10 Dec 2019 19:53:46 +0000 (14:53 -0500)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Tue, 14 Apr 2020 14:44:39 +0000 (11:44 -0300)
Add a public reset api, so a context can be reset and reused;
add apis to init a context for a route or mac update.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
zebra/zebra_dplane.c
zebra/zebra_dplane.h

index a2365ee76b1bd4faa4e8da2e138702cd78f67b50..dde572df93301afe6586ae41e432b1dc6654bb4a 100644 (file)
@@ -401,7 +401,7 @@ static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw,
 static enum zebra_dplane_result intf_addr_update_internal(
        const struct interface *ifp, const struct connected *ifc,
        enum dplane_op_e op);
-static enum zebra_dplane_result mac_update_internal(
+static enum zebra_dplane_result mac_update_common(
        enum dplane_op_e op, const struct interface *ifp,
        const struct interface *br_ifp,
        vlanid_t vid, const struct ethaddr *mac,
@@ -445,23 +445,15 @@ void dplane_enable_sys_route_notifs(void)
 }
 
 /*
- * Free a dataplane results context.
+ * Clean up dependent/internal allocations inside a context object
  */
-static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
+static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
 {
-       if (pctx == NULL)
-               return;
-
-       DPLANE_CTX_VALID(*pctx);
-
-       /* TODO -- just freeing memory, but would like to maintain
-        * a pool
-        */
-
-       /* Some internal allocations may need to be freed, depending on
+       /*
+        * Some internal allocations may need to be freed, depending on
         * the type of info captured in the ctx.
         */
-       switch ((*pctx)->zd_op) {
+       switch (ctx->zd_op) {
        case DPLANE_OP_ROUTE_INSTALL:
        case DPLANE_OP_ROUTE_UPDATE:
        case DPLANE_OP_ROUTE_DELETE:
@@ -470,33 +462,33 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_ROUTE_NOTIFY:
 
                /* Free allocated nexthops */
-               if ((*pctx)->u.rinfo.zd_ng.nexthop) {
+               if (ctx->u.rinfo.zd_ng.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.rinfo.zd_ng.nexthop);
+                       nexthops_free(ctx->u.rinfo.zd_ng.nexthop);
 
-                       (*pctx)->u.rinfo.zd_ng.nexthop = NULL;
+                       ctx->u.rinfo.zd_ng.nexthop = NULL;
                }
 
                /* Free backup info also (if present) */
-               if ((*pctx)->u.rinfo.backup_ng.nexthop) {
+               if (ctx->u.rinfo.backup_ng.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.rinfo.backup_ng.nexthop);
+                       nexthops_free(ctx->u.rinfo.backup_ng.nexthop);
 
-                       (*pctx)->u.rinfo.backup_ng.nexthop = NULL;
+                       ctx->u.rinfo.backup_ng.nexthop = NULL;
                }
 
-               if ((*pctx)->u.rinfo.zd_old_ng.nexthop) {
+               if (ctx->u.rinfo.zd_old_ng.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.rinfo.zd_old_ng.nexthop);
+                       nexthops_free(ctx->u.rinfo.zd_old_ng.nexthop);
 
-                       (*pctx)->u.rinfo.zd_old_ng.nexthop = NULL;
+                       ctx->u.rinfo.zd_old_ng.nexthop = NULL;
                }
 
-               if ((*pctx)->u.rinfo.old_backup_ng.nexthop) {
+               if (ctx->u.rinfo.old_backup_ng.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.rinfo.old_backup_ng.nexthop);
+                       nexthops_free(ctx->u.rinfo.old_backup_ng.nexthop);
 
-                       (*pctx)->u.rinfo.old_backup_ng.nexthop = NULL;
+                       ctx->u.rinfo.old_backup_ng.nexthop = NULL;
                }
 
                break;
@@ -504,11 +496,11 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_NH_INSTALL:
        case DPLANE_OP_NH_UPDATE:
        case DPLANE_OP_NH_DELETE: {
-               if ((*pctx)->u.rinfo.nhe.ng.nexthop) {
+               if (ctx->u.rinfo.nhe.ng.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.rinfo.nhe.ng.nexthop);
+                       nexthops_free(ctx->u.rinfo.nhe.ng.nexthop);
 
-                       (*pctx)->u.rinfo.nhe.ng.nexthop = NULL;
+                       ctx->u.rinfo.nhe.ng.nexthop = NULL;
                }
                break;
        }
@@ -521,7 +513,7 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
                zebra_nhlfe_t *nhlfe, *next;
 
                /* Free allocated NHLFEs */
-               for (nhlfe = (*pctx)->u.lsp.nhlfe_list; nhlfe; nhlfe = next) {
+               for (nhlfe = ctx->u.lsp.nhlfe_list; nhlfe; nhlfe = next) {
                        next = nhlfe->next;
 
                        zebra_mpls_nhlfe_del(nhlfe);
@@ -530,8 +522,8 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
                /* Clear pointers in lsp struct, in case we're cacheing
                 * free context structs.
                 */
-               (*pctx)->u.lsp.nhlfe_list = NULL;
-               (*pctx)->u.lsp.best_nhlfe = NULL;
+               ctx->u.lsp.nhlfe_list = NULL;
+               ctx->u.lsp.best_nhlfe = NULL;
 
                break;
        }
@@ -539,21 +531,21 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_PW_INSTALL:
        case DPLANE_OP_PW_UNINSTALL:
                /* Free allocated nexthops */
-               if ((*pctx)->u.pw.nhg.nexthop) {
+               if (ctx->u.pw.nhg.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free((*pctx)->u.pw.nhg.nexthop);
+                       nexthops_free(ctx->u.pw.nhg.nexthop);
 
-                       (*pctx)->u.pw.nhg.nexthop = NULL;
+                       ctx->u.pw.nhg.nexthop = NULL;
                }
                break;
 
        case DPLANE_OP_ADDR_INSTALL:
        case DPLANE_OP_ADDR_UNINSTALL:
                /* Maybe free label string, if allocated */
-               if ((*pctx)->u.intf.label != NULL &&
-                   (*pctx)->u.intf.label != (*pctx)->u.intf.label_buf) {
-                       free((*pctx)->u.intf.label);
-                       (*pctx)->u.intf.label = NULL;
+               if (ctx->u.intf.label != NULL &&
+                   ctx->u.intf.label != ctx->u.intf.label_buf) {
+                       free(ctx->u.intf.label);
+                       ctx->u.intf.label = NULL;
                }
                break;
 
@@ -567,10 +559,40 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_NONE:
                break;
        }
+}
+
+/*
+ * Free a dataplane results context.
+ */
+static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
+{
+       if (pctx == NULL)
+               return;
+
+       DPLANE_CTX_VALID(*pctx);
+
+       /* TODO -- just freeing memory, but would like to maintain
+        * a pool
+        */
+
+       /* Some internal allocations may need to be freed, depending on
+        * the type of info captured in the ctx.
+        */
+       dplane_ctx_free_internal(*pctx);
 
        XFREE(MTYPE_DP_CTX, *pctx);
 }
 
+/*
+ * Reset an allocated context object for re-use. All internal allocations are
+ * freed and the context is memset.
+ */
+void dplane_ctx_reset(struct zebra_dplane_ctx *ctx)
+{
+       dplane_ctx_free_internal(ctx);
+       memset(ctx, 0, sizeof(*ctx));
+}
+
 /*
  * Return a context block to the dplane module after processing
  */
@@ -2470,8 +2492,8 @@ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
        enum zebra_dplane_result result;
 
        /* Use common helper api */
-       result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp,
-                                    vid, mac, vtep_ip, sticky);
+       result = mac_update_common(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp,
+                                  vid, mac, vtep_ip, sticky);
        return result;
 }
 
@@ -2487,41 +2509,25 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
        enum zebra_dplane_result result;
 
        /* Use common helper api */
-       result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp,
-                                    vid, mac, vtep_ip, false);
+       result = mac_update_common(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp,
+                                  vid, mac, vtep_ip, false);
        return result;
 }
 
 /*
- * Common helper api for MAC address/vxlan updates
+ * Public api to init an empty context - either newly-allocated or
+ * reset/cleared - for a MAC update.
  */
-static enum zebra_dplane_result
-mac_update_internal(enum dplane_op_e op,
-                   const struct interface *ifp,
-                   const struct interface *br_ifp,
-                   vlanid_t vid,
-                   const struct ethaddr *mac,
-                   struct in_addr vtep_ip,
-                   bool sticky)
+void dplane_mac_init(struct zebra_dplane_ctx *ctx,
+                    const struct interface *ifp,
+                    const struct interface *br_ifp,
+                    vlanid_t vid,
+                    const struct ethaddr *mac,
+                    struct in_addr vtep_ip,
+                    bool sticky)
 {
-       enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
-       int ret;
-       struct zebra_dplane_ctx *ctx = NULL;
        struct zebra_ns *zns;
 
-       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-               char buf1[ETHER_ADDR_STRLEN], buf2[PREFIX_STRLEN];
-
-               zlog_debug("init mac ctx %s: mac %s, ifp %s, vtep %s",
-                          dplane_op2str(op),
-                          prefix_mac2str(mac, buf1, sizeof(buf1)),
-                          ifp->name,
-                          inet_ntop(AF_INET, &vtep_ip, buf2, sizeof(buf2)));
-       }
-
-       ctx = dplane_ctx_alloc();
-
-       ctx->zd_op = op;
        ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
        ctx->zd_vrf_id = ifp->vrf_id;
 
@@ -2539,6 +2545,39 @@ mac_update_internal(enum dplane_op_e op,
        ctx->u.macinfo.mac = *mac;
        ctx->u.macinfo.vid = vid;
        ctx->u.macinfo.is_sticky = sticky;
+}
+
+/*
+ * Common helper api for MAC address/vxlan updates
+ */
+static enum zebra_dplane_result
+mac_update_common(enum dplane_op_e op,
+                 const struct interface *ifp,
+                 const struct interface *br_ifp,
+                 vlanid_t vid,
+                 const struct ethaddr *mac,
+                 struct in_addr vtep_ip,
+                 bool sticky)
+{
+       enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+       int ret;
+       struct zebra_dplane_ctx *ctx = NULL;
+
+       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
+               char buf1[ETHER_ADDR_STRLEN], buf2[PREFIX_STRLEN];
+
+               zlog_debug("init mac ctx %s: mac %s, ifp %s, vtep %s",
+                          dplane_op2str(op),
+                          prefix_mac2str(mac, buf1, sizeof(buf1)),
+                          ifp->name,
+                          inet_ntop(AF_INET, &vtep_ip, buf2, sizeof(buf2)));
+       }
+
+       ctx = dplane_ctx_alloc();
+       ctx->zd_op = op;
+
+       /* Common init for the ctx */
+       dplane_mac_init(ctx, ifp, br_ifp, vid, mac, vtep_ip, sticky);
 
        /* Enqueue for processing on the dplane pthread */
        ret = dplane_update_enqueue(ctx);
index 9ce4df197c3f6eebc5684646dd6bb68ee00642d8..9fe8b3b513da37200c367016aba66bef55c6b2b4 100644 (file)
@@ -180,6 +180,12 @@ TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx);
 /* Allocate a context object */
 struct zebra_dplane_ctx *dplane_ctx_alloc(void);
 
+/*
+ * Reset an allocated context object for re-use. All internal allocations are
+ * freed.
+ */
+void dplane_ctx_reset(struct zebra_dplane_ctx *ctx);
+
 /* Return a dataplane results context block after use; the caller's pointer will
  * be cleared.
  */
@@ -451,6 +457,15 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
                                        const struct ethaddr *mac,
                                        struct in_addr vtep_ip);
 
+/* Helper api to init an empty or new context for a MAC update */
+void dplane_mac_init(struct zebra_dplane_ctx *ctx,
+                    const struct interface *ifp,
+                    const struct interface *br_ifp,
+                    vlanid_t vid,
+                    const struct ethaddr *mac,
+                    struct in_addr vtep_ip,
+                    bool sticky);
+
 /*
  * Enqueue evpn neighbor updates for the dataplane.
  */