Signed-off-by: Lou Berger <[email protected]>
Signed-off-by: David Lamparter <[email protected]>
---
lib/prefix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/prefix.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------
lib/zebra.h | 6 ++++--
3 files changed, 103 insertions(+), 8 deletions(-)
diff --git a/lib/prefix.c b/lib/prefix.c
index 936e9fc..afc3344 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -208,6 +208,8 @@ afi2family (afi_t afi)
else if (afi == AFI_IP6)
return AF_INET6;
#endif /* HAVE_IPV6 */
+ else if (afi == AFI_ETHER)
+ return AF_ETHERNET;
return 0;
}
@@ -220,9 +222,28 @@ family2afi (int family)
else if (family == AF_INET6)
return AFI_IP6;
#endif /* HAVE_IPV6 */
+ else if (family == AF_ETHERNET)
+ return AFI_ETHER;
return 0;
}
+const char *
+safi2str(safi_t safi)
+{
+ switch (safi)
+ {
+ case SAFI_UNICAST:
+ return "unicast";
+ case SAFI_MULTICAST:
+ return "multicast";
+ case SAFI_ENCAP:
+ return "encap";
+ case SAFI_MPLS_VPN:
+ return "vpn";
+ }
+ return NULL;
+}
+
/* If n includes p prefix then return 1 else return 0. */
int
prefix_match (const struct prefix *n, const struct prefix *p)
@@ -270,6 +291,10 @@ prefix_copy (struct prefix *dest, const struct prefix *src)
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",
@@ -299,6 +324,9 @@ prefix_same (const struct prefix *p1, const struct prefix
*p2)
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;
}
return 0;
}
@@ -390,6 +418,8 @@ prefix_family_str (const struct prefix *p)
if (p->family == AF_INET6)
return "inet6";
#endif /* HAVE_IPV6 */
+ if (p->family == AF_ETHERNET)
+ return "ether";
return "unspec";
}
@@ -746,6 +776,8 @@ prefix_blen (const struct prefix *p)
return IPV6_MAX_BYTELEN;
break;
#endif /* HAVE_IPV6 */
+ case AF_ETHERNET:
+ return ETHER_ADDR_LEN;
}
return 0;
}
@@ -777,6 +809,22 @@ prefix2str (union prefix46constptr pu, char *str, int size)
const struct prefix *p = pu.p;
char buf[BUFSIZ];
+ if (p->family == AF_ETHERNET)
+ {
+ int i;
+ char *s = str;
+
+ assert(size > (3*ETHER_ADDR_LEN));
+ for (i = 0; i <= ETHER_ADDR_LEN; ++i)
+ {
+ sprintf(s, "%02x", p->u.prefix_eth.octet[i]);
+ if (i < (ETHER_ADDR_LEN - 1))
+ *(s+2) = ':';
+ s += 3;
+ }
+ return 0;
+ }
+
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
snprintf (str, size, "%s/%d", buf, p->prefixlen);
return str;
diff --git a/lib/prefix.h b/lib/prefix.h
index a517d79..7f7fd3d 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -23,8 +23,34 @@
#ifndef _ZEBRA_PREFIX_H
#define _ZEBRA_PREFIX_H
+#ifdef SUNOS_5
+# include <sys/ethernet.h>
+# define ETHER_ADDR_LEN ETHERADDRL
+#else
+# include <net/ethernet.h>
+#endif
#include "sockunion.h"
+#ifdef __GNUC__
+# ifdef __LP64__ /* is m64, 8 byte align */
+# define PREFIX_GCC_ALIGN_ATTRIBUTES __attribute__ ((aligned (8)))
+# else /* must be m32, 4 byte align */
+# define PREFIX_GCC_ALIGN_ATTRIBUTES __attribute__ ((aligned (4)))
+# endif
+#else /* not GCC, no alignment attributes */
+# define PREFIX_GCC_ALIGN_ATTRIBUTES
+#endif
+
+
+/*
+ * there isn't a portable ethernet address type. We define our
+ * own to simplify internal handling
+ */
+struct ethaddr {
+ u_char octet[ETHER_ADDR_LEN];
+} __packed;
+
+
/*
* A struct prefix contains an address family, a prefix length, and an
* address. This can represent either a 'network prefix' as defined
@@ -34,6 +60,15 @@
* interface.
*/
+/* different OSes use different names */
+#if defined(AF_PACKET)
+#define AF_ETHERNET AF_PACKET
+#else
+#if defined(AF_LINK)
+#define AF_ETHERNET AF_LINK
+#endif
+#endif
+
/* IPv4 and IPv6 unified prefix structure. */
struct prefix
{
@@ -42,15 +77,16 @@ struct prefix
union
{
u_char prefix;
- struct in_addr prefix4;
+ struct in_addr prefix4; /* AF_INET */
#ifdef HAVE_IPV6
- struct in6_addr prefix6;
+ struct in6_addr prefix6; /* AF_INET6 */
#endif /* HAVE_IPV6 */
struct
{
struct in_addr id;
struct in_addr adv_router;
} lp;
+ struct ethaddr prefix_eth; /* AF_ETHERNET */
u_char val[8];
uintptr_t ptr;
} u __attribute__ ((aligned (8)));
@@ -61,7 +97,7 @@ struct prefix_ipv4
{
u_char family;
u_char prefixlen;
- struct in_addr prefix __attribute__ ((aligned (8)));
+ struct in_addr prefix PREFIX_GCC_ALIGN_ATTRIBUTES;
};
/* IPv6 prefix structure. */
@@ -70,7 +106,7 @@ struct prefix_ipv6
{
u_char family;
u_char prefixlen;
- struct in6_addr prefix __attribute__ ((aligned (8)));
+ struct in6_addr prefix PREFIX_GCC_ALIGN_ATTRIBUTES;
};
#endif /* HAVE_IPV6 */
@@ -78,7 +114,7 @@ struct prefix_ls
{
u_char family;
u_char prefixlen;
- struct in_addr id __attribute__ ((aligned (8)));
+ struct in_addr id PREFIX_GCC_ALIGN_ATTRIBUTES;
struct in_addr adv_router;
};
@@ -87,7 +123,15 @@ struct prefix_rd
{
u_char family;
u_char prefixlen;
- u_char val[8] __attribute__ ((aligned (8)));
+ u_char val[8] PREFIX_GCC_ALIGN_ATTRIBUTES;
+};
+
+/* Prefix for ethernet. */
+struct prefix_eth
+{
+ u_char family;
+ u_char prefixlen;
+ struct ethaddr eth_addr; /* AF_ETHERNET */
};
/* Prefix for a generic pointer */
@@ -173,6 +217,7 @@ union prefix46constptr
extern int str2family(const char *);
extern int afi2family (afi_t);
extern afi_t family2afi (int);
+extern const char *safi2str(safi_t safi);
/* Check bit of the prefix. */
extern unsigned int prefix_bit (const u_char *prefix, const u_char prefixlen);
diff --git a/lib/zebra.h b/lib/zebra.h
index a607437..31e1b3d 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -485,14 +485,16 @@ extern const char *zserv_command_string (unsigned int
command);
/* Address family numbers from RFC1700. */
#define AFI_IP 1
#define AFI_IP6 2
-#define AFI_MAX 3
+#define AFI_ETHER 3 /* RFC 1700 has "6" for 802.* */
+#define AFI_MAX 4
/* Subsequent Address Family Identifier. */
#define SAFI_UNICAST 1
#define SAFI_MULTICAST 2
#define SAFI_RESERVED_3 3
#define SAFI_MPLS_VPN 4
-#define SAFI_MAX 5
+#define SAFI_ENCAP 7
+#define SAFI_MAX 8
/* Filter direction. */
#define FILTER_IN 0
--
2.1.3
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev