]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: rmac ext comm
authorMitesh Kanjariya <mitesh@cumulusnetworks.com>
Mon, 9 Oct 2017 11:55:57 +0000 (04:55 -0700)
committerMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 14 Dec 2017 18:57:05 +0000 (10:57 -0800)
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_attr_evpn.c
bgpd/bgp_attr_evpn.h
bgpd/bgp_ecommunity.c
bgpd/bgp_evpn.c
bgpd/bgp_evpn_private.h

index e80889500f089df249d0dbeb656f51124b532bb4..da6042d34059b7c4191931eb8b56d52df369b9eb 100644 (file)
@@ -1879,6 +1879,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
        attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
        attr->sticky = sticky;
 
+       /* Extract the Rmac, if any */
+       bgp_attr_rmac(attr, &attr->rmac);
+
        return BGP_ATTR_PARSE_PROCEED;
 }
 
index f694f01adb10be860f746d0d0d3232b3cc288908..1de1bee0f9d69fea750edecb6101e668cccf95bc 100644 (file)
@@ -182,6 +182,9 @@ struct attr {
 
        /* EVPN MAC Mobility sequence number, if any. */
        u_int32_t mm_seqnum;
+
+       /* EVPN local router-mac */
+       struct ethaddr rmac;
 };
 
 /* rmap_change_flags definition */
index 300c9ddb506a4f471a788ba351dfa4af33474986..eaa4e329d455b616ffd71ac6d2c22fadb05a8a81 100644 (file)
@@ -105,6 +105,35 @@ char *ecom_mac2str(char *ecom_mac)
        return prefix_mac2str((struct ethaddr *)en, NULL, 0);
 }
 
+/* Fetch router-mac from extended community */
+void bgp_attr_rmac(struct attr *attr,
+                  struct ethaddr *rmac)
+{
+       int i = 0;
+       struct ecommunity *ecom;
+
+       ecom = attr->ecommunity;
+       if (!ecom || !ecom->size)
+               return;
+
+       /* If there is a router mac extended community, set RMAC in attr */
+       for (i = 0; i < ecom->size; i++) {
+               u_char *pnt = NULL;
+               u_char type = 0;
+               u_char sub_type = 0;
+
+               pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
+               type = *pnt++;
+               sub_type = *pnt++;
+
+               if (!(type == ECOMMUNITY_ENCODE_EVPN &&
+                    sub_type == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC))
+                       continue;
+
+               memcpy(rmac, pnt, ETH_ALEN);
+       }
+}
+
 /*
  * Fetch and return the sequence number from MAC Mobility extended
  * community, if present, else 0.
index 15d9e126e404cd8e2ac42a4fa5a653355f507b7a..8b55cb30020bf4f7a168afad88b6adc43f90035e 100644 (file)
@@ -59,7 +59,7 @@ extern void bgp_add_routermac_ecom(struct attr *attr,
                                   struct ethaddr *routermac);
 extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag,
                                 struct prefix *dst);
-
+extern void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac);
 extern u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
                                              u_char *sticky);
 
index e19f516505f0d840c443bbfd8be00c3c52a0b8c2..9caf38d569b35a355f5f5fb60870d1961873c151 100644 (file)
@@ -695,19 +695,19 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
                } else if (type == ECOMMUNITY_ENCODE_EVPN) {
                        if (filter == ECOMMUNITY_ROUTE_TARGET)
                                continue;
-                       if (*pnt == ECOMMUNITY_SITE_ORIGIN) {
-                               char macaddr[6];
+                       if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC) {
+                               struct ethaddr rmac;
                                pnt++;
-                               memcpy(&macaddr, pnt, 6);
+                               memcpy(&rmac, pnt, ETH_ALEN);
                                len = sprintf(
                                        str_buf + str_pnt,
-                                       "EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
-                                       (uint8_t)macaddr[0],
-                                       (uint8_t)macaddr[1],
-                                       (uint8_t)macaddr[2],
-                                       (uint8_t)macaddr[3],
-                                       (uint8_t)macaddr[4],
-                                       (uint8_t)macaddr[5]);
+                                       "Rmac:%02x:%02x:%02x:%02x:%02x:%02x",
+                                       (uint8_t)rmac.octet[0],
+                                       (uint8_t)rmac.octet[1],
+                                       (uint8_t)rmac.octet[2],
+                                       (uint8_t)rmac.octet[3],
+                                       (uint8_t)rmac.octet[4],
+                                       (uint8_t)rmac.octet[5]);
                        } else if (*pnt
                                   == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
                                u_int32_t seqnum;
index b625297ac1e23725fe29436ebb22c462d0624287..64b2501705fd482e9e181273c1e58784234299d2 100644 (file)
@@ -433,8 +433,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr)
 {
        struct ecommunity ecom_encap;
        struct ecommunity ecom_sticky;
+       struct ecommunity ecom_rmac;
        struct ecommunity_val eval;
        struct ecommunity_val eval_sticky;
+       struct ecommunity_val eval_rmac;
        bgp_encap_types tnl_type;
        struct listnode *node, *nnode;
        struct ecommunity *ecom;
@@ -473,6 +475,15 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr)
                        ecommunity_merge(attr->ecommunity, &ecom_sticky);
        }
 
+       if (!is_zero_mac(&attr->rmac)) {
+               memset(&ecom_rmac, 0, sizeof(ecom_rmac));
+               encode_rmac_extcomm(&eval_rmac, &attr->rmac);
+               ecom_rmac.size = 1;
+               ecom_rmac.val = (uint8_t *)eval_rmac.val;
+               attr->ecommunity = ecommunity_merge(attr->ecommunity,
+                                                   &ecom_rmac);
+       }
+
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
 }
 
@@ -843,6 +854,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
        attr.mp_nexthop_global_in = vpn->originator_ip;
        attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
        attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0;
+       bgpevpn_get_rmac(vpn, &attr.rmac);
 
        /* Set up RT and ENCAP extended community. */
        build_evpn_route_extcomm(vpn, &attr);
@@ -989,10 +1001,12 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
        attr.nexthop = vpn->originator_ip;
        attr.mp_nexthop_global_in = vpn->originator_ip;
        attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
+       bgpevpn_get_rmac(vpn, &attr.rmac);
        attr_sticky.nexthop = vpn->originator_ip;
        attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
        attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
        attr_sticky.sticky = 1;
+       bgpevpn_get_rmac(vpn, &attr_sticky.rmac);
 
        /* Set up RT, ENCAP and sticky MAC extended community. */
        build_evpn_route_extcomm(vpn, &attr);
index e11f99f099da875c982a19ec485f1a9346472343..b983a00a767268ad62ea7645ba9113127be2ad03 100644 (file)
@@ -222,6 +222,15 @@ static inline vni_t label2vni(mpls_label_t *label)
        return vni;
 }
 
+static inline void encode_rmac_extcomm(struct ecommunity_val *eval,
+                                      struct ethaddr *rmac)
+{
+       memset(eval, 0, sizeof(*eval));
+       eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
+       eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC;
+       memcpy(&eval->val[2], rmac, ETH_ALEN);
+}
+
 static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq,
                                               struct ecommunity_val *eval)
 {