Signed-off-by: Lou Berger <lber...@labn.net>
Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
---
 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
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to