mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 11:24:42 +00:00
lib: Refine EVPN prefix definition
Modify EVPN prefix to use the generic IP address structure. Add support for EVPN type-2 and type-3 prefix dump. Fix references to modified fields as needed. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
482c0fb076
commit
86f1ef44f7
@ -125,13 +125,13 @@ bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
|
|||||||
p_evpn_p->eth_tag = eth_tag;
|
p_evpn_p->eth_tag = eth_tag;
|
||||||
p_evpn_p->ip_prefix_length = p2.prefixlen;
|
p_evpn_p->ip_prefix_length = p2.prefixlen;
|
||||||
if (src->family == AF_INET) {
|
if (src->family == AF_INET) {
|
||||||
p_evpn_p->flags = IP_PREFIX_V4;
|
SET_IPADDR_V4 (&p_evpn_p->ip);
|
||||||
memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4,
|
memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4,
|
||||||
sizeof(struct in_addr));
|
sizeof(struct in_addr));
|
||||||
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
|
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
|
||||||
} else {
|
} else {
|
||||||
p_evpn_p->flags = IP_PREFIX_V6;
|
SET_IPADDR_V6 (&p_evpn_p->ip);
|
||||||
memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6,
|
memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6,
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6;
|
dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6;
|
||||||
}
|
}
|
||||||
|
@ -124,20 +124,20 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
|||||||
/* determine IPv4 or IPv6 prefix */
|
/* determine IPv4 or IPv6 prefix */
|
||||||
if (route_length - 4 - 10 - 8 -
|
if (route_length - 4 - 10 - 8 -
|
||||||
3 /* label to be read */ >= 32) {
|
3 /* label to be read */ >= 32) {
|
||||||
p_evpn_p->flags = IP_PREFIX_V6;
|
SET_IPADDR_V6 (&p_evpn_p->ip);
|
||||||
memcpy(&(p_evpn_p->ip.v6_addr), pnt, 16);
|
memcpy(&(p_evpn_p->ip.ipaddr_v6), pnt, 16);
|
||||||
pnt += 16;
|
pnt += 16;
|
||||||
memcpy(&evpn.gw_ip.ipv6, pnt, 16);
|
memcpy(&evpn.gw_ip.ipv6, pnt, 16);
|
||||||
pnt += 16;
|
pnt += 16;
|
||||||
} else {
|
} else {
|
||||||
p_evpn_p->flags = IP_PREFIX_V4;
|
SET_IPADDR_V4 (&p_evpn_p->ip);
|
||||||
memcpy(&(p_evpn_p->ip.v4_addr), pnt, 4);
|
memcpy(&(p_evpn_p->ip.ipaddr_v4), pnt, 4);
|
||||||
pnt += 4;
|
pnt += 4;
|
||||||
memcpy(&evpn.gw_ip.ipv4, pnt, 4);
|
memcpy(&evpn.gw_ip.ipv4, pnt, 4);
|
||||||
pnt += 4;
|
pnt += 4;
|
||||||
}
|
}
|
||||||
p.family = AFI_L2VPN;
|
p.family = AFI_L2VPN;
|
||||||
if (p_evpn_p->flags == IP_PREFIX_V4)
|
if (IS_IPADDR_V4(&p_evpn_p->ip))
|
||||||
p.prefixlen =
|
p.prefixlen =
|
||||||
(u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
|
(u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
|
||||||
else
|
else
|
||||||
@ -184,7 +184,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
|
|||||||
if (p->family != AF_ETHERNET)
|
if (p->family != AF_ETHERNET)
|
||||||
return;
|
return;
|
||||||
p_evpn_p = &(p->u.prefix_evpn);
|
p_evpn_p = &(p->u.prefix_evpn);
|
||||||
if (p_evpn_p->flags & IP_PREFIX_V4)
|
if (IS_IPADDR_V4(&p_evpn_p->ip))
|
||||||
len = 8; /* ipv4 */
|
len = 8; /* ipv4 */
|
||||||
else
|
else
|
||||||
len = 32; /* ipv6 */
|
len = 32; /* ipv6 */
|
||||||
@ -199,12 +199,12 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
|
|||||||
stream_put(s, &temp, 10);
|
stream_put(s, &temp, 10);
|
||||||
stream_putl(s, p_evpn_p->eth_tag);
|
stream_putl(s, p_evpn_p->eth_tag);
|
||||||
stream_putc(s, p_evpn_p->ip_prefix_length);
|
stream_putc(s, p_evpn_p->ip_prefix_length);
|
||||||
if (p_evpn_p->flags & IP_PREFIX_V4)
|
if (IS_IPADDR_V4(&p_evpn_p->ip))
|
||||||
stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr);
|
stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr);
|
||||||
else
|
else
|
||||||
stream_put(s, &p_evpn_p->ip.v6_addr, 16);
|
stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16);
|
||||||
if (attr && attr->extra) {
|
if (attr && attr->extra) {
|
||||||
if (p_evpn_p->flags & IP_PREFIX_V4)
|
if (IS_IPADDR_V4(&p_evpn_p->ip))
|
||||||
stream_put_ipv4(s,
|
stream_put_ipv4(s,
|
||||||
attr->extra->evpn_overlay.gw_ip.ipv4.
|
attr->extra->evpn_overlay.gw_ip.ipv4.
|
||||||
s_addr);
|
s_addr);
|
||||||
@ -212,7 +212,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
|
|||||||
stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6),
|
stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6),
|
||||||
16);
|
16);
|
||||||
} else {
|
} else {
|
||||||
if (p_evpn_p->flags & IP_PREFIX_V4)
|
if (IS_IPADDR_V4(&p_evpn_p->ip))
|
||||||
stream_put_ipv4(s, 0);
|
stream_put_ipv4(s, 0);
|
||||||
else
|
else
|
||||||
stream_put(s, &temp, 16);
|
stream_put(s, &temp, 16);
|
||||||
|
@ -4608,8 +4608,10 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str
|
|||||||
vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
|
vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6))
|
if((gw_ip.family == AF_INET &&
|
||||||
|| (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4)))
|
IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)&p)) ||
|
||||||
|
(gw_ip.family == AF_INET6 &&
|
||||||
|
IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)&p)))
|
||||||
{
|
{
|
||||||
vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
|
vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
@ -6815,11 +6817,11 @@ route_vty_out_overlay (struct vty *vty, struct prefix *p,
|
|||||||
char *str = esi2str(id);
|
char *str = esi2str(id);
|
||||||
vty_out (vty, "%s", str);
|
vty_out (vty, "%s", str);
|
||||||
XFREE (MTYPE_TMP, str);
|
XFREE (MTYPE_TMP, str);
|
||||||
if (p->u.prefix_evpn.flags & IP_PREFIX_V4)
|
if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p))
|
||||||
{
|
{
|
||||||
vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
|
vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
|
||||||
}
|
}
|
||||||
else if (p->u.prefix_evpn.flags & IP_PREFIX_V6)
|
else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)p))
|
||||||
{
|
{
|
||||||
vty_out (vty, "/%s",
|
vty_out (vty, "/%s",
|
||||||
inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
|
inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
|
||||||
|
83
lib/prefix.c
83
lib/prefix.c
@ -852,6 +852,66 @@ str2prefix (const char *str, struct prefix *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
prefixeth2str (const struct prefix *p, char *str, int size)
|
||||||
|
{
|
||||||
|
u_char family;
|
||||||
|
char buf[PREFIX2STR_BUFFER];
|
||||||
|
char buf2[ETHER_ADDR_STRLEN];
|
||||||
|
|
||||||
|
if (p->u.prefix_evpn.route_type == 2)
|
||||||
|
{
|
||||||
|
if (IS_EVPN_PREFIX_IPADDR_NONE((struct prefix_evpn *)p))
|
||||||
|
snprintf (str, size, "[%d]:[%s]/%d",
|
||||||
|
p->u.prefix_evpn.route_type,
|
||||||
|
prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)),
|
||||||
|
p->prefixlen);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
|
||||||
|
AF_INET : AF_INET6;
|
||||||
|
snprintf (str, size, "[%d]:[%s]:[%s]/%d",
|
||||||
|
p->u.prefix_evpn.route_type,
|
||||||
|
prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)),
|
||||||
|
inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
|
||||||
|
buf, PREFIX2STR_BUFFER),
|
||||||
|
p->prefixlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (p->u.prefix_evpn.route_type == 3)
|
||||||
|
{
|
||||||
|
family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
|
||||||
|
AF_INET : AF_INET6;
|
||||||
|
snprintf (str, size, "[%d]:[%s]/%d",
|
||||||
|
p->u.prefix_evpn.route_type,
|
||||||
|
inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
|
||||||
|
buf, PREFIX2STR_BUFFER),
|
||||||
|
p->prefixlen);
|
||||||
|
}
|
||||||
|
else if (p->u.prefix_evpn.route_type == 5)
|
||||||
|
{
|
||||||
|
family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
|
||||||
|
AF_INET : AF_INET6;
|
||||||
|
snprintf (str, size, "[%d]:[%u][%s]/%d",
|
||||||
|
p->u.prefix_evpn.route_type,
|
||||||
|
p->u.prefix_evpn.eth_tag,
|
||||||
|
inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
|
||||||
|
buf, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
prefix2str (union prefixconstptr pu, char *str, int size)
|
prefix2str (union prefixconstptr pu, char *str, int size)
|
||||||
{
|
{
|
||||||
@ -868,28 +928,9 @@ prefix2str (union prefixconstptr pu, char *str, int size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_ETHERNET:
|
case AF_ETHERNET:
|
||||||
if (p->u.prefix_evpn.route_type == 5)
|
prefixeth2str (p, str, size);
|
||||||
{
|
|
||||||
u_char family;
|
|
||||||
family = (p->u.prefix_evpn.flags & (IP_ADDR_V4 | IP_PREFIX_V4)) ?
|
|
||||||
AF_INET : AF_INET6;
|
|
||||||
snprintf (str, size, "[%d]:[%u][%s]/%d",
|
|
||||||
p->u.prefix_evpn.route_type,
|
|
||||||
p->u.prefix_evpn.eth_tag,
|
|
||||||
inet_ntop (family, &p->u.prefix_evpn.ip.addr,
|
|
||||||
buf, 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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprintf (str, "UNK prefix");
|
sprintf (str, "UNK prefix");
|
||||||
break;
|
break;
|
||||||
|
30
lib/prefix.h
30
lib/prefix.h
@ -32,6 +32,7 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#include "sockunion.h"
|
#include "sockunion.h"
|
||||||
|
#include "ipaddr.h"
|
||||||
|
|
||||||
#ifndef ETHER_ADDR_LEN
|
#ifndef ETHER_ADDR_LEN
|
||||||
#ifdef ETHERADDRL
|
#ifdef ETHERADDRL
|
||||||
@ -62,30 +63,23 @@ struct ethaddr {
|
|||||||
struct evpn_addr
|
struct evpn_addr
|
||||||
{
|
{
|
||||||
u_char route_type;
|
u_char route_type;
|
||||||
u_char flags;
|
u_char ip_prefix_length;
|
||||||
#define IP_ADDR_NONE 0x0
|
|
||||||
#define IP_ADDR_V4 0x1
|
|
||||||
#define IP_ADDR_V6 0x2
|
|
||||||
#define IP_PREFIX_V4 0x4
|
|
||||||
#define IP_PREFIX_V6 0x8
|
|
||||||
struct ethaddr mac;
|
struct ethaddr mac;
|
||||||
uint32_t eth_tag;
|
uint32_t eth_tag;
|
||||||
u_char ip_prefix_length;
|
ipaddr_t ip;
|
||||||
|
#if 0
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
u_char addr;
|
u_char addr;
|
||||||
struct in_addr v4_addr;
|
struct in_addr v4_addr;
|
||||||
struct in6_addr v6_addr;
|
struct in6_addr v6_addr;
|
||||||
} ip;
|
} ip;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* EVPN prefix structure. */
|
#define IS_EVPN_PREFIX_IPADDR_NONE(evp) IS_IPADDR_NONE(&(evp)->prefix.ip)
|
||||||
struct prefix_evpn
|
#define IS_EVPN_PREFIX_IPADDR_V4(evp) IS_IPADDR_V4(&(evp)->prefix.ip)
|
||||||
{
|
#define IS_EVPN_PREFIX_IPADDR_V6(evp) IS_IPADDR_V6(&(evp)->prefix.ip)
|
||||||
u_char family;
|
|
||||||
u_char prefixlen;
|
|
||||||
struct evpn_addr prefix __attribute__ ((aligned (8)));
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A struct prefix contains an address family, a prefix length, and an
|
* A struct prefix contains an address family, a prefix length, and an
|
||||||
@ -167,6 +161,14 @@ struct prefix_eth
|
|||||||
struct ethaddr eth_addr __attribute__ ((aligned (8))); /* AF_ETHERNET */
|
struct ethaddr eth_addr __attribute__ ((aligned (8))); /* AF_ETHERNET */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* EVPN prefix structure. */
|
||||||
|
struct prefix_evpn
|
||||||
|
{
|
||||||
|
u_char family;
|
||||||
|
u_char prefixlen;
|
||||||
|
struct evpn_addr prefix __attribute__ ((aligned (8)));
|
||||||
|
};
|
||||||
|
|
||||||
/* Prefix for a generic pointer */
|
/* Prefix for a generic pointer */
|
||||||
struct prefix_ptr
|
struct prefix_ptr
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user