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,
}
/*
- * 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:
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;
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;
}
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);
/* 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;
}
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;
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
*/
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;
}
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;
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);