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