mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
zebra: dplane APIs for programming evpn-mh access port attributes
This includes - 1. non-DF block filter 2. List of es-peers that need to be blocked per-access port (for split horizon filtering) 3. Backup nexthop group to failover local-es via the VxLAN overlay Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
1103c5c6cd
commit
c60522f702
|
@ -1321,6 +1321,7 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
|
|||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||
case DPLANE_OP_ROUTE_NOTIFY:
|
||||
case DPLANE_OP_LSP_NOTIFY:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
return FRR_NETLINK_SUCCESS;
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "zebra/rt.h"
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/zebra_pbr.h"
|
||||
#include "printfrr.h"
|
||||
|
||||
/* Memory type for context blocks */
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx")
|
||||
|
@ -148,6 +149,17 @@ struct dplane_pw_info {
|
|||
union pw_protocol_fields fields;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bridge port info for the dataplane
|
||||
*/
|
||||
struct dplane_br_port_info {
|
||||
uint32_t sph_filter_cnt;
|
||||
struct in_addr sph_filters[ES_VTEP_MAX_CNT];
|
||||
/* DPLANE_BR_PORT_XXX - see zebra_dplane.h*/
|
||||
uint32_t flags;
|
||||
uint32_t backup_nhg_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface/prefix info for the dataplane
|
||||
*/
|
||||
|
@ -272,6 +284,7 @@ struct zebra_dplane_ctx {
|
|||
struct dplane_route_info rinfo;
|
||||
zebra_lsp_t lsp;
|
||||
struct dplane_pw_info pw;
|
||||
struct dplane_br_port_info br_port;
|
||||
struct dplane_intf_info intf;
|
||||
struct dplane_mac_info macinfo;
|
||||
struct dplane_neigh_info neigh;
|
||||
|
@ -390,6 +403,9 @@ static struct zebra_dplane_globals {
|
|||
_Atomic uint32_t dg_pws_in;
|
||||
_Atomic uint32_t dg_pw_errors;
|
||||
|
||||
_Atomic uint32_t dg_br_port_in;
|
||||
_Atomic uint32_t dg_br_port_errors;
|
||||
|
||||
_Atomic uint32_t dg_intf_addrs_in;
|
||||
_Atomic uint32_t dg_intf_addr_errors;
|
||||
|
||||
|
@ -610,6 +626,7 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_RULE_DELETE:
|
||||
case DPLANE_OP_RULE_UPDATE:
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NONE:
|
||||
break;
|
||||
}
|
||||
|
@ -803,6 +820,10 @@ const char *dplane_op2str(enum dplane_op_e op)
|
|||
ret = "SYS_ROUTE_DEL";
|
||||
break;
|
||||
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
ret = "BR_PORT_UPDATE";
|
||||
break;
|
||||
|
||||
case DPLANE_OP_ADDR_INSTALL:
|
||||
ret = "ADDR_INSTALL";
|
||||
break;
|
||||
|
@ -1763,6 +1784,37 @@ dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx)
|
|||
return &(ctx->u.rule.old.dst_ip);
|
||||
}
|
||||
|
||||
uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.br_port.flags;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.br_port.sph_filter_cnt;
|
||||
}
|
||||
|
||||
const struct in_addr *
|
||||
dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.br_port.sph_filters;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
DPLANE_CTX_VALID(ctx);
|
||||
|
||||
return ctx->u.br_port.backup_nhg_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of dplane context accessors
|
||||
*/
|
||||
|
@ -2838,6 +2890,80 @@ done:
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue access br_port update.
|
||||
*/
|
||||
enum zebra_dplane_result
|
||||
dplane_br_port_update(const struct interface *ifp, bool non_df,
|
||||
uint32_t sph_filter_cnt,
|
||||
const struct in_addr *sph_filters, uint32_t backup_nhg_id)
|
||||
{
|
||||
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
uint32_t flags = 0;
|
||||
int ret;
|
||||
struct zebra_dplane_ctx *ctx = NULL;
|
||||
struct zebra_ns *zns;
|
||||
enum dplane_op_e op = DPLANE_OP_BR_PORT_UPDATE;
|
||||
|
||||
if (non_df)
|
||||
flags |= DPLANE_BR_PORT_NON_DF;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
uint32_t i;
|
||||
char vtep_str[ES_VTEP_LIST_STR_SZ];
|
||||
|
||||
vtep_str[0] = '\0';
|
||||
for (i = 0; i < sph_filter_cnt; ++i) {
|
||||
snprintfrr(vtep_str + strlen(vtep_str),
|
||||
sizeof(vtep_str) - strlen(vtep_str), "%pI4 ",
|
||||
&sph_filters[i]);
|
||||
}
|
||||
zlog_debug(
|
||||
"init br_port ctx %s: ifp %s, flags 0x%x backup_nhg 0x%x sph %s",
|
||||
dplane_op2str(op), ifp->name, flags, backup_nhg_id,
|
||||
vtep_str);
|
||||
}
|
||||
|
||||
ctx = dplane_ctx_alloc();
|
||||
|
||||
ctx->zd_op = op;
|
||||
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
ctx->zd_vrf_id = ifp->vrf_id;
|
||||
|
||||
zns = zebra_ns_lookup(ifp->vrf_id);
|
||||
dplane_ctx_ns_init(ctx, zns, false);
|
||||
|
||||
ctx->zd_ifindex = ifp->ifindex;
|
||||
strlcpy(ctx->zd_ifname, ifp->name, sizeof(ctx->zd_ifname));
|
||||
|
||||
/* Init the br-port-specific data area */
|
||||
memset(&ctx->u.br_port, 0, sizeof(ctx->u.br_port));
|
||||
|
||||
ctx->u.br_port.flags = flags;
|
||||
ctx->u.br_port.backup_nhg_id = backup_nhg_id;
|
||||
ctx->u.br_port.sph_filter_cnt = sph_filter_cnt;
|
||||
memcpy(ctx->u.br_port.sph_filters, sph_filters,
|
||||
sizeof(ctx->u.br_port.sph_filters[0]) * sph_filter_cnt);
|
||||
|
||||
/* Enqueue for processing on the dplane pthread */
|
||||
ret = dplane_update_enqueue(ctx);
|
||||
|
||||
/* Increment counter */
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_br_port_in, 1,
|
||||
memory_order_relaxed);
|
||||
|
||||
if (ret == AOK) {
|
||||
result = ZEBRA_DPLANE_REQUEST_QUEUED;
|
||||
} else {
|
||||
/* Error counter */
|
||||
atomic_fetch_add_explicit(&zdplane_info.dg_br_port_errors, 1,
|
||||
memory_order_relaxed);
|
||||
dplane_ctx_free(&ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue interface address add for the dataplane.
|
||||
*/
|
||||
|
@ -3450,6 +3576,13 @@ int dplane_show_helper(struct vty *vty, bool detailed)
|
|||
vty_out(vty, "Rule updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "Rule errors: %" PRIu64 "\n", errs);
|
||||
|
||||
incoming = atomic_load_explicit(&zdplane_info.dg_br_port_in,
|
||||
memory_order_relaxed);
|
||||
errs = atomic_load_explicit(&zdplane_info.dg_br_port_errors,
|
||||
memory_order_relaxed);
|
||||
vty_out(vty, "Bridge port updates: %" PRIu64 "\n", incoming);
|
||||
vty_out(vty, "Bridge port errors: %" PRIu64 "\n", errs);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3834,6 +3967,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||
case DPLANE_OP_ROUTE_NOTIFY:
|
||||
case DPLANE_OP_LSP_NOTIFY:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
break;
|
||||
|
@ -3938,6 +4072,7 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_SYS_ROUTE_DELETE:
|
||||
case DPLANE_OP_ROUTE_NOTIFY:
|
||||
case DPLANE_OP_LSP_NOTIFY:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
break;
|
||||
|
||||
case DPLANE_OP_NONE:
|
||||
|
|
|
@ -152,6 +152,9 @@ enum dplane_op_e {
|
|||
|
||||
/* Link layer address discovery */
|
||||
DPLANE_OP_NEIGH_DISCOVER,
|
||||
|
||||
/* bridge port update */
|
||||
DPLANE_OP_BR_PORT_UPDATE,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -184,6 +187,8 @@ enum dplane_op_e {
|
|||
#define DPLANE_NEIGH_SET_STATIC (1 << 2)
|
||||
#define DPLANE_NEIGH_SET_INACTIVE (1 << 3)
|
||||
|
||||
#define DPLANE_BR_PORT_NON_DF (1 << 0)
|
||||
|
||||
/* Enable system route notifications */
|
||||
void dplane_enable_sys_route_notifs(void);
|
||||
|
||||
|
@ -444,6 +449,15 @@ dplane_ctx_rule_get_dst_ip(const struct zebra_dplane_ctx *ctx);
|
|||
const struct prefix *
|
||||
dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/* Accessors for bridge port information */
|
||||
uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx);
|
||||
uint32_t
|
||||
dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx);
|
||||
const struct in_addr *
|
||||
dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx);
|
||||
uint32_t
|
||||
dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/* Namespace info - esp. for netlink communication */
|
||||
const struct zebra_dplane_info *dplane_ctx_get_ns(
|
||||
const struct zebra_dplane_ctx *ctx);
|
||||
|
@ -479,6 +493,12 @@ enum zebra_dplane_result dplane_route_notif_update(
|
|||
enum dplane_op_e op,
|
||||
struct zebra_dplane_ctx *ctx);
|
||||
|
||||
/*
|
||||
* Enqueue bridge port changes for the dataplane.
|
||||
*/
|
||||
enum zebra_dplane_result dplane_br_port_update(
|
||||
const struct interface *ifp, bool non_df, uint32_t sph_filter_cnt,
|
||||
const struct in_addr *sph_filters, uint32_t backup_nhg_id);
|
||||
|
||||
/* Forward ref of nhg_hash_entry */
|
||||
struct nhg_hash_entry;
|
||||
|
|
|
@ -2692,6 +2692,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_RULE_DELETE:
|
||||
case DPLANE_OP_RULE_UPDATE:
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NONE:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3831,6 +3831,7 @@ static int rib_process_dplane_results(struct thread *thread)
|
|||
case DPLANE_OP_VTEP_ADD:
|
||||
case DPLANE_OP_VTEP_DELETE:
|
||||
case DPLANE_OP_NEIGH_DISCOVER:
|
||||
case DPLANE_OP_BR_PORT_UPDATE:
|
||||
case DPLANE_OP_NONE:
|
||||
/* Don't expect this: just return the struct? */
|
||||
dplane_ctx_fini(&ctx);
|
||||
|
|
Loading…
Reference in a new issue