mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 15:16:20 +00:00
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:
parent
b34fd35d3a
commit
b03b88986e
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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))) {
|
||||
|
35
lib/prefix.c
35
lib/prefix.c
@ -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:
|
||||
|
15
lib/prefix.h
15
lib/prefix.h
@ -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)));
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user