]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, bgpd: Distinguish between AF_EVPN and AF_ETHERNET
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Aug 2017 14:16:12 +0000 (10:16 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Aug 2017 14:34:31 +0000 (10:34 -0400)
Create AF_EVPN for internal use and start using it.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
bgpd/bgp_attr_evpn.c
bgpd/bgp_evpn.c
bgpd/bgp_evpn_private.h
bgpd/bgp_route.c
lib/prefix.c
lib/prefix.h

index 2f0b566ccf0fa7c7c88bbe1b37dc542add17655b..6ead059261e635da03fcb3dbbcadbeac1fe8e154 100644 (file)
@@ -169,7 +169,7 @@ extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
        prefix_copy(src, dst);
        memset(dst, 0, sizeof(struct prefix));
        p_evpn_p = &(dst->u.prefix_evpn);
-       dst->family = AF_ETHERNET;
+       dst->family = AF_EVPN;
        p_evpn_p->route_type = evpn_type;
        if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
                p_evpn_p->eth_tag = eth_tag;
index 67484efe12184e4629bf9b10644b9287ad15eeca..0560dc46f961db6864c77465abc979c815e462a6 100644 (file)
@@ -1807,7 +1807,7 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
 
        /* Make EVPN prefix. */
        memset(&p, 0, sizeof(struct prefix_evpn));
-       p.family = AF_ETHERNET;
+       p.family = AF_EVPN;
        p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
        p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
 
@@ -1896,7 +1896,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
 
        /* Make EVPN prefix. */
        memset(&p, 0, sizeof(struct prefix_evpn));
-       p.family = AF_ETHERNET;
+       p.family = AF_EVPN;
        p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
        p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
 
@@ -1961,7 +1961,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
 
        /* Make EVPN prefix. */
        memset(&p, 0, sizeof(struct prefix_evpn));
-       p.family = AF_ETHERNET;
+       p.family = AF_EVPN;
        p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
 
        /* Additional information outside of prefix - ESI and GW IP */
@@ -2030,7 +2030,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
        struct evpn_addr *p_evpn_p;
 
        memset(&temp, 0, 16);
-       if (p->family != AF_ETHERNET)
+       if (p->family != AF_EVPN)
                return;
        p_evpn_p = &(p->u.prefix_evpn);
 
@@ -2213,7 +2213,7 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
                                           PREFIX2STR_BUFFER));
                }
        } else {
-               /* Currently, this is to cater to other AF_ETHERNET code. */
+               /* For EVPN route types not supported yet. */
        }
 
        return (buf);
index e6f6301405b1de827fd34f90962f2e1eb393c5f3..9dc459cd4e3c1ff88c6233fa492f2693f9427534 100644 (file)
@@ -174,7 +174,7 @@ static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
                                           struct ipaddr *ip)
 {
        memset(p, 0, sizeof(struct prefix_evpn));
-       p->family = AF_ETHERNET;
+       p->family = AF_EVPN;
        p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
        p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
        memcpy(&p->prefix.mac.octet, mac->octet, ETH_ALEN);
@@ -187,7 +187,7 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
                                           struct in_addr originator_ip)
 {
        memset(p, 0, sizeof(struct prefix_evpn));
-       p->family = AF_ETHERNET;
+       p->family = AF_EVPN;
        p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
        p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
        p->prefix.ip.ipa_type = IPADDR_V4;
index bce54ab2d0bcbfe9c132262d52b828696554cea4..35f793f8612b61a24dee0699fde8afceef0e54d2 100644 (file)
@@ -6246,6 +6246,9 @@ static void route_vty_out_route(struct prefix *p, struct vty *vty)
                } else
                        len += vty_out(vty, "/%d", p->prefixlen);
        } else if (p->family == AF_ETHERNET) {
+               prefix2str(p, buf, PREFIX_STRLEN);
+               len = vty_out(vty, "%s", buf);
+       } else if (p->family == AF_EVPN) {
 #if defined(HAVE_CUMULUS)
                len = vty_out(vty, "%s",
                              bgp_evpn_route2str((struct prefix_evpn *)p, buf,
@@ -6808,7 +6811,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p,
        if (attr) {
                if (((p->family == AF_INET)
                     && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
-                   || (safi == SAFI_EVPN && p->family == AF_ETHERNET
+                   || (safi == SAFI_EVPN
                        && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
                    || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
                        if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
@@ -6833,7 +6836,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p,
                        }
                } else if (((p->family == AF_INET6)
                            && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
-                          || (safi == SAFI_EVPN && p->family == AF_ETHERNET
+                          || (safi == SAFI_EVPN
                               && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
                           || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
                        char buf_a[BUFSIZ];
@@ -7333,7 +7336,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
 
                /* Line2 display Next-hop, Neighbor, Router-id */
                /* Display the nexthop */
-               if ((p->family == AF_INET || p->family == AF_ETHERNET)
+               if ((p->family == AF_INET || p->family == AF_ETHERNET ||
+                    p->family == AF_EVPN)
                    && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                        || safi == SAFI_EVPN
                        || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
index edfc22fb428d118704f7cdd0a91f9262f3d20b24..df638b0fc87b0a59129a34dd0290f5ce44f2e8e2 100644 (file)
@@ -334,6 +334,8 @@ int str2family(const char *string)
                return AF_INET6;
        else if (!strcmp("ethernet", string))
                return AF_ETHERNET;
+       else if (!strcmp("evpn", string))
+               return AF_EVPN;
        return -1;
 }
 
@@ -346,6 +348,7 @@ int afi2family(afi_t afi)
                return AF_INET6;
        else if (afi == AFI_L2VPN)
                return AF_ETHERNET;
+       /* NOTE: EVPN code should NOT use this interface. */
        return 0;
 }
 
@@ -355,7 +358,7 @@ afi_t family2afi(int family)
                return AFI_IP;
        else if (family == AF_INET6)
                return AFI_IP6;
-       else if (family == AF_ETHERNET)
+       else if (family == AF_ETHERNET || family == AF_EVPN)
                return AFI_L2VPN;
        return 0;
 }
@@ -461,6 +464,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
        else if (src->family == AF_INET6)
                dest->u.prefix6 = src->u.prefix6;
        else if (src->family == AF_ETHERNET) {
+               memcpy(&dest->u.prefix_eth, &src->u.prefix_eth,
+                      sizeof(struct ethaddr));
+       } else if (src->family == AF_EVPN) {
                memcpy(&dest->u.prefix_evpn, &src->u.prefix_evpn,
                       sizeof(struct evpn_addr));
        } else if (src->family == AF_UNSPEC) {
@@ -517,6 +523,10 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2)
                                           &p2->u.prefix6.s6_addr))
                                return 1;
                if (p1->family == AF_ETHERNET)
+                       if (!memcmp(&p1->u.prefix_eth, &p2->u.prefix_eth,
+                                   sizeof(struct ethaddr)))
+                               return 1;
+               if (p1->family == AF_EVPN)
                        if (!memcmp(&p1->u.prefix_evpn, &p2->u.prefix_evpn,
                                    sizeof(struct evpn_addr)))
                                return 1;
@@ -581,6 +591,8 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2)
        if (p1->family == AF_INET6)
                length = IPV6_MAX_BYTELEN;
        if (p1->family == AF_ETHERNET)
+               length = ETH_ALEN;
+       if (p1->family == AF_EVPN)
                length = 8 * sizeof(struct evpn_addr);
 
        if (p1->family != p2->family || !length)
@@ -609,6 +621,8 @@ const char *prefix_family_str(const struct prefix *p)
                return "inet6";
        if (p->family == AF_ETHERNET)
                return "ether";
+       if (p->family == AF_EVPN)
+               return "evpn";
        return "unspec";
 }
 
@@ -965,6 +979,7 @@ int prefix_blen(const struct prefix *p)
                break;
        case AF_ETHERNET:
                return ETH_ALEN;
+               break;
        }
        return 0;
 }
@@ -992,7 +1007,7 @@ int str2prefix(const char *str, struct prefix *p)
        return 0;
 }
 
-static const char *prefixeth2str(const struct prefix *p, char *str, int size)
+static const char *prefixevpn2str(const struct prefix *p, char *str, int size)
 {
        u_char family;
        char buf[PREFIX2STR_BUFFER];
@@ -1036,12 +1051,8 @@ static const char *prefixeth2str(const struct prefix *p, char *str, int size)
                                   PREFIX2STR_BUFFER),
                         p->prefixlen);
        } else {
-               sprintf(str, "UNK AF_ETHER prefix");
-               snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
-                        p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1],
-                        p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3],
-                        p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5],
-                        p->prefixlen);
+               sprintf(str, "Unsupported EVPN route type %d",
+                        p->u.prefix_evpn.route_type);
        }
 
        return str;
@@ -1061,7 +1072,13 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
                break;
 
        case AF_ETHERNET:
-               prefixeth2str(p, str, size);
+               snprintf(str, size, "%s/%d",
+                        prefix_mac2str(&p->u.prefix_eth, buf, sizeof(buf)),
+                        p->prefixlen);
+               break;
+
+       case AF_EVPN:
+               prefixevpn2str(p, str, size);
                break;
 
        default:
index f665f55dfd7536adf98148679ffc0c924b7c370e..3ebf6154684c1e8c9a8a890e687ea8944ee8add1 100644 (file)
@@ -116,7 +116,18 @@ struct evpn_addr {
 #endif
 #endif
 
-/* IPv4 and IPv6 unified prefix structure. */
+/* The 'family' in the prefix structure is internal to FRR and need not
+ * map to standard OS AF_ definitions except where needed for interacting
+ * with the kernel. However, AF_ definitions are currently in use and
+ * prevalent across the code. Define a new FRR-specific AF for EVPN to
+ * distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and
+ * ensure it does not conflict with any OS AF_ definition.
+ */
+#if !defined(AF_EVPN)
+#define AF_EVPN (AF_MAX + 1)
+#endif
+
+/* FRR generic prefix structure. */
 struct prefix {
        u_char family;
        u_char prefixlen;
@@ -131,7 +142,7 @@ struct prefix {
                struct ethaddr prefix_eth; /* AF_ETHERNET */
                u_char val[8];
                uintptr_t ptr;
-               struct evpn_addr prefix_evpn;
+               struct evpn_addr prefix_evpn; /* AF_EVPN */
        } u __attribute__((aligned(8)));
 };