lib, bgpd: Distinguish between AF_EVPN and AF_ETHERNET

Create AF_EVPN for internal use and start using it.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-08-08 10:16:12 -04:00
parent b34fd35d3a
commit b03b88986e
6 changed files with 54 additions and 22 deletions

View 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;

View 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);

View 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;

View 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))) {

View 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:

View 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)));
};