diff options
author | mitesh <mitesh@cumulusnetworks.com> | 2018-04-14 00:37:30 +0200 |
---|---|---|
committer | mitesh <mitesh@cumulusnetworks.com> | 2018-05-03 02:49:17 +0200 |
commit | 3714a3853c8c2b147e42cdd32b55958b4951917a (patch) | |
tree | 43b669aa91d7e6d4f9fe8d052517c1363820a8c7 /lib | |
parent | Merge pull request #2125 from qlyoung/fix-gcc-build-command-graph (diff) | |
download | frr-3714a3853c8c2b147e42cdd32b55958b4951917a.tar.xz frr-3714a3853c8c2b147e42cdd32b55958b4951917a.zip |
*: change struct evpn_addr to include a union of all evpn route types
EVPN prefix depends on the EVPN route type.
Currently, in FRR we have a prefix_evpn/evpn_addr which relates to a evpn prefix.
We need to convert this to encompass an union of various EVPN route-types.
This diff handles the necessary code changes to adopt the new struct evpn_addr.
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/prefix.c | 128 | ||||
-rw-r--r-- | lib/prefix.h | 91 |
2 files changed, 166 insertions, 53 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index b38dd9458..05af190e9 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1206,54 +1206,104 @@ int str2prefix(const char *str, struct prefix *p) return 0; } -static const char *prefixevpn2str(const struct prefix *p, char *str, int size) +static const char *prefixevpn_ead2str(const struct prefix_evpn *p, char *str, + int size) +{ + snprintf(str, size, "Unsupported EVPN prefix"); + return str; +} + +static const char *prefixevpn_macip2str(const struct prefix_evpn *p, char *str, + int size) { uint8_t 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), + if (is_evpn_prefix_ipaddr_none(p)) + snprintf(str, size, "[%d]:[%s]/%d", + p->prefix.route_type, + prefix_mac2str(&p->prefix.macip_addr.mac, + buf2, sizeof(buf2)), p->prefixlen); - } else if (p->u.prefix_evpn.route_type == 5) { - family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) + else { + family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6; - snprintf(str, size, "[%d]:[%u][%s/%d]/%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->u.prefix_evpn.ip_prefix_length, p->prefixlen); - } else { - sprintf(str, "Unsupported EVPN route type %d", - p->u.prefix_evpn.route_type); + snprintf(str, size, "[%d]:[%s]:[%s]/%d", + p->prefix.route_type, + prefix_mac2str(&p->prefix.macip_addr.mac, + buf2, sizeof(buf2)), + inet_ntop(family, + &p->prefix.macip_addr.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->prefixlen); } + return str; +} + +static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str, + int size) +{ + uint8_t family; + char buf[PREFIX2STR_BUFFER]; + + family = is_evpn_prefix_ipaddr_v4(p) + ? AF_INET + : AF_INET6; + snprintf(str, size, "[%d]:[%s]/%d", p->prefix.route_type, + inet_ntop(family, + &p->prefix.imet_addr.ip.ip.addr, buf, + PREFIX2STR_BUFFER), + p->prefixlen); + return str; +} +static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str, + int size) +{ + snprintf(str, size, "Unsupported EVPN prefix"); + return str; +} + +static const char *prefixevpn_prefix2str(const struct prefix_evpn *p, char *str, + int size) +{ + uint8_t family; + char buf[PREFIX2STR_BUFFER]; + + family = is_evpn_prefix_ipaddr_v4(p) + ? AF_INET + : AF_INET6; + snprintf(str, size, "[%d]:[%u][%s/%d]/%d", + p->prefix.route_type, + p->prefix.prefix_addr.eth_tag, + inet_ntop(family, + &p->prefix.prefix_addr.ip.ip.addr, buf, + PREFIX2STR_BUFFER), + p->prefix.prefix_addr.ip_prefix_length, + p->prefixlen); + return str; +} + +static const char *prefixevpn2str(const struct prefix_evpn *p, char *str, + int size) +{ + switch (p->prefix.route_type) { + case 1: + return prefixevpn_ead2str(p, str, size); + case 2: + return prefixevpn_macip2str(p, str, size); + case 3: + return prefixevpn_imet2str(p, str, size); + case 4: + return prefixevpn_es2str(p, str, size); + case 5: + return prefixevpn_prefix2str(p, str, size); + default: + snprintf(str, size, "Unsupported EVPN prefix"); + break; + } return str; } @@ -1277,7 +1327,7 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size) break; case AF_EVPN: - prefixevpn2str(p, str, size); + prefixevpn2str((const struct prefix_evpn *)p, str, size); break; case AF_FLOWSPEC: diff --git a/lib/prefix.h b/lib/prefix.h index f01c85b81..ab3c05ae7 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -56,26 +56,56 @@ struct ethaddr { #define PREFIX_LEN_ROUTE_TYPE_5_IPV4 (18*8) #define PREFIX_LEN_ROUTE_TYPE_5_IPV6 (30*8) -/* EVPN address (RFC 7432) */ -struct evpn_addr { - uint8_t route_type; +typedef struct esi_t_ { + uint8_t val[10]; +} esi_t; + +struct evpn_ead_addr { + esi_t esi; + uint32_t eth_tag; +}; + +struct evpn_macip_addr { + uint32_t eth_tag; uint8_t ip_prefix_length; struct ethaddr mac; + struct ipaddr ip; +}; + +struct evpn_imet_addr { uint32_t eth_tag; + uint8_t ip_prefix_length; struct ipaddr ip; -#if 0 - union - { - uint8_t addr; - struct in_addr v4_addr; - struct in6_addr v6_addr; - } ip; -#endif }; -#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) +struct evpn_es_addr { + esi_t esi; + uint8_t ip_prefix_length; + struct ipaddr ip; +}; + +struct evpn_prefix_addr { + uint32_t eth_tag; + uint8_t ip_prefix_length; + struct ipaddr ip; +}; + +/* EVPN address (RFC 7432) */ +struct evpn_addr { + uint8_t route_type; + union { + struct evpn_ead_addr _ead_addr; + struct evpn_macip_addr _macip_addr; + struct evpn_imet_addr _imet_addr; + struct evpn_es_addr _es_addr; + struct evpn_prefix_addr _prefix_addr; + } u; +#define ead_addr u._ead_addr +#define macip_addr u._macip_addr +#define imet_addr u._imet_addr +#define es_addr u._es_addr +#define prefix_addr u._prefix_addr +}; /* * A struct prefix contains an address family, a prefix length, and an @@ -177,6 +207,39 @@ struct prefix_evpn { struct evpn_addr prefix __attribute__((aligned(8))); }; +static inline int is_evpn_prefix_ipaddr_none(const struct prefix_evpn *evp) +{ + if (evp->prefix.route_type == 2) + return IS_IPADDR_NONE(&(evp)->prefix.macip_addr.ip); + if (evp->prefix.route_type == 3) + return IS_IPADDR_NONE(&(evp)->prefix.imet_addr.ip); + if (evp->prefix.route_type == 5) + return IS_IPADDR_NONE(&(evp)->prefix.prefix_addr.ip); + return 0; +} + +static inline int is_evpn_prefix_ipaddr_v4(const struct prefix_evpn *evp) +{ + if (evp->prefix.route_type == 2) + return IS_IPADDR_V4(&(evp)->prefix.macip_addr.ip); + if (evp->prefix.route_type == 3) + return IS_IPADDR_V4(&(evp)->prefix.imet_addr.ip); + if (evp->prefix.route_type == 5) + return IS_IPADDR_V4(&(evp)->prefix.prefix_addr.ip); + return 0; +} + +static inline int is_evpn_prefix_ipaddr_v6(const struct prefix_evpn *evp) +{ + if (evp->prefix.route_type == 2) + return IS_IPADDR_V6(&(evp)->prefix.macip_addr.ip); + if (evp->prefix.route_type == 3) + return IS_IPADDR_V6(&(evp)->prefix.imet_addr.ip); + if (evp->prefix.route_type == 5) + return IS_IPADDR_V6(&(evp)->prefix.prefix_addr.ip); + return 0; +} + /* Prefix for a generic pointer */ struct prefix_ptr { uint8_t family; |