]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd, zebra: Handle EVPN router MAC per next hop 2124/head
authorvivek <vivek@cumulusnetworks.com>
Wed, 29 Nov 2017 07:40:30 +0000 (23:40 -0800)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 26 Apr 2018 11:50:34 +0000 (07:50 -0400)
Ensure that when EVPN routes are installed into zebra, the router MAC
is passed per next hop and appropriately handled. This is required for
proper multipath operation.

Ticket: CM-18999
Reviewed By:
Testing Done: Verified failed scenario, other manual tests
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
12 files changed:
bgpd/bgp_zebra.c
lib/zclient.c
lib/zclient.h
zebra/connected.c
zebra/kernel_socket.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/zapi_msg.c
zebra/zebra_rib.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h

index 1c3229174049ff1112f7dca7775f03e90a622d0b..51bdacf36bb526d43786f881a3ade1a608a07a90 100644 (file)
@@ -1070,7 +1070,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
 
        /* Make Zebra API structure. */
        memset(&api, 0, sizeof(api));
-       memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
        api.vrf_id = bgp->vrf_id;
        api.type = ZEBRA_ROUTE_BGP;
        api.safi = safi;
@@ -1276,6 +1275,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
                        api_nh->label_num = 1;
                        api_nh->labels[0] = label;
                }
+               memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
+                      sizeof(struct ethaddr));
                valid_nh_count++;
        }
 
@@ -1387,7 +1388,6 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
                return;
 
        memset(&api, 0, sizeof(api));
-       memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
        api.vrf_id = bgp->vrf_id;
        api.type = ZEBRA_ROUTE_BGP;
        api.safi = safi;
index dc27cbef701bfcdd9b747088b38b8932a6f23a30..98b3856deade7d7d2a9cb814123a25231a02c4ad 100644 (file)
@@ -975,8 +975,6 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
        stream_putl(s, api->flags);
        stream_putc(s, api->message);
        stream_putc(s, api->safi);
-       if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
-               stream_put(s, &(api->rmac), sizeof(struct ethaddr));
 
        /* Put prefix information. */
        stream_putc(s, api->prefix.family);
@@ -1061,6 +1059,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
                                           api_nh->label_num
                                                   * sizeof(mpls_label_t));
                        }
+
+                       /* Router MAC for EVPN routes. */
+                       if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+                               stream_put(s, &(api_nh->rmac),
+                                          sizeof(struct ethaddr));
                }
        }
 
@@ -1101,8 +1104,6 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
        STREAM_GETL(s, api->flags);
        STREAM_GETC(s, api->message);
        STREAM_GETC(s, api->safi);
-       if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
-               STREAM_GET(&(api->rmac), s, sizeof(struct ethaddr));
 
        /* Prefix. */
        STREAM_GETC(s, api->prefix.family);
@@ -1212,6 +1213,11 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
                                           api_nh->label_num
                                                   * sizeof(mpls_label_t));
                        }
+
+                       /* Router MAC for EVPN routes. */
+                       if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+                               stream_get(&(api_nh->rmac), s,
+                                          sizeof(struct ethaddr));
                }
        }
 
index 71f5b383843bb39155609de6e7149a70d0654a6d..cda0803f611dcf9de12885d78c932259de979280 100644 (file)
@@ -298,6 +298,8 @@ struct zapi_nexthop {
        /* MPLS labels for BGP-LU or Segment Routing */
        uint8_t label_num;
        mpls_label_t labels[MPLS_MAX_LABELS];
+
+       struct ethaddr rmac;
 };
 
 /*
@@ -338,8 +340,6 @@ struct zapi_route {
        vrf_id_t vrf_id;
 
        uint32_t tableid;
-
-       struct ethaddr rmac;
 };
 
 /* Zebra IPv4 route message API. */
index 23f2f666a0593c3b0665714b44098e3d8dc0b857..a9a4dfe08f469f786a45af04438c95aa67c8c38f 100644 (file)
@@ -403,10 +403,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
         * head.
         */
        rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
-                  &p, NULL, &nh, 0, 0, false, NULL);
+                  &p, NULL, &nh, 0, 0, false);
 
        rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
-                  &p, NULL, &nh, 0, 0, false, NULL);
+                  &p, NULL, &nh, 0, 0, false);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
                char buf[PREFIX_STRLEN];
index 1a94807317242f6f9a850d334cc0c2b071ad0d30..666a9cc45a75d2ff3e4852b99b45c45e48ca17da 100644 (file)
@@ -1043,7 +1043,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true, NULL);
+                                  NULL, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = NEXTHOP_TYPE_IPV4;
@@ -1058,7 +1058,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true, NULL);
+                                  &nh, 0, 0, true);
        }
        if (dest.sa.sa_family == AF_INET6) {
                /* One day we might have a debug section here like one in the
@@ -1089,7 +1089,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true, NULL);
+                                  NULL, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1106,7 +1106,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true, NULL);
+                                  &nh, 0, 0, true);
        }
 }
 
index 810ee33839a71bfe4af5631e3f6932aaae0fe0af..5a6565aec9cf145c0c6a1f814047a0dd920dcd55 100644 (file)
@@ -592,7 +592,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
 
        rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
                   re->flags, &p, NULL, re->ng.nexthop,
-                  zebrad.rtm_table_default, re->metric, false, NULL);
+                  zebrad.rtm_table_default, re->metric, false);
 
        return 0;
 }
index d68bf787c0c387fb00f569e8d5d1f4d8ed2beb57..7b9e6d56a78f7e92e87b6039dd6a8105cfaef4f9 100644 (file)
@@ -313,8 +313,7 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                       unsigned short instance, int flags, struct prefix *p,
                       struct prefix_ipv6 *src_p, const struct nexthop *nh,
-                      uint32_t table_id, uint32_t metric, bool fromkernel,
-                      struct ethaddr *rmac);
+                      uint32_t table_id, uint32_t metric, bool fromkernel);
 
 extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                                     union g_addr *addr,
index cdc52211cccedfe466f6b88363fc2b9c7521f260..1d2d265b5acadb5cb6c1e973fe6c767c43d9f0a8 100644 (file)
@@ -586,12 +586,12 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
                        if (gate)
                                memcpy(&nh.gate, gate, sz);
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, NULL, &nh, table, metric, true, NULL);
+                                  &p, NULL, &nh, table, metric, true);
                } else {
                        /* XXX: need to compare the entire list of nexthops
                         * here for NLM_F_APPEND stupidity */
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, NULL, NULL, table, metric, true, NULL);
+                                  &p, NULL, NULL, table, metric, true);
                }
        }
 
index 2ff660b3f92b138d26639fa0587ec95cbff33302..6bd12391dbf223148baedb5735db572bfdf1cc60 100644 (file)
@@ -1382,7 +1382,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
                                               &(api_nh->gate.ipv4),
                                               sizeof(struct in_addr));
                                        zebra_vxlan_evpn_vrf_route_add(
-                                               vrf_id, &api.rmac, &vtep_ip,
+                                               vrf_id, &api_nh->rmac, &vtep_ip,
                                                &api.prefix);
                                }
                                break;
@@ -1415,7 +1415,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
                                               &(api_nh->gate.ipv6),
                                               sizeof(struct in6_addr));
                                        zebra_vxlan_evpn_vrf_route_add(
-                                               vrf_id, &api.rmac, &vtep_ip,
+                                               vrf_id, &api_nh->rmac, &vtep_ip,
                                                &api.prefix);
                                }
                                break;
@@ -1522,7 +1522,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
                   api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
-                  false, &api.rmac);
+                  false);
 
        /* Stats */
        switch (api.prefix.family) {
@@ -1724,7 +1724,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
        table_id = zvrf->table_id;
 
        rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, NULL, NULL, table_id, 0, false, NULL);
+                  api.flags, &p, NULL, NULL, table_id, 0, false);
        client->v4_route_del_cnt++;
 
 stream_failure:
@@ -2148,8 +2148,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
                src_pp = NULL;
 
        rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, false,
-                  NULL);
+                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
 
        client->v6_route_del_cnt++;
 
index 67832f2d3fe54ba157f6c205ccb6d8dcf00f29cc..7ec640164afcc57081cd5ba519379e93bd31d0d3 100644 (file)
@@ -2394,8 +2394,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                unsigned short instance, int flags, struct prefix *p,
                struct prefix_ipv6 *src_p, const struct nexthop *nh,
-               uint32_t table_id, uint32_t metric, bool fromkernel,
-               struct ethaddr *rmac)
+               uint32_t table_id, uint32_t metric, bool fromkernel)
 {
        struct route_table *table;
        struct route_node *rn;
@@ -2569,7 +2568,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                               &(tmp_nh->gate.ipv6),
                                               sizeof(struct in6_addr));
                                }
-                               zebra_vxlan_evpn_vrf_route_del(re->vrf_id, rmac,
+                               zebra_vxlan_evpn_vrf_route_del(re->vrf_id,
                                                               &vtep_ip, p);
                        }
                }
index 6e901a0457c6750487deb1a90da518fe4d35de4c..af01cd9c70aa9fc17847a69dc6e162e6980b0a61 100644 (file)
@@ -3238,15 +3238,9 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
 
 
 /* handle rmac delete */
-static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
+static void zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac,
                                  struct prefix *host_prefix)
 {
-       zebra_mac_t *zrmac = NULL;
-
-       zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
-       if (!zrmac)
-               return -1;
-
        host_list_delete_host(zrmac->host_list, host_prefix);
        if (list_isempty(zrmac->host_list)) {
 
@@ -3256,7 +3250,6 @@ static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
                /* del the rmac entry */
                zl3vni_rmac_del(zl3vni, zrmac);
        }
-       return 0;
 }
 
 /*
@@ -3394,15 +3387,9 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
 }
 
 /* handle nh neigh delete */
-static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
-                               struct prefix *host_prefix)
+static void zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *nh,
+                                struct prefix *host_prefix)
 {
-       zebra_neigh_t *nh = NULL;
-
-       nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
-       if (!nh)
-               return -1;
-
        host_list_delete_host(nh->host_list, host_prefix);
        if (list_isempty(nh->host_list)) {
 
@@ -3412,8 +3399,6 @@ static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
                /* delete the nh entry */
                zl3vni_nh_del(zl3vni, nh);
        }
-
-       return 0;
 }
 
 /* handle neigh update from kernel - the only thing of interest is to
@@ -3971,21 +3956,31 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
 }
 
 /* handle evpn vrf route delete */
-void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, struct ethaddr *rmac,
+void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
                                    struct ipaddr *vtep_ip,
                                    struct prefix *host_prefix)
 {
        zebra_l3vni_t *zl3vni = NULL;
+       zebra_neigh_t *nh = NULL;
+       zebra_mac_t *zrmac = NULL;
 
        zl3vni = zl3vni_from_vrf(vrf_id);
        if (!zl3vni)
                return;
 
+       /* find the next hop entry and rmac entry */
+       nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
+       if (!nh)
+               return;
+       zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
+
        /* delete the next hop entry */
-       zl3vni_remote_nh_del(zl3vni, vtep_ip, host_prefix);
+       zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
 
        /* delete the rmac entry */
-       zl3vni_remote_rmac_del(zl3vni, rmac, host_prefix);
+       if (zrmac)
+               zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix);
+
 }
 
 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
index 6153c7d7e32f31f45a2501250957405697d27e7f..34d115275102ddab077e868e43cbcbd4661e69b7 100644 (file)
@@ -160,7 +160,6 @@ extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
                                           struct ipaddr *ip,
                                           struct prefix *host_prefix);
 extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
-                                          struct ethaddr *rmac,
                                           struct ipaddr *vtep_ip,
                                           struct prefix *host_prefix);