mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 06:32:33 +00:00
lib: add AF_ETHERNET/AFI_ETHER
This commit is contained in:
parent
b645912484
commit
32ac65d9fa
@ -196,6 +196,9 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case AFI_ETHER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
|
||||
|
@ -958,6 +958,11 @@ vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
break;
|
||||
case AFI_ETHER:
|
||||
default:
|
||||
vty_out (vty, "%% Unrecognized AFI (%d)%s", afi, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* ge and le check. */
|
||||
|
114
lib/prefix.c
114
lib/prefix.c
@ -194,8 +194,9 @@ str2family(const char *string)
|
||||
return AF_INET;
|
||||
else if (!strcmp("ipv6", string))
|
||||
return AF_INET6;
|
||||
else
|
||||
return -1;
|
||||
else if (!strcmp("ethernet", string))
|
||||
return AF_ETHERNET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Address Famiy Identifier to Address Family converter. */
|
||||
@ -208,6 +209,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 +223,27 @@ 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 *
|
||||
afi2str(afi_t afi)
|
||||
{
|
||||
switch (afi) {
|
||||
case AFI_IP:
|
||||
return "IPv4";
|
||||
case AFI_IP6:
|
||||
return "IPv6";
|
||||
case AFI_ETHER:
|
||||
return "ethernet";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
safi2str(safi_t safi)
|
||||
{
|
||||
@ -286,6 +307,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",
|
||||
@ -321,6 +346,10 @@ 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;
|
||||
}
|
||||
@ -412,6 +441,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";
|
||||
}
|
||||
|
||||
@ -482,6 +513,60 @@ str2prefix_ipv4 (const char *str, struct prefix_ipv4 *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* When string format is invalid return 0. */
|
||||
int
|
||||
str2prefix_eth (const char *str, struct prefix_eth *p)
|
||||
{
|
||||
int ret = 0;
|
||||
int plen = 48;
|
||||
char *pnt;
|
||||
char *cp = NULL;
|
||||
const char *str_addr = str;
|
||||
unsigned int a[6];
|
||||
int i;
|
||||
|
||||
/* Find slash inside string. */
|
||||
pnt = strchr (str, '/');
|
||||
|
||||
if (pnt)
|
||||
{
|
||||
/* Get prefix length. */
|
||||
plen = (u_char) atoi (++pnt);
|
||||
if (plen > 48)
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
cp = XMALLOC (MTYPE_TMP, (pnt - str) + 1);
|
||||
strncpy (cp, str, pnt - str);
|
||||
*(cp + (pnt - str)) = '\0';
|
||||
|
||||
str_addr = cp;
|
||||
}
|
||||
|
||||
/* Convert string to prefix. */
|
||||
if (sscanf(str_addr, "%2x:%2x:%2x:%2x:%2x:%2x",
|
||||
a+0, a+1, a+2, a+3, a+4, a+5) != 6)
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
p->eth_addr.octet[i] = a[i] & 0xff;
|
||||
}
|
||||
p->prefixlen = plen;
|
||||
p->family = AF_ETHERNET;
|
||||
ret = 1;
|
||||
|
||||
done:
|
||||
if (cp)
|
||||
XFREE (MTYPE_TMP, cp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convert masklen into IP address's netmask (network byte order). */
|
||||
void
|
||||
masklen2ip (const int masklen, struct in_addr *netmask)
|
||||
@ -768,6 +853,8 @@ prefix_blen (const struct prefix *p)
|
||||
return IPV6_MAX_BYTELEN;
|
||||
break;
|
||||
#endif /* HAVE_IPV6 */
|
||||
case AF_ETHERNET:
|
||||
return ETHER_ADDR_LEN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -790,6 +877,11 @@ str2prefix (const char *str, struct prefix *p)
|
||||
return ret;
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
/* Next we try to convert string to struct prefix_eth. */
|
||||
ret = str2prefix_eth (str, (struct prefix_eth *) p);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -799,6 +891,24 @@ prefix2str (union prefix46constptr pu, char *str, int size)
|
||||
const struct prefix *p = pu.p;
|
||||
char buf[PREFIX2STR_BUFFER];
|
||||
|
||||
if (p->family == AF_ETHERNET) {
|
||||
int i;
|
||||
char *s = str;
|
||||
|
||||
assert(size > (3*ETHER_ADDR_LEN) + 1 /* slash */ + 3 /* plen */ );
|
||||
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;
|
||||
} else {
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
sprintf(s, "/%d", p->prefixlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf (str, size, "%s/%d",
|
||||
inet_ntop (p->family, &p->u.prefix, buf, PREFIX2STR_BUFFER),
|
||||
p->prefixlen);
|
||||
|
43
lib/prefix.h
43
lib/prefix.h
@ -23,8 +23,30 @@
|
||||
#ifndef _ZEBRA_PREFIX_H
|
||||
#define _ZEBRA_PREFIX_H
|
||||
|
||||
#ifdef SUNOS_5
|
||||
# include <sys/ethernet.h>
|
||||
#else
|
||||
# ifdef GNU_LINUX
|
||||
# include <net/ethernet.h>
|
||||
# else
|
||||
# include <netinet/if_ether.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "sockunion.h"
|
||||
|
||||
#ifndef ETHER_ADDR_LEN
|
||||
#define ETHER_ADDR_LEN ETHERADDRL
|
||||
#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 +56,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
|
||||
{
|
||||
@ -51,6 +82,7 @@ struct prefix
|
||||
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)));
|
||||
@ -90,6 +122,14 @@ struct prefix_rd
|
||||
u_char val[8] __attribute__ ((aligned (8)));
|
||||
};
|
||||
|
||||
/* Prefix for ethernet. */
|
||||
struct prefix_eth
|
||||
{
|
||||
u_char family;
|
||||
u_char prefixlen;
|
||||
struct ethaddr eth_addr __attribute__ ((aligned (8))); /* AF_ETHERNET */
|
||||
};
|
||||
|
||||
/* Prefix for a generic pointer */
|
||||
struct prefix_ptr
|
||||
{
|
||||
@ -174,6 +214,7 @@ extern int str2family(const char *);
|
||||
extern int afi2family (afi_t);
|
||||
extern afi_t family2afi (int);
|
||||
extern const char *safi2str(safi_t safi);
|
||||
extern const char *afi2str(afi_t afi);
|
||||
|
||||
/* Check bit of the prefix. */
|
||||
extern unsigned int prefix_bit (const u_char *prefix, const u_char prefixlen);
|
||||
@ -205,6 +246,8 @@ extern struct prefix *sockunion2prefix (const union sockunion *dest,
|
||||
extern struct prefix *sockunion2hostprefix (const union sockunion *, struct prefix *p);
|
||||
extern void prefix2sockunion (const struct prefix *, union sockunion *);
|
||||
|
||||
extern int str2prefix_eth (const char *, struct prefix_eth *);
|
||||
|
||||
extern struct prefix_ipv4 *prefix_ipv4_new (void);
|
||||
extern void prefix_ipv4_free (struct prefix_ipv4 *);
|
||||
extern int str2prefix_ipv4 (const char *, struct prefix_ipv4 *);
|
||||
|
@ -502,7 +502,8 @@ extern const char *zserv_command_string (unsigned int command);
|
||||
typedef enum {
|
||||
AFI_IP = 1,
|
||||
AFI_IP6 = 2,
|
||||
#define AFI_MAX 3
|
||||
AFI_ETHER = 3, /* RFC 1700 has "6" for 802.* */
|
||||
AFI_MAX = 4
|
||||
} afi_t;
|
||||
|
||||
/* Subsequent Address Family Identifier. */
|
||||
|
Loading…
Reference in New Issue
Block a user