summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet6/in6.c1
-rw-r--r--sys/netinet6/in6_var.h1
-rw-r--r--sys/netinet6/nd6.c28
-rw-r--r--usr.sbin/ndp/ndp.829
-rw-r--r--usr.sbin/ndp/ndp.c33
-rw-r--r--usr.sbin/rtadvd/config.c30
6 files changed, 112 insertions, 10 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 77124f5..53d2c2d 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -361,6 +361,7 @@ in6_control(so, cmd, data, ifp, td)
/* FALLTHROUGH */
case OSIOCGIFINFO_IN6:
case SIOCGIFINFO_IN6:
+ case SIOCSIFINFO_IN6:
case SIOCGDRLST_IN6:
case SIOCGPRLST_IN6:
case SIOCGNBRINFO_IN6:
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index 148fdbd..6bf87b2 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -404,6 +404,7 @@ struct in6_rrenumreq {
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
#endif
#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq)
+#define SIOCSIFINFO_IN6 _IOWR('i', 109, struct in6_ndireq)
#define SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 46b1ea1..ae3664f 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1441,6 +1441,34 @@ nd6_ioctl(cmd, data, ifp)
ND = *ND_IFINFO(ifp);
ND.linkmtu = IN6_LINKMTU(ifp);
break;
+ case SIOCSIFINFO_IN6:
+ /*
+ * used to change host variables from userland.
+ * intented for a use on router to reflect RA configurations.
+ */
+ /* 0 means 'unspecified' */
+ if (ND.linkmtu != 0) {
+ if (ND.linkmtu < IPV6_MMTU ||
+ ND.linkmtu > IN6_LINKMTU(ifp)) {
+ error = EINVAL;
+ break;
+ }
+ ND_IFINFO(ifp)->linkmtu = ND.linkmtu;
+ }
+
+ if (ND.basereachable != 0) {
+ int obasereachable = ND_IFINFO(ifp)->basereachable;
+
+ ND_IFINFO(ifp)->basereachable = ND.basereachable;
+ if (ND.basereachable != obasereachable)
+ ND_IFINFO(ifp)->reachable =
+ ND_COMPUTE_RTIME(ND.basereachable);
+ }
+ if (ND.retrans != 0)
+ ND_IFINFO(ifp)->retrans = ND.retrans;
+ if (ND.chlim != 0)
+ ND_IFINFO(ifp)->chlim = ND.chlim;
+ /* FALLTHROUGH */
case SIOCSIFINFO_FLAGS:
ND_IFINFO(ifp)->flags = ND.flags;
break;
diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8
index 5c31c41..ea33646 100644
--- a/usr.sbin/ndp/ndp.8
+++ b/usr.sbin/ndp/ndp.8
@@ -63,7 +63,7 @@
.Op Fl nt
.Fl i
.Ar interface
-.Op Ar flags ...
+.Op Ar expressions ...
.Nm
.Op Fl nt
.Fl I Op Ar interface | Li delete
@@ -153,19 +153,20 @@ The
will be used as the default.
.It Fl I Li delete
The current default interface will be deleted from the kernel.
-.It Fl i Ar interface Op Ar flags ...
+.It Fl i Ar interface Op Ar expressions ...
View ND information for the specified interface.
If additional arguments
-.Ar flags
+.Ar expressions
are given,
.Nm
-sets or clears the specified flags for the interface.
-Each flag should be separated by white spaces or tab characters.
-Possible flags are as follows.
-All of the flags can begin with the
+sets or clears the flags or variables for the interface as specified in
+the expression.
+Each expression should be separated by white spaces or tab characters.
+Possible expressions are as follows.
+Some of the expressions can begin with the
special character
.Ql - ,
-which means the flag should be cleared.
+which means the flag specified in the expression should be cleared.
Note that you need
.Fl -
before
@@ -196,6 +197,18 @@ For more details about the entire algorithm of source address
selection, see the
.Pa IMPLEMENTATION
file supplied with the KAME kit.
+.It Xo
+.Ic basereachable=(number)
+.Xc
+Specify the BaseReachbleTimer on the interface in millisecond.
+.It Xo
+.Ic retrans=(number)
+.Xc
+Specify the RetransTimer on the interface in millisecond.
+.It Xo
+.Ic curhlim=(number)
+.Xc
+Specify the Cur Hop Limit on the interface.
.El
.It Fl n
Do not try to resolve numeric addresses to hostnames.
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index de3a80a..31ed677 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -965,6 +965,27 @@ ifinfo(ifname, argc, argv)
newflags |= (f);\
}\
} while (0)
+/*
+ * XXX: this macro is not 100% correct, in that it matches "nud" against
+ * "nudbogus". But we just let it go since this is minor.
+ */
+#define SETVALUE(f, v) \
+ do { \
+ char *valptr; \
+ unsigned long newval; \
+ v = 0; /* unspecified */ \
+ if (strncmp(cp, f, strlen(f)) == 0) { \
+ valptr = strchr(cp, '='); \
+ if (valptr == NULL) \
+ err(1, "syntax error in %s field", (f)); \
+ errno = 0; \
+ newval = strtoul(++valptr, NULL, 0); \
+ if (errno) \
+ err(1, "syntax error in %s's value", (f)); \
+ v = newval; \
+ } \
+ } while (0)
+
SETFLAG("nud", ND6_IFF_PERFORMNUD);
#ifdef ND6_IFF_ACCEPT_RTADV
SETFLAG("accept_rtadv", ND6_IFF_ACCEPT_RTADV);
@@ -972,13 +993,17 @@ ifinfo(ifname, argc, argv)
#ifdef ND6_IFF_PREFER_SOURCE
SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
#endif
+ SETVALUE("basereachable", ND.basereachable);
+ SETVALUE("retrans", ND.retrans);
+ SETVALUE("curhlim", ND.chlim);
ND.flags = newflags;
- if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
- err(1, "ioctl(SIOCSIFINFO_FLAGS)");
+ if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd) < 0) {
+ err(1, "ioctl(SIOCSIFINFO_IN6)");
/* NOTREACHED */
}
#undef SETFLAG
+#undef SETVALUE
}
if (!ND.initialized) {
@@ -986,6 +1011,10 @@ ifinfo(ifname, argc, argv)
/* NOTREACHED */
}
+ if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) {
+ err(1, "ioctl(SIOCGIFINFO_IN6)");
+ /* NOTREACHED */
+ }
printf("linkmtu=%d", ND.linkmtu);
printf(", maxmtu=%d", ND.maxmtu);
printf(", curhlim=%d", ND.chlim);
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
index 09e4eac..e9e3b97 100644
--- a/usr.sbin/rtadvd/config.c
+++ b/usr.sbin/rtadvd/config.c
@@ -46,6 +46,7 @@
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
+#include <netinet6/nd6.h>
#include <arpa/inet.h>
@@ -407,6 +408,35 @@ getconfig(intface)
exit(1);
}
+#ifdef SIOCSIFINFO_IN6
+ {
+ struct in6_ndireq ndi;
+ int s;
+
+ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ syslog(LOG_ERR, "<%s> socket: %s", __func__,
+ strerror(errno));
+ exit(1);
+ }
+ memset(&ndi, 0, sizeof(ndi));
+ strncpy(ndi.ifname, intface, IFNAMSIZ);
+ if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&ndi) < 0) {
+ syslog(LOG_INFO, "<%s> ioctl:SIOCGIFINFO_IN6 at %s: %s",
+ __func__, intface, strerror(errno));
+ }
+
+ /* reflect the RA info to the host variables in kernel */
+ ndi.ndi.chlim = tmp->hoplimit;
+ ndi.ndi.retrans = tmp->retranstimer;
+ ndi.ndi.basereachable = tmp->reachabletime;
+ if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&ndi) < 0) {
+ syslog(LOG_INFO, "<%s> ioctl:SIOCSIFINFO_IN6 at %s: %s",
+ __func__, intface, strerror(errno));
+ }
+ close(s);
+ }
+#endif
+
/* route information */
#ifdef ROUTEINFO
tmp->routes = 0;
OpenPOWER on IntegriCloud