]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: initial dplane support for MAC updates
authorMark Stapp <mjs@voltanet.io>
Fri, 26 Jul 2019 16:10:03 +0000 (12:10 -0400)
committerMark Stapp <mjs@voltanet.io>
Fri, 26 Jul 2019 18:17:31 +0000 (14:17 -0400)
Initial data struct and api changes to support EVPN MAC
updates via the dataplane subsystem (no handlers yet).

Signed-off-by: Mark Stapp <mjs@voltanet.io>
zebra/zebra_dplane.c
zebra/zebra_dplane.h

index bb60600f3aab3c7989c4865fa9e2da86e9dcc1a2..5d99500397eb68bee5bac0923c962b294c33ec4a 100644 (file)
@@ -147,6 +147,17 @@ struct dplane_intf_info {
        char label_buf[32];
 };
 
+/*
+ * MAC address info for the dataplane.
+ */
+struct dplane_mac_info {
+       vlanid_t vid;
+       struct ethaddr mac;
+       struct in_addr vtep_ip;
+       bool is_sticky;
+
+};
+
 /*
  * The context block used to exchange info about route updates across
  * the boundary between the zebra main context (and pthread) and the
@@ -192,6 +203,7 @@ struct zebra_dplane_ctx {
                zebra_lsp_t lsp;
                struct dplane_pw_info pw;
                struct dplane_intf_info intf;
+               struct dplane_mac_info macinfo;
        } u;
 
        /* Namespace info, used especially for netlink kernel communication */
@@ -306,6 +318,9 @@ static struct zebra_dplane_globals {
        _Atomic uint32_t dg_intf_addrs_in;
        _Atomic uint32_t dg_intf_addr_errors;
 
+       _Atomic uint32_t dg_macs_in;
+       _Atomic uint32_t dg_mac_errors;
+
        _Atomic uint32_t dg_update_yields;
 
        /* Dataplane pthread */
@@ -346,6 +361,10 @@ static enum zebra_dplane_result pw_update_internal(struct zebra_pw *pw,
 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(
+       enum dplane_op_e op, const struct interface *ifp,
+       vlanid_t vid, const struct ethaddr *mac,
+       struct in_addr vtep_ip, bool sticky);
 
 /*
  * Public APIs
@@ -464,6 +483,8 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
                }
                break;
 
+       case DPLANE_OP_MAC_INSTALL:
+       case DPLANE_OP_MAC_DELETE:
        case DPLANE_OP_NONE:
                break;
        }
@@ -624,6 +645,12 @@ const char *dplane_op2str(enum dplane_op_e op)
                ret = "ADDR_UNINSTALL";
                break;
 
+       case DPLANE_OP_MAC_INSTALL:
+               ret = "MAC_INSTALL";
+               break;
+       case DPLANE_OP_MAC_DELETE:
+               ret = "MAC_DELETE";
+               break;
        }
 
        return ret;
@@ -1177,6 +1204,33 @@ const char *dplane_ctx_get_intf_label(const struct zebra_dplane_ctx *ctx)
        return ctx->u.intf.label;
 }
 
+/* Accessors for MAC information */
+vlanid_t dplane_ctx_mac_get_vlan(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+       return ctx->u.macinfo.vid;
+}
+
+bool dplane_ctx_mac_is_sticky(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+       return ctx->u.macinfo.is_sticky;
+}
+
+const struct ethaddr *dplane_ctx_mac_get_addr(
+       const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+       return &(ctx->u.macinfo.mac);
+}
+
+const struct in_addr *dplane_ctx_mac_get_vtep_ip(
+       const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+       return &(ctx->u.macinfo.vtep_ip);
+}
+
 /*
  * End of dplane context accessors
  */
@@ -2011,6 +2065,94 @@ static enum zebra_dplane_result intf_addr_update_internal(
        return result;
 }
 
+/*
+ * Enqueue vxlan/evpn mac add (or update).
+ */
+enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
+                                       vlanid_t vid,
+                                       const struct ethaddr *mac,
+                                       struct in_addr vtep_ip,
+                                       bool sticky)
+{
+       enum zebra_dplane_result result;
+
+       /* Use common helper api */
+       result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, vid,
+                                    mac, vtep_ip, sticky);
+       return result;
+}
+
+/*
+ * Enqueue vxlan/evpn mac delete.
+ */
+enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
+                                       vlanid_t vid,
+                                       const struct ethaddr *mac,
+                                       struct in_addr vtep_ip)
+{
+       enum zebra_dplane_result result;
+
+       /* Use common helper api */
+       result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, vid, mac,
+                                    vtep_ip, false);
+       return result;
+}
+
+/*
+ * Common helper api for MAC address/vxlan updates
+ */
+static enum zebra_dplane_result
+mac_update_internal(enum dplane_op_e op,
+                   const struct interface *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;
+
+       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);
+
+       strlcpy(ctx->zd_ifname, ifp->name, sizeof(ctx->zd_ifname));
+       ctx->zd_ifindex = ifp->ifindex;
+
+       /* Init the mac-specific data area */
+       memset(&ctx->u.macinfo, 0, sizeof(ctx->u.macinfo));
+
+       ctx->u.macinfo.vtep_ip = vtep_ip;
+       ctx->u.macinfo.mac = *mac;
+       ctx->u.macinfo.vid = vid;
+       ctx->u.macinfo.is_sticky = sticky;
+
+       /* Enqueue for processing on the dplane pthread */
+       ret = dplane_update_enqueue(ctx);
+
+       /* Increment counter */
+       atomic_fetch_add_explicit(&zdplane_info.dg_macs_in, 1,
+                                 memory_order_relaxed);
+
+       if (ret == AOK)
+               result = ZEBRA_DPLANE_REQUEST_QUEUED;
+       else {
+               /* Error counter */
+               atomic_fetch_add_explicit(&zdplane_info.dg_mac_errors, 1,
+                                         memory_order_relaxed);
+               dplane_ctx_free(&ctx);
+       }
+
+       return result;
+}
+
 /*
  * Handler for 'show dplane'
  */
index 01a23b08817041b807c9b0b2b522e92c20ab66f6..912fda45d34c6274590197c5de446bfc24502cfe 100644 (file)
@@ -25,6 +25,7 @@
 #include "lib/nexthop.h"
 #include "lib/nexthop_group.h"
 #include "lib/queue.h"
+#include "lib/vlan.h"
 #include "zebra/zebra_ns.h"
 #include "zebra/rib.h"
 #include "zebra/zserv.h"
@@ -124,6 +125,10 @@ enum dplane_op_e {
        /* Interface address update */
        DPLANE_OP_ADDR_INSTALL,
        DPLANE_OP_ADDR_UNINSTALL,
+
+       /* MAC address update */
+       DPLANE_OP_MAC_INSTALL,
+       DPLANE_OP_MAC_DELETE,
 };
 
 /* Enable system route notifications */
@@ -291,6 +296,14 @@ const struct prefix *dplane_ctx_get_intf_dest(
 bool dplane_ctx_intf_has_label(const struct zebra_dplane_ctx *ctx);
 const char *dplane_ctx_get_intf_label(const struct zebra_dplane_ctx *ctx);
 
+/* Accessors for MAC information */
+vlanid_t dplane_ctx_mac_get_vlan(const struct zebra_dplane_ctx *ctx);
+bool dplane_ctx_mac_is_sticky(const struct zebra_dplane_ctx *ctx);
+const struct ethaddr *dplane_ctx_mac_get_addr(
+       const struct zebra_dplane_ctx *ctx);
+const struct in_addr *dplane_ctx_mac_get_vtep_ip(
+       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);
@@ -352,6 +365,19 @@ enum zebra_dplane_result dplane_intf_addr_set(const struct interface *ifp,
 enum zebra_dplane_result dplane_intf_addr_unset(const struct interface *ifp,
                                                const struct connected *ifc);
 
+/*
+ * Enqueue evpn mac operations for the dataplane.
+ */
+enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
+                                       vlanid_t vid,
+                                       const struct ethaddr *mac,
+                                       struct in_addr vtep_ip,
+                                       bool sticky);
+
+enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
+                                       vlanid_t vid,
+                                       const struct ethaddr *mac,
+                                       struct in_addr vtep_ip);
 
 /* Retrieve the limit on the number of pending, unprocessed updates. */
 uint32_t dplane_get_in_queue_limit(void);