summaryrefslogtreecommitdiff
path: root/lib/prefix.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/prefix.c')
-rw-r--r--lib/prefix.c170
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;
+}