]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: dplane APIs for programming evpn-mh access port attributes
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 8 May 2020 23:53:25 +0000 (16:53 -0700)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Mon, 26 Oct 2020 17:32:51 +0000 (10:32 -0700)
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>
zebra/kernel_netlink.c
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_nhg.c
zebra/zebra_rib.c

index 129703d9a902fd4699ee78d31ef540a1e424f109..76da00c61910e2328919033f7303cb45165f8dc4 100644 (file)
@@ -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:
index e93444d22eef4756d00f098047d3f16c9afa399d..56545d07663c00be12b03a02b633e5ca2c47737c 100644 (file)
@@ -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:
index fd70211f7c8d93e22d989d9f41649e8580a2910d..b37bf665ae21489ff35c193f3b9b2cae46d9877f 100644 (file)
@@ -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;
index ebefa020c8d5d508da2fc0183589c68d89afb39f..196e3c83d0a4ae18398f1a0a1dff3d6f9adce0b1 100644 (file)
@@ -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;
        }
index ab7423a12ad7a115709209cc8c7ef2271a8c9de5..08daddb16408efb0065218704984a36442abbe7d 100644 (file)
@@ -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);