diff options
author | vivek <vivek@cumulusnetworks.com> | 2017-05-15 07:20:33 +0200 |
---|---|---|
committer | vivek <vivek@cumulusnetworks.com> | 2017-05-25 19:20:03 +0200 |
commit | 86f1ef44f703ef4e6e1d127b30c5524becb80b5e (patch) | |
tree | c3f531cbb95d067a91dadc62c9ce18288bf9143f | |
parent | lib: Define generic IP address structure (diff) | |
download | frr-86f1ef44f703ef4e6e1d127b30c5524becb80b5e.tar.xz frr-86f1ef44f703ef4e6e1d127b30c5524becb80b5e.zip |
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>
-rw-r--r-- | bgpd/bgp_attr_evpn.c | 8 | ||||
-rw-r--r-- | bgpd/bgp_evpn.c | 22 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 10 | ||||
-rw-r--r-- | lib/prefix.c | 83 | ||||
-rw-r--r-- | lib/prefix.h | 30 |
5 files changed, 99 insertions, 54 deletions
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index e565d0801..6970d5a67 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -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->ip_prefix_length = p2.prefixlen; if (src->family == AF_INET) { - p_evpn_p->flags = IP_PREFIX_V4; - memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4, + SET_IPADDR_V4 (&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4, sizeof(struct in_addr)); dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; } else { - p_evpn_p->flags = IP_PREFIX_V6; - memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6, + SET_IPADDR_V6 (&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6, sizeof(struct in6_addr)); dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6; } diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c5a0ef889..6738f3cd1 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -124,20 +124,20 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, /* determine IPv4 or IPv6 prefix */ if (route_length - 4 - 10 - 8 - 3 /* label to be read */ >= 32) { - p_evpn_p->flags = IP_PREFIX_V6; - memcpy(&(p_evpn_p->ip.v6_addr), pnt, 16); + SET_IPADDR_V6 (&p_evpn_p->ip); + memcpy(&(p_evpn_p->ip.ipaddr_v6), pnt, 16); pnt += 16; memcpy(&evpn.gw_ip.ipv6, pnt, 16); pnt += 16; } else { - p_evpn_p->flags = IP_PREFIX_V4; - memcpy(&(p_evpn_p->ip.v4_addr), pnt, 4); + SET_IPADDR_V4 (&p_evpn_p->ip); + memcpy(&(p_evpn_p->ip.ipaddr_v4), pnt, 4); pnt += 4; memcpy(&evpn.gw_ip.ipv4, pnt, 4); pnt += 4; } p.family = AFI_L2VPN; - if (p_evpn_p->flags == IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) p.prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; else @@ -184,7 +184,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s, if (p->family != AF_ETHERNET) return; 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 */ else len = 32; /* ipv6 */ @@ -199,12 +199,12 @@ bgp_packet_mpattr_route_type_5(struct stream *s, stream_put(s, &temp, 10); stream_putl(s, p_evpn_p->eth_tag); stream_putc(s, p_evpn_p->ip_prefix_length); - if (p_evpn_p->flags & IP_PREFIX_V4) - stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr); + if (IS_IPADDR_V4(&p_evpn_p->ip)) + stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr); 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 (p_evpn_p->flags & IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4. 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), 16); } else { - if (p_evpn_p->flags & IP_PREFIX_V4) + if (IS_IPADDR_V4(&p_evpn_p->ip)) stream_put_ipv4(s, 0); else stream_put(s, &temp, 16); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7a328e79d..8f028b32c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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); return CMD_WARNING; } - if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6)) - || (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4))) + if((gw_ip.family == AF_INET && + 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); return CMD_WARNING; @@ -6815,11 +6817,11 @@ route_vty_out_overlay (struct vty *vty, struct prefix *p, char *str = esi2str(id); vty_out (vty, "%s", 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)); } - 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", inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6), diff --git a/lib/prefix.c b/lib/prefix.c index 9c228cf95..1bf196551 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -852,6 +852,66 @@ str2prefix (const char *str, struct prefix *p) 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 * prefix2str (union prefixconstptr pu, char *str, int size) { @@ -868,28 +928,9 @@ prefix2str (union prefixconstptr pu, char *str, int size) break; case AF_ETHERNET: - if (p->u.prefix_evpn.route_type == 5) - { - 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); - } + prefixeth2str (p, str, size); break; + default: sprintf (str, "UNK prefix"); break; diff --git a/lib/prefix.h b/lib/prefix.h index 35dfddd9d..a377c2757 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -32,6 +32,7 @@ # endif #endif #include "sockunion.h" +#include "ipaddr.h" #ifndef ETHER_ADDR_LEN #ifdef ETHERADDRL @@ -62,30 +63,23 @@ struct ethaddr { struct evpn_addr { u_char route_type; - u_char flags; -#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 + u_char ip_prefix_length; struct ethaddr mac; uint32_t eth_tag; - u_char ip_prefix_length; + ipaddr_t ip; +#if 0 union { u_char addr; struct in_addr v4_addr; struct in6_addr v6_addr; } ip; +#endif }; -/* EVPN prefix structure. */ -struct prefix_evpn -{ - u_char family; - u_char prefixlen; - struct evpn_addr prefix __attribute__ ((aligned (8))); -}; +#define IS_EVPN_PREFIX_IPADDR_NONE(evp) IS_IPADDR_NONE(&(evp)->prefix.ip) +#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) /* * 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 */ }; +/* EVPN prefix structure. */ +struct prefix_evpn +{ + u_char family; + u_char prefixlen; + struct evpn_addr prefix __attribute__ ((aligned (8))); +}; + /* Prefix for a generic pointer */ struct prefix_ptr { |