[Midnightbsd-cvs] src [11210] trunk/sbin/ifconfig: sync with freebsd
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Jul 1 16:46:16 EDT 2018
Revision: 11210
http://svnweb.midnightbsd.org/src/?rev=11210
Author: laffer1
Date: 2018-07-01 16:46:16 -0400 (Sun, 01 Jul 2018)
Log Message:
-----------
sync with freebsd
Modified Paths:
--------------
trunk/sbin/ifconfig/Makefile
trunk/sbin/ifconfig/af_atalk.c
trunk/sbin/ifconfig/af_inet.c
trunk/sbin/ifconfig/af_inet6.c
trunk/sbin/ifconfig/af_ipx.c
trunk/sbin/ifconfig/af_link.c
trunk/sbin/ifconfig/af_nd6.c
trunk/sbin/ifconfig/ifbridge.c
trunk/sbin/ifconfig/ifclone.c
trunk/sbin/ifconfig/ifconfig.8
trunk/sbin/ifconfig/ifconfig.c
trunk/sbin/ifconfig/ifconfig.h
trunk/sbin/ifconfig/iffib.c
trunk/sbin/ifconfig/ifgif.c
trunk/sbin/ifconfig/ifgre.c
trunk/sbin/ifconfig/ifgroup.c
trunk/sbin/ifconfig/ifieee80211.c
trunk/sbin/ifconfig/iflagg.c
trunk/sbin/ifconfig/ifmac.c
trunk/sbin/ifconfig/ifmedia.c
trunk/sbin/ifconfig/ifpfsync.c
trunk/sbin/ifconfig/ifvlan.c
Added Paths:
-----------
trunk/sbin/ifconfig/carp.c
trunk/sbin/ifconfig/ifvxlan.c
trunk/sbin/ifconfig/sfp.c
Property Changed:
----------------
trunk/sbin/ifconfig/ifconfig.8
Modified: trunk/sbin/ifconfig/Makefile
===================================================================
--- trunk/sbin/ifconfig/Makefile 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/Makefile 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,5 +1,6 @@
+# $MidnightBSD$
# From: @(#)Makefile 8.1 (Berkeley) 6/5/93
-# $MidnightBSD$
+# $FreeBSD: stable/10/sbin/ifconfig/Makefile 286810 2015-08-15 17:52:55Z melifaro $
.include <bsd.own.mk>
@@ -31,16 +32,23 @@
SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support
SRCS+= iffib.c # non-default FIB support
SRCS+= ifvlan.c # SIOC[GS]ETVLAN support
+SRCS+= ifvxlan.c # VXLAN support
SRCS+= ifgre.c # GRE keys etc
SRCS+= ifgif.c # GIF reversed header workaround
+SRCS+= sfp.c # SFP/SFP+ information
+DPADD+= ${LIBM}
+LDADD+= -lm
+
SRCS+= ifieee80211.c regdomain.c # SIOC[GS]IEEE80211 support
-DPADD+= ${LIBBSDXML} ${LIBJAIL} ${LIBSBUF}
-LDADD+= -lbsdxml -ljail -lsbuf
+DPADD+= ${LIBBSDXML} ${LIBSBUF}
+LDADD+= -lbsdxml -lsbuf
-SRCS+= ifcarp.c # SIOC[GS]VH support
+SRCS+= carp.c # SIOC[GS]VH support
SRCS+= ifgroup.c # ...
+.if ${MK_PF} != "no"
SRCS+= ifpfsync.c # pfsync(4) support
+.endif
SRCS+= ifbridge.c # bridge support
SRCS+= iflagg.c # lagg support
@@ -56,6 +64,11 @@
DPADD+= ${LIBIPX}
LDADD+= -lipx
.endif
+.if ${MK_JAIL} != "no" && !defined(RELEASE_CRUNCH) && !defined(RESCUE)
+CFLAGS+= -DJAIL
+DPADD+= ${LIBJAIL}
+LDADD+= -ljail
+.endif
MAN= ifconfig.8
Modified: trunk/sbin/ifconfig/af_atalk.c
===================================================================
--- trunk/sbin/ifconfig/af_atalk.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_atalk.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,10 +30,10 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_atalk.c 289986 2015-10-26 03:43:28Z ngie $";
#endif /* not lint */
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -172,11 +173,9 @@
static __constructor void
atalk_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(atalk_cmds); i++)
+ for (i = 0; i < nitems(atalk_cmds); i++)
cmd_register(&atalk_cmds[i]);
af_register(&af_atalk);
-#undef N
}
Modified: trunk/sbin/ifconfig/af_inet.c
===================================================================
--- trunk/sbin/ifconfig/af_inet.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_inet.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,10 +30,10 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_inet.c 300285 2016-05-20 07:14:03Z truckman $";
#endif /* not lint */
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -84,8 +85,11 @@
if (ifa->ifa_flags & IFF_BROADCAST) {
sin = (struct sockaddr_in *)ifa->ifa_broadaddr;
if (sin != NULL && sin->sin_addr.s_addr != 0)
- printf("broadcast %s", inet_ntoa(sin->sin_addr));
+ printf("broadcast %s ", inet_ntoa(sin->sin_addr));
}
+
+ print_vhid(ifa, " ");
+
putchar('\n');
}
@@ -98,14 +102,12 @@
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;
sin->sin_len = sizeof(*sin);
- if (which != MASK)
- sin->sin_family = AF_INET;
+ sin->sin_family = AF_INET;
if (which == ADDR) {
char *p = NULL;
@@ -124,6 +126,7 @@
*p = '/';
errx(1, "%s: bad value (width %s)", s, errstr);
}
+ min->sin_family = AF_INET;
min->sin_len = sizeof(*min);
min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) &
0xffffffff);
@@ -139,7 +142,6 @@
sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
else
errx(1, "%s: bad value", s);
-#undef MIN
}
static void
@@ -151,7 +153,7 @@
const struct sockaddr *sa = (const struct sockaddr *) &ifr.ifr_addr;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, name, IFNAMSIZ);
+ strlcpy(ifr.ifr_name, name, IFNAMSIZ);
if (ioctl(s, SIOCGIFPSRCADDR, (caddr_t)&ifr) < 0)
return;
@@ -176,7 +178,7 @@
struct in_aliasreq addreq;
memset(&addreq, 0, sizeof(addreq));
- strncpy(addreq.ifra_name, name, IFNAMSIZ);
+ strlcpy(addreq.ifra_name, name, IFNAMSIZ);
memcpy(&addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
memcpy(&addreq.ifra_dstaddr, dstres->ai_addr, dstres->ai_addr->sa_len);
Modified: trunk/sbin/ifconfig/af_inet6.c
===================================================================
--- trunk/sbin/ifconfig/af_inet6.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_inet6.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,7 +30,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_inet6.c 319265 2017-05-30 22:45:01Z asomers $";
#endif /* not lint */
#include <sys/param.h>
@@ -42,6 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <time.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
@@ -98,10 +100,11 @@
setip6lifetime(const char *cmd, const char *val, int s,
const struct afswtch *afp)
{
- time_t newval, t;
+ struct timespec now;
+ time_t newval;
char *ep;
- t = time(NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
newval = (time_t)strtoul(val, &ep, 0);
if (val == ep)
errx(1, "invalid %s", cmd);
@@ -108,10 +111,10 @@
if (afp->af_af != AF_INET6)
errx(1, "%s not allowed for the AF", cmd);
if (strcmp(cmd, "vltime") == 0) {
- in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
+ in6_addreq.ifra_lifetime.ia6t_expire = now.tv_sec + newval;
in6_addreq.ifra_lifetime.ia6t_vltime = newval;
} else if (strcmp(cmd, "pltime") == 0) {
- in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
+ in6_addreq.ifra_lifetime.ia6t_preferred = now.tv_sec + newval;
in6_addreq.ifra_lifetime.ia6t_pltime = newval;
}
}
@@ -172,9 +175,11 @@
int s6;
u_int32_t flags6;
struct in6_addrlifetime lifetime;
- time_t t = time(NULL);
+ struct timespec now;
int error;
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+
memset(&null_sin, 0, sizeof(null_sin));
sin = (struct sockaddr_in6 *)ifa->ifa_addr;
@@ -181,7 +186,7 @@
if (sin == NULL)
return;
- strncpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
+ strlcpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
warn("socket(AF_INET6,SOCK_DGRAM)");
return;
@@ -250,26 +255,31 @@
printf("autoconf ");
if ((flags6 & IN6_IFF_TEMPORARY) != 0)
printf("temporary ");
+ if ((flags6 & IN6_IFF_PREFER_SOURCE) != 0)
+ printf("prefer_source ");
- if (sin->sin6_scope_id)
- printf("scopeid 0x%x ", sin->sin6_scope_id);
+ if (((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id)
+ printf("scopeid 0x%x ",
+ ((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_scope_id);
if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) {
printf("pltime ");
if (lifetime.ia6t_preferred) {
- printf("%s ", lifetime.ia6t_preferred < t
- ? "0" : sec2str(lifetime.ia6t_preferred - t));
+ printf("%s ", 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 < t
- ? "0" : sec2str(lifetime.ia6t_expire - t));
+ printf("%s ", lifetime.ia6t_expire < now.tv_sec
+ ? "0" : sec2str(lifetime.ia6t_expire - now.tv_sec));
} else
printf("infty ");
}
+ print_vhid(ifa, " ");
+
putchar('\n');
}
@@ -327,12 +337,14 @@
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
error = getaddrinfo(s, NULL, &hints, &res);
+ if (error != 0) {
+ if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
+ errx(1, "%s: bad value", s);
+ } else {
+ bcopy(res->ai_addr, sin, res->ai_addrlen);
+ freeaddrinfo(res);
+ }
}
- if (error != 0) {
- if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
- errx(1, "%s: bad value", s);
- } else
- bcopy(res->ai_addr, sin, res->ai_addrlen);
}
static int
@@ -413,7 +425,7 @@
const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr;
memset(&in6_ifr, 0, sizeof(in6_ifr));
- strncpy(in6_ifr.ifr_name, name, IFNAMSIZ);
+ strlcpy(in6_ifr.ifr_name, name, sizeof(in6_ifr.ifr_name));
if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0)
return;
@@ -440,7 +452,7 @@
struct in6_aliasreq in6_addreq;
memset(&in6_addreq, 0, sizeof(in6_addreq));
- strncpy(in6_addreq.ifra_name, name, IFNAMSIZ);
+ strlcpy(in6_addreq.ifra_name, name, sizeof(in6_addreq.ifra_name));
memcpy(&in6_addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr,
dstres->ai_addr->sa_len);
@@ -458,6 +470,8 @@
DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags),
DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags),
DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags),
+ DEF_CMD("prefer_source",IN6_IFF_PREFER_SOURCE, setip6flags),
+ DEF_CMD("-prefer_source",-IN6_IFF_PREFER_SOURCE,setip6flags),
DEF_CMD("accept_rtadv", ND6_IFF_ACCEPT_RTADV, setnd6flags),
DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV, setnd6flags),
DEF_CMD("no_radr", ND6_IFF_NO_RADR, setnd6flags),
@@ -468,12 +482,12 @@
DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags),
DEF_CMD("nud", ND6_IFF_PERFORMNUD, setnd6flags),
DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags),
- DEF_CMD("prefer_source",ND6_IFF_PREFER_SOURCE, setnd6flags),
- DEF_CMD("-prefer_source",-ND6_IFF_PREFER_SOURCE,setnd6flags),
DEF_CMD("auto_linklocal",ND6_IFF_AUTO_LINKLOCAL,setnd6flags),
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),
Modified: trunk/sbin/ifconfig/af_ipx.c
===================================================================
--- trunk/sbin/ifconfig/af_ipx.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_ipx.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,7 +30,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_ipx.c 170679 2007-06-13 18:07:59Z rwatson $";
#endif /* not lint */
#include <sys/types.h>
Modified: trunk/sbin/ifconfig/af_link.c
===================================================================
--- trunk/sbin/ifconfig/af_link.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_link.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,7 +30,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_link.c 318430 2017-05-17 22:29:25Z rpokala $";
#endif /* not lint */
#include <sys/types.h>
@@ -42,6 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include <ifaddrs.h>
+#include <unistd.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -69,6 +71,41 @@
printf("\tlladdr %s\n", link_ntoa(sdl) + n);
}
+ /* Best-effort (i.e. failures are silent) to get original
+ * hardware address, as read by NIC driver at attach time. Only
+ * applies to Ethernet NICs (IFT_ETHER). However, laggX
+ * interfaces claim to be IFT_ETHER, and re-type their component
+ * Ethernet NICs as IFT_IEEE8023ADLAG. So, check for both. If
+ * the MAC is zeroed, then it's actually a lagg.
+ */
+ if ((sdl->sdl_type == IFT_ETHER ||
+ sdl->sdl_type == IFT_IEEE8023ADLAG) &&
+ sdl->sdl_alen == ETHER_ADDR_LEN) {
+ struct ifreq ifr;
+ int sock_hw;
+ int rc;
+ static const u_char laggaddr[6] = {0};
+
+ strncpy(ifr.ifr_name, ifa->ifa_name,
+ sizeof(ifr.ifr_name));
+ memcpy(&ifr.ifr_addr, ifa->ifa_addr,
+ sizeof(ifa->ifa_addr->sa_len));
+ ifr.ifr_addr.sa_family = AF_LOCAL;
+ if ((sock_hw = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
+ warn("socket(AF_LOCAL,SOCK_DGRAM)");
+ return;
+ }
+ rc = ioctl(sock_hw, SIOCGHWADDR, &ifr);
+ close(sock_hw);
+ if (rc != 0) {
+ return;
+ }
+ if (memcmp(ifr.ifr_addr.sa_data, laggaddr, sdl->sdl_alen) == 0) {
+ return;
+ }
+ printf("\thwaddr %s\n", ether_ntoa((const struct ether_addr *)
+ &ifr.ifr_addr.sa_data));
+ }
}
}
Modified: trunk/sbin/ifconfig/af_nd6.c
===================================================================
--- trunk/sbin/ifconfig/af_nd6.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/af_nd6.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 2009 Hiroki Sato. All rights reserved.
*
@@ -25,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/af_nd6.c 319264 2017-05-30 22:44:05Z asomers $";
#endif /* not lint */
#include <sys/param.h>
@@ -58,7 +59,7 @@
#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\011NO_DAD\020DEFAULTIF"
static int isnd6defif(int);
void setnd6flags(const char *, int, int, const struct afswtch *);
@@ -74,7 +75,7 @@
int error;
memset(&nd, 0, sizeof(nd));
- strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
+ strlcpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
error = ioctl(s, SIOCGIFINFO_IN6, &nd);
if (error) {
warn("ioctl(SIOCGIFINFO_IN6)");
@@ -99,7 +100,7 @@
int error;
memset(&ndifreq, 0, sizeof(ndifreq));
- strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname));
+ strlcpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname));
if (d < 0) {
if (isnd6defif(s)) {
@@ -126,7 +127,7 @@
int error;
memset(&ndifreq, 0, sizeof(ndifreq));
- strncpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname));
+ strlcpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname));
ifindex = if_nametoindex(ndifreq.ifname);
error = ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq);
@@ -146,9 +147,9 @@
int isdefif;
memset(&nd, 0, sizeof(nd));
- strncpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
+ strlcpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname));
if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- if (errno != EPROTONOSUPPORT)
+ if (errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
warn("socket(AF_INET6, SOCK_DGRAM)");
return;
}
Added: trunk/sbin/ifconfig/carp.c
===================================================================
--- trunk/sbin/ifconfig/carp.c (rev 0)
+++ trunk/sbin/ifconfig/carp.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -0,0 +1,227 @@
+/* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sbin/ifconfig/carp.c 289986 2015-10-26 03:43:28Z ngie $ */
+/* from $OpenBSD: ifconfig.c,v 1.82 2003/10/19 05:43:35 mcbride Exp $ */
+
+/*
+ * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
+ * Copyright (c) 2003 Ryan McBride. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <stdlib.h>
+#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>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+
+#include "ifconfig.h"
+
+static const char *carp_states[] = { CARP_STATES };
+
+static void carp_status(int s);
+static void setcarp_vhid(const char *, int, int, const struct afswtch *rafp);
+static void setcarp_callback(int, void *);
+static void setcarp_advbase(const char *,int, int, const struct afswtch *rafp);
+static void setcarp_advskew(const char *, int, int, const struct afswtch *rafp);
+static void setcarp_passwd(const char *, int, int, const struct afswtch *rafp);
+
+static int carpr_vhid = -1;
+static int carpr_advskew = -1;
+static int carpr_advbase = -1;
+static int carpr_state = -1;
+static unsigned char const *carpr_key;
+
+static void
+carp_status(int s)
+{
+ struct carpreq carpr[CARP_MAXVHID];
+ int i;
+
+ bzero(carpr, sizeof(struct carpreq) * CARP_MAXVHID);
+ carpr[0].carpr_count = CARP_MAXVHID;
+ ifr.ifr_data = (caddr_t)&carpr;
+
+ if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
+ return;
+
+ for (i = 0; i < carpr[0].carpr_count; i++) {
+ printf("\tcarp: %s vhid %d advbase %d advskew %d",
+ carp_states[carpr[i].carpr_state], carpr[i].carpr_vhid,
+ carpr[i].carpr_advbase, carpr[i].carpr_advskew);
+ if (printkeys && carpr[i].carpr_key[0] != '\0')
+ printf(" key \"%s\"\n", carpr[i].carpr_key);
+ else
+ printf("\n");
+ }
+}
+
+static void
+setcarp_vhid(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ carpr_vhid = atoi(val);
+
+ if (carpr_vhid <= 0 || carpr_vhid > CARP_MAXVHID)
+ errx(1, "vhid must be greater than 0 and less than %u",
+ CARP_MAXVHID);
+
+ switch (afp->af_af) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct in_aliasreq *ifra;
+
+ ifra = (struct in_aliasreq *)afp->af_addreq;
+ ifra->ifra_vhid = carpr_vhid;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct in6_aliasreq *ifra;
+
+ ifra = (struct in6_aliasreq *)afp->af_addreq;
+ ifra->ifra_vhid = carpr_vhid;
+ break;
+ }
+#endif
+ default:
+ errx(1, "%s doesn't support carp(4)", afp->af_name);
+ }
+
+ callback_register(setcarp_callback, NULL);
+}
+
+static void
+setcarp_callback(int s, void *arg __unused)
+{
+ struct carpreq carpr;
+
+ bzero(&carpr, sizeof(struct carpreq));
+ carpr.carpr_vhid = carpr_vhid;
+ carpr.carpr_count = 1;
+ ifr.ifr_data = (caddr_t)&carpr;
+
+ if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1 && errno != ENOENT)
+ err(1, "SIOCGVH");
+
+ if (carpr_key != NULL)
+ /* XXX Should hash the password into the key here? */
+ strlcpy(carpr.carpr_key, carpr_key, CARP_KEY_LEN);
+ if (carpr_advskew > -1)
+ carpr.carpr_advskew = carpr_advskew;
+ if (carpr_advbase > -1)
+ carpr.carpr_advbase = carpr_advbase;
+ if (carpr_state > -1)
+ carpr.carpr_state = carpr_state;
+
+ if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSVH");
+}
+
+static void
+setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ if (carpr_vhid == -1)
+ errx(1, "passwd requires vhid");
+
+ carpr_key = val;
+}
+
+static void
+setcarp_advskew(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ if (carpr_vhid == -1)
+ errx(1, "advskew requires vhid");
+
+ carpr_advskew = atoi(val);
+}
+
+static void
+setcarp_advbase(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ if (carpr_vhid == -1)
+ errx(1, "advbase requires vhid");
+
+ carpr_advbase = atoi(val);
+}
+
+static void
+setcarp_state(const char *val, int d, int s, const struct afswtch *afp)
+{
+ int i;
+
+ if (carpr_vhid == -1)
+ errx(1, "state requires vhid");
+
+ for (i = 0; i <= CARP_MAXSTATE; i++)
+ if (strcasecmp(carp_states[i], val) == 0) {
+ carpr_state = i;
+ return;
+ }
+
+ errx(1, "unknown state");
+}
+
+static struct cmd carp_cmds[] = {
+ DEF_CMD_ARG("advbase", setcarp_advbase),
+ DEF_CMD_ARG("advskew", setcarp_advskew),
+ DEF_CMD_ARG("pass", setcarp_passwd),
+ DEF_CMD_ARG("vhid", setcarp_vhid),
+ DEF_CMD_ARG("state", setcarp_state),
+};
+static struct afswtch af_carp = {
+ .af_name = "af_carp",
+ .af_af = AF_UNSPEC,
+ .af_other_status = carp_status,
+};
+
+static __constructor void
+carp_ctor(void)
+{
+ int i;
+
+ for (i = 0; i < nitems(carp_cmds); i++)
+ cmd_register(&carp_cmds[i]);
+ af_register(&af_carp);
+}
Property changes on: trunk/sbin/ifconfig/carp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sbin/ifconfig/ifbridge.c
===================================================================
--- trunk/sbin/ifconfig/ifbridge.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifbridge.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright 2001 Wasabi Systems, Inc.
* All rights reserved.
@@ -35,7 +36,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifbridge.c 289986 2015-10-26 03:43:28Z ngie $";
#endif /* not lint */
#include <sys/param.h>
@@ -749,11 +750,9 @@
static __constructor void
bridge_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
- for (i = 0; i < N(bridge_cmds); i++)
+ for (i = 0; i < nitems(bridge_cmds); i++)
cmd_register(&bridge_cmds[i]);
af_register(&af_bridge);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifclone.c
===================================================================
--- trunk/sbin/ifconfig/ifclone.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifclone.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -29,12 +30,12 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifclone.c 319265 2017-05-30 22:45:01Z asomers $";
#endif /* not lint */
+#include <sys/param.h>
+#include <sys/ioctl.h>
#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -87,6 +88,7 @@
putchar('\n');
free(buf);
+ close(s);
}
struct clone_defcb {
@@ -144,11 +146,12 @@
}
/*
- * If we get a different name back than we put in, print it.
+ * If we get a different name back than we put in, update record and
+ * indicate it should be printed later.
*/
if (strncmp(name, ifr.ifr_name, sizeof(name)) != 0) {
strlcpy(name, ifr.ifr_name, sizeof(name));
- printf("%s\n", name);
+ printifname = 1;
}
}
@@ -161,7 +164,7 @@
static
DECL_CMD_FUNC(clone_destroy, arg, d)
{
- (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCIFDESTROY, &ifr) < 0)
err(1, "SIOCIFDESTROY");
}
@@ -184,11 +187,9 @@
static __constructor void
clone_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(clone_cmds); i++)
+ for (i = 0; i < nitems(clone_cmds); i++)
cmd_register(&clone_cmds[i]);
opt_register(&clone_Copt);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifconfig.8
===================================================================
--- trunk/sbin/ifconfig/ifconfig.8 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifconfig.8 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -26,9 +27,9 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/sbin/ifconfig/ifconfig.8 290736 2015-11-13 01:03:59Z smh $
.\"
-.Dd January 10, 2013
+.Dd November 6, 2015
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -141,13 +142,13 @@
.Pq Dq link
address
is specified as a series of colon-separated hex digits.
-This can be used to
-e.g.,\& set a new MAC address on an ethernet interface, though the
-mechanism used is not ethernet-specific.
+This can be used to, for example,
+set a new MAC address on an Ethernet interface, though the
+mechanism used is not Ethernet specific.
If the interface is already
up when this option is used, it will be briefly brought down and
then brought back up again in order to ensure that the receive
-filter in the underlying ethernet hardware is properly reprogrammed.
+filter in the underlying Ethernet hardware is properly reprogrammed.
.It Ar address_family
Specify the
address family
@@ -174,6 +175,18 @@
.Dq lladdr
are synonyms for
.Dq link .
+When using the
+.Fl l
+flag, the
+.Dq ether
+address family has special meaning and is no longer synonymous with
+.Dq link
+or
+.Dq lladdr .
+Specifying
+.Fl l Dq ether
+will list only Ethernet interfaces, excluding all other interface types,
+including the loopback interface.
.It Ar dest_address
Specify the address of the correspondent on the other end
of a point to point link.
@@ -309,6 +322,14 @@
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 ipdst
This is used to specify an Internet host who is willing to receive
IP packets encapsulating IPX packets bound for a remote network.
@@ -700,7 +721,8 @@
.Cm defaultif .
.It Cm ifdisabled
Set a flag to disable all of IPv6 network communications on the
-specified interface. Note that if there are already configured IPv6
+specified interface.
+Note that if there are already configured IPv6
addresses on that interface, all of them are marked as
.Dq tentative
and DAD will be performed when this flag is cleared.
@@ -716,12 +738,6 @@
.It Cm -nud
Clear a flag
.Cm nud .
-.It Cm prefer_source
-Set a flag to prefer addresses on the interface as candidates of the
-source address for outgoing packets.
-.It Cm -prefer_source
-Clear a flag
-.Cm prefer_source .
.It Cm no_prefer_iface
Set a flag to not prefer address on the interface as candidates of the
source address for outgoing packets, even when the interface is
@@ -729,8 +745,26 @@
.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.
+Note that the address family keyword
+.Dq Li inet6
+is needed for them:
+.Bl -tag -width indent
+.It Cm prefer_source
+Set a flag to prefer address as a candidate of the source address for
+outgoing packets.
+.It Cm -prefer_source
+Clear a flag
+.Cm prefer_source .
+.El
+.Pp
The following parameters are specific to cloning
IEEE 802.11 wireless interfaces with the
.Cm create
@@ -1060,7 +1094,9 @@
Country/Region codes are specified as a 2-character abbreviation
defined by ISO 3166 or using a longer, but possibly ambiguous, spelling;
e.g., "ES" and "Spain".
-The set of country codes are taken from /etc/regdomain.xml and can also
+The set of country codes are taken from
+.Pa /etc/regdomain.xml
+and can also
be viewed with the ``list countries'' request.
Note that not all devices support changing the country code from a default
setting; typically stored in EEPROM.
@@ -1078,7 +1114,9 @@
DFS support is mandatory for some 5GHz frequencies in certain
locales (e.g., ETSI).
By default DFS is enabled according to the regulatory definitions
-specified in /etc/regdomain.xml and the current country code, regdomain,
+specified in
+.Pa /etc/regdomain.xml
+and the current country code, regdomain,
and channel.
Note the underlying device (and driver) must support radar detection
for full DFS support to work.
@@ -1127,6 +1165,41 @@
specifies the number of beacon intervals between DTIM
and must be in the range 1 to 15.
By default DTIM is 1 (i.e., DTIM occurs at each beacon).
+.It Cm quiet
+Enable the use of quiet IE.
+Hostap will use this to silence other
+stations to reduce interference for radar detection when
+operating on 5GHz frequency and doth support is enabled.
+Use
+.Fl quiet
+to disable this functionality.
+.It Cm quiet_period Ar period
+Set the QUIET
+.Ar period
+to the number of beacon intervals between the start of regularly
+scheduled quiet intervals defined by Quiet element.
+.It Cm quiet_count Ar count
+Set the QUIET
+.Ar count
+to the number of TBTTs until the beacon interval during which the
+next quiet interval shall start.
+A value of 1 indicates the quiet
+interval will start during the beacon interval starting at the next
+TBTT.
+A value 0 is reserved.
+.It Cm quiet_offset Ar offset
+Set the QUIET
+.Ar offset
+to the offset of the start of the quiet interval from the TBTT
+specified by the Quiet count, expressed in TUs.
+The value of the
+.Ar offset
+shall be less than one beacon interval.
+.It Cm quiet_duration Ar dur
+Set the QUIET
+.Ar dur
+to the duration of the Quiet interval, expressed in TUs.
+The value should be less than beacon interval.
.It Cm dturbo
Enable the use of Atheros Dynamic Turbo mode when communicating with
another Dynamic Turbo-capable station.
@@ -1552,7 +1625,9 @@
In particular the set of available channels, how the wireless device
will operation on the channels, and the maximum transmit power that
can be used on a channel are defined by this setting.
-Regdomain codes (SKU's) are taken from /etc/regdomain.xml and can also
+Regdomain codes (SKU's) are taken from
+.Pa /etc/regdomain.xml
+and can also
be viewed with the ``list countries'' request.
Note that not all devices support changing the regdomain from a default
setting; typically stored in EEPROM.
@@ -1986,6 +2061,12 @@
By default
.Cm meshforward
is enabled.
+.It Cm meshgate
+This attribute specifies whether or not the mesh STA activates mesh gate
+announcements.
+By default
+.Cm meshgate
+is disabled.
.It Cm meshmetric Ar protocol
Set the specified
.Ar protocol
@@ -2020,7 +2101,7 @@
Nodes on the mesh without a path to this root mesh station with try to
discover a path to us.
.It Cm PROACTIVE
-Send broadcast path requests every two seconds and every node must reply with
+Send broadcast path requests every two seconds and every node must reply
with a path reply even if it already has a path to this root mesh station.
.It Cm RANN
Send broadcast root announcement (RANN) frames.
@@ -2313,9 +2394,16 @@
from the aggregation interface.
.It Cm laggproto Ar proto
Set the aggregation protocol.
-The default is failover.
-The available options are failover, fec, lacp, loadbalance, roundrobin and
-none.
+The default is
+.Li failover .
+The available options are
+.Li failover ,
+.Li lacp ,
+.Li loadbalance ,
+.Li roundrobin ,
+.Li broadcast
+and
+.Li none .
.It Cm lagghash Ar option Ns Oo , Ns Ar option Oc
Set the packet layers to hash for aggregation protocols which load balance.
The default is
@@ -2330,7 +2418,53 @@
.It Cm l4
src/dst port for TCP/UDP/SCTP.
.El
-.Pp
+.It Cm use_flowid
+Enable local hash computation for RSS hash on the interface.
+The
+.Li loadbalance
+and
+.Li lacp
+modes will use the RSS hash from the network card if available
+to avoid computing one, this may give poor traffic distribution
+if the hash is invalid or uses less of the protocol header information.
+.Cm use_flowid
+disables use of RSS hash from the network card.
+The default value can be set via the
+.Va net.link.lagg.default_use_flowid
+.Xr sysctl 8
+variable.
+.Li 0
+means
+.Dq disabled
+and
+.Li 1
+means
+.Dq enabled .
+.It Cm -use_flowid
+Disable local hash computation for RSS hash on the interface.
+.It Cm flowid_shift Ar number
+Set a shift parameter for RSS local hash computation.
+Hash is calculated by using flowid bits in a packet header mbuf
+which are shifted by the number of this parameter.
+.It Cm lacp_fast_timeout
+Enable lacp fast-timeout on the interface.
+.It Cm -lacp_fast_timeout
+Disable lacp fast-timeout on the interface.
+.It Cm lacp_strict
+Enable lacp strict compliance on the interface.
+The default value can be set via the
+.Va net.link.lagg.lacp.default_strict_mode
+.Xr sysctl 8
+variable.
+.Li 0
+means
+.Dq disabled
+and
+.Li 1
+means
+.Dq enabled .
+.It Cm -lacp_strict
+Disable lacp strict compliance on the interface.
.El
.Pp
The following parameters are specific to IP tunnel interfaces,
@@ -2355,7 +2489,8 @@
parameter.
.It Cm accept_rev_ethip_ver
Set a flag to accept both correct EtherIP packets and ones
-with reversed version field. Enabled by default.
+with reversed version field.
+Enabled by default.
This is for backward compatibility with
.Fx 6.1 ,
6.2, 6.3, 7.0, and 7.1.
@@ -2362,9 +2497,18 @@
.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. Disabled by default.
+field intentionally.
+Disabled by default.
This is for backward compatibility with
.Fx 6.1 ,
6.2, 6.3, 7.0, and 7.1.
@@ -2387,10 +2531,28 @@
.Xr pfsync 4
interfaces:
.Bl -tag -width indent
+.It Cm syncdev Ar iface
+Use the specified interface
+to send and receive pfsync state synchronisation messages.
+.It Fl syncdev
+Stop sending pfsync state synchronisation messages over the network.
+.It Cm syncpeer Ar peer_address
+Make the pfsync link point-to-point rather than using
+multicast to broadcast the state synchronisation messages.
+The peer_address is the IP address of the other host taking part in
+the pfsync cluster.
+.It Fl syncpeer
+Broadcast the packets using multicast.
.It Cm maxupd Ar n
Set the maximum number of updates for a single state which
can be collapsed into one.
This is an 8-bit number; the default value is 128.
+.It Cm defer
+Defer transmission of the first packet in a state until a peer has
+acknowledged that the associated state has been inserted.
+.It Fl defer
+Do not defer the first packet in a state.
+This is the default.
.El
.Pp
The following parameters are specific to
@@ -2400,7 +2562,7 @@
.It Cm vlan Ar vlan_tag
Set the VLAN tag value to
.Ar vlan_tag .
-This value is a 16-bit number which is used to create an 802.1Q
+This value is a 12-bit VLAN Identifier (VID) which is used to create an 802.1Q
VLAN header for packets sent from the
.Xr vlan 4
interface.
@@ -2422,7 +2584,7 @@
.Ar iface
with 802.1Q VLAN encapsulation.
Packets with 802.1Q encapsulation received
-by the parent interface with the correct VLAN tag will be diverted to
+by the parent interface with the correct VLAN Identifier will be diverted to
the associated
.Xr vlan 4
pseudo-interface.
@@ -2429,7 +2591,7 @@
The
.Xr vlan 4
interface is assigned a
-copy of the parent interface's flags and the parent's ethernet address.
+copy of the parent interface's flags and the parent's Ethernet address.
The
.Cm vlandev
and
@@ -2461,22 +2623,113 @@
This breaks the link between the
.Xr vlan 4
interface and its parent,
-clears its VLAN tag, flags and its link address and shuts the interface down.
+clears its VLAN Identifier, flags and its link address and shuts the interface
+down.
The
.Ar iface
argument is useless and hence deprecated.
.El
.Pp
-The following parameters are specific to
+The following parameters are used to configure
+.Xr vxlan 4
+interfaces.
+.Bl -tag -width indent
+.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 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 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 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 vxlanlocalport Ar port
+The port number the interface will listen on.
+The default port number is 4789.
+.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 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
+for more effective load balancing.
+The default range is between the
+.Xr sysctl 8
+variables
+.Va net.inet.ip.portrange.first
+and
+.Va net.inet.ip.portrange.last
+.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 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 vxlanttl Ar ttl
+The TTL used in the encapsulating IPv4/IPv6 header.
+The default is 64.
+.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 vxlanlearn
+The forwarding table is not populated by recevied packets.
+.It Cm vxlanflush
+Delete all dynamically-learned addresses from the forwarding table.
+.It Cm vxlanflushall
+Delete all addresses, including static addresses, from the forwarding table.
+.El
+.Pp
+The following parameters are used to configure
.Xr carp 4
-interfaces:
+protocol on an interface:
.Bl -tag -width indent
+.It Cm vhid Ar n
+Set the virtual host ID.
+This is a required setting to initiate
+.Xr carp 4 .
+If the virtual host ID does not exist yet, it is created and attached to the
+interface, otherwise configuration of an existing vhid is adjusted.
+If the
+.Cm vhid
+keyword is supplied along with an
+.Dq inet6
+or
+.Dq inet
+address, then this address is configured to be run under control of the
+specified vhid.
+Whenever a last address that refers to a particular vhid is removed from an
+interface, the vhid is automatically removed from interface and destroyed.
+Any other configuration parameters for the
+.Xr carp 4
+protocol should be supplied along with the
+.Cm vhid
+keyword.
+Acceptable values for vhid are 1 to 255.
.It Cm advbase Ar seconds
Specifies the base of the advertisement interval in seconds.
The acceptable values are 1 to 255.
The default value is 1.
-.\" The default value is
-.\" .Dv CARP_DFLTINTV .
.It Cm advskew Ar interval
Specifies the skew to add to the base advertisement interval to
make one host advertise slower than another host.
@@ -2486,17 +2739,8 @@
.It Cm pass Ar phrase
Set the authentication key to
.Ar phrase .
-.It Cm vhid Ar n
-Set the virtual host ID.
-This is a required setting.
-Acceptable values are 1 to 255.
-.It Cm state Ar state
-Force the interface into state
-.Ar state .
-Valid states are INIT, BACKUP, and MASTER. Note that manually setting the state
-to INIT is ignored by
-.Xr carp 4 .
-This state is set automatically when the underlying interface is down.
+.It Cm state Ar MASTER|BACKUP
+Forcibly change state of a given vhid.
.El
.Pp
The
@@ -2537,6 +2781,11 @@
.Fl l
flag may be used to list all available interfaces on the system, with
no other additional information.
+If an
+.Ar address_family
+is specified, only interfaces of that type will be listed.
+.Fl l Dq ether
+will list only Ethernet adapters, excluding the loopback interface.
Use of this flag is mutually exclusive
with all other flags and commands, except for
.Fl d
@@ -2559,8 +2808,9 @@
.Fl k
flag causes keying information for the interface, if available, to be
printed.
-For example, the values of 802.11 WEP keys will be printed, if accessible to
-the current user.
+For example, the values of 802.11 WEP keys and
+.Xr carp 4
+passphrases will be printed, if accessible to the current user.
This information is not printed by default, as it may be considered
sensitive.
.Pp
@@ -2619,6 +2869,11 @@
.Fl alias :
.Dl # ifconfig em0 inet6 2001:db8:bdbd::123/48 delete
.Pp
+Configure a single CARP redundant address on igb0, and then switch it
+to be master:
+.Dl # ifconfig igb0 vhid 1 10.0.0.1/24 pass foobar up
+.Dl # ifconfig igb0 vhid 1 state master
+.Pp
Configure the interface
.Li xl0 ,
to use 100baseTX, full duplex Ethernet media options:
@@ -2650,6 +2905,7 @@
.Xr pfsync 4 ,
.Xr polling 4 ,
.Xr vlan 4 ,
+.Xr vxlan 4 ,
.Xr devd.conf 5 ,
.\" .Xr eon 5 ,
.Xr devd 8 ,
Property changes on: trunk/sbin/ifconfig/ifconfig.8
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sbin/ifconfig/ifconfig.c
===================================================================
--- trunk/sbin/ifconfig/ifconfig.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifconfig.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -38,15 +39,15 @@
static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94";
#endif
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifconfig.c 319265 2017-05-30 22:45:01Z asomers $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/module.h>
+#include <sys/linker.h>
#include <sys/socket.h>
#include <sys/time.h>
-#include <sys/module.h>
-#include <sys/linker.h>
#include <net/ethernet.h>
#include <net/if.h>
@@ -66,7 +67,9 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#ifdef JAIL
#include <jail.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -76,7 +79,7 @@
/*
* Since "struct ifreq" is composed of various union members, callers
- * should pay special attention to interprete the value.
+ * should pay special attention to interpret the value.
* (.e.g. little/big endian difference in the structure.)
*/
struct ifreq ifr;
@@ -91,6 +94,7 @@
int newaddr = 1;
int verbose;
int noload;
+int printifname = 0;
int supmedia = 0;
int printkeys = 0; /* Print keying material for interfaces. */
@@ -100,12 +104,14 @@
static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
struct ifaddrs *ifa);
static void tunnel_status(int s);
-static void usage(void);
+static void usage(void) _Noreturn;
static struct afswtch *af_getbyname(const char *name);
static struct afswtch *af_getbyfamily(int af);
static void af_other_status(int);
+void printifnamemaybe(void);
+
static struct option *opts = NULL;
void
@@ -139,6 +145,12 @@
exit(1);
}
+void printifnamemaybe()
+{
+ if (printifname)
+ printf("%s\n", name);
+}
+
int
main(int argc, char *argv[])
{
@@ -154,6 +166,12 @@
size_t iflen;
all = downonly = uponly = namesonly = noload = verbose = 0;
+
+ /*
+ * Ensure we print interface name when expected to,
+ * even if we terminate early due to error.
+ */
+ atexit(printifnamemaybe);
/* Parse leading line options */
strlcpy(options, "adklmnuv", sizeof(options));
@@ -255,6 +273,7 @@
ifconfig(argc, argv, 1, NULL);
exit(0);
}
+#ifdef JAIL
/*
* NOTE: We have to special-case the `-vnet' command
* right here as we would otherwise fail when trying
@@ -268,6 +287,7 @@
ifconfig(argc, argv, 0, NULL);
exit(0);
}
+#endif
errx(1, "interface %s does not exist", ifname);
}
}
@@ -285,7 +305,7 @@
ifindex = 0;
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
memset(&paifr, 0, sizeof(paifr));
- strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name));
+ strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name));
if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) {
memcpy(&paifr.ifr_addr, ifa->ifa_addr,
ifa->ifa_addr->sa_len);
@@ -431,7 +451,6 @@
static const struct cmd *
cmd_lookup(const char *name, int iscreate)
{
-#define N(a) (sizeof(a)/sizeof(a[0]))
const struct cmd *p;
for (p = cmds; p != NULL; p = p->c_next)
@@ -445,7 +464,6 @@
}
}
return NULL;
-#undef N
}
struct callback {
@@ -485,7 +503,7 @@
struct callback *cb;
int s;
- strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+ strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
afp = NULL;
if (uafp != NULL)
afp = uafp;
@@ -516,7 +534,7 @@
AF_LOCAL : afp->af_af;
if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 &&
- (uafp != NULL || errno != EPROTONOSUPPORT ||
+ (uafp != NULL || errno != EAFNOSUPPORT ||
(s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0))
err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family);
@@ -560,26 +578,24 @@
*/
p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd);
}
- if (p->c_u.c_func || p->c_u.c_func2) {
- if (p->c_parameter == NEXTARG) {
- if (argv[1] == NULL)
- errx(1, "'%s' requires argument",
- p->c_name);
- p->c_u.c_func(argv[1], 0, s, afp);
+ if (p->c_parameter == NEXTARG && p->c_u.c_func) {
+ if (argv[1] == NULL)
+ errx(1, "'%s' requires argument",
+ p->c_name);
+ p->c_u.c_func(argv[1], 0, s, afp);
+ argc--, argv++;
+ } else if (p->c_parameter == OPTARG && p->c_u.c_func) {
+ p->c_u.c_func(argv[1], 0, s, afp);
+ if (argv[1] != NULL)
argc--, argv++;
- } else if (p->c_parameter == OPTARG) {
- p->c_u.c_func(argv[1], 0, s, afp);
- if (argv[1] != NULL)
- argc--, argv++;
- } else if (p->c_parameter == NEXTARG2) {
- if (argc < 3)
- errx(1, "'%s' requires 2 arguments",
- p->c_name);
- p->c_u.c_func2(argv[1], argv[2], s, afp);
- argc -= 2, argv += 2;
- } else
- p->c_u.c_func(*argv, p->c_parameter, s, afp);
- }
+ } else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) {
+ if (argc < 3)
+ errx(1, "'%s' requires 2 arguments",
+ p->c_name);
+ p->c_u.c_func2(argv[1], argv[2], s, afp);
+ argc -= 2, argv += 2;
+ } else if (p->c_u.c_func)
+ p->c_u.c_func(*argv, p->c_parameter, s, afp);
argc--, argv++;
}
@@ -606,7 +622,8 @@
}
if (clearaddr) {
int ret;
- strncpy(afp->af_ridreq, name, sizeof ifr.ifr_name);
+ strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name,
+ sizeof ifr.ifr_name);
ret = ioctl(s, afp->af_difaddr, afp->af_ridreq);
if (ret < 0) {
if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
@@ -623,7 +640,8 @@
}
}
if (newaddr && (setaddr || setmask)) {
- strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
+ strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name,
+ sizeof ifr.ifr_name);
if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0)
Perror("ioctl (SIOCAIFADDR)");
}
@@ -688,6 +706,7 @@
err(1, "SIOCDIFPHYADDR");
}
+#ifdef JAIL
static void
setifvnet(const char *jname, int dummy __unused, int s,
const struct afswtch *afp)
@@ -715,6 +734,7 @@
if (ioctl(s, SIOCSIFRVNET, &my_ifr) < 0)
err(1, "SIOCSIFRVNET(%d, %s)", my_ifr.ifr_jid, my_ifr.ifr_name);
}
+#endif
static void
setifnetmask(const char *addr, int dummy __unused, int s,
@@ -831,10 +851,10 @@
setifmetric(const char *val, int dummy __unused, int s,
const struct afswtch *afp)
{
- strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
ifr.ifr_metric = atoi(val);
if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
- warn("ioctl (set metric)");
+ err(1, "ioctl SIOCSIFMETRIC (set metric)");
}
static void
@@ -841,10 +861,10 @@
setifmtu(const char *val, int dummy __unused, int s,
const struct afswtch *afp)
{
- strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
ifr.ifr_mtu = atoi(val);
if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0)
- warn("ioctl (set mtu)");
+ err(1, "ioctl SIOCSIFMTU (set mtu)");
}
static void
@@ -852,18 +872,18 @@
const struct afswtch *afp)
{
char *newname;
+
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
newname = strdup(val);
- if (newname == NULL) {
- warn("no memory to set ifname");
- return;
- }
+ if (newname == NULL)
+ err(1, "no memory to set ifname");
ifr.ifr_data = newname;
if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) {
- warn("ioctl (set name)");
free(newname);
- return;
+ err(1, "ioctl SIOCSIFNAME (set name)");
}
+ printifname = 1;
strlcpy(name, newname, sizeof(name));
free(newname);
}
@@ -875,6 +895,8 @@
{
char *newdescr;
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
ifr.ifr_buffer.length = strlen(val) + 1;
if (ifr.ifr_buffer.length == 1) {
ifr.ifr_buffer.buffer = newdescr = NULL;
@@ -889,7 +911,7 @@
}
if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0)
- warn("ioctl (set descr)");
+ err(1, "ioctl SIOCSIFDESCR (set descr)");
free(newdescr);
}
@@ -910,7 +932,7 @@
#define IFCAPBITS \
"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
"\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \
-"\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \
+"\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \
"\26RXCSUM_IPV6\27TXCSUM_IPV6"
/*
@@ -933,7 +955,7 @@
ifr.ifr_addr.sa_family =
afp->af_af == AF_LINK ? AF_LOCAL : afp->af_af;
}
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
if (s < 0)
@@ -1015,10 +1037,13 @@
else if (afp->af_other_status != NULL)
afp->af_other_status(s);
- strncpy(ifs.ifs_name, name, sizeof ifs.ifs_name);
+ strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name);
if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0)
printf("%s", ifs.ascii);
+ if (verbose > 0)
+ sfp_status(s, &ifr, verbose);
+
close(s);
return;
}
@@ -1060,8 +1085,8 @@
printf("%s=%o", s, v);
else
printf("%s=%x", s, v);
- bits++;
if (bits) {
+ bits++;
putchar('<');
while ((i = *bits++) != '\0') {
if (v & (1 << (i-1))) {
@@ -1079,6 +1104,21 @@
}
void
+print_vhid(const struct ifaddrs *ifa, const char *s)
+{
+ struct if_data *ifd;
+
+ if (ifa->ifa_data == NULL)
+ return;
+
+ ifd = ifa->ifa_data;
+ if (ifd->ifi_vhid == 0)
+ return;
+
+ printf("vhid %d ", ifd->ifi_vhid);
+}
+
+void
ifmaybeload(const char *name)
{
#define MOD_PREFIX_LEN 3 /* "if_" */
@@ -1100,9 +1140,8 @@
}
/* 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);
@@ -1119,14 +1158,17 @@
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;
}
}
- /* not present, we should try to load it */
- kldload(ifkind);
+ /*
+ * Try to load the module. But ignore failures, because ifconfig can't
+ * infer the names of all drivers (eg mlx4en(4)).
+ */
+ (void) kldload(ifkind);
}
static struct cmd basic_cmds[] = {
@@ -1159,8 +1201,10 @@
DEF_CMD_ARG2("tunnel", settunnel),
DEF_CMD("-tunnel", 0, deletetunnel),
DEF_CMD("deletetunnel", 0, deletetunnel),
+#ifdef JAIL
DEF_CMD_ARG("vnet", setifvnet),
DEF_CMD_ARG("-vnet", setifrvnet),
+#endif
DEF_CMD("link0", IFF_LINK0, setifflags),
DEF_CMD("-link0", -IFF_LINK0, setifflags),
DEF_CMD("link1", IFF_LINK1, setifflags),
@@ -1189,6 +1233,8 @@
DEF_CMD("-tso4", -IFCAP_TSO4, setifcap),
DEF_CMD("tso", IFCAP_TSO, setifcap),
DEF_CMD("-tso", -IFCAP_TSO, setifcap),
+ DEF_CMD("toe", IFCAP_TOE, setifcap),
+ DEF_CMD("-toe", -IFCAP_TOE, setifcap),
DEF_CMD("lro", IFCAP_LRO, setifcap),
DEF_CMD("-lro", -IFCAP_LRO, setifcap),
DEF_CMD("wol", IFCAP_WOL, setifcap),
@@ -1209,10 +1255,8 @@
static __constructor void
ifconfig_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(basic_cmds); i++)
+ for (i = 0; i < nitems(basic_cmds); i++)
cmd_register(&basic_cmds[i]);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifconfig.h
===================================================================
--- trunk/sbin/ifconfig/ifconfig.h 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifconfig.h 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1997 Peter Wemm.
* All rights reserved.
@@ -31,7 +32,7 @@
*
* so there!
*
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/ifconfig/ifconfig.h 296425 2016-03-06 08:52:03Z kp $
*/
#define __constructor __attribute__((constructor))
@@ -74,6 +75,7 @@
#define DEF_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func }, 0, NULL }
#define DEF_CLONE_CMD(name, param, func) { name, param, { .c_func = func }, 1, NULL }
#define DEF_CLONE_CMD_ARG(name, func) { name, NEXTARG, { .c_func = func }, 1, NULL }
+#define DEF_CLONE_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func }, 1, NULL }
struct ifaddrs;
struct addrinfo;
@@ -132,6 +134,7 @@
extern int printkeys;
extern int newaddr;
extern int verbose;
+extern int printifname;
void setifcap(const char *, int value, int s, const struct afswtch *);
@@ -143,8 +146,13 @@
typedef void clone_callback_func(int, struct ifreq *);
void clone_setdefcallback(const char *, clone_callback_func *);
+void sfp_status(int s, struct ifreq *ifr, int verbose);
+
/*
* XXX expose this so modules that neeed to know of any pending
* operations on ifmedia can avoid cmd line ordering confusion.
*/
struct ifmediareq *ifmedia_getstate(int s);
+
+void print_vhid(const struct ifaddrs *, const char *);
+
Modified: trunk/sbin/ifconfig/iffib.c
===================================================================
--- trunk/sbin/ifconfig/iffib.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/iffib.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2011 Alexander V. Chernikov
* Copyright (c) 2011 Christian S.J. Peron
@@ -25,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/ifconfig/iffib.c 300285 2016-05-20 07:14:03Z truckman $
*/
#include <sys/param.h>
@@ -49,16 +50,16 @@
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(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));
+ strlcpy(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
@@ -74,14 +75,34 @@
return;
}
- strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
ifr.ifr_fib = fib;
if (ioctl(s, SIOCSIFFIB, (caddr_t)&ifr) < 0)
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;
+ }
+
+ strlcpy(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 = {
@@ -93,11 +114,9 @@
static __constructor void
fib_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(fib_cmds); i++)
+ for (i = 0; i < nitems(fib_cmds); i++)
cmd_register(&fib_cmds[i]);
af_register(&af_fib);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifgif.c
===================================================================
--- trunk/sbin/ifconfig/ifgif.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifgif.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2009 Hiroki Sato. All rights reserved.
*
@@ -25,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifgif.c 288055 2015-09-21 03:03:57Z hrs $";
#endif
#include <sys/param.h>
@@ -51,7 +52,7 @@
#include "ifconfig.h"
-#define GIFBITS "\020\1ACCEPT_REV_ETHIP_VER\5SEND_REV_ETHIP_VER"
+#define GIFBITS "\020\2IGNORE_SOURCE"
static void gif_status(int);
@@ -70,11 +71,12 @@
}
static void
-setgifopts(const char *val,
- int d, int s, const struct afswtch *afp)
+setgifopts(const char *val, int d, int s, const struct afswtch *afp)
{
int opts;
+ if (d == 0)
+ return;
ifr.ifr_data = (caddr_t)&opts;
if (ioctl(s, GIFGOPTS, &ifr) == -1) {
warn("ioctl(GIFGOPTS)");
@@ -93,10 +95,12 @@
}
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("send_rev_ethip_ver", GIF_SEND_REVETHIP, setgifopts),
- DEF_CMD("-send_rev_ethip_ver", -GIF_SEND_REVETHIP, setgifopts),
+ DEF_CMD("accept_rev_ethip_ver", 0, setgifopts),
+ DEF_CMD("-accept_rev_ethip_ver",0, setgifopts),
+ DEF_CMD("ignore_source", GIF_IGNORE_SOURCE, setgifopts),
+ DEF_CMD("-ignore_source", -GIF_IGNORE_SOURCE, setgifopts),
+ DEF_CMD("send_rev_ethip_ver", 0, setgifopts),
+ DEF_CMD("-send_rev_ethip_ver", 0, setgifopts),
};
static struct afswtch af_gif = {
@@ -108,11 +112,9 @@
static __constructor void
gif_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(gif_cmds); i++)
+ for (i = 0; i < nitems(gif_cmds); i++)
cmd_register(&gif_cmds[i]);
af_register(&af_gif);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifgre.c
===================================================================
--- trunk/sbin/ifconfig/ifgre.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifgre.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2008 Andrew Thompson. All rights reserved.
*
@@ -23,45 +24,43 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef lint
-static const char rcsid[] =
- "$MidnightBSD$";
-#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sbin/ifconfig/ifgre.c 300285 2016-05-20 07:14:03Z truckman $");
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_gre.h>
-#include <net/route.h>
#include <ctype.h>
+#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
#include <err.h>
-#include <errno.h>
#include "ifconfig.h"
+#define GREBITS "\020\01ENABLE_CSUM\02ENABLE_SEQ"
+
static void gre_status(int s);
static void
gre_status(int s)
{
- int grekey = 0;
+ uint32_t opts = 0;
- ifr.ifr_data = (caddr_t)&grekey;
+ ifr.ifr_data = (caddr_t)&opts;
if (ioctl(s, GREGKEY, &ifr) == 0)
- if (grekey != 0)
- printf("\tgrekey: %d\n", grekey);
+ if (opts != 0)
+ printf("\tgrekey: 0x%x (%u)\n", opts, opts);
+ opts = 0;
+ if (ioctl(s, GREGOPTS, &ifr) != 0 || opts == 0)
+ return;
+ printb("\toptions", opts, GREBITS);
+ putchar('\n');
}
static void
@@ -68,16 +67,43 @@
setifgrekey(const char *val, int dummy __unused, int s,
const struct afswtch *afp)
{
- uint32_t grekey = atol(val);
+ uint32_t grekey = strtol(val, NULL, 0);
- strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
ifr.ifr_data = (caddr_t)&grekey;
if (ioctl(s, GRESKEY, (caddr_t)&ifr) < 0)
warn("ioctl (set grekey)");
}
+static void
+setifgreopts(const char *val, int d, int s, const struct afswtch *afp)
+{
+ uint32_t opts;
+
+ ifr.ifr_data = (caddr_t)&opts;
+ if (ioctl(s, GREGOPTS, &ifr) == -1) {
+ warn("ioctl(GREGOPTS)");
+ return;
+ }
+
+ if (d < 0)
+ opts &= ~(-d);
+ else
+ opts |= d;
+
+ if (ioctl(s, GRESOPTS, &ifr) == -1) {
+ warn("ioctl(GIFSOPTS)");
+ return;
+ }
+}
+
+
static struct cmd gre_cmds[] = {
DEF_CMD_ARG("grekey", setifgrekey),
+ DEF_CMD("enable_csum", GRE_ENABLE_CSUM, setifgreopts),
+ DEF_CMD("-enable_csum",-GRE_ENABLE_CSUM,setifgreopts),
+ DEF_CMD("enable_seq", GRE_ENABLE_SEQ, setifgreopts),
+ DEF_CMD("-enable_seq",-GRE_ENABLE_SEQ, setifgreopts),
};
static struct afswtch af_gre = {
.af_name = "af_gre",
@@ -88,11 +114,9 @@
static __constructor void
gre_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(gre_cmds); i++)
+ for (i = 0; i < nitems(gre_cmds); i++)
cmd_register(&gre_cmds[i]);
af_register(&af_gre);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifgroup.c
===================================================================
--- trunk/sbin/ifconfig/ifgroup.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifgroup.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2006 Max Laier. All rights reserved.
*
@@ -25,10 +26,10 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifgroup.c 289986 2015-10-26 03:43:28Z ngie $";
#endif /* not lint */
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -57,7 +58,7 @@
if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
errx(1, "setifgroup: group name too long");
- if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1)
+ if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1 && errno != EEXIST)
err(1," SIOCAIFGROUP");
}
@@ -75,7 +76,7 @@
if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ)
errx(1, "unsetifgroup: group name too long");
- if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1)
+ if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1 && errno != ENOENT)
err(1, "SIOCDIFGROUP");
}
@@ -175,12 +176,10 @@
static __constructor void
group_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
- for (i = 0; i < N(group_cmds); i++)
+ for (i = 0; i < nitems(group_cmds); i++)
cmd_register(&group_cmds[i]);
af_register(&af_group);
opt_register(&group_gopt);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifieee80211.c
===================================================================
--- trunk/sbin/ifconfig/ifieee80211.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifieee80211.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright 2001 The Aerospace Corporation. All rights reserved.
*
@@ -24,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/ifconfig/ifieee80211.c 301556 2016-06-07 16:53:05Z truckman $
*/
/*-
@@ -223,7 +224,7 @@
canpromote(int i, int from, int to)
{
const struct ieee80211_channel *fc = &chaninfo->ic_chans[i];
- int j;
+ u_int j;
if ((fc->ic_flags & from) != from)
return i;
@@ -302,7 +303,7 @@
static void
mapfreq(struct ieee80211_channel *chan, int freq, int flags)
{
- int i;
+ u_int i;
for (i = 0; i < chaninfo->ic_nchans; i++) {
const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
@@ -322,7 +323,7 @@
static void
mapchan(struct ieee80211_channel *chan, int ieee, int flags)
{
- int i;
+ u_int i;
for (i = 0; i < chaninfo->ic_nchans; i++) {
const struct ieee80211_channel *c = &chaninfo->ic_chans[i];
@@ -884,7 +885,7 @@
}
/*
- * This function is purely a NetBSD compatability interface. The NetBSD
+ * This function is purely a NetBSD compatibility interface. The NetBSD
* interface is too inflexible, but it's there so we'll support it since
* it's not all that hard.
*/
@@ -1337,6 +1338,36 @@
}
static void
+set80211quiet(const char *val, int d, int s, const struct afswtch *rafp)
+{
+ set80211(s, IEEE80211_IOC_QUIET, d, 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211quietperiod, val, d)
+{
+ set80211(s, IEEE80211_IOC_QUIET_PERIOD, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211quietcount, val, d)
+{
+ set80211(s, IEEE80211_IOC_QUIET_COUNT, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211quietduration, val, d)
+{
+ set80211(s, IEEE80211_IOC_QUIET_DUR, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211quietoffset, val, d)
+{
+ set80211(s, IEEE80211_IOC_QUIET_OFFSET, atoi(val), 0, NULL);
+}
+
+static void
set80211bgscan(const char *val, int d, int s, const struct afswtch *rafp)
{
set80211(s, IEEE80211_IOC_BGSCAN, d, 0, NULL);
@@ -1853,6 +1884,12 @@
}
static
+DECL_CMD_FUNC(set80211meshgate, val, d)
+{
+ set80211(s, IEEE80211_IOC_MESH_GATE, d, 0, NULL);
+}
+
+static
DECL_CMD_FUNC(set80211meshpeering, val, d)
{
set80211(s, IEEE80211_IOC_MESH_AP, d, 0, NULL);
@@ -2820,7 +2857,6 @@
static void
printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
u_int8_t len = ie[1];
printf("%s", tag);
@@ -2861,7 +2897,7 @@
break;
case IEEE80211_WPS_DEV_PASS_ID:
n = LE_READ_2(ie);
- if (n < N(dev_pass_id))
+ if (n < nitems(dev_pass_id))
printf(" dpi:%s", dev_pass_id[n]);
break;
case IEEE80211_WPS_UUID_E:
@@ -2875,7 +2911,6 @@
}
printf(">");
}
-#undef N
}
static void
@@ -2905,7 +2940,7 @@
{
const u_int8_t *p;
size_t maxlen;
- int i;
+ u_int i;
if (essid_len > bufsize)
maxlen = bufsize;
@@ -3205,7 +3240,7 @@
return;
}
(void) memset(&ireq, 0, sizeof(ireq));
- (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
ireq.i_type = IEEE80211_IOC_SCAN_REQ;
memset(&sr, 0, sizeof(sr));
@@ -3382,7 +3417,6 @@
static const char *
mesh_linkstate_string(uint8_t state)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
static const char *state_names[] = {
[0] = "IDLE",
[1] = "OPEN-TX",
@@ -3392,13 +3426,12 @@
[5] = "HOLDING",
};
- if (state >= N(state_names)) {
+ if (state >= nitems(state_names)) {
static char buf[10];
snprintf(buf, sizeof(buf), "#%u", state);
return buf;
} else
return state_names[state];
-#undef N
}
static const char *
@@ -3594,6 +3627,7 @@
/* suppress duplicates as above */
if (isset(reported, c->ic_ieee) && !verbose) {
/* XXX we assume duplicates are adjacent */
+ assert(achans->ic_nchans > 0);
prev = &achans->ic_chans[achans->ic_nchans-1];
/* display highest power on channel */
if (c->ic_maxpower > prev->ic_maxpower)
@@ -3673,7 +3707,7 @@
struct ieee80211req ireq;
(void) memset(&ireq, 0, sizeof(ireq));
- (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
ireq.i_type = param;
ireq.i_len = ac;
if (ioctl(s, SIOCG80211, &ireq) < 0) {
@@ -3854,7 +3888,7 @@
char c;
(void) memset(&ireq, 0, sizeof(ireq));
- (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); /* XXX ?? */
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name)); /* XXX ?? */
ireq.i_type = IEEE80211_IOC_MACCMD;
ireq.i_val = IEEE80211_MACCMD_POLICY;
if (ioctl(s, SIOCG80211, &ireq) < 0) {
@@ -3960,7 +3994,7 @@
struct ieee80211req_mesh_route *rt;
(void) memset(&ireq, 0, sizeof(ireq));
- (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
ireq.i_type = IEEE80211_IOC_MESH_RTCMD;
ireq.i_val = IEEE80211_MESH_RTCMD_LIST;
ireq.i_data = &routes;
@@ -3984,10 +4018,14 @@
ether_ntoa((const struct ether_addr *)rt->imr_nexthop),
rt->imr_nhops, rt->imr_metric, rt->imr_lifetime,
rt->imr_lastmseq,
+ (rt->imr_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) ?
+ 'D' :
(rt->imr_flags & IEEE80211_MESHRT_FLAGS_VALID) ?
'V' : '!',
(rt->imr_flags & IEEE80211_MESHRT_FLAGS_PROXY) ?
- 'P' : ' ');
+ 'P' :
+ (rt->imr_flags & IEEE80211_MESHRT_FLAGS_GATE) ?
+ 'G' :' ');
}
}
@@ -4038,7 +4076,7 @@
struct ifmediareq ifmr;
(void) memset(&ifmr, 0, sizeof(ifmr));
- (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+ (void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
@@ -4097,7 +4135,7 @@
printkey(const struct ieee80211req_key *ik)
{
static const uint8_t zerodata[IEEE80211_KEYBUF_SIZE];
- int keylen = ik->ik_keylen;
+ u_int keylen = ik->ik_keylen;
int printcontents;
printcontents = printkeys &&
@@ -4134,7 +4172,7 @@
break;
}
if (printcontents) {
- int i;
+ u_int i;
printf(" <");
for (i = 0; i < keylen; i++)
@@ -4182,7 +4220,7 @@
struct ieee80211req ireq;
(void) memset(&ireq, 0, sizeof(ireq));
- (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+ (void) strlcpy(ireq.i_name, name, sizeof(ireq.i_name));
ireq.i_type = (!mesh) ? IEEE80211_IOC_SSID : IEEE80211_IOC_MESH_ID;
ireq.i_val = ix;
ireq.i_data = data;
@@ -4802,6 +4840,12 @@
else
LINE_CHECK("-meshforward");
}
+ if (get80211val(s, IEEE80211_IOC_MESH_GATE, &val) != -1) {
+ if (val)
+ LINE_CHECK("meshgate");
+ else
+ LINE_CHECK("-meshgate");
+ }
if (get80211len(s, IEEE80211_IOC_MESH_PR_METRIC, data, 12,
&len) != -1) {
data[len] = '\0';
@@ -5158,6 +5202,12 @@
DEF_CMD_ARG("bgscanidle", set80211bgscanidle),
DEF_CMD_ARG("bgscanintvl", set80211bgscanintvl),
DEF_CMD_ARG("scanvalid", set80211scanvalid),
+ DEF_CMD("quiet", 1, set80211quiet),
+ DEF_CMD("-quiet", 0, set80211quiet),
+ DEF_CMD_ARG("quiet_count", set80211quietcount),
+ DEF_CMD_ARG("quiet_period", set80211quietperiod),
+ DEF_CMD_ARG("quiet_dur", set80211quietduration),
+ DEF_CMD_ARG("quiet_offset", set80211quietoffset),
DEF_CMD_ARG("roam:rssi", set80211roamrssi),
DEF_CMD_ARG("roam:rate", set80211roamrate),
DEF_CMD_ARG("mcastrate", set80211mcastrate),
@@ -5235,6 +5285,8 @@
DEF_CMD_ARG("meshttl", set80211meshttl),
DEF_CMD("meshforward", 1, set80211meshforward),
DEF_CMD("-meshforward", 0, set80211meshforward),
+ DEF_CMD("meshgate", 1, set80211meshgate),
+ DEF_CMD("-meshgate", 0, set80211meshgate),
DEF_CMD("meshpeering", 1, set80211meshpeering),
DEF_CMD("-meshpeering", 0, set80211meshpeering),
DEF_CMD_ARG("meshmetric", set80211meshmetric),
@@ -5266,12 +5318,10 @@
static __constructor void
ieee80211_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
- for (i = 0; i < N(ieee80211_cmds); i++)
+ for (i = 0; i < nitems(ieee80211_cmds); i++)
cmd_register(&ieee80211_cmds[i]);
af_register(&af_ieee80211);
clone_setdefcallback("wlan", wlan_create);
-#undef N
}
Modified: trunk/sbin/ifconfig/iflagg.c
===================================================================
--- trunk/sbin/ifconfig/iflagg.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/iflagg.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,9 +1,10 @@
+/* $MidnightBSD$ */
/*-
*/
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/iflagg.c 319265 2017-05-30 22:45:01Z asomers $";
#endif /* not lint */
#include <sys/param.h>
@@ -17,6 +18,7 @@
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_lagg.h>
+#include <net/ieee8023ad_lacp.h>
#include <net/route.h>
#include <ctype.h>
@@ -68,7 +70,7 @@
bzero(&ra, sizeof(ra));
ra.ra_proto = LAGG_PROTO_MAX;
- for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) {
+ for (i = 0; i < nitems(lpr); i++) {
if (strcmp(val, lpr[i].lpr_name) == 0) {
ra.ra_proto = lpr[i].lpr_proto;
break;
@@ -83,6 +85,50 @@
}
static void
+setlaggflowidshift(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct lagg_reqopts ro;
+
+ bzero(&ro, sizeof(ro));
+ ro.ro_opts = LAGG_OPT_FLOWIDSHIFT;
+ strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
+ ro.ro_flowid_shift = (int)strtol(val, NULL, 10);
+ if (ro.ro_flowid_shift & ~LAGG_OPT_FLOWIDSHIFT_MASK)
+ errx(1, "Invalid flowid_shift option: %s", val);
+
+ if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
+ err(1, "SIOCSLAGGOPTS");
+}
+
+static void
+setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct lagg_reqopts ro;
+
+ bzero(&ro, sizeof(ro));
+ ro.ro_opts = d;
+ switch (ro.ro_opts) {
+ case LAGG_OPT_USE_FLOWID:
+ case -LAGG_OPT_USE_FLOWID:
+ case LAGG_OPT_LACP_STRICT:
+ case -LAGG_OPT_LACP_STRICT:
+ case LAGG_OPT_LACP_TXTEST:
+ case -LAGG_OPT_LACP_TXTEST:
+ case LAGG_OPT_LACP_RXTEST:
+ case -LAGG_OPT_LACP_RXTEST:
+ case LAGG_OPT_LACP_TIMEOUT:
+ case -LAGG_OPT_LACP_TIMEOUT:
+ break;
+ default:
+ err(1, "Invalid lagg option");
+ }
+ strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
+
+ if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
+ err(1, "SIOCSLAGGOPTS");
+}
+
+static void
setlagghash(const char *val, int d, int s, const struct afswtch *afp)
{
struct lagg_reqflags rf;
@@ -98,10 +144,8 @@
rf.rf_flags |= LAGG_F_HASHL3;
else if (strcmp(tok, "l4") == 0)
rf.rf_flags |= LAGG_F_HASHL4;
- else {
- free(str);
+ else
errx(1, "Invalid lagghash option: %s", tok);
- }
}
free(str);
if (rf.rf_flags == 0)
@@ -144,26 +188,24 @@
lagg_status(int s)
{
struct lagg_protos lpr[] = LAGG_PROTOS;
- struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
+ struct lagg_reqport rpbuf[LAGG_MAX_PORTS];
struct lagg_reqall ra;
+ struct lagg_reqopts ro;
struct lagg_reqflags rf;
struct lacp_opreq *lp;
const char *proto = "<unknown>";
- int i, isport = 0;
+ int i;
- bzero(&rp, sizeof(rp));
bzero(&ra, sizeof(ra));
+ bzero(&ro, sizeof(ro));
- strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
- strlcpy(rp.rp_portname, name, sizeof(rp.rp_portname));
-
- if (ioctl(s, SIOCGLAGGPORT, &rp) == 0)
- isport = 1;
-
strlcpy(ra.ra_ifname, name, sizeof(ra.ra_ifname));
ra.ra_size = sizeof(rpbuf);
ra.ra_port = rpbuf;
+ strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
+ ioctl(s, SIOCGLAGGOPTS, &ro);
+
strlcpy(rf.rf_ifname, name, sizeof(rf.rf_ifname));
if (ioctl(s, SIOCGLAGGFLAGS, &rf) != 0)
rf.rf_flags = 0;
@@ -171,7 +213,7 @@
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
lp = (struct lacp_opreq *)&ra.ra_lacpreq;
- for (i = 0; i < (sizeof(lpr) / sizeof(lpr[0])); i++) {
+ for (i = 0; i < nitems(lpr); i++) {
if (ra.ra_proto == lpr[i].lpr_proto) {
proto = lpr[i].lpr_name;
break;
@@ -196,12 +238,20 @@
sep = ",";
}
}
- if (isport)
- printf(" laggdev %s", rp.rp_ifname);
putchar('\n');
- if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
- printf("\tlag id: %s\n",
- lacp_format_peer(lp, "\n\t\t "));
+ if (verbose) {
+ printf("\tlagg options:\n");
+ printb("\t\tflags", ro.ro_opts, LAGG_OPT_BITS);
+ putchar('\n');
+ printf("\t\tflowid_shift: %d\n", ro.ro_flowid_shift);
+ printf("\tlagg statistics:\n");
+ printf("\t\tactive ports: %d\n", ro.ro_active);
+ printf("\t\tflapping: %u\n", ro.ro_flapping);
+ if (ra.ra_proto == LAGG_PROTO_LACP) {
+ printf("\tlag id: %s\n",
+ lacp_format_peer(lp, "\n\t\t "));
+ }
+ }
for (i = 0; i < ra.ra_ports; i++) {
lp = (struct lacp_opreq *)&rpbuf[i].rp_lacpreq;
@@ -208,7 +258,8 @@
printf("\tlaggport: %s ", rpbuf[i].rp_portname);
printb("flags", rpbuf[i].rp_flags, LAGG_PORT_BITS);
if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
- printf(" state=%X", lp->actor_state);
+ printb(" state", lp->actor_state,
+ LACP_STATE_BITS);
putchar('\n');
if (verbose && ra.ra_proto == LAGG_PROTO_LACP)
printf("\t\t%s\n",
@@ -228,6 +279,17 @@
DEF_CMD_ARG("-laggport", unsetlaggport),
DEF_CMD_ARG("laggproto", setlaggproto),
DEF_CMD_ARG("lagghash", setlagghash),
+ DEF_CMD("use_flowid", LAGG_OPT_USE_FLOWID, setlaggsetopt),
+ DEF_CMD("-use_flowid", -LAGG_OPT_USE_FLOWID, setlaggsetopt),
+ DEF_CMD("lacp_strict", LAGG_OPT_LACP_STRICT, setlaggsetopt),
+ DEF_CMD("-lacp_strict", -LAGG_OPT_LACP_STRICT, setlaggsetopt),
+ DEF_CMD("lacp_txtest", LAGG_OPT_LACP_TXTEST, setlaggsetopt),
+ DEF_CMD("-lacp_txtest", -LAGG_OPT_LACP_TXTEST, setlaggsetopt),
+ DEF_CMD("lacp_rxtest", LAGG_OPT_LACP_RXTEST, setlaggsetopt),
+ DEF_CMD("-lacp_rxtest", -LAGG_OPT_LACP_RXTEST, setlaggsetopt),
+ DEF_CMD("lacp_fast_timeout", LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
+ DEF_CMD("-lacp_fast_timeout", -LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
+ DEF_CMD_ARG("flowid_shift", setlaggflowidshift),
};
static struct afswtch af_lagg = {
.af_name = "af_lagg",
@@ -238,11 +300,9 @@
static __constructor void
lagg_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
- for (i = 0; i < N(lagg_cmds); i++)
+ for (i = 0; i < nitems(lagg_cmds); i++)
cmd_register(&lagg_cmds[i]);
af_register(&af_lagg);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifmac.c
===================================================================
--- trunk/sbin/ifconfig/ifmac.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifmac.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2001 Networks Associates Technology, Inc.
* All rights reserved.
@@ -31,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/ifconfig/ifmac.c 300285 2016-05-20 07:14:03Z truckman $
*/
#include <sys/param.h>
@@ -57,7 +58,7 @@
char *label_text;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (mac_prepare_ifnet_label(&label) == -1)
return;
@@ -90,7 +91,7 @@
}
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_ifru.ifru_data = (void *)label;
error = ioctl(s, SIOCSIFMAC, &ifr);
@@ -111,11 +112,9 @@
static __constructor void
mac_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(mac_cmds); i++)
+ for (i = 0; i < nitems(mac_cmds); i++)
cmd_register(&mac_cmds[i]);
af_register(&af_mac);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifmedia.c
===================================================================
--- trunk/sbin/ifconfig/ifmedia.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifmedia.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */
-/* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sbin/ifconfig/ifmedia.c 300285 2016-05-20 07:14:03Z truckman $ */
/*
* Copyright (c) 1997 Jason R. Thorpe.
@@ -109,11 +110,17 @@
{
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));
+ (void) strlcpy(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 +137,13 @@
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 +206,7 @@
{
static struct ifmediareq *ifmr = NULL;
int *mwords;
+ int xmedia = 1;
if (ifmr == NULL) {
ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
@@ -201,7 +214,7 @@
err(1, "malloc");
(void) memset(ifmr, 0, sizeof(struct ifmediareq));
- (void) strncpy(ifmr->ifm_name, name,
+ (void) strlcpy(ifmr->ifm_name, name,
sizeof(ifmr->ifm_name));
ifmr->ifm_count = 0;
@@ -213,7 +226,10 @@
* 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 +241,13 @@
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;
@@ -267,7 +288,7 @@
*/
subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val);
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
@@ -299,7 +320,7 @@
options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val);
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = ifmr->ifm_current;
if (clear)
ifr.ifr_media &= ~options;
@@ -326,7 +347,7 @@
if (inst < 0 || inst > (int)IFM_INST_MAX)
errx(1, "invalid media instance: %s", val);
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
ifmr->ifm_current = ifr.ifr_media;
@@ -343,7 +364,7 @@
mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val);
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
ifmr->ifm_current = ifr.ifr_media;
@@ -825,11 +846,9 @@
static __constructor void
ifmedia_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(media_cmds); i++)
+ for (i = 0; i < nitems(media_cmds); i++)
cmd_register(&media_cmds[i]);
af_register(&af_media);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifpfsync.c
===================================================================
--- trunk/sbin/ifconfig/ifpfsync.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifpfsync.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 2003 Ryan McBride. All rights reserved.
* Copyright (c) 2004 Max Laier. All rights reserved.
@@ -23,10 +24,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sbin/ifconfig/ifpfsync.c 319265 2017-05-30 22:45:01Z asomers $
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
@@ -52,6 +53,7 @@
void unsetpfsync_syncpeer(const char *, int, int, const struct afswtch *);
void setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
void setpfsync_maxupd(const char *, int, int, const struct afswtch *);
+void setpfsync_defer(const char *, int, int, const struct afswtch *);
void pfsync_status(int);
void
@@ -119,6 +121,7 @@
if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
err(1, "SIOCSETPFSYNC");
+ freeaddrinfo(peerres);
}
/* ARGSUSED */
@@ -162,7 +165,24 @@
err(1, "SIOCSETPFSYNC");
}
+/* ARGSUSED */
void
+setpfsync_defer(const char *val, int d, int s, const struct afswtch *rafp)
+{
+ struct pfsyncreq preq;
+
+ memset((char *)&preq, 0, sizeof(struct pfsyncreq));
+ ifr.ifr_data = (caddr_t)&preq;
+
+ if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
+ err(1, "SIOCGETPFSYNC");
+
+ preq.pfsyncr_defer = d;
+ if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSETPFSYNC");
+}
+
+void
pfsync_status(int s)
{
struct pfsyncreq preq;
@@ -183,8 +203,10 @@
printf("syncpeer: %s ", inet_ntoa(preq.pfsyncr_syncpeer));
if (preq.pfsyncr_syncdev[0] != '\0' ||
- preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
- printf("maxupd: %d\n", preq.pfsyncr_maxupdates);
+ preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP) {
+ printf("maxupd: %d ", preq.pfsyncr_maxupdates);
+ printf("defer: %s\n", preq.pfsyncr_defer ? "on" : "off");
+ }
}
static struct cmd pfsync_cmds[] = {
@@ -194,7 +216,9 @@
DEF_CMD("-syncif", 1, unsetpfsync_syncdev),
DEF_CMD_ARG("syncpeer", setpfsync_syncpeer),
DEF_CMD("-syncpeer", 1, unsetpfsync_syncpeer),
- DEF_CMD_ARG("maxupd", setpfsync_maxupd)
+ DEF_CMD_ARG("maxupd", setpfsync_maxupd),
+ DEF_CMD("defer", 1, setpfsync_defer),
+ DEF_CMD("-defer", 0, setpfsync_defer),
};
static struct afswtch af_pfsync = {
.af_name = "af_pfsync",
@@ -205,11 +229,9 @@
static __constructor void
pfsync_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
int i;
- for (i = 0; i < N(pfsync_cmds); i++)
+ for (i = 0; i < nitems(pfsync_cmds); i++)
cmd_register(&pfsync_cmds[i]);
af_register(&af_pfsync);
-#undef N
}
Modified: trunk/sbin/ifconfig/ifvlan.c
===================================================================
--- trunk/sbin/ifconfig/ifvlan.c 2018-07-01 20:45:07 UTC (rev 11209)
+++ trunk/sbin/ifconfig/ifvlan.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*
* Copyright (c) 1999
* Bill Paul <wpaul at ctr.columbia.edu>. All rights reserved.
@@ -56,7 +57,7 @@
#ifndef lint
static const char rcsid[] =
- "$MidnightBSD$";
+ "$FreeBSD: stable/10/sbin/ifconfig/ifvlan.c 289986 2015-10-26 03:43:28Z ngie $";
#endif
#define NOTAG ((u_short) -1)
@@ -195,13 +196,11 @@
static __constructor void
vlan_ctor(void)
{
-#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
- for (i = 0; i < N(vlan_cmds); i++)
+ for (i = 0; i < nitems(vlan_cmds); i++)
cmd_register(&vlan_cmds[i]);
af_register(&af_vlan);
callback_register(vlan_cb, NULL);
clone_setdefcallback("vlan", vlan_create);
-#undef N
}
Added: trunk/sbin/ifconfig/ifvxlan.c
===================================================================
--- trunk/sbin/ifconfig/ifvxlan.c (rev 0)
+++ trunk/sbin/ifconfig/ifvxlan.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -0,0 +1,647 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Bryan Venteicher <bryanv at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sbin/ifconfig/ifvxlan.c 289986 2015-10-26 03:43:28Z ngie $");
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#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>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+
+#include "ifconfig.h"
+
+static struct ifvxlanparam params = {
+ .vxlp_vni = VXLAN_VNI_MAX,
+};
+
+static int
+get_val(const char *cp, u_long *valp)
+{
+ char *endptr;
+ u_long val;
+
+ errno = 0;
+ val = strtoul(cp, &endptr, 0);
+ if (cp[0] == '\0' || endptr[0] != '\0' || errno == ERANGE)
+ return (-1);
+
+ *valp = val;
+ return (0);
+}
+
+static int
+do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
+{
+ struct ifdrv ifd;
+
+ bzero(&ifd, sizeof(ifd));
+
+ strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
+ ifd.ifd_cmd = op;
+ ifd.ifd_len = argsize;
+ ifd.ifd_data = arg;
+
+ return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
+}
+
+static int
+vxlan_exists(int sock)
+{
+ struct ifvxlancfg cfg;
+
+ bzero(&cfg, sizeof(cfg));
+
+ return (do_cmd(sock, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) != -1);
+}
+
+static void
+vxlan_status(int s)
+{
+ struct ifvxlancfg cfg;
+ char src[NI_MAXHOST], dst[NI_MAXHOST];
+ char srcport[NI_MAXSERV], dstport[NI_MAXSERV];
+ struct sockaddr *lsa, *rsa;
+ int vni, mc, ipv6;
+
+ bzero(&cfg, sizeof(cfg));
+
+ if (do_cmd(s, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) < 0)
+ return;
+
+ vni = cfg.vxlc_vni;
+ lsa = &cfg.vxlc_local_sa.sa;
+ rsa = &cfg.vxlc_remote_sa.sa;
+ ipv6 = rsa->sa_family == AF_INET6;
+
+ /* Just report nothing if the network identity isn't set yet. */
+ if (vni >= VXLAN_VNI_MAX)
+ return;
+
+ if (getnameinfo(lsa, lsa->sa_len, src, sizeof(src),
+ srcport, sizeof(srcport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ src[0] = srcport[0] = '\0';
+ if (getnameinfo(rsa, rsa->sa_len, dst, sizeof(dst),
+ dstport, sizeof(dstport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ dst[0] = dstport[0] = '\0';
+
+ if (!ipv6) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)rsa;
+ mc = IN_MULTICAST(ntohl(sin->sin_addr.s_addr));
+ } else {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rsa;
+ mc = IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr);
+ }
+
+ printf("\tvxlan vni %d", vni);
+ printf(" local %s%s%s:%s", ipv6 ? "[" : "", src, ipv6 ? "]" : "",
+ srcport);
+ printf(" %s %s%s%s:%s", mc ? "group" : "remote", ipv6 ? "[" : "",
+ dst, ipv6 ? "]" : "", dstport);
+
+ if (verbose) {
+ printf("\n\t\tconfig: ");
+ printf("%slearning portrange %d-%d ttl %d",
+ cfg.vxlc_learn ? "" : "no", cfg.vxlc_port_min,
+ cfg.vxlc_port_max, cfg.vxlc_ttl);
+ printf("\n\t\tftable: ");
+ printf("cnt %d max %d timeout %d",
+ cfg.vxlc_ftable_cnt, cfg.vxlc_ftable_max,
+ cfg.vxlc_ftable_timeout);
+ }
+
+ putchar('\n');
+}
+
+#define _LOCAL_ADDR46 \
+ (VXLAN_PARAM_WITH_LOCAL_ADDR4 | VXLAN_PARAM_WITH_LOCAL_ADDR6)
+#define _REMOTE_ADDR46 \
+ (VXLAN_PARAM_WITH_REMOTE_ADDR4 | VXLAN_PARAM_WITH_REMOTE_ADDR6)
+
+static void
+vxlan_check_params(void)
+{
+
+ if ((params.vxlp_with & _LOCAL_ADDR46) == _LOCAL_ADDR46)
+ errx(1, "cannot specify both local IPv4 and IPv6 addresses");
+ if ((params.vxlp_with & _REMOTE_ADDR46) == _REMOTE_ADDR46)
+ errx(1, "cannot specify both remote IPv4 and IPv6 addresses");
+ if ((params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4 &&
+ params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) ||
+ (params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6 &&
+ params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4))
+ errx(1, "cannot mix IPv4 and IPv6 addresses");
+}
+
+#undef _LOCAL_ADDR46
+#undef _REMOTE_ADDR46
+
+static void
+vxlan_cb(int s, void *arg)
+{
+
+}
+
+static void
+vxlan_create(int s, struct ifreq *ifr)
+{
+
+ vxlan_check_params();
+
+ ifr->ifr_data = (caddr_t) ¶ms;
+ if (ioctl(s, SIOCIFCREATE2, ifr) < 0)
+ err(1, "SIOCIFCREATE2");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_vni, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || val >= VXLAN_VNI_MAX)
+ errx(1, "invalid network identifier: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_VNI;
+ params.vxlp_vni = val;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_vni = val;
+
+ if (do_cmd(s, VXLAN_CMD_SET_VNI, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_VNI");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_local, addr, d)
+{
+ struct ifvxlancmd cmd;
+ struct addrinfo *ai;
+ struct sockaddr *sa;
+ int error;
+
+ bzero(&cmd, sizeof(cmd));
+
+ if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
+ errx(1, "error in parsing local address string: %s",
+ gai_strerror(error));
+
+ sa = ai->ai_addr;
+
+ switch (ai->ai_family) {
+#ifdef INET
+ case AF_INET: {
+ struct in_addr addr = ((struct sockaddr_in *) sa)->sin_addr;
+
+ if (IN_MULTICAST(ntohl(addr.s_addr)))
+ errx(1, "local address cannot be multicast");
+
+ cmd.vxlcmd_sa.in4.sin_family = AF_INET;
+ cmd.vxlcmd_sa.in4.sin_addr = addr;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+
+ if (IN6_IS_ADDR_MULTICAST(addr))
+ errx(1, "local address cannot be multicast");
+
+ cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
+ cmd.vxlcmd_sa.in6.sin6_addr = *addr;
+ break;
+ }
+#endif
+ default:
+ errx(1, "local address %s not supported", addr);
+ }
+
+ freeaddrinfo(ai);
+
+ if (!vxlan_exists(s)) {
+ if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR4;
+ params.vxlp_local_in4 = cmd.vxlcmd_sa.in4.sin_addr;
+ } else {
+ params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR6;
+ params.vxlp_local_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
+ }
+ return;
+ }
+
+ if (do_cmd(s, VXLAN_CMD_SET_LOCAL_ADDR, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_LOCAL_ADDR");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_remote, addr, d)
+{
+ struct ifvxlancmd cmd;
+ struct addrinfo *ai;
+ struct sockaddr *sa;
+ int error;
+
+ bzero(&cmd, sizeof(cmd));
+
+ if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
+ errx(1, "error in parsing remote address string: %s",
+ gai_strerror(error));
+
+ sa = ai->ai_addr;
+
+ switch (ai->ai_family) {
+#ifdef INET
+ case AF_INET: {
+ struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
+
+ if (IN_MULTICAST(ntohl(addr.s_addr)))
+ errx(1, "remote address cannot be multicast");
+
+ cmd.vxlcmd_sa.in4.sin_family = AF_INET;
+ cmd.vxlcmd_sa.in4.sin_addr = addr;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+
+ if (IN6_IS_ADDR_MULTICAST(addr))
+ errx(1, "remote address cannot be multicast");
+
+ cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
+ cmd.vxlcmd_sa.in6.sin6_addr = *addr;
+ break;
+ }
+#endif
+ default:
+ errx(1, "remote address %s not supported", addr);
+ }
+
+ freeaddrinfo(ai);
+
+ if (!vxlan_exists(s)) {
+ if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
+ params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
+ } else {
+ params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
+ params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
+ }
+ return;
+ }
+
+ if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_group, addr, d)
+{
+ struct ifvxlancmd cmd;
+ struct addrinfo *ai;
+ struct sockaddr *sa;
+ int error;
+
+ bzero(&cmd, sizeof(cmd));
+
+ if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
+ errx(1, "error in parsing group address string: %s",
+ gai_strerror(error));
+
+ sa = ai->ai_addr;
+
+ switch (ai->ai_family) {
+#ifdef INET
+ case AF_INET: {
+ struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
+
+ if (!IN_MULTICAST(ntohl(addr.s_addr)))
+ errx(1, "group address must be multicast");
+
+ cmd.vxlcmd_sa.in4.sin_family = AF_INET;
+ cmd.vxlcmd_sa.in4.sin_addr = addr;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+
+ if (!IN6_IS_ADDR_MULTICAST(addr))
+ errx(1, "group address must be multicast");
+
+ cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
+ cmd.vxlcmd_sa.in6.sin6_addr = *addr;
+ break;
+ }
+#endif
+ default:
+ errx(1, "group address %s not supported", addr);
+ }
+
+ freeaddrinfo(ai);
+
+ if (!vxlan_exists(s)) {
+ if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
+ params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
+ } else {
+ params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
+ params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
+ }
+ return;
+ }
+
+ if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_local_port, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
+ errx(1, "invalid local port: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_PORT;
+ params.vxlp_local_port = val;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_port = val;
+
+ if (do_cmd(s, VXLAN_CMD_SET_LOCAL_PORT, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_LOCAL_PORT");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_remote_port, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
+ errx(1, "invalid remote port: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_PORT;
+ params.vxlp_remote_port = val;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_port = val;
+
+ if (do_cmd(s, VXLAN_CMD_SET_REMOTE_PORT, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_REMOTE_PORT");
+}
+
+static
+DECL_CMD_FUNC2(setvxlan_port_range, arg1, arg2)
+{
+ struct ifvxlancmd cmd;
+ u_long min, max;
+
+ if (get_val(arg1, &min) < 0 || min >= UINT16_MAX)
+ errx(1, "invalid port range minimum: %s", arg1);
+ if (get_val(arg2, &max) < 0 || max >= UINT16_MAX)
+ errx(1, "invalid port range maximum: %s", arg2);
+ if (max < min)
+ errx(1, "invalid port range");
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_PORT_RANGE;
+ params.vxlp_min_port = min;
+ params.vxlp_max_port = max;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_port_min = min;
+ cmd.vxlcmd_port_max = max;
+
+ if (do_cmd(s, VXLAN_CMD_SET_PORT_RANGE, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_PORT_RANGE");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_timeout, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
+ errx(1, "invalid timeout value: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_TIMEOUT;
+ params.vxlp_ftable_timeout = val & 0xFFFFFFFF;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_ftable_timeout = val & 0xFFFFFFFF;
+
+ if (do_cmd(s, VXLAN_CMD_SET_FTABLE_TIMEOUT, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_FTABLE_TIMEOUT");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_maxaddr, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
+ errx(1, "invalid maxaddr value: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_MAX;
+ params.vxlp_ftable_max = val & 0xFFFFFFFF;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_ftable_max = val & 0xFFFFFFFF;
+
+ if (do_cmd(s, VXLAN_CMD_SET_FTABLE_MAX, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_FTABLE_MAX");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_dev, arg, d)
+{
+ struct ifvxlancmd cmd;
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_MULTICAST_IF;
+ strlcpy(params.vxlp_mc_ifname, arg,
+ sizeof(params.vxlp_mc_ifname));
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ strlcpy(cmd.vxlcmd_ifname, arg, sizeof(cmd.vxlcmd_ifname));
+
+ if (do_cmd(s, VXLAN_CMD_SET_MULTICAST_IF, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_MULTICAST_IF");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_ttl, arg, d)
+{
+ struct ifvxlancmd cmd;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || val > 256)
+ errx(1, "invalid TTL value: %s", arg);
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_TTL;
+ params.vxlp_ttl = val;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ cmd.vxlcmd_ttl = val;
+
+ if (do_cmd(s, VXLAN_CMD_SET_TTL, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_TTL");
+}
+
+static
+DECL_CMD_FUNC(setvxlan_learn, arg, d)
+{
+ struct ifvxlancmd cmd;
+
+ if (!vxlan_exists(s)) {
+ params.vxlp_with |= VXLAN_PARAM_WITH_LEARN;
+ params.vxlp_learn = d;
+ return;
+ }
+
+ bzero(&cmd, sizeof(cmd));
+ if (d != 0)
+ cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_LEARN;
+
+ if (do_cmd(s, VXLAN_CMD_SET_LEARN, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_SET_LEARN");
+}
+
+static void
+setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifvxlancmd cmd;
+
+ bzero(&cmd, sizeof(cmd));
+ if (d != 0)
+ cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_FLUSH_ALL;
+
+ if (do_cmd(s, VXLAN_CMD_FLUSH, &cmd, sizeof(cmd), 1) < 0)
+ err(1, "VXLAN_CMD_FLUSH");
+}
+
+static struct cmd vxlan_cmds[] = {
+
+ 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("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("vxlanttl", setvxlan_ttl),
+ DEF_CMD("vxlanlearn", 1, setvxlan_learn),
+ DEF_CMD("-vxlanlearn", 0, setvxlan_learn),
+
+ DEF_CMD("vxlanflush", 0, setvxlan_flush),
+ DEF_CMD("vxlanflushall", 1, setvxlan_flush),
+};
+
+static struct afswtch af_vxlan = {
+ .af_name = "af_vxlan",
+ .af_af = AF_UNSPEC,
+ .af_other_status = vxlan_status,
+};
+
+static __constructor void
+vxlan_ctor(void)
+{
+ size_t i;
+
+ for (i = 0; i < nitems(vxlan_cmds); i++)
+ cmd_register(&vxlan_cmds[i]);
+ af_register(&af_vxlan);
+ callback_register(vxlan_cb, NULL);
+ clone_setdefcallback("vxlan", vxlan_create);
+}
Property changes on: trunk/sbin/ifconfig/ifvxlan.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sbin/ifconfig/sfp.c
===================================================================
--- trunk/sbin/ifconfig/sfp.c (rev 0)
+++ trunk/sbin/ifconfig/sfp.c 2018-07-01 20:46:16 UTC (rev 11210)
@@ -0,0 +1,917 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Alexander V. Chernikov. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD: stable/10/sbin/ifconfig/sfp.c 297640 2016-04-07 07:12:14Z hselasky $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/sff8436.h>
+#include <net/sff8472.h>
+
+#include <math.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ifconfig.h"
+
+struct i2c_info {
+ 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);
+
+struct _nv {
+ int v;
+ const char *n;
+};
+
+const char *find_value(struct _nv *x, int value);
+const char *find_zero_bit(struct _nv *x, int value, int sz);
+
+/* SFF-8472 Rev. 11.4 table 3.4: Connector values */
+static struct _nv conn[] = {
+ { 0x00, "Unknown" },
+ { 0x01, "SC" },
+ { 0x02, "Fibre Channel Style 1 copper" },
+ { 0x03, "Fibre Channel Style 2 copper" },
+ { 0x04, "BNC/TNC" },
+ { 0x05, "Fibre Channel coaxial" },
+ { 0x06, "FiberJack" },
+ { 0x07, "LC" },
+ { 0x08, "MT-RJ" },
+ { 0x09, "MU" },
+ { 0x0A, "SG" },
+ { 0x0B, "Optical pigtail" },
+ { 0x0C, "MPO Parallel Optic" },
+ { 0x20, "HSSDC II" },
+ { 0x21, "Copper pigtail" },
+ { 0x22, "RJ45" },
+ { 0x23, "No separate connector" }, /* SFF-8436 */
+ { 0, NULL }
+};
+
+/* SFF-8472 Rev. 11.4 table 3.5: Transceiver codes */
+/* 10G Ethernet/IB compliance codes, byte 3 */
+static struct _nv eth_10g[] = {
+ { 0x80, "10G Base-ER" },
+ { 0x40, "10G Base-LRM" },
+ { 0x20, "10G Base-LR" },
+ { 0x10, "10G Base-SR" },
+ { 0x08, "1X SX" },
+ { 0x04, "1X LX" },
+ { 0x02, "1X Copper Active" },
+ { 0x01, "1X Copper Passive" },
+ { 0, NULL }
+};
+
+/* Ethernet compliance codes, byte 6 */
+static struct _nv eth_compat[] = {
+ { 0x80, "BASE-PX" },
+ { 0x40, "BASE-BX10" },
+ { 0x20, "100BASE-FX" },
+ { 0x10, "100BASE-LX/LX10" },
+ { 0x08, "1000BASE-T" },
+ { 0x04, "1000BASE-CX" },
+ { 0x02, "1000BASE-LX" },
+ { 0x01, "1000BASE-SX" },
+ { 0, NULL }
+};
+
+/* FC link length, byte 7 */
+static struct _nv fc_len[] = {
+ { 0x80, "very long distance" },
+ { 0x40, "short distance" },
+ { 0x20, "intermediate distance" },
+ { 0x10, "long distance" },
+ { 0x08, "medium distance" },
+ { 0, NULL }
+};
+
+/* Channel/Cable technology, byte 7-8 */
+static struct _nv cab_tech[] = {
+ { 0x0400, "Shortwave laser (SA)" },
+ { 0x0200, "Longwave laser (LC)" },
+ { 0x0100, "Electrical inter-enclosure (EL)" },
+ { 0x80, "Electrical intra-enclosure (EL)" },
+ { 0x40, "Shortwave laser (SN)" },
+ { 0x20, "Shortwave laser (SL)" },
+ { 0x10, "Longwave laser (LL)" },
+ { 0x08, "Active Cable" },
+ { 0x04, "Passive Cable" },
+ { 0, NULL }
+};
+
+/* FC Transmission media, byte 9 */
+static struct _nv fc_media[] = {
+ { 0x80, "Twin Axial Pair" },
+ { 0x40, "Twisted Pair" },
+ { 0x20, "Miniature Coax" },
+ { 0x10, "Viao Coax" },
+ { 0x08, "Miltimode, 62.5um" },
+ { 0x04, "Multimode, 50um" },
+ { 0x02, "" },
+ { 0x01, "Single Mode" },
+ { 0, NULL }
+};
+
+/* FC Speed, byte 10 */
+static struct _nv fc_speed[] = {
+ { 0x80, "1200 MBytes/sec" },
+ { 0x40, "800 MBytes/sec" },
+ { 0x20, "1600 MBytes/sec" },
+ { 0x10, "400 MBytes/sec" },
+ { 0x08, "3200 MBytes/sec" },
+ { 0x04, "200 MBytes/sec" },
+ { 0x01, "100 MBytes/sec" },
+ { 0, NULL }
+};
+
+/* SFF-8436 Rev. 4.8 table 33: Specification compliance */
+
+/* 10/40G Ethernet compliance codes, byte 128 + 3 */
+static struct _nv eth_1040g[] = {
+ { 0x80, "Extended" },
+ { 0x40, "10GBASE-LRM" },
+ { 0x20, "10GBASE-LR" },
+ { 0x10, "10GBASE-SR" },
+ { 0x08, "40GBASE-CR4" },
+ { 0x04, "40GBASE-SR4" },
+ { 0x02, "40GBASE-LR4" },
+ { 0x01, "40G Active Cable" },
+ { 0, NULL }
+};
+#define SFF_8636_EXT_COMPLIANCE 0x80
+
+/* SFF-8024 Rev. 3.4 table 4.4: Extended Specification Compliance */
+static struct _nv eth_extended_comp[] = {
+ { 0xFF, "Reserved" },
+ { 0x1A, "2 lambda DWDM 100G" },
+ { 0x19, "100G ACC or 25GAUI C2M ACC" },
+ { 0x18, "100G AOC or 25GAUI C2M AOC" },
+ { 0x17, "100G CLR4" },
+ { 0x16, "10GBASE-T with SFI electrical interface" },
+ { 0x15, "G959.1 profile P1L1-2D2" },
+ { 0x14, "G959.1 profile P1S1-2D2" },
+ { 0x13, "G959.1 profile P1I1-2D1" },
+ { 0x12, "40G PSM4 Parallel SMF" },
+ { 0x11, "4 x 10GBASE-SR" },
+ { 0x10, "40GBASE-ER4" },
+ { 0x0F, "Reserved" },
+ { 0x0D, "25GBASE-CR CA-N" },
+ { 0x0C, "25GBASE-CR CA-S" },
+ { 0x0B, "100GBASE-CR4 or 25GBASE-CR CA-L" },
+ { 0x0A, "Reserved" },
+ { 0x09, "100G CWDM4 MSA without FEC" },
+ { 0x08, "100G ACC (Active Copper Cable)" },
+ { 0x07, "100G PSM4 Parallel SMF" },
+ { 0x06, "100G CWDM4 MSA with FEC" },
+ { 0x05, "100GBASE-SR10" },
+ { 0x04, "100GBASE-ER4" },
+ { 0x03, "100GBASE-LR4" },
+ { 0x02, "100GBASE-SR4" },
+ { 0x01, "100G AOC (Active Optical Cable) or 25GAUI C2M ACC" },
+ { 0x00, "Unspecified" }
+};
+
+/* 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)
+{
+ for (; x->n != NULL; x++)
+ if (x->v == value)
+ return (x->n);
+ return (NULL);
+}
+
+const char *
+find_zero_bit(struct _nv *x, int value, int sz)
+{
+ int v, m;
+ const char *s;
+
+ v = 1;
+ for (v = 1, m = 1 << (8 * sz); v < m; v *= 2) {
+ if ((value & v) == 0)
+ continue;
+ if ((s = find_value(x, value & v)) != NULL) {
+ value &= ~v;
+ return (s);
+ }
+ }
+
+ return (NULL);
+}
+
+static void
+convert_sff_identifier(char *buf, size_t size, uint8_t value)
+{
+ const char *x;
+
+ x = NULL;
+ if (value <= SFF_8024_ID_LAST)
+ x = sff_8024_id[value];
+ else {
+ if (value > 0x80)
+ x = "Vendor specific";
+ else
+ x = "Reserved";
+ }
+
+ snprintf(buf, size, "%s", x);
+}
+
+static void
+convert_sff_connector(char *buf, size_t size, uint8_t value)
+{
+ const char *x;
+
+ if ((x = find_value(conn, value)) == NULL) {
+ if (value >= 0x0D && value <= 0x1F)
+ x = "Unallocated";
+ else if (value >= 0x24 && value <= 0x7F)
+ x = "Unallocated";
+ else
+ x = "Vendor specific";
+ }
+
+ snprintf(buf, size, "%s", x);
+}
+
+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;
+
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_ID, 1, &data);
+ convert_sff_identifier(buf, size, data);
+}
+
+static void
+get_sfp_connector(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t data;
+
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, &data);
+ convert_sff_connector(buf, size, data);
+}
+
+static void
+get_qsfp_identifier(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t data;
+
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_ID, 1, &data);
+ convert_sff_identifier(buf, size, data);
+}
+
+static void
+get_qsfp_connector(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t data;
+
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, &data);
+ convert_sff_connector(buf, size, data);
+}
+
+static void
+printf_sfp_transceiver_descr(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[12];
+ const char *tech_class, *tech_len, *tech_tech, *tech_media, *tech_speed;
+
+ tech_class = NULL;
+ tech_len = NULL;
+ tech_tech = NULL;
+ tech_media = NULL;
+ tech_speed = NULL;
+
+ /* Read bytes 3-10 at once */
+ 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);
+ if (tech_class == NULL) {
+ /* No match. Try 1G */
+ tech_class = find_zero_bit(eth_compat, xbuf[6], 1);
+ }
+
+ tech_len = find_zero_bit(fc_len, xbuf[7], 1);
+ tech_tech = find_zero_bit(cab_tech, xbuf[7] << 8 | xbuf[8], 2);
+ tech_media = find_zero_bit(fc_media, xbuf[9], 1);
+ tech_speed = find_zero_bit(fc_speed, xbuf[10], 1);
+
+ printf("Class: %s\n", tech_class);
+ printf("Length: %s\n", tech_len);
+ printf("Tech: %s\n", tech_tech);
+ printf("Media: %s\n", tech_media);
+ printf("Speed: %s\n", tech_speed);
+}
+
+static void
+get_sfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size)
+{
+ const char *tech_class;
+ uint8_t code;
+
+ unsigned char qbuf[8];
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (uint8_t *)qbuf);
+
+ /* Check 10G Ethernet/IB first */
+ 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 */
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3,
+ 1, (caddr_t)&code);
+ tech_class = find_zero_bit(eth_compat, code, 1);
+ }
+
+ if (tech_class == NULL)
+ tech_class = "Unknown";
+
+ snprintf(buf, size, "%s", tech_class);
+}
+
+static void
+get_qsfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size)
+{
+ const char *tech_class;
+ uint8_t code;
+
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_CODE_E1040100G, 1, &code);
+
+ /* Check for extended specification compliance */
+ if (code & SFF_8636_EXT_COMPLIANCE) {
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_OPTIONS_START, 1, &code);
+ tech_class = find_value(eth_extended_comp, code);
+ } else
+ /* Check 10/40G Ethernet class only */
+ tech_class = find_zero_bit(eth_1040g, code, 1);
+
+ if (tech_class == NULL)
+ tech_class = "Unknown";
+
+ snprintf(buf, size, "%s", tech_class);
+}
+
+/*
+ * Print SFF-8472/SFF-8436 string to supplied buffer.
+ * All (vendor-specific) strings are padded right with '0x20'.
+ */
+static void
+convert_sff_name(char *buf, size_t size, char *xbuf)
+{
+ char *p;
+
+ for (p = &xbuf[16]; *(p - 1) == 0x20; p--)
+ ;
+ *p = '\0';
+ snprintf(buf, size, "%s", xbuf);
+}
+
+static void
+convert_sff_date(char *buf, size_t size, char *xbuf)
+{
+
+ snprintf(buf, size, "20%c%c-%c%c-%c%c", xbuf[0], xbuf[1],
+ xbuf[2], xbuf[3], xbuf[4], xbuf[5]);
+}
+
+static void
+get_sfp_vendor_name(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_sfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_sfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_sfp_vendor_date(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[6];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ /* Date code, see Table 3.8 for description */
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, (uint8_t *)xbuf);
+ convert_sff_date(buf, size, xbuf);
+}
+
+static void
+get_qsfp_vendor_name(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_qsfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_qsfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[17];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, (uint8_t *)xbuf);
+ convert_sff_name(buf, size, xbuf);
+}
+
+static void
+get_qsfp_vendor_date(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[6];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, (uint8_t *)xbuf);
+ convert_sff_date(buf, size, xbuf);
+}
+
+static void
+print_sfp_vendor(struct i2c_info *ii, char *buf, size_t size)
+{
+ char xbuf[80];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ if (ii->qsfp != 0) {
+ get_qsfp_vendor_name(ii, xbuf, 20);
+ get_qsfp_vendor_pn(ii, &xbuf[20], 20);
+ get_qsfp_vendor_sn(ii, &xbuf[40], 20);
+ get_qsfp_vendor_date(ii, &xbuf[60], 20);
+ } else {
+ get_sfp_vendor_name(ii, xbuf, 20);
+ get_sfp_vendor_pn(ii, &xbuf[20], 20);
+ get_sfp_vendor_sn(ii, &xbuf[40], 20);
+ get_sfp_vendor_date(ii, &xbuf[60], 20);
+ }
+
+ snprintf(buf, size, "vendor: %s PN: %s SN: %s DATE: %s",
+ xbuf, &xbuf[20], &xbuf[40], &xbuf[60]);
+}
+
+/*
+ * Converts internal templerature (SFF-8472, SFF-8436)
+ * 16-bit unsigned value to human-readable representation:
+ *
+ * Internally measured Module temperature are represented
+ * as a 16-bit signed twos complement value in increments of
+ * 1/256 degrees Celsius, yielding a total range of –128C to +128C
+ * that is considered valid between –40 and +125C.
+ *
+ */
+static void
+convert_sff_temp(char *buf, size_t size, uint8_t *xbuf)
+{
+ double d;
+
+ d = (double)xbuf[0];
+ d += (double)xbuf[1] / 256;
+
+ snprintf(buf, size, "%.2f C", d);
+}
+
+/*
+ * Retrieves supplied voltage (SFF-8472, SFF-8436).
+ * 16-bit usigned value, treated as range 0..+6.55 Volts
+ */
+static void
+convert_sff_voltage(char *buf, size_t size, uint8_t *xbuf)
+{
+ double d;
+
+ d = (double)((xbuf[0] << 8) | xbuf[1]);
+ snprintf(buf, size, "%.2f Volts", d / 10000);
+}
+
+/*
+ * Converts value in @xbuf to both milliwats and dBm
+ * human representation.
+ */
+static void
+convert_sff_power(struct i2c_info *ii, char *buf, size_t size, uint8_t *xbuf)
+{
+ uint16_t mW;
+ double dbm;
+
+ mW = (xbuf[0] << 8) + xbuf[1];
+
+ /* Convert mw to dbm */
+ dbm = 10.0 * log10(1.0 * mW / 10000);
+
+ /*
+ * Assume internally-calibrated data.
+ * This is always true for SFF-8346, and explicitly
+ * checked for SFF-8472.
+ */
+
+ /* Table 3.9, bit 5 is set, internally calibrated */
+ snprintf(buf, size, "%d.%02d mW (%.2f dBm)",
+ mW / 10000, (mW % 10000) / 100, dbm);
+}
+
+static void
+get_sfp_temp(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(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)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf);
+ convert_sff_voltage(buf, size, xbuf);
+}
+
+static int
+get_qsfp_temp(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf);
+ if ((xbuf[0] == 0xFF && xbuf[1] == 0xFF) || (xbuf[0] == 0 && xbuf[1] == 0))
+ return (-1);
+ convert_sff_temp(buf, size, xbuf);
+ return (0);
+}
+
+static void
+get_qsfp_voltage(struct i2c_info *ii, char *buf, size_t size)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(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)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(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)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(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)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(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)
+{
+ uint8_t xbuf[2];
+
+ memset(xbuf, 0, sizeof(xbuf));
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan-1)*2, 2, xbuf);
+ convert_sff_power(ii, buf, size, xbuf);
+}
+
+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(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
+ uint8_t *buf)
+{
+ struct ifi2creq req;
+ int i, l;
+
+ if (ii->error != 0)
+ return (ii->error);
+
+ ii->ifr->ifr_data = (caddr_t)&req;
+
+ i = 0;
+ l = 0;
+ memset(&req, 0, sizeof(req));
+ req.dev_addr = addr;
+ req.offset = off;
+ req.len = len;
+
+ while (len > 0) {
+ l = (len > sizeof(req.data)) ? sizeof(req.data) : len;
+ req.len = l;
+ if (ioctl(ii->fd, SIOCGI2C, ii->ifr) != 0) {
+ ii->error = errno;
+ return (errno);
+ }
+
+ memcpy(&buf[i], req.data, l);
+ len -= l;
+ i += l;
+ req.offset += l;
+ }
+
+ return (0);
+}
+
+static void
+dump_i2c_data(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len)
+{
+ unsigned char buf[16];
+ int i, read;
+
+ while (len > 0) {
+ memset(buf, 0, sizeof(buf));
+ read = (len > sizeof(buf)) ? sizeof(buf) : len;
+ read_i2c(ii, addr, off, read, buf);
+ if (ii->error != 0) {
+ fprintf(stderr, "Error reading i2c info\n");
+ return;
+ }
+
+ printf("\t");
+ for (i = 0; i < read; i++)
+ printf("%02X ", buf[i]);
+ printf("\n");
+ len -= read;
+ off += read;
+ }
+}
+
+static void
+print_qsfp_status(struct i2c_info *ii, int verbose)
+{
+ char buf[80], buf2[40], buf3[40];
+ uint32_t bitrate;
+ int i;
+
+ ii->qsfp = 1;
+
+ /* Transceiver type */
+ get_qsfp_identifier(ii, buf, sizeof(buf));
+ get_qsfp_transceiver_class(ii, buf2, sizeof(buf2));
+ get_qsfp_connector(ii, buf3, sizeof(buf3));
+ if (ii->error == 0)
+ printf("\tplugged: %s %s (%s)\n", buf, buf2, buf3);
+ print_sfp_vendor(ii, buf, sizeof(buf));
+ 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);
+ }
+
+ /*
+ * The standards in this area are not clear when the
+ * additional measurements are present or not. Use a valid
+ * temperature reading as an indicator for the presence of
+ * voltage and TX/RX power measurements.
+ */
+ if (get_qsfp_temp(ii, buf, sizeof(buf)) == 0) {
+ get_qsfp_voltage(ii, buf2, sizeof(buf2));
+ printf("\tmodule temperature: %s voltage: %s\n", buf, buf2);
+ for (i = 1; i <= 4; i++) {
+ get_qsfp_rx_power(ii, buf, sizeof(buf), i);
+ get_qsfp_tx_power(ii, buf2, sizeof(buf2), i);
+ printf("\tlane %d: RX: %s TX: %s\n", i, buf, buf2);
+ }
+ }
+
+ if (verbose > 2) {
+ printf("\n\tSFF8436 DUMP (0xA0 128..255 range):\n");
+ dump_i2c_data(ii, SFF_8436_BASE, 128, 128);
+ printf("\n\tSFF8436 DUMP (0xA0 0..81 range):\n");
+ dump_i2c_data(ii, SFF_8436_BASE, 0, 82);
+ }
+}
+
+static void
+print_sfp_status(struct i2c_info *ii, int verbose)
+{
+ char buf[80], buf2[40], buf3[40];
+ uint8_t diag_type, flags;
+
+ /* Read diagnostic monitoring type */
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type);
+ if (ii->error != 0)
+ return;
+
+ /*
+ * Read monitoring data IFF it is supplied AND is
+ * internally calibrated
+ */
+ flags = SFF_8472_DDM_DONE | SFF_8472_DDM_INTERNAL;
+ if ((diag_type & flags) == flags)
+ ii->do_diag = 1;
+
+ /* Transceiver type */
+ get_sfp_identifier(ii, buf, sizeof(buf));
+ get_sfp_transceiver_class(ii, buf2, sizeof(buf2));
+ get_sfp_connector(ii, buf3, sizeof(buf3));
+ if (ii->error == 0)
+ printf("\tplugged: %s %s (%s)\n", buf, buf2, buf3);
+ print_sfp_vendor(ii, buf, sizeof(buf));
+ if (ii->error == 0)
+ printf("\t%s\n", buf);
+
+ if (verbose > 5)
+ printf_sfp_transceiver_descr(ii, buf, sizeof(buf));
+ /*
+ * Request current measurements iff they are provided:
+ */
+ if (ii->do_diag != 0) {
+ get_sfp_temp(ii, buf, sizeof(buf));
+ get_sfp_voltage(ii, buf2, sizeof(buf2));
+ printf("\tmodule temperature: %s Voltage: %s\n", buf, buf2);
+ get_sfp_rx_power(ii, buf, sizeof(buf));
+ get_sfp_tx_power(ii, buf2, sizeof(buf2));
+ printf("\tRX: %s TX: %s\n", buf, buf2);
+ }
+
+ if (verbose > 2) {
+ printf("\n\tSFF8472 DUMP (0xA0 0..127 range):\n");
+ dump_i2c_data(ii, SFF_8472_BASE, 0, 128);
+ }
+}
+
+void
+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));
+ ii.fd = s;
+ ii.ifr = ifr;
+
+ /*
+ * Try to read byte 0 from i2c:
+ * Both SFF-8472 and SFF-8436 use it as
+ * 'identification byte'.
+ * Stop reading status on zero as value -
+ * this might happen in case of empty transceiver slot.
+ */
+ id_byte = 0;
+ read_i2c(&ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&id_byte);
+ if (ii.error != 0 || id_byte == 0)
+ return;
+
+ switch (id_byte) {
+ case SFF_8024_ID_QSFP:
+ case SFF_8024_ID_QSFPPLUS:
+ case SFF_8024_ID_QSFP28:
+ print_qsfp_status(&ii, verbose);
+ break;
+ default:
+ print_sfp_status(&ii, verbose);
+ };
+}
+
Property changes on: trunk/sbin/ifconfig/sfp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
More information about the Midnightbsd-cvs
mailing list