diff options
Diffstat (limited to 'lib/prefix.c')
| -rw-r--r-- | lib/prefix.c | 170 |
1 files changed, 100 insertions, 70 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index 84a04c5300..0cc759bb7c 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -207,11 +207,9 @@ afi2family (afi_t afi) { if (afi == AFI_IP) return AF_INET; -#ifdef HAVE_IPV6 else if (afi == AFI_IP6) return AF_INET6; -#endif /* HAVE_IPV6 */ - else if (afi == AFI_ETHER) + else if (afi == AFI_L2VPN) return AF_ETHERNET; return 0; } @@ -221,12 +219,10 @@ family2afi (int family) { if (family == AF_INET) return AFI_IP; -#ifdef HAVE_IPV6 else if (family == AF_INET6) return AFI_IP6; -#endif /* HAVE_IPV6 */ else if (family == AF_ETHERNET) - return AFI_ETHER; + return AFI_L2VPN; return 0; } @@ -238,8 +234,8 @@ afi2str(afi_t afi) return "IPv4"; case AFI_IP6: return "IPv6"; - case AFI_ETHER: - return "ethernet"; + case AFI_L2VPN: + return "l2vpn"; case AFI_MAX: return "bad-value"; default: @@ -260,6 +256,8 @@ safi2str(safi_t safi) return "encap"; case SAFI_MPLS_VPN: return "vpn"; + case SAFI_EVPN: + return "evpn"; } return NULL; } @@ -302,23 +300,20 @@ prefix_copy (struct prefix *dest, const struct prefix *src) if (src->family == AF_INET) dest->u.prefix4 = src->u.prefix4; -#ifdef HAVE_IPV6 else if (src->family == AF_INET6) dest->u.prefix6 = src->u.prefix6; -#endif /* HAVE_IPV6 */ + else if (src->family == AF_ETHERNET) + { + memcpy (&dest->u.prefix_evpn, &src->u.prefix_evpn, sizeof (struct evpn_addr)); + } else if (src->family == AF_UNSPEC) { dest->u.lp.id = src->u.lp.id; dest->u.lp.adv_router = src->u.lp.adv_router; } - else if (src->family == AF_ETHERNET) - { - dest->u.prefix_eth = src->u.prefix_eth; - } else { - zlog (NULL, LOG_ERR, "prefix_copy(): Unknown address family %d", - src->family); + zlog_err("prefix_copy(): Unknown address family %d", src->family); assert (0); } } @@ -345,15 +340,12 @@ prefix_same (const struct prefix *p1, const struct prefix *p2) if (p1->family == AF_INET) if (IPV4_ADDR_SAME (&p1->u.prefix4.s_addr, &p2->u.prefix4.s_addr)) return 1; -#ifdef HAVE_IPV6 if (p1->family == AF_INET6 ) if (IPV6_ADDR_SAME (&p1->u.prefix6.s6_addr, &p2->u.prefix6.s6_addr)) return 1; -#endif /* HAVE_IPV6 */ - if (p1->family == AF_ETHERNET) { - if (!memcmp(p1->u.prefix_eth.octet, p2->u.prefix_eth.octet, ETHER_ADDR_LEN)) - return 1; - } + if (p1->family == AF_ETHERNET ) + if (!memcmp (&p1->u.prefix_evpn, &p2->u.prefix_evpn, sizeof (struct evpn_addr))) + return 1; } return 0; } @@ -414,10 +406,11 @@ prefix_common_bits (const struct prefix *p1, const struct prefix *p2) if (p1->family == AF_INET) length = IPV4_MAX_BYTELEN; -#ifdef HAVE_IPV6 if (p1->family == AF_INET6) length = IPV6_MAX_BYTELEN; -#endif + if (p1->family == AF_ETHERNET) + length = 8 * sizeof (struct evpn_addr); + if (p1->family != p2->family || !length) return -1; @@ -441,10 +434,8 @@ prefix_family_str (const struct prefix *p) { if (p->family == AF_INET) return "inet"; -#ifdef HAVE_IPV6 if (p->family == AF_INET6) return "inet6"; -#endif /* HAVE_IPV6 */ if (p->family == AF_ETHERNET) return "ether"; return "unspec"; @@ -617,8 +608,6 @@ prefix_ipv4_any (const struct prefix_ipv4 *p) return (p->prefix.s_addr == 0 && p->prefixlen == 0); } -#ifdef HAVE_IPV6 - /* Allocate a new ip version 6 route */ struct prefix_ipv6 * prefix_ipv6_new (void) @@ -737,21 +726,6 @@ apply_mask_ipv6 (struct prefix_ipv6 *p) } void -str2in6_addr (const char *str, struct in6_addr *addr) -{ - int i; - unsigned int x; - - /* %x must point to unsinged int */ - for (i = 0; i < 16; i++) - { - sscanf (str + (i * 2), "%02x", &x); - addr->s6_addr[i] = x & 0xff; - } -} -#endif /* HAVE_IPV6 */ - -void apply_mask (struct prefix *p) { switch (p->family) @@ -759,11 +733,9 @@ apply_mask (struct prefix *p) case AF_INET: apply_mask_ipv4 ((struct prefix_ipv4 *)p); break; -#ifdef HAVE_IPV6 case AF_INET6: apply_mask_ipv6 ((struct prefix_ipv6 *)p); break; -#endif /* HAVE_IPV6 */ default: break; } @@ -786,7 +758,6 @@ sockunion2prefix (const union sockunion *dest, p->prefixlen = ip_masklen (mask->sin.sin_addr); return (struct prefix *) p; } -#ifdef HAVE_IPV6 if (dest->sa.sa_family == AF_INET6) { struct prefix_ipv6 *p; @@ -797,7 +768,6 @@ sockunion2prefix (const union sockunion *dest, memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr)); return (struct prefix *) p; } -#endif /* HAVE_IPV6 */ return NULL; } @@ -815,7 +785,6 @@ sockunion2hostprefix (const union sockunion *su, struct prefix *prefix) p->prefixlen = IPV4_MAX_BITLEN; return (struct prefix *) p; } -#ifdef HAVE_IPV6 if (su->sa.sa_family == AF_INET6) { struct prefix_ipv6 *p; @@ -826,7 +795,6 @@ sockunion2hostprefix (const union sockunion *su, struct prefix *prefix) memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr)); return (struct prefix *) p; } -#endif /* HAVE_IPV6 */ return NULL; } @@ -838,10 +806,8 @@ prefix2sockunion (const struct prefix *p, union sockunion *su) su->sa.sa_family = p->family; if (p->family == AF_INET) su->sin.sin_addr = p->u.prefix4; -#ifdef HAVE_IPV6 if (p->family == AF_INET6) memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr)); -#endif /* HAVE_IPV6 */ } int @@ -852,11 +818,9 @@ prefix_blen (const struct prefix *p) case AF_INET: return IPV4_MAX_BYTELEN; break; -#ifdef HAVE_IPV6 case AF_INET6: return IPV6_MAX_BYTELEN; break; -#endif /* HAVE_IPV6 */ case AF_ETHERNET: return ETHER_ADDR_LEN; } @@ -874,12 +838,10 @@ str2prefix (const char *str, struct prefix *p) if (ret) return ret; -#ifdef HAVE_IPV6 /* Next we try to convert string to struct prefix_ipv6. */ ret = str2prefix_ipv6 (str, (struct prefix_ipv6 *) p); if (ret) return ret; -#endif /* HAVE_IPV6 */ /* Next we try to convert string to struct prefix_eth. */ ret = str2prefix_eth (str, (struct prefix_eth *) p); @@ -890,23 +852,46 @@ str2prefix (const char *str, struct prefix *p) } const char * -prefix2str (union prefix46constptr pu, char *str, int size) +prefix2str (union prefixconstptr pu, char *str, int size) { const struct prefix *p = pu.p; + char buf[PREFIX2STR_BUFFER]; - if (p->family == AF_ETHERNET) - { - 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); - } - else + switch (p->family) { - char buf[PREFIX2STR_BUFFER]; - inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf)); - snprintf(str, size, "%s/%d", buf, p->prefixlen); + case AF_INET: + case AF_INET6: + snprintf (str, size, "%s/%d", + inet_ntop (p->family, &p->u.prefix, buf, PREFIX2STR_BUFFER), + p->prefixlen); + 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); + } + break; + default: + sprintf (str, "UNK prefix"); + break; } return str; @@ -1035,7 +1020,6 @@ netmask_str2prefix_str (const char *net_str, const char *mask_str, return 1; } -#ifdef HAVE_IPV6 /* Utility function for making IPv6 address string. */ const char * inet6_ntoa (struct in6_addr addr) @@ -1045,4 +1029,50 @@ inet6_ntoa (struct in6_addr addr) inet_ntop (AF_INET6, &addr, buf, INET6_ADDRSTRLEN); return buf; } -#endif /* HAVE_IPV6 */ + +/* converts to internal representation of mac address + * returns 1 on success, 0 otherwise + * format accepted: AA:BB:CC:DD:EE:FF + * if mac parameter is null, then check only + */ +int prefix_str2mac(const char *str, struct ethaddr *mac) +{ + unsigned int a[6]; + int i; + + if (!str) + return 0; + + if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x", + a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6) + { + /* error in incoming str length */ + return 0; + } + /* valid mac address */ + if (!mac) + return 1; + for (i = 0; i < 6; ++i) + mac->octet[i] = a[i] & 0xff; + return 1; +} + +char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size) +{ + char *ptr; + + if (!mac) + return NULL; + if (!buf) + ptr = (char *)XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN* sizeof(char)); + else + { + assert (size >= ETHER_ADDR_STRLEN); + ptr = buf; + } + snprintf(ptr, (ETHER_ADDR_STRLEN), + "%02x:%02x:%02x:%02x:%02x:%02x", (uint8_t) mac->octet[0], + (uint8_t) mac->octet[1], (uint8_t) mac->octet[2], (uint8_t) mac->octet[3], + (uint8_t) mac->octet[4], (uint8_t) mac->octet[5]); + return ptr; +} |
