]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: data plane FPM add support RMAC VNI
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Mon, 13 Jan 2020 19:34:03 +0000 (16:34 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Tue, 14 Apr 2020 16:45:39 +0000 (13:45 -0300)
Store VNI information in the data plane context so we can use it to
build the FPM netlink update with that information later.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
lib/nexthop.h
zebra/dplane_fpm_nl.c
zebra/rt_netlink.c
zebra/rt_netlink.h
zebra/zebra_dplane.c

index c4e88dd844fce956345194d42d26e73108c02f87..9b71262589534bc45dc5ccc68f7aabbef6c143e1 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "prefix.h"
 #include "mpls.h"
+#include "vxlan.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -60,6 +61,10 @@ enum blackhole_type {
                ? (type)                                                       \
                : ((type) | 1)
 
+enum nh_encap_type {
+       NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
+};
+
 /* Nexthop structure. */
 struct nexthop {
        struct nexthop *next;
@@ -123,6 +128,12 @@ struct nexthop {
         * only meaningful if the HAS_BACKUP flag is set.
         */
        uint8_t backup_idx;
+
+       /* Encapsulation information. */
+       enum nh_encap_type nh_encap_type;
+       union {
+               vni_t vni;
+       } nh_encap;
 };
 
 /* Backup index value is limited */
index 7d78b534f8b089e775f3d61fa60bc757757f677e..4b8948b71ca5c33a18985eec6931d44966d993d9 100644 (file)
@@ -626,7 +626,7 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_ROUTE_UPDATE:
        case DPLANE_OP_ROUTE_DELETE:
                rv = netlink_route_multipath(RTM_DELROUTE, ctx, nl_buf,
-                                            sizeof(nl_buf));
+                                            sizeof(nl_buf), true);
                if (rv <= 0) {
                        zlog_debug("%s: netlink_route_multipath failed",
                                   __func__);
@@ -643,7 +643,7 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_ROUTE_INSTALL:
                rv = netlink_route_multipath(RTM_NEWROUTE, ctx,
                                             &nl_buf[nl_buf_len],
-                                            sizeof(nl_buf) - nl_buf_len);
+                                            sizeof(nl_buf) - nl_buf_len, true);
                if (rv <= 0) {
                        zlog_debug("%s: netlink_route_multipath failed",
                                   __func__);
@@ -829,8 +829,8 @@ static void fpm_enqueue_rmac_table(struct hash_backet *backet, void *arg)
        dplane_ctx_reset(fra->ctx);
        dplane_ctx_set_op(fra->ctx, DPLANE_OP_MAC_INSTALL);
        dplane_mac_init(fra->ctx, fra->zl3vni->vxlan_if,
-                       zif->brslave_info.br_if, vid, &zrmac->macaddr,
-                       zrmac->fwd_info.r_vtep_ip, sticky);
+                       zif->brslave_info.br_if, vid,
+                       &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, sticky);
        if (fpm_nl_enqueue(fra->fnc, fra->ctx) == -1) {
                thread_add_timer(zrouter.master, fpm_rmac_send,
                                 fra->fnc, 1, &fra->fnc->t_rmacwalk);
index 06da711303e012056b6a4bdde01c59ea086c4e2e..7ca4425dc81a1097468cf614c0c169cfe572b2b0 100644 (file)
@@ -1528,11 +1528,28 @@ static bool nexthop_set_src(const struct nexthop *nexthop, int family,
        return false;
 }
 
+static void netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
+                                       struct nexthop *nh)
+{
+       struct rtattr *nest;
+
+       switch (nh->nh_encap_type) {
+       case NET_VXLAN:
+               addattr_l(n, nlen, RTA_ENCAP_TYPE, &nh->nh_encap_type,
+                         sizeof(uint16_t));
+
+               nest = addattr_nest(n, nlen, RTA_ENCAP);
+               addattr32(n, nlen, 0 /* VXLAN_VNI */, nh->nh_encap.vni);
+               addattr_nest_end(n, nest);
+               break;
+       }
+}
+
 /*
  * Routing table change via netlink interface, using a dataplane context object
  */
 ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
-                               uint8_t *data, size_t datalen)
+                               uint8_t *data, size_t datalen, bool fpm)
 {
        int bytelen;
        struct nexthop *nexthop = NULL;
@@ -1744,7 +1761,16 @@ ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
                                nexthop_num++;
                                break;
                        }
+
+                       /*
+                        * Add encapsulation information when installing via
+                        * FPM.
+                        */
+                       if (fpm)
+                               netlink_route_nexthop_encap(&req->n, datalen,
+                                                           nexthop);
                }
+
                if (setsrc) {
                        if (p->family == AF_INET)
                                addattr_l(&req->n, datalen, RTA_PREFSRC,
@@ -1796,7 +1822,16 @@ ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
                                        setsrc = 1;
                                }
                        }
+
+                       /*
+                        * Add encapsulation information when installing via
+                        * FPM.
+                        */
+                       if (fpm)
+                               netlink_route_nexthop_encap(&req->n, datalen,
+                                                           nexthop);
                }
+
                if (setsrc) {
                        if (p->family == AF_INET)
                                addattr_l(&req->n, datalen, RTA_PREFSRC,
@@ -2149,7 +2184,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                        if (RSYSTEM_ROUTE(dplane_ctx_get_type(ctx)) &&
                            !RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
                                netlink_route_multipath(RTM_DELROUTE, ctx,
-                                                       nl_pkt, sizeof(nl_pkt));
+                                                       nl_pkt, sizeof(nl_pkt),
+                                                       false);
                                netlink_talk_info(netlink_talk_filter,
                                                  (struct nlmsghdr *)nl_pkt,
                                                  dplane_ctx_get_ns(ctx), 0);
@@ -2169,7 +2205,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                         */
                        if (!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx))) {
                                netlink_route_multipath(RTM_DELROUTE, ctx,
-                                                       nl_pkt, sizeof(nl_pkt));
+                                                       nl_pkt, sizeof(nl_pkt),
+                                                       false);
                                netlink_talk_info(netlink_talk_filter,
                                                  (struct nlmsghdr *)nl_pkt,
                                                  dplane_ctx_get_ns(ctx), 0);
@@ -2182,7 +2219,8 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
        }
 
        if (!RSYSTEM_ROUTE(dplane_ctx_get_type(ctx))) {
-               netlink_route_multipath(cmd, ctx, nl_pkt, sizeof(nl_pkt));
+               netlink_route_multipath(cmd, ctx, nl_pkt, sizeof(nl_pkt),
+                                       false);
                ret = netlink_talk_info(netlink_talk_filter,
                                        (struct nlmsghdr *)nl_pkt,
                                        dplane_ctx_get_ns(ctx), 0);
index 15ef43c5389a999d6bad39ef3f302946072aecf4..d6a993e78abef17557fc258ed1caa0b16c07c2ed 100644 (file)
@@ -67,7 +67,8 @@ void rt_netlink_init(void);
 extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
 
 extern ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
-                                      uint8_t *data, size_t datalen);
+                                      uint8_t *data, size_t datalen,
+                                      bool fpm);
 extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
                                         uint8_t *data, size_t datalen);
 
index e3eeecefc4ac40387cb63a72cc2cd2c3d4a91ce3..abbd136948d795ed08db1acadb269d12ec2d07bc 100644 (file)
@@ -32,6 +32,7 @@
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_router.h"
 #include "zebra/zebra_dplane.h"
+#include "zebra/zebra_vxlan_private.h"
 #include "zebra/rt.h"
 #include "zebra/debug.h"
 
@@ -178,7 +179,6 @@ struct dplane_mac_info {
        struct ethaddr mac;
        struct in_addr vtep_ip;
        bool is_sticky;
-
 };
 
 /*
@@ -1535,6 +1535,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
        struct zebra_ns *zns;
        struct zebra_vrf *zvrf;
        struct nexthop *nexthop;
+       zebra_l3vni_t *zl3vni;
 
        if (!ctx || !rn || !re)
                goto done;
@@ -1584,10 +1585,24 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
                              re->nhe->backup_info->nhe->nhg.nexthop, NULL);
        }
 
-       /* Ensure that the dplane nexthops' flags are clear. */
-       for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop))
+       /*
+        * Ensure that the dplane nexthops' flags are clear and copy
+        * encapsulation information.
+        */
+       for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop)) {
                UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
+               /* Check for available encapsulations. */
+               if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+                       continue;
+
+               zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
+               if (zl3vni && is_l3vni_oper_up(zl3vni)) {
+                       nexthop->nh_encap_type = NET_VXLAN;
+                       nexthop->nh_encap.vni = zl3vni->vni;
+               }
+       }
+
        /* Don't need some info when capturing a system notification */
        if (op == DPLANE_OP_SYS_ROUTE_ADD ||
            op == DPLANE_OP_SYS_ROUTE_DELETE) {