summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-08-08 16:16:12 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-08-08 16:34:31 +0200
commitb03b88986e529eeb0cd7de1ce9a07d8d2a83b6d3 (patch)
treec402bb8a37a4d02d0bdc71fd454eda541fbbb106 /lib
parentlib, bgpd: Address Review comments. (diff)
downloadfrr-b03b88986e529eeb0cd7de1ce9a07d8d2a83b6d3.tar.xz
frr-b03b88986e529eeb0cd7de1ce9a07d8d2a83b6d3.zip
lib, bgpd: Distinguish between AF_EVPN and AF_ETHERNET
Create AF_EVPN for internal use and start using it. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/prefix.c35
-rw-r--r--lib/prefix.h15
2 files changed, 39 insertions, 11 deletions
diff --git a/lib/prefix.c b/lib/prefix.c
index edfc22fb4..df638b0fc 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -334,6 +334,8 @@ int str2family(const char *string)
return AF_INET6;
else if (!strcmp("ethernet", string))
return AF_ETHERNET;
+ else if (!strcmp("evpn", string))
+ return AF_EVPN;
return -1;
}
@@ -346,6 +348,7 @@ int afi2family(afi_t afi)
return AF_INET6;
else if (afi == AFI_L2VPN)
return AF_ETHERNET;
+ /* NOTE: EVPN code should NOT use this interface. */
return 0;
}
@@ -355,7 +358,7 @@ afi_t family2afi(int family)
return AFI_IP;
else if (family == AF_INET6)
return AFI_IP6;
- else if (family == AF_ETHERNET)
+ else if (family == AF_ETHERNET || family == AF_EVPN)
return AFI_L2VPN;
return 0;
}
@@ -461,6 +464,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
else if (src->family == AF_INET6)
dest->u.prefix6 = src->u.prefix6;
else if (src->family == AF_ETHERNET) {
+ memcpy(&dest->u.prefix_eth, &src->u.prefix_eth,
+ sizeof(struct ethaddr));
+ } else if (src->family == AF_EVPN) {
memcpy(&dest->u.prefix_evpn, &src->u.prefix_evpn,
sizeof(struct evpn_addr));
} else if (src->family == AF_UNSPEC) {
@@ -517,6 +523,10 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2)
&p2->u.prefix6.s6_addr))
return 1;
if (p1->family == AF_ETHERNET)
+ if (!memcmp(&p1->u.prefix_eth, &p2->u.prefix_eth,
+ sizeof(struct ethaddr)))
+ return 1;
+ if (p1->family == AF_EVPN)
if (!memcmp(&p1->u.prefix_evpn, &p2->u.prefix_evpn,
sizeof(struct evpn_addr)))
return 1;
@@ -581,6 +591,8 @@ int prefix_common_bits(const struct prefix *p1, const struct prefix *p2)
if (p1->family == AF_INET6)
length = IPV6_MAX_BYTELEN;
if (p1->family == AF_ETHERNET)
+ length = ETH_ALEN;
+ if (p1->family == AF_EVPN)
length = 8 * sizeof(struct evpn_addr);
if (p1->family != p2->family || !length)
@@ -609,6 +621,8 @@ const char *prefix_family_str(const struct prefix *p)
return "inet6";
if (p->family == AF_ETHERNET)
return "ether";
+ if (p->family == AF_EVPN)
+ return "evpn";
return "unspec";
}
@@ -965,6 +979,7 @@ int prefix_blen(const struct prefix *p)
break;
case AF_ETHERNET:
return ETH_ALEN;
+ break;
}
return 0;
}
@@ -992,7 +1007,7 @@ int str2prefix(const char *str, struct prefix *p)
return 0;
}
-static const char *prefixeth2str(const struct prefix *p, char *str, int size)
+static const char *prefixevpn2str(const struct prefix *p, char *str, int size)
{
u_char family;
char buf[PREFIX2STR_BUFFER];
@@ -1036,12 +1051,8 @@ static const char *prefixeth2str(const struct prefix *p, char *str, int size)
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);
+ sprintf(str, "Unsupported EVPN route type %d",
+ p->u.prefix_evpn.route_type);
}
return str;
@@ -1061,7 +1072,13 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
break;
case AF_ETHERNET:
- prefixeth2str(p, str, size);
+ snprintf(str, size, "%s/%d",
+ prefix_mac2str(&p->u.prefix_eth, buf, sizeof(buf)),
+ p->prefixlen);
+ break;
+
+ case AF_EVPN:
+ prefixevpn2str(p, str, size);
break;
default:
diff --git a/lib/prefix.h b/lib/prefix.h
index f665f55df..3ebf61546 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -116,7 +116,18 @@ struct evpn_addr {
#endif
#endif
-/* IPv4 and IPv6 unified prefix structure. */
+/* The 'family' in the prefix structure is internal to FRR and need not
+ * map to standard OS AF_ definitions except where needed for interacting
+ * with the kernel. However, AF_ definitions are currently in use and
+ * prevalent across the code. Define a new FRR-specific AF for EVPN to
+ * distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and
+ * ensure it does not conflict with any OS AF_ definition.
+ */
+#if !defined(AF_EVPN)
+#define AF_EVPN (AF_MAX + 1)
+#endif
+
+/* FRR generic prefix structure. */
struct prefix {
u_char family;
u_char prefixlen;
@@ -131,7 +142,7 @@ struct prefix {
struct ethaddr prefix_eth; /* AF_ETHERNET */
u_char val[8];
uintptr_t ptr;
- struct evpn_addr prefix_evpn;
+ struct evpn_addr prefix_evpn; /* AF_EVPN */
} u __attribute__((aligned(8)));
};