mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 01:47:29 +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);
|
prefix_copy(src, dst);
|
||||||
memset(dst, 0, sizeof(struct prefix));
|
memset(dst, 0, sizeof(struct prefix));
|
||||||
p_evpn_p = &(dst->u.prefix_evpn);
|
p_evpn_p = &(dst->u.prefix_evpn);
|
||||||
dst->family = AF_ETHERNET;
|
dst->family = AF_EVPN;
|
||||||
p_evpn_p->route_type = evpn_type;
|
p_evpn_p->route_type = evpn_type;
|
||||||
if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
|
if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
|
||||||
p_evpn_p->eth_tag = eth_tag;
|
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. */
|
/* Make EVPN prefix. */
|
||||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||||
p.family = AF_ETHERNET;
|
p.family = AF_EVPN;
|
||||||
p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
||||||
p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
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. */
|
/* Make EVPN prefix. */
|
||||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||||
p.family = AF_ETHERNET;
|
p.family = AF_EVPN;
|
||||||
p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
||||||
p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
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. */
|
/* Make EVPN prefix. */
|
||||||
memset(&p, 0, sizeof(struct prefix_evpn));
|
memset(&p, 0, sizeof(struct prefix_evpn));
|
||||||
p.family = AF_ETHERNET;
|
p.family = AF_EVPN;
|
||||||
p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
|
p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
|
||||||
|
|
||||||
/* Additional information outside of prefix - ESI and GW IP */
|
/* 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;
|
struct evpn_addr *p_evpn_p;
|
||||||
|
|
||||||
memset(&temp, 0, 16);
|
memset(&temp, 0, 16);
|
||||||
if (p->family != AF_ETHERNET)
|
if (p->family != AF_EVPN)
|
||||||
return;
|
return;
|
||||||
p_evpn_p = &(p->u.prefix_evpn);
|
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));
|
PREFIX2STR_BUFFER));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Currently, this is to cater to other AF_ETHERNET code. */
|
/* For EVPN route types not supported yet. */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (buf);
|
return (buf);
|
||||||
|
@ -174,7 +174,7 @@ static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
|
|||||||
struct ipaddr *ip)
|
struct ipaddr *ip)
|
||||||
{
|
{
|
||||||
memset(p, 0, sizeof(struct prefix_evpn));
|
memset(p, 0, sizeof(struct prefix_evpn));
|
||||||
p->family = AF_ETHERNET;
|
p->family = AF_EVPN;
|
||||||
p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
|
||||||
p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
|
||||||
memcpy(&p->prefix.mac.octet, mac->octet, ETH_ALEN);
|
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)
|
struct in_addr originator_ip)
|
||||||
{
|
{
|
||||||
memset(p, 0, sizeof(struct prefix_evpn));
|
memset(p, 0, sizeof(struct prefix_evpn));
|
||||||
p->family = AF_ETHERNET;
|
p->family = AF_EVPN;
|
||||||
p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
|
||||||
p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
|
||||||
p->prefix.ip.ipa_type = IPADDR_V4;
|
p->prefix.ip.ipa_type = IPADDR_V4;
|
||||||
|
@ -6246,6 +6246,9 @@ static void route_vty_out_route(struct prefix *p, struct vty *vty)
|
|||||||
} else
|
} else
|
||||||
len += vty_out(vty, "/%d", p->prefixlen);
|
len += vty_out(vty, "/%d", p->prefixlen);
|
||||||
} else if (p->family == AF_ETHERNET) {
|
} 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)
|
#if defined(HAVE_CUMULUS)
|
||||||
len = vty_out(vty, "%s",
|
len = vty_out(vty, "%s",
|
||||||
bgp_evpn_route2str((struct prefix_evpn *)p, buf,
|
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 (attr) {
|
||||||
if (((p->family == AF_INET)
|
if (((p->family == AF_INET)
|
||||||
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|
&& ((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))
|
||||||
|| (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
|| (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||||
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|
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)
|
} else if (((p->family == AF_INET6)
|
||||||
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|
&& ((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))
|
||||||
|| (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
|| (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
||||||
char buf_a[BUFSIZ];
|
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 */
|
/* Line2 display Next-hop, Neighbor, Router-id */
|
||||||
/* Display the nexthop */
|
/* 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_MPLS_VPN || safi == SAFI_ENCAP
|
||||||
|| safi == SAFI_EVPN
|
|| safi == SAFI_EVPN
|
||||||
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
|
|| !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;
|
return AF_INET6;
|
||||||
else if (!strcmp("ethernet", string))
|
else if (!strcmp("ethernet", string))
|
||||||
return AF_ETHERNET;
|
return AF_ETHERNET;
|
||||||
|
else if (!strcmp("evpn", string))
|
||||||
|
return AF_EVPN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +348,7 @@ int afi2family(afi_t afi)
|
|||||||
return AF_INET6;
|
return AF_INET6;
|
||||||
else if (afi == AFI_L2VPN)
|
else if (afi == AFI_L2VPN)
|
||||||
return AF_ETHERNET;
|
return AF_ETHERNET;
|
||||||
|
/* NOTE: EVPN code should NOT use this interface. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +358,7 @@ afi_t family2afi(int family)
|
|||||||
return AFI_IP;
|
return AFI_IP;
|
||||||
else if (family == AF_INET6)
|
else if (family == AF_INET6)
|
||||||
return AFI_IP6;
|
return AFI_IP6;
|
||||||
else if (family == AF_ETHERNET)
|
else if (family == AF_ETHERNET || family == AF_EVPN)
|
||||||
return AFI_L2VPN;
|
return AFI_L2VPN;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -461,6 +464,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
|
|||||||
else if (src->family == AF_INET6)
|
else if (src->family == AF_INET6)
|
||||||
dest->u.prefix6 = src->u.prefix6;
|
dest->u.prefix6 = src->u.prefix6;
|
||||||
else if (src->family == AF_ETHERNET) {
|
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,
|
memcpy(&dest->u.prefix_evpn, &src->u.prefix_evpn,
|
||||||
sizeof(struct evpn_addr));
|
sizeof(struct evpn_addr));
|
||||||
} else if (src->family == AF_UNSPEC) {
|
} 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))
|
&p2->u.prefix6.s6_addr))
|
||||||
return 1;
|
return 1;
|
||||||
if (p1->family == AF_ETHERNET)
|
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,
|
if (!memcmp(&p1->u.prefix_evpn, &p2->u.prefix_evpn,
|
||||||
sizeof(struct evpn_addr)))
|
sizeof(struct evpn_addr)))
|
||||||
return 1;
|
return 1;
|
||||||
@ -581,6 +591,8 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2)
|
|||||||
if (p1->family == AF_INET6)
|
if (p1->family == AF_INET6)
|
||||||
length = IPV6_MAX_BYTELEN;
|
length = IPV6_MAX_BYTELEN;
|
||||||
if (p1->family == AF_ETHERNET)
|
if (p1->family == AF_ETHERNET)
|
||||||
|
length = ETH_ALEN;
|
||||||
|
if (p1->family == AF_EVPN)
|
||||||
length = 8 * sizeof(struct evpn_addr);
|
length = 8 * sizeof(struct evpn_addr);
|
||||||
|
|
||||||
if (p1->family != p2->family || !length)
|
if (p1->family != p2->family || !length)
|
||||||
@ -609,6 +621,8 @@ const char *prefix_family_str(const struct prefix *p)
|
|||||||
return "inet6";
|
return "inet6";
|
||||||
if (p->family == AF_ETHERNET)
|
if (p->family == AF_ETHERNET)
|
||||||
return "ether";
|
return "ether";
|
||||||
|
if (p->family == AF_EVPN)
|
||||||
|
return "evpn";
|
||||||
return "unspec";
|
return "unspec";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,6 +979,7 @@ int prefix_blen(const struct prefix *p)
|
|||||||
break;
|
break;
|
||||||
case AF_ETHERNET:
|
case AF_ETHERNET:
|
||||||
return ETH_ALEN;
|
return ETH_ALEN;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -992,7 +1007,7 @@ int str2prefix(const char *str, struct prefix *p)
|
|||||||
return 0;
|
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;
|
u_char family;
|
||||||
char buf[PREFIX2STR_BUFFER];
|
char buf[PREFIX2STR_BUFFER];
|
||||||
@ -1036,12 +1051,8 @@ static const char *prefixeth2str(const struct prefix *p, char *str, int size)
|
|||||||
PREFIX2STR_BUFFER),
|
PREFIX2STR_BUFFER),
|
||||||
p->prefixlen);
|
p->prefixlen);
|
||||||
} else {
|
} else {
|
||||||
sprintf(str, "UNK AF_ETHER prefix");
|
sprintf(str, "Unsupported EVPN route type %d",
|
||||||
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
|
p->u.prefix_evpn.route_type);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
@ -1061,7 +1072,13 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_ETHERNET:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
15
lib/prefix.h
15
lib/prefix.h
@ -116,7 +116,18 @@ struct evpn_addr {
|
|||||||
#endif
|
#endif
|
||||||
#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 {
|
struct prefix {
|
||||||
u_char family;
|
u_char family;
|
||||||
u_char prefixlen;
|
u_char prefixlen;
|
||||||
@ -131,7 +142,7 @@ struct prefix {
|
|||||||
struct ethaddr prefix_eth; /* AF_ETHERNET */
|
struct ethaddr prefix_eth; /* AF_ETHERNET */
|
||||||
u_char val[8];
|
u_char val[8];
|
||||||
uintptr_t ptr;
|
uintptr_t ptr;
|
||||||
struct evpn_addr prefix_evpn;
|
struct evpn_addr prefix_evpn; /* AF_EVPN */
|
||||||
} u __attribute__((aligned(8)));
|
} u __attribute__((aligned(8)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user