diff options
author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-05-09 01:53:25 +0200 |
---|---|---|
committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-10-26 18:32:51 +0100 |
commit | c60522f7026b51e7440832f4b0d80fcd0111270f (patch) | |
tree | 25ae877fe3fefd7e6a93b13d6a17c7dd30829feb | |
parent | zebra: changes to run DF election (diff) | |
download | frr-c60522f7026b51e7440832f4b0d80fcd0111270f.tar.xz frr-c60522f7026b51e7440832f4b0d80fcd0111270f.zip |
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>
-rw-r--r-- | zebra/kernel_netlink.c | 1 | ||||
-rw-r--r-- | zebra/zebra_dplane.c | 135 | ||||
-rw-r--r-- | zebra/zebra_dplane.h | 20 | ||||
-rw-r--r-- | zebra/zebra_nhg.c | 1 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 1 |
5 files changed, 158 insertions, 0 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 129703d9a..76da00c61 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -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: diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index e93444d22..56545d076 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -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") @@ -149,6 +150,17 @@ struct dplane_pw_info { }; /* + * 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 */ struct dplane_intf_info { @@ -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 */ @@ -2839,6 +2891,80 @@ done: } /* + * 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. */ enum zebra_dplane_result dplane_intf_addr_set(const struct interface *ifp, @@ -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: diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index fd70211f7..b37bf665a 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -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; diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index ebefa020c..196e3c83d 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -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; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ab7423a12..08daddb16 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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); |