diff options
author | sjg <sjg@FreeBSD.org> | 2015-05-27 01:19:58 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2015-05-27 01:19:58 +0000 |
commit | 65145fa4c81da358fcbc3b650156dab705dfa34e (patch) | |
tree | 55c065b6730aaac2afb6c29933ee6ec5fa4c4249 /sbin/ifconfig | |
parent | 60ff4eb0dff94a04d75d0d52a3957aaaf5f8c693 (diff) | |
parent | e6b664c390af88d4a87208bc042ce503da664c3b (diff) | |
download | FreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.zip FreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.tar.gz |
Merge sync of head
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r-- | sbin/ifconfig/Makefile | 13 | ||||
-rw-r--r-- | sbin/ifconfig/af_inet.c | 5 | ||||
-rw-r--r-- | sbin/ifconfig/af_inet6.c | 49 | ||||
-rw-r--r-- | sbin/ifconfig/af_nd6.c | 4 | ||||
-rw-r--r-- | sbin/ifconfig/carp.c | 1 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 53 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 188 | ||||
-rw-r--r-- | sbin/ifconfig/iffib.c | 36 | ||||
-rw-r--r-- | sbin/ifconfig/ifgif.c | 4 | ||||
-rw-r--r-- | sbin/ifconfig/ifgroup.c | 5 | ||||
-rw-r--r-- | sbin/ifconfig/ifmedia.c | 32 | ||||
-rw-r--r-- | sbin/ifconfig/ifvlan.c | 1 | ||||
-rw-r--r-- | sbin/ifconfig/ifvxlan.c | 55 | ||||
-rw-r--r-- | sbin/ifconfig/sfp.c | 189 | ||||
-rw-r--r-- | sbin/ifconfig/tests/Makefile | 13 |
15 files changed, 474 insertions, 174 deletions
diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index 8aba6b4..ac7faf9 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -35,12 +35,10 @@ SRCS+= ifgre.c # GRE keys etc SRCS+= ifgif.c # GIF reversed header workaround SRCS+= sfp.c # SFP/SFP+ information -DPADD+= ${LIBM} -LDADD+= -lm +LIBADD+= m SRCS+= ifieee80211.c regdomain.c # SIOC[GS]IEEE80211 support -DPADD+= ${LIBBSDXML} ${LIBSBUF} -LDADD+= -lbsdxml -lsbuf +LIBADD+= bsdxml sbuf SRCS+= carp.c # SIOC[GS]VH support SRCS+= ifgroup.c # ... @@ -59,8 +57,7 @@ CFLAGS+= -DINET .endif .if ${MK_JAIL} != "no" && !defined(RELEASE_CRUNCH) && !defined(RESCUE) CFLAGS+= -DJAIL -DPADD+= ${LIBJAIL} -LDADD+= -ljail +LIBADD+= jail .endif MAN= ifconfig.8 @@ -68,4 +65,8 @@ MAN= ifconfig.8 CFLAGS+= -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wnested-externs WARNS?= 2 +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.prog.mk> diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index c733373..eff1ce5 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -32,7 +32,7 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> @@ -46,7 +46,6 @@ static const char rcsid[] = #include <ifaddrs.h> #include <netinet/in.h> -#include <net/if_var.h> /* for struct ifaddr */ #include <netinet/in_var.h> #include <arpa/inet.h> #include <netdb.h> @@ -101,7 +100,6 @@ static struct sockaddr_in *sintab[] = { static void in_getaddr(const char *s, int which) { -#define MIN(a,b) ((a)<(b)?(a):(b)) struct sockaddr_in *sin = sintab[which]; struct hostent *hp; struct netent *np; @@ -142,7 +140,6 @@ in_getaddr(const char *s, int which) sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); else errx(1, "%s: bad value", s); -#undef MIN } static void diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 0f8688a..6dd8622 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -48,7 +48,6 @@ static const char rcsid[] = #include <arpa/inet.h> #include <netinet/in.h> -#include <net/if_var.h> /* for struct ifaddr */ #include <netinet/in_var.h> #include <arpa/inet.h> #include <netdb.h> @@ -58,8 +57,8 @@ static const char rcsid[] = #include "ifconfig.h" static struct in6_ifreq in6_ridreq; -static struct in6_aliasreq in6_addreq = - { .ifra_flags = 0, +static struct in6_aliasreq in6_addreq = + { .ifra_flags = 0, .ifra_lifetime = { 0, 0, ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME } }; static int ip6lifetime; @@ -265,14 +264,16 @@ in6_status(int s __unused, const struct ifaddrs *ifa) printf("pltime "); if (lifetime.ia6t_preferred) { printf("%s ", lifetime.ia6t_preferred < now.tv_sec - ? "0" : sec2str(lifetime.ia6t_preferred - now.tv_sec)); + ? "0" : + sec2str(lifetime.ia6t_preferred - now.tv_sec)); } else printf("infty "); printf("vltime "); if (lifetime.ia6t_expire) { printf("%s ", lifetime.ia6t_expire < now.tv_sec - ? "0" : sec2str(lifetime.ia6t_expire - now.tv_sec)); + ? "0" : + sec2str(lifetime.ia6t_expire - now.tv_sec)); } else printf("infty "); } @@ -347,25 +348,25 @@ in6_getaddr(const char *s, int which) static int prefix(void *val, int size) { - u_char *name = (u_char *)val; - int byte, bit, plen = 0; + u_char *name = (u_char *)val; + int byte, bit, plen = 0; - for (byte = 0; byte < size; byte++, plen += 8) - if (name[byte] != 0xff) - break; + for (byte = 0; byte < size; byte++, plen += 8) + if (name[byte] != 0xff) + break; if (byte == size) return (plen); for (bit = 7; bit != 0; bit--, plen++) - if (!(name[byte] & (1 << bit))) - break; - for (; bit != 0; bit--) - if (name[byte] & (1 << bit)) - return(0); - byte++; - for (; byte < size; byte++) - if (name[byte]) - return(0); - return (plen); + if (!(name[byte] & (1 << bit))) + break; + for (; bit != 0; bit--) + if (name[byte] & (1 << bit)) + return(0); + byte++; + for (; byte < size; byte++) + if (name[byte]) + return(0); + return (plen); } static char * @@ -483,6 +484,8 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-auto_linklocal",-ND6_IFF_AUTO_LINKLOCAL,setnd6flags), DEF_CMD("no_prefer_iface",ND6_IFF_NO_PREFER_IFACE,setnd6flags), DEF_CMD("-no_prefer_iface",-ND6_IFF_NO_PREFER_IFACE,setnd6flags), + DEF_CMD("no_dad", ND6_IFF_NO_DAD, setnd6flags), + DEF_CMD("-no_dad", -ND6_IFF_NO_DAD, setnd6flags), DEF_CMD_ARG("pltime", setip6pltime), DEF_CMD_ARG("vltime", setip6vltime), DEF_CMD("eui64", 0, setip6eui64), @@ -509,7 +512,11 @@ in6_Lopt_cb(const char *optarg __unused) { ip6lifetime++; /* print IPv6 address lifetime */ } -static struct option in6_Lopt = { .opt = "L", .opt_usage = "[-L]", .cb = in6_Lopt_cb }; +static struct option in6_Lopt = { + .opt = "L", + .opt_usage = "[-L]", + .cb = in6_Lopt_cb +}; static __constructor void inet6_ctor(void) diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c index b3db0a8..9a1be79 100644 --- a/sbin/ifconfig/af_nd6.c +++ b/sbin/ifconfig/af_nd6.c @@ -46,7 +46,6 @@ static const char rcsid[] = #include <arpa/inet.h> #include <netinet/in.h> -#include <net/if_var.h> #include <netinet/in_var.h> #include <arpa/inet.h> #include <netdb.h> @@ -58,7 +57,8 @@ static const char rcsid[] = #define MAX_SYSCTL_TRY 5 #define ND6BITS "\020\001PERFORMNUD\002ACCEPT_RTADV\003PREFER_SOURCE" \ "\004IFDISABLED\005DONT_SET_IFROUTE\006AUTO_LINKLOCAL" \ - "\007NO_RADR\010NO_PREFER_IFACE\020DEFAULTIF" + "\007NO_RADR\010NO_PREFER_IFACE\011IGNORELOOP\012NO_DAD" \ + "\020DEFAULTIF" static int isnd6defif(int); void setnd6flags(const char *, int, int, const struct afswtch *); diff --git a/sbin/ifconfig/carp.c b/sbin/ifconfig/carp.c index 2c58fcb..adff153 100644 --- a/sbin/ifconfig/carp.c +++ b/sbin/ifconfig/carp.c @@ -36,7 +36,6 @@ #include <unistd.h> #include <net/if.h> -#include <net/if_var.h> #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/ip_carp.h> diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 064a62d..56b5c14 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd October 20, 2014 +.Dd May 15, 2015 .Dt IFCONFIG 8 .Os .Sh NAME @@ -316,6 +316,14 @@ using the kernel configuration option, or the .Va net.fibs tunable. +.It Cm tunnelfib Ar fib_number +Specify tunnel FIB. +A FIB +.Ar fib_number +is assigned to all packets encapsulated by tunnel interface, e.g., +.Xr gif 4 +and +.Xr gre 4 . .It Cm maclabel Ar label If Mandatory Access Control support is enabled in the kernel, set the MAC label to @@ -687,6 +695,11 @@ policy table, configurable with .It Cm -no_prefer_iface Clear a flag .Cm no_prefer_iface . +.It Cm no_dad +Set a flag to disable Duplicate Address Detection. +.It Cm -no_dad +Clear a flag +.Cm no_dad . .El .Pp The following parameters are specific for IPv6 addresses. @@ -2415,6 +2428,14 @@ This is for backward compatibility with .It Cm -accept_rev_ethip_ver Clear a flag .Cm accept_rev_ethip_ver . +.It Cm ignore_source +Set a flag to accept encapsulated packets destined to this host +independently from source address. +This may be useful for hosts, that receive encapsulated packets +from the load balancers. +.It Cm -ignore_source +Clear a flag +.Cm ignore_source . .It Cm send_rev_ethip_ver Set a flag to send EtherIP packets with reversed version field intentionally. @@ -2544,33 +2565,33 @@ The following parameters are used to configure .Xr vxlan 4 interfaces. .Bl -tag -width indent -.It Cm vni Ar identifier +.It Cm vxlanid Ar identifier This value is a 24-bit VXLAN Network Identifier (VNI) that identifies the virtual network segment membership of the interface. -.It Cm local Ar address +.It Cm vxlanlocal Ar address The source address used in the encapsulating IPv4/IPv6 header. The address should already be assigned to an existing interface. When the interface is configured in unicast mode, the listening socket is bound to this address. -.It Cm remote Ar address +.It Cm vxlanremote Ar address The interface can be configured in a unicast, or point-to-point, mode to create a tunnel between two hosts. This is the IP address of the remote end of the tunnel. -.It Cm group Ar address +.It Cm vxlangroup Ar address The interface can be configured in a multicast mode to create a virtual network of hosts. This is the IP multicast group address the interface will join. -.It Cm localport Ar port +.It Cm vxlanlocalport Ar port The port number the interface will listen on. The default port number is 4789. -.It Cm remoteport Ar port +.It Cm vxlanremoteport Ar port The destination port number used in the encapsulating IPv4/IPv6 header. The remote host should be listening on this port. The default port number is 4789. Note some other implementations, such as Linux, do not default to the IANA assigned port, but instead listen on port 8472. -.It Cm portrange Ar low high +.It Cm vxlanportrange Ar low high The range of source ports used in the encapsulating IPv4/IPv6 header. The port selected within the range is based on a hash of the inner frame. A range is useful to provide entropy within the outer IP header @@ -2581,32 +2602,32 @@ variables .Va net.inet.ip.portrange.first and .Va net.inet.ip.portrange.last -.It Cm timeout Ar timeout +.It Cm vxlantimeout Ar timeout The maximum time, in seconds, before an entry in the forwarding table is pruned. The default is 1200 seconds (20 minutes). -.It Cm maxaddr Ar max +.It Cm vxlanmaxaddr Ar max The maximum number of entries in the forwarding table. The default is 2000. .It Cm vxlandev Ar dev When the interface is configured in multicast mode, the .Cm dev interface is used to transmit IP multicast packets. -.It Cm ttl Ar ttl +.It Cm vxlanttl Ar ttl The TTL used in the encapsulating IPv4/IPv6 header. The default is 64. -.It Cm learn +.It Cm vxlanlearn The source IP address and inner source Ethernet MAC address of received packets are used to dynamically populate the forwarding table. When in multicast mode, an entry in the forwarding table allows the interface to send the frame directly to the remote host instead of broadcasting the frame to the multicast group. This is the default. -.It Fl learn +.It Fl vxlanlearn The forwarding table is not populated by recevied packets. -.It Cm flush +.It Cm vxlanflush Delete all dynamically-learned addresses from the forwarding table. -.It Cm flushall +.It Cm vxlanflushall Delete all addresses, including static addresses, from the forwarding table. .El .Pp @@ -2819,9 +2840,9 @@ tried to alter an interface's configuration. .Xr devd.conf 5 , .\" .Xr eon 5 , .Xr devd 8 , +.Xr jail 8 , .Xr rc 8 , .Xr routed 8 , -.Xr jail 8 , .Xr sysctl 8 .Sh HISTORY The diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 61fd155..4a79992 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -47,10 +47,10 @@ static const char rcsid[] = #include <sys/time.h> #include <sys/module.h> #include <sys/linker.h> +#include <sys/queue.h> #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> #include <net/route.h> @@ -110,6 +110,15 @@ static void af_other_status(int); static struct option *opts = NULL; +struct ifa_order_elt { + int if_order; + int af_orders[255]; + struct ifaddrs *ifa; + TAILQ_ENTRY(ifa_order_elt) link; +}; + +TAILQ_HEAD(ifa_queue, ifa_order_elt); + void opt_register(struct option *p) { @@ -141,16 +150,165 @@ usage(void) exit(1); } +#define ORDERS_SIZE(x) sizeof(x) / sizeof(x[0]) + +static int +calcorders(struct ifaddrs *ifa, struct ifa_queue *q) +{ + struct ifaddrs *prev; + struct ifa_order_elt *cur; + unsigned int ord, af, ifa_ord; + + prev = NULL; + cur = NULL; + ord = 0; + ifa_ord = 0; + + while (ifa != NULL) { + if (prev == NULL || + strcmp(ifa->ifa_name, prev->ifa_name) != 0) { + cur = calloc(1, sizeof(*cur)); + + if (cur == NULL) + return (-1); + + TAILQ_INSERT_TAIL(q, cur, link); + cur->if_order = ifa_ord ++; + cur->ifa = ifa; + ord = 0; + } + + if (ifa->ifa_addr) { + af = ifa->ifa_addr->sa_family; + + if (af < ORDERS_SIZE(cur->af_orders) && + cur->af_orders[af] == 0) + cur->af_orders[af] = ++ord; + } + prev = ifa; + ifa = ifa->ifa_next; + } + + return (0); +} + +static int +cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q) +{ + struct ifa_order_elt *cur, *e1, *e2; + unsigned int af1, af2; + int ret; + + e1 = e2 = NULL; + + ret = strcmp(a->ifa_name, b->ifa_name); + if (ret != 0) { + TAILQ_FOREACH(cur, q, link) { + if (e1 && e2) + break; + + if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) + e1 = cur; + else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0) + e2 = cur; + } + + if (!e1 || !e2) + return (0); + else + return (e1->if_order - e2->if_order); + + } else if (a->ifa_addr != NULL && b->ifa_addr != NULL) { + TAILQ_FOREACH(cur, q, link) { + if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) { + e1 = cur; + break; + } + } + + if (!e1) + return (0); + + af1 = a->ifa_addr->sa_family; + af2 = b->ifa_addr->sa_family; + + if (af1 < ORDERS_SIZE(e1->af_orders) && + af2 < ORDERS_SIZE(e1->af_orders)) + return (e1->af_orders[af1] - e1->af_orders[af2]); + } + + return (0); +} + +#undef ORDERS_SIZE + +static struct ifaddrs * +sortifaddrs(struct ifaddrs *list, + int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *), + struct ifa_queue *q) +{ + struct ifaddrs *right, *temp, *last, *result, *next, *tail; + + right = list; + temp = list; + last = list; + result = NULL; + next = NULL; + tail = NULL; + + if (!list || !list->ifa_next) + return (list); + + while (temp && temp->ifa_next) { + last = right; + right = right->ifa_next; + temp = temp->ifa_next->ifa_next; + } + + last->ifa_next = NULL; + + list = sortifaddrs(list, compare, q); + right = sortifaddrs(right, compare, q); + + while (list || right) { + + if (!right) { + next = list; + list = list->ifa_next; + } else if (!list) { + next = right; + right = right->ifa_next; + } else if (compare(list, right, q) <= 0) { + next = list; + list = list->ifa_next; + } else { + next = right; + right = right->ifa_next; + } + + if (!result) + result = next; + else + tail->ifa_next = next; + + tail = next; + } + + return (result); +} + int main(int argc, char *argv[]) { int c, all, namesonly, downonly, uponly; const struct afswtch *afp = NULL; int ifindex; - struct ifaddrs *ifap, *ifa; + struct ifaddrs *ifap, *sifap, *ifa; struct ifreq paifr; const struct sockaddr_dl *sdl; char options[1024], *cp, *namecp = NULL; + struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); + struct ifa_order_elt *cur, *tmp; const char *ifname; struct option *p; size_t iflen; @@ -285,9 +443,19 @@ main(int argc, char *argv[]) if (getifaddrs(&ifap) != 0) err(EXIT_FAILURE, "getifaddrs"); + cp = NULL; + + if (calcorders(ifap, &q) != 0) + err(EXIT_FAILURE, "calcorders"); + + sifap = sortifaddrs(ifap, cmpifaddrs, &q); + + TAILQ_FOREACH_SAFE(cur, &q, link, tmp) + free(cur); + ifindex = 0; - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + for (ifa = sifap; ifa; ifa = ifa->ifa_next) { memset(&paifr, 0, sizeof(paifr)); strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { @@ -333,7 +501,8 @@ main(int argc, char *argv[]) sdl->sdl_alen != ETHER_ADDR_LEN) continue; } else { - if (ifa->ifa_addr->sa_family != afp->af_af) + if (ifa->ifa_addr->sa_family + != afp->af_af) continue; } } @@ -669,7 +838,7 @@ settunnel(const char *src, const char *dst, int s, const struct afswtch *afp) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); - if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) + if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); @@ -1110,9 +1279,8 @@ ifmaybeload(const char *name) } /* turn interface and unit into module name */ - strcpy(ifkind, "if_"); - strlcpy(ifkind + MOD_PREFIX_LEN, ifname, - sizeof(ifkind) - MOD_PREFIX_LEN); + strlcpy(ifkind, "if_", sizeof(ifkind)); + strlcat(ifkind, ifname, sizeof(ifkind)); /* scan files in kernel */ mstat.version = sizeof(struct module_stat); @@ -1129,8 +1297,8 @@ ifmaybeload(const char *name) cp = mstat.name; } /* already loaded? */ - if (strncmp(ifname, cp, strlen(ifname) + 1) == 0 || - strncmp(ifkind, cp, strlen(ifkind) + 1) == 0) + if (strcmp(ifname, cp) == 0 || + strcmp(ifkind, cp) == 0) return; } } diff --git a/sbin/ifconfig/iffib.c b/sbin/ifconfig/iffib.c index f3498b4..07ded3c 100644 --- a/sbin/ifconfig/iffib.c +++ b/sbin/ifconfig/iffib.c @@ -50,15 +50,15 @@ fib_status(int s) memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFFIB, (caddr_t)&ifr) == 0 && + ifr.ifr_fib != RT_DEFAULT_FIB) + printf("\tfib: %u\n", ifr.ifr_fib); - if (ioctl(s, SIOCGIFFIB, (caddr_t)&ifr) < 0) - return; - - /* Ignore if it is the default. */ - if (ifr.ifr_fib == 0) - return; - - printf("\tfib: %u\n", ifr.ifr_fib); + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGTUNFIB, (caddr_t)&ifr) == 0 && + ifr.ifr_fib != RT_DEFAULT_FIB) + printf("\ttunnelfib: %u\n", ifr.ifr_fib); } static void @@ -80,8 +80,28 @@ setiffib(const char *val, int dummy __unused, int s, warn("ioctl (SIOCSIFFIB)"); } +static void +settunfib(const char *val, int dummy __unused, int s, + const struct afswtch *afp) +{ + unsigned long fib; + char *ep; + + fib = strtoul(val, &ep, 0); + if (*ep != '\0' || fib > UINT_MAX) { + warn("fib %s not valid", val); + return; + } + + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + ifr.ifr_fib = fib; + if (ioctl(s, SIOCSTUNFIB, (caddr_t)&ifr) < 0) + warn("ioctl (SIOCSTUNFIB)"); +} + static struct cmd fib_cmds[] = { DEF_CMD_ARG("fib", setiffib), + DEF_CMD_ARG("tunnelfib", settunfib), }; static struct afswtch af_fib = { diff --git a/sbin/ifconfig/ifgif.c b/sbin/ifconfig/ifgif.c index f91508b..91c433c 100644 --- a/sbin/ifconfig/ifgif.c +++ b/sbin/ifconfig/ifgif.c @@ -51,7 +51,7 @@ static const char rcsid[] = #include "ifconfig.h" -#define GIFBITS "\020\1ACCEPT_REV_ETHIP_VER\5SEND_REV_ETHIP_VER" +#define GIFBITS "\020\1ACCEPT_REV_ETHIP_VER\2IGNORE_SOURCE\5SEND_REV_ETHIP_VER" static void gif_status(int); @@ -95,6 +95,8 @@ setgifopts(const char *val, static struct cmd gif_cmds[] = { DEF_CMD("accept_rev_ethip_ver", GIF_ACCEPT_REVETHIP, setgifopts), DEF_CMD("-accept_rev_ethip_ver",-GIF_ACCEPT_REVETHIP, setgifopts), + DEF_CMD("ignore_source", GIF_IGNORE_SOURCE, setgifopts), + DEF_CMD("-ignore_source", -GIF_IGNORE_SOURCE, setgifopts), DEF_CMD("send_rev_ethip_ver", GIF_SEND_REVETHIP, setgifopts), DEF_CMD("-send_rev_ethip_ver", -GIF_SEND_REVETHIP, setgifopts), }; diff --git a/sbin/ifconfig/ifgroup.c b/sbin/ifconfig/ifgroup.c index f8b18b4..e3f271d 100644 --- a/sbin/ifconfig/ifgroup.c +++ b/sbin/ifconfig/ifgroup.c @@ -86,9 +86,6 @@ getifgroups(int s) struct ifgroupreq ifgr; struct ifg_req *ifg; - if (!verbose) - return; - memset(&ifgr, 0, sizeof(ifgr)); strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); @@ -121,6 +118,8 @@ getifgroups(int s) } if (cnt) printf("\n"); + + free(ifgr.ifgr_groups); } static void diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c index 0b0daa3..eee3391 100644 --- a/sbin/ifconfig/ifmedia.c +++ b/sbin/ifconfig/ifmedia.c @@ -109,11 +109,17 @@ media_status(int s) { struct ifmediareq ifmr; int *media_list, i; + int xmedia = 1; (void) memset(&ifmr, 0, sizeof(ifmr)); (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + /* + * Check if interface supports extended media types. + */ + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0) + xmedia = 0; + if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { /* * Interface doesn't support SIOC{G,S}IFMEDIA. */ @@ -130,8 +136,13 @@ media_status(int s) err(1, "malloc"); ifmr.ifm_ulist = media_list; - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) - err(1, "SIOCGIFMEDIA"); + if (xmedia) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFXMEDIA"); + } else { + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } printf("\tmedia: "); print_media_word(ifmr.ifm_current, 1); @@ -194,6 +205,7 @@ ifmedia_getstate(int s) { static struct ifmediareq *ifmr = NULL; int *mwords; + int xmedia = 1; if (ifmr == NULL) { ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); @@ -213,7 +225,10 @@ ifmedia_getstate(int s) * the current media type and the top-level type. */ - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) { + xmedia = 0; + } + if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { err(1, "SIOCGIFMEDIA"); } @@ -225,8 +240,13 @@ ifmedia_getstate(int s) err(1, "malloc"); ifmr->ifm_ulist = mwords; - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) - err(1, "SIOCGIFMEDIA"); + if (xmedia) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFXMEDIA"); + } else { + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } } return ifmr; diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c index cefcbbc..1a3fbaa 100644 --- a/sbin/ifconfig/ifvlan.c +++ b/sbin/ifconfig/ifvlan.c @@ -40,7 +40,6 @@ #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_vlan_var.h> #include <net/route.h> diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c index 7234667..48f5331 100644 --- a/sbin/ifconfig/ifvxlan.c +++ b/sbin/ifconfig/ifvxlan.c @@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$"); #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_vxlan.h> #include <net/route.h> #include <netinet/in.h> @@ -595,36 +594,36 @@ setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp) static struct cmd vxlan_cmds[] = { - DEF_CLONE_CMD_ARG("vni", setvxlan_vni), - DEF_CLONE_CMD_ARG("local", setvxlan_local), - DEF_CLONE_CMD_ARG("remote", setvxlan_remote), - DEF_CLONE_CMD_ARG("group", setvxlan_group), - DEF_CLONE_CMD_ARG("localport", setvxlan_local_port), - DEF_CLONE_CMD_ARG("remoteport", setvxlan_remote_port), - DEF_CLONE_CMD_ARG2("portrange", setvxlan_port_range), - DEF_CLONE_CMD_ARG("timeout", setvxlan_timeout), - DEF_CLONE_CMD_ARG("maxaddr", setvxlan_maxaddr), + DEF_CLONE_CMD_ARG("vxlanid", setvxlan_vni), + DEF_CLONE_CMD_ARG("vxlanlocal", setvxlan_local), + DEF_CLONE_CMD_ARG("vxlanremote", setvxlan_remote), + DEF_CLONE_CMD_ARG("vxlangroup", setvxlan_group), + DEF_CLONE_CMD_ARG("vxlanlocalport", setvxlan_local_port), + DEF_CLONE_CMD_ARG("vxlanremoteport", setvxlan_remote_port), + DEF_CLONE_CMD_ARG2("vxlanportrange", setvxlan_port_range), + DEF_CLONE_CMD_ARG("vxlantimeout", setvxlan_timeout), + DEF_CLONE_CMD_ARG("vxlanmaxaddr", setvxlan_maxaddr), DEF_CLONE_CMD_ARG("vxlandev", setvxlan_dev), - DEF_CLONE_CMD_ARG("ttl", setvxlan_ttl), - DEF_CLONE_CMD("learn", 1, setvxlan_learn), - DEF_CLONE_CMD("-learn", 0, setvxlan_learn), - - DEF_CMD_ARG("vni", setvxlan_vni), - DEF_CMD_ARG("local", setvxlan_local), - DEF_CMD_ARG("remote", setvxlan_remote), - DEF_CMD_ARG("group", setvxlan_group), - DEF_CMD_ARG("localport", setvxlan_local_port), - DEF_CMD_ARG("remoteport", setvxlan_remote_port), - DEF_CMD_ARG2("portrange", setvxlan_port_range), - DEF_CMD_ARG("timeout", setvxlan_timeout), - DEF_CMD_ARG("maxaddr", setvxlan_maxaddr), + DEF_CLONE_CMD_ARG("vxlanttl", setvxlan_ttl), + DEF_CLONE_CMD("vxlanlearn", 1, setvxlan_learn), + DEF_CLONE_CMD("-vxlanlearn", 0, setvxlan_learn), + + DEF_CMD_ARG("vxlanvni", setvxlan_vni), + DEF_CMD_ARG("vxlanlocal", setvxlan_local), + DEF_CMD_ARG("vxlanremote", setvxlan_remote), + DEF_CMD_ARG("vxlangroup", setvxlan_group), + DEF_CMD_ARG("vxlanlocalport", setvxlan_local_port), + DEF_CMD_ARG("vxlanremoteport", setvxlan_remote_port), + DEF_CMD_ARG2("vxlanportrange", setvxlan_port_range), + DEF_CMD_ARG("vxlantimeout", setvxlan_timeout), + DEF_CMD_ARG("vxlanmaxaddr", setvxlan_maxaddr), DEF_CMD_ARG("vxlandev", setvxlan_dev), - DEF_CMD_ARG("ttl", setvxlan_ttl), - DEF_CMD("learn", 1, setvxlan_learn), - DEF_CMD("-learn", 0, setvxlan_learn), + DEF_CMD_ARG("vxlanttl", setvxlan_ttl), + DEF_CMD("vxlanlearn", 1, setvxlan_learn), + DEF_CMD("-vxlanlearn", 0, setvxlan_learn), - DEF_CMD("flush", 0, setvxlan_flush), - DEF_CMD("flushall", 1, setvxlan_flush), + DEF_CMD("vxlanflush", 0, setvxlan_flush), + DEF_CMD("vxlanflushall", 1, setvxlan_flush), }; static struct afswtch af_vxlan = { diff --git a/sbin/ifconfig/sfp.c b/sbin/ifconfig/sfp.c index d4da8c3..7c090e1 100644 --- a/sbin/ifconfig/sfp.c +++ b/sbin/ifconfig/sfp.c @@ -48,25 +48,16 @@ static const char rcsid[] = #include "ifconfig.h" -struct i2c_info; -typedef int (read_i2c)(struct i2c_info *ii, uint8_t addr, uint8_t off, - uint8_t len, caddr_t buf); - struct i2c_info { - int s; - int error; - int bshift; - int qsfp; - int do_diag; - struct ifreq *ifr; - read_i2c *f; - char *textbuf; - size_t bufsize; - int cfd; - int port_id; - int chip_id; + int fd; /* fd to issue SIOCGI2C */ + int error; /* Store first error */ + int qsfp; /* True if transceiver is QSFP */ + int do_diag; /* True if we need to request DDM */ + struct ifreq *ifr; /* Pointer to pre-filled ifreq */ }; +static int read_i2c(struct i2c_info *ii, uint8_t addr, uint8_t off, + uint8_t len, uint8_t *buf); static void dump_i2c_data(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len); @@ -191,6 +182,18 @@ static struct _nv eth_1040g[] = { { 0, NULL } }; +/* SFF-8636 Rev. 2.5 table 6.3: Revision compliance */ +static struct _nv rev_compl[] = { + { 0x1, "SFF-8436 rev <=4.8" }, + { 0x2, "SFF-8436 rev <=4.8" }, + { 0x3, "SFF-8636 rev <=1.3" }, + { 0x4, "SFF-8636 rev <=1.4" }, + { 0x5, "SFF-8636 rev <=1.5" }, + { 0x6, "SFF-8636 rev <=2.0" }, + { 0x7, "SFF-8636 rev <=2.5" }, + { 0x0, "Unspecified" } +}; + const char * find_value(struct _nv *x, int value) { @@ -255,11 +258,24 @@ convert_sff_connector(char *buf, size_t size, uint8_t value) } static void +convert_sff_rev_compliance(char *buf, size_t size, uint8_t value) +{ + const char *x; + + if (value > 0x07) + x = "Unallocated"; + else + x = find_value(rev_compl, value); + + snprintf(buf, size, "%s", x); +} + +static void get_sfp_identifier(struct i2c_info *ii, char *buf, size_t size) { uint8_t data; - ii->f(ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&data); + read_i2c(ii, SFF_8472_BASE, SFF_8472_ID, 1, &data); convert_sff_identifier(buf, size, data); } @@ -268,7 +284,7 @@ get_sfp_connector(struct i2c_info *ii, char *buf, size_t size) { uint8_t data; - ii->f(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, (caddr_t)&data); + read_i2c(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, &data); convert_sff_connector(buf, size, data); } @@ -277,7 +293,7 @@ get_qsfp_identifier(struct i2c_info *ii, char *buf, size_t size) { uint8_t data; - ii->f(ii, SFF_8436_BASE, SFF_8436_ID, 1, (caddr_t)&data); + read_i2c(ii, SFF_8436_BASE, SFF_8436_ID, 1, &data); convert_sff_identifier(buf, size, data); } @@ -286,7 +302,7 @@ get_qsfp_connector(struct i2c_info *ii, char *buf, size_t size) { uint8_t data; - ii->f(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, (caddr_t)&data); + read_i2c(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, &data); convert_sff_connector(buf, size, data); } @@ -303,7 +319,7 @@ printf_sfp_transceiver_descr(struct i2c_info *ii, char *buf, size_t size) tech_speed = NULL; /* Read bytes 3-10 at once */ - ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, &xbuf[3]); + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, &xbuf[3]); /* Check 10G ethernet first */ tech_class = find_zero_bit(eth_10g, xbuf[3], 1); @@ -331,14 +347,14 @@ get_sfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size) uint8_t code; unsigned char qbuf[8]; - ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (caddr_t)qbuf); + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (uint8_t *)qbuf); /* Check 10G Ethernet/IB first */ - ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, (caddr_t)&code); + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, &code); tech_class = find_zero_bit(eth_10g, code, 1); if (tech_class == NULL) { /* No match. Try Ethernet 1G */ - ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3, + read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3, 1, (caddr_t)&code); tech_class = find_zero_bit(eth_compat, code, 1); } @@ -356,7 +372,7 @@ get_qsfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size) uint8_t code; /* Check 10/40G Ethernet class only */ - ii->f(ii, SFF_8436_BASE, SFF_8436_CODE_E1040G, 1, (caddr_t)&code); + read_i2c(ii, SFF_8436_BASE, SFF_8436_CODE_E1040G, 1, &code); tech_class = find_zero_bit(eth_1040g, code, 1); if (tech_class == NULL) tech_class = "Unknown"; @@ -393,7 +409,7 @@ get_sfp_vendor_name(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, xbuf); + read_i2c(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -403,7 +419,7 @@ get_sfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, xbuf); + read_i2c(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -413,7 +429,7 @@ get_sfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, xbuf); + read_i2c(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -424,7 +440,7 @@ get_sfp_vendor_date(struct i2c_info *ii, char *buf, size_t size) memset(xbuf, 0, sizeof(xbuf)); /* Date code, see Table 3.8 for description */ - ii->f(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, xbuf); + read_i2c(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, (uint8_t *)xbuf); convert_sff_date(buf, size, xbuf); } @@ -434,7 +450,7 @@ get_qsfp_vendor_name(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -444,7 +460,7 @@ get_qsfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -454,7 +470,7 @@ get_qsfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size) char xbuf[17]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, (uint8_t *)xbuf); convert_sff_name(buf, size, xbuf); } @@ -464,7 +480,7 @@ get_qsfp_vendor_date(struct i2c_info *ii, char *buf, size_t size) char xbuf[6]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, (uint8_t *)xbuf); convert_sff_date(buf, size, xbuf); } @@ -501,12 +517,12 @@ print_sfp_vendor(struct i2c_info *ii, char *buf, size_t size) * */ static void -convert_sff_temp(char *buf, size_t size, char *xbuf) +convert_sff_temp(char *buf, size_t size, uint8_t *xbuf) { double d; - d = (double)(int8_t)xbuf[0]; - d += (double)(uint8_t)xbuf[1] / 256; + d = (double)xbuf[0]; + d += (double)xbuf[1] / 256; snprintf(buf, size, "%.2f C", d); } @@ -516,11 +532,11 @@ convert_sff_temp(char *buf, size_t size, char *xbuf) * 16-bit usigned value, treated as range 0..+6.55 Volts */ static void -convert_sff_voltage(char *buf, size_t size, char *xbuf) +convert_sff_voltage(char *buf, size_t size, uint8_t *xbuf) { double d; - d = (double)(((uint8_t)xbuf[0] << 8) | (uint8_t)xbuf[1]); + d = (double)((xbuf[0] << 8) | xbuf[1]); snprintf(buf, size, "%.2f Volts", d / 10000); } @@ -529,12 +545,12 @@ convert_sff_voltage(char *buf, size_t size, char *xbuf) * human representation. */ static void -convert_sff_power(struct i2c_info *ii, char *buf, size_t size, char *xbuf) +convert_sff_power(struct i2c_info *ii, char *buf, size_t size, uint8_t *xbuf) { uint16_t mW; double dbm; - mW = ((uint8_t)xbuf[0] << 8) + (uint8_t)xbuf[1]; + mW = (xbuf[0] << 8) + xbuf[1]; /* Convert mw to dbm */ dbm = 10.0 * log10(1.0 * mW / 10000); @@ -553,87 +569,116 @@ convert_sff_power(struct i2c_info *ii, char *buf, size_t size, char *xbuf) static void get_sfp_temp(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_DIAG, SFF_8472_TEMP, 2, xbuf); + read_i2c(ii, SFF_8472_DIAG, SFF_8472_TEMP, 2, xbuf); convert_sff_temp(buf, size, xbuf); } static void get_sfp_voltage(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf); + read_i2c(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf); convert_sff_voltage(buf, size, xbuf); } static void get_qsfp_temp(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf); convert_sff_temp(buf, size, xbuf); } static void get_qsfp_voltage(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_VCC, 2, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_VCC, 2, xbuf); convert_sff_voltage(buf, size, xbuf); } static void get_sfp_rx_power(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_DIAG, SFF_8472_RX_POWER, 2, xbuf); + read_i2c(ii, SFF_8472_DIAG, SFF_8472_RX_POWER, 2, xbuf); convert_sff_power(ii, buf, size, xbuf); } static void get_sfp_tx_power(struct i2c_info *ii, char *buf, size_t size) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8472_DIAG, SFF_8472_TX_POWER, 2, xbuf); + read_i2c(ii, SFF_8472_DIAG, SFF_8472_TX_POWER, 2, xbuf); convert_sff_power(ii, buf, size, xbuf); } static void get_qsfp_rx_power(struct i2c_info *ii, char *buf, size_t size, int chan) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_RX_CH1_MSB + (chan - 1) * 2, 2, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_RX_CH1_MSB + (chan-1)*2, 2, xbuf); convert_sff_power(ii, buf, size, xbuf); } static void get_qsfp_tx_power(struct i2c_info *ii, char *buf, size_t size, int chan) { - char xbuf[2]; + uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); - ii->f(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan -1) * 2, 2, xbuf); + read_i2c(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan-1)*2, 2, xbuf); convert_sff_power(ii, buf, size, xbuf); } -/* Generic handler */ +static void +get_qsfp_rev_compliance(struct i2c_info *ii, char *buf, size_t size) +{ + uint8_t xbuf; + + xbuf = 0; + read_i2c(ii, SFF_8436_BASE, SFF_8436_STATUS, 1, &xbuf); + convert_sff_rev_compliance(buf, size, xbuf); +} + +static uint32_t +get_qsfp_br(struct i2c_info *ii) +{ + uint8_t xbuf; + uint32_t rate; + + xbuf = 0; + read_i2c(ii, SFF_8436_BASE, SFF_8436_BITRATE, 1, &xbuf); + rate = xbuf * 100; + if (xbuf == 0xFF) { + read_i2c(ii, SFF_8436_BASE, SFF_8636_BITRATE, 1, &xbuf); + rate = xbuf * 250; + } + + return (rate); +} + +/* + * Reads i2c data from opened kernel socket. + */ static int -read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len, - caddr_t buf) +read_i2c(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len, + uint8_t *buf) { struct ifi2creq req; int i, l; @@ -653,7 +698,7 @@ read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len, while (len > 0) { l = (len > sizeof(req.data)) ? sizeof(req.data) : len; req.len = l; - if (ioctl(ii->s, SIOCGI2C, ii->ifr) != 0) { + if (ioctl(ii->fd, SIOCGI2C, ii->ifr) != 0) { ii->error = errno; return (errno); } @@ -676,7 +721,7 @@ dump_i2c_data(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len) while (len > 0) { memset(buf, 0, sizeof(buf)); read = (len > sizeof(buf)) ? sizeof(buf) : len; - ii->f(ii, addr, off, read, buf); + read_i2c(ii, addr, off, read, buf); if (ii->error != 0) { fprintf(stderr, "Error reading i2c info\n"); return; @@ -696,10 +741,11 @@ print_qsfp_status(struct i2c_info *ii, int verbose) { char buf[80], buf2[40], buf3[40]; uint8_t diag_type; + uint32_t bitrate; int i; /* Read diagnostic monitoring type */ - ii->f(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type); + read_i2c(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type); if (ii->error != 0) return; @@ -722,6 +768,16 @@ print_qsfp_status(struct i2c_info *ii, int verbose) if (ii->error == 0) printf("\t%s\n", buf); + if (verbose > 1) { + get_qsfp_rev_compliance(ii, buf, sizeof(buf)); + if (ii->error == 0) + printf("\tcompliance level: %s\n", buf); + + bitrate = get_qsfp_br(ii); + if (ii->error == 0 && bitrate > 0) + printf("\tnominal bitrate: %u Mbps\n", bitrate); + } + /* Request current measurements if they are provided: */ if (ii->do_diag != 0) { get_qsfp_temp(ii, buf, sizeof(buf)); @@ -749,7 +805,7 @@ print_sfp_status(struct i2c_info *ii, int verbose) uint8_t diag_type, flags; /* Read diagnostic monitoring type */ - ii->f(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type); + read_i2c(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type); if (ii->error != 0) return; @@ -797,11 +853,10 @@ sfp_status(int s, struct ifreq *ifr, int verbose) struct i2c_info ii; uint8_t id_byte; + /* Prepare necessary into pass to i2c reader */ memset(&ii, 0, sizeof(ii)); - /* Prepare necessary into to pass to NIC handler */ - ii.s = s; + ii.fd = s; ii.ifr = ifr; - ii.f = read_i2c_generic; /* * Try to read byte 0 from i2c: @@ -811,7 +866,7 @@ sfp_status(int s, struct ifreq *ifr, int verbose) * this might happen in case of empty transceiver slot. */ id_byte = 0; - ii.f(&ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&id_byte); + read_i2c(&ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&id_byte); if (ii.error != 0 || id_byte == 0) return; diff --git a/sbin/ifconfig/tests/Makefile b/sbin/ifconfig/tests/Makefile new file mode 100644 index 0000000..044e979 --- /dev/null +++ b/sbin/ifconfig/tests/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR}/../../.. +SRCTOP= ${.CURDIR}/../../.. +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/sbin/ifconfig + +TESTSDIR= ${TESTSBASE}/sbin/ifconfig + +NETBSD_ATF_TESTS_SH= nonexistent_test + +.include <netbsd-tests.test.mk> + +.include <bsd.test.mk> |