mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-02 18:56:53 +00:00
zebra: dataplane context reset and init apis
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>
This commit is contained in:
parent
f78fe8f3d6
commit
f73a84672d
@ -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(
|
static enum zebra_dplane_result intf_addr_update_internal(
|
||||||
const struct interface *ifp, const struct connected *ifc,
|
const struct interface *ifp, const struct connected *ifc,
|
||||||
enum dplane_op_e op);
|
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,
|
enum dplane_op_e op, const struct interface *ifp,
|
||||||
const struct interface *br_ifp,
|
const struct interface *br_ifp,
|
||||||
vlanid_t vid, const struct ethaddr *mac,
|
vlanid_t vid, const struct ethaddr *mac,
|
||||||
@ -444,6 +444,123 @@ void dplane_enable_sys_route_notifs(void)
|
|||||||
zdplane_info.dg_sys_route_notifs = true;
|
zdplane_info.dg_sys_route_notifs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up dependent/internal allocations inside a context object
|
||||||
|
*/
|
||||||
|
static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Some internal allocations may need to be freed, depending on
|
||||||
|
* the type of info captured in the ctx.
|
||||||
|
*/
|
||||||
|
switch (ctx->zd_op) {
|
||||||
|
case DPLANE_OP_ROUTE_INSTALL:
|
||||||
|
case DPLANE_OP_ROUTE_UPDATE:
|
||||||
|
case DPLANE_OP_ROUTE_DELETE:
|
||||||
|
case DPLANE_OP_SYS_ROUTE_ADD:
|
||||||
|
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||||
|
case DPLANE_OP_ROUTE_NOTIFY:
|
||||||
|
|
||||||
|
/* Free allocated nexthops */
|
||||||
|
if (ctx->u.rinfo.zd_ng.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.rinfo.zd_ng.nexthop);
|
||||||
|
|
||||||
|
ctx->u.rinfo.zd_ng.nexthop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free backup info also (if present) */
|
||||||
|
if (ctx->u.rinfo.backup_ng.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.rinfo.backup_ng.nexthop);
|
||||||
|
|
||||||
|
ctx->u.rinfo.backup_ng.nexthop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->u.rinfo.zd_old_ng.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.rinfo.zd_old_ng.nexthop);
|
||||||
|
|
||||||
|
ctx->u.rinfo.zd_old_ng.nexthop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->u.rinfo.old_backup_ng.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.rinfo.old_backup_ng.nexthop);
|
||||||
|
|
||||||
|
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 (ctx->u.rinfo.nhe.ng.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.rinfo.nhe.ng.nexthop);
|
||||||
|
|
||||||
|
ctx->u.rinfo.nhe.ng.nexthop = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPLANE_OP_LSP_INSTALL:
|
||||||
|
case DPLANE_OP_LSP_UPDATE:
|
||||||
|
case DPLANE_OP_LSP_DELETE:
|
||||||
|
case DPLANE_OP_LSP_NOTIFY:
|
||||||
|
{
|
||||||
|
zebra_nhlfe_t *nhlfe, *next;
|
||||||
|
|
||||||
|
/* Free allocated NHLFEs */
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
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 (ctx->u.pw.nhg.nexthop) {
|
||||||
|
/* This deals with recursive nexthops too */
|
||||||
|
nexthops_free(ctx->u.pw.nhg.nexthop);
|
||||||
|
|
||||||
|
ctx->u.pw.nhg.nexthop = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DPLANE_OP_ADDR_INSTALL:
|
||||||
|
case DPLANE_OP_ADDR_UNINSTALL:
|
||||||
|
/* Maybe free label string, if allocated */
|
||||||
|
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_MAC_INSTALL:
|
||||||
|
case DPLANE_OP_MAC_DELETE:
|
||||||
|
case DPLANE_OP_NEIGH_INSTALL:
|
||||||
|
case DPLANE_OP_NEIGH_UPDATE:
|
||||||
|
case DPLANE_OP_NEIGH_DELETE:
|
||||||
|
case DPLANE_OP_VTEP_ADD:
|
||||||
|
case DPLANE_OP_VTEP_DELETE:
|
||||||
|
case DPLANE_OP_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free a dataplane results context.
|
* Free a dataplane results context.
|
||||||
*/
|
*/
|
||||||
@ -461,116 +578,21 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
|
|||||||
/* 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.
|
* the type of info captured in the ctx.
|
||||||
*/
|
*/
|
||||||
switch ((*pctx)->zd_op) {
|
dplane_ctx_free_internal(*pctx);
|
||||||
case DPLANE_OP_ROUTE_INSTALL:
|
|
||||||
case DPLANE_OP_ROUTE_UPDATE:
|
|
||||||
case DPLANE_OP_ROUTE_DELETE:
|
|
||||||
case DPLANE_OP_SYS_ROUTE_ADD:
|
|
||||||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
|
||||||
case DPLANE_OP_ROUTE_NOTIFY:
|
|
||||||
|
|
||||||
/* Free allocated nexthops */
|
|
||||||
if ((*pctx)->u.rinfo.zd_ng.nexthop) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.rinfo.zd_ng.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->u.rinfo.zd_ng.nexthop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free backup info also (if present) */
|
|
||||||
if ((*pctx)->u.rinfo.backup_ng.nexthop) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.rinfo.backup_ng.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->u.rinfo.backup_ng.nexthop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*pctx)->u.rinfo.zd_old_ng.nexthop) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.rinfo.zd_old_ng.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->u.rinfo.zd_old_ng.nexthop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*pctx)->u.rinfo.old_backup_ng.nexthop) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.rinfo.old_backup_ng.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->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) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.rinfo.nhe.ng.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->u.rinfo.nhe.ng.nexthop = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DPLANE_OP_LSP_INSTALL:
|
|
||||||
case DPLANE_OP_LSP_UPDATE:
|
|
||||||
case DPLANE_OP_LSP_DELETE:
|
|
||||||
case DPLANE_OP_LSP_NOTIFY:
|
|
||||||
{
|
|
||||||
zebra_nhlfe_t *nhlfe, *next;
|
|
||||||
|
|
||||||
/* Free allocated NHLFEs */
|
|
||||||
for (nhlfe = (*pctx)->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;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DPLANE_OP_PW_INSTALL:
|
|
||||||
case DPLANE_OP_PW_UNINSTALL:
|
|
||||||
/* Free allocated nexthops */
|
|
||||||
if ((*pctx)->u.pw.nhg.nexthop) {
|
|
||||||
/* This deals with recursive nexthops too */
|
|
||||||
nexthops_free((*pctx)->u.pw.nhg.nexthop);
|
|
||||||
|
|
||||||
(*pctx)->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;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DPLANE_OP_MAC_INSTALL:
|
|
||||||
case DPLANE_OP_MAC_DELETE:
|
|
||||||
case DPLANE_OP_NEIGH_INSTALL:
|
|
||||||
case DPLANE_OP_NEIGH_UPDATE:
|
|
||||||
case DPLANE_OP_NEIGH_DELETE:
|
|
||||||
case DPLANE_OP_VTEP_ADD:
|
|
||||||
case DPLANE_OP_VTEP_DELETE:
|
|
||||||
case DPLANE_OP_NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
XFREE(MTYPE_DP_CTX, *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
|
* 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;
|
enum zebra_dplane_result result;
|
||||||
|
|
||||||
/* Use common helper api */
|
/* Use common helper api */
|
||||||
result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp,
|
result = mac_update_common(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp,
|
||||||
vid, mac, vtep_ip, sticky);
|
vid, mac, vtep_ip, sticky);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2487,41 +2509,25 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
|
|||||||
enum zebra_dplane_result result;
|
enum zebra_dplane_result result;
|
||||||
|
|
||||||
/* Use common helper api */
|
/* Use common helper api */
|
||||||
result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp,
|
result = mac_update_common(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp,
|
||||||
vid, mac, vtep_ip, false);
|
vid, mac, vtep_ip, false);
|
||||||
return result;
|
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
|
void dplane_mac_init(struct zebra_dplane_ctx *ctx,
|
||||||
mac_update_internal(enum dplane_op_e op,
|
const struct interface *ifp,
|
||||||
const struct interface *ifp,
|
const struct interface *br_ifp,
|
||||||
const struct interface *br_ifp,
|
vlanid_t vid,
|
||||||
vlanid_t vid,
|
const struct ethaddr *mac,
|
||||||
const struct ethaddr *mac,
|
struct in_addr vtep_ip,
|
||||||
struct in_addr vtep_ip,
|
bool sticky)
|
||||||
bool sticky)
|
|
||||||
{
|
{
|
||||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
|
||||||
int ret;
|
|
||||||
struct zebra_dplane_ctx *ctx = NULL;
|
|
||||||
struct zebra_ns *zns;
|
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_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||||
ctx->zd_vrf_id = ifp->vrf_id;
|
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.mac = *mac;
|
||||||
ctx->u.macinfo.vid = vid;
|
ctx->u.macinfo.vid = vid;
|
||||||
ctx->u.macinfo.is_sticky = sticky;
|
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 */
|
/* Enqueue for processing on the dplane pthread */
|
||||||
ret = dplane_update_enqueue(ctx);
|
ret = dplane_update_enqueue(ctx);
|
||||||
|
@ -180,6 +180,12 @@ TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx);
|
|||||||
/* Allocate a context object */
|
/* Allocate a context object */
|
||||||
struct zebra_dplane_ctx *dplane_ctx_alloc(void);
|
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
|
/* Return a dataplane results context block after use; the caller's pointer will
|
||||||
* be cleared.
|
* be cleared.
|
||||||
*/
|
*/
|
||||||
@ -451,6 +457,15 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
|
|||||||
const struct ethaddr *mac,
|
const struct ethaddr *mac,
|
||||||
struct in_addr vtep_ip);
|
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.
|
* Enqueue evpn neighbor updates for the dataplane.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user