MFC: added an ioctl option in kernel so that ndp/rtadvd can change some NDP-related kernel variables based on their configurations (RFC2461 p.43 6.2.1 mandates this for IPv6 routers)
Revision Changes Path 1.56 +1 -0 src/sys/netinet6/in6.c 1.26 +1 -0 src/sys/netinet6/in6_var.h 1.57 +28 -0 src/sys/netinet6/nd6.c 1.17 +21 -8 src/usr.sbin/ndp/ndp.8 1.17 +31 -2 src/usr.sbin/ndp/ndp.c 1.25 +30 -0 src/usr.sbin/rtadvd/config.c
This commit is contained in:
parent
d3ffc1647d
commit
038918b0d7
@ -364,6 +364,7 @@ in6_control(so, cmd, data, ifp, td)
|
|||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case OSIOCGIFINFO_IN6:
|
case OSIOCGIFINFO_IN6:
|
||||||
case SIOCGIFINFO_IN6:
|
case SIOCGIFINFO_IN6:
|
||||||
|
case SIOCSIFINFO_IN6:
|
||||||
case SIOCGDRLST_IN6:
|
case SIOCGDRLST_IN6:
|
||||||
case SIOCGPRLST_IN6:
|
case SIOCGPRLST_IN6:
|
||||||
case SIOCGNBRINFO_IN6:
|
case SIOCGNBRINFO_IN6:
|
||||||
|
@ -404,6 +404,7 @@ struct in6_rrenumreq {
|
|||||||
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
|
#define OSIOCGIFINFO_IN6 _IOWR('i', 76, struct in6_ondireq)
|
||||||
#endif
|
#endif
|
||||||
#define SIOCGIFINFO_IN6 _IOWR('i', 108, struct in6_ndireq)
|
#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 SIOCSNDFLUSH_IN6 _IOWR('i', 77, struct in6_ifreq)
|
||||||
#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
|
#define SIOCGNBRINFO_IN6 _IOWR('i', 78, struct in6_nbrinfo)
|
||||||
#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
|
#define SIOCSPFXFLUSH_IN6 _IOWR('i', 79, struct in6_ifreq)
|
||||||
|
@ -1426,6 +1426,7 @@ nd6_ioctl(cmd, data, ifp)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case OSIOCGIFINFO_IN6:
|
case OSIOCGIFINFO_IN6:
|
||||||
|
#define ND ndi->ndi
|
||||||
/* XXX: old ndp(8) assumes a positive value for linkmtu. */
|
/* XXX: old ndp(8) assumes a positive value for linkmtu. */
|
||||||
bzero(&ndi->ndi, sizeof(ndi->ndi));
|
bzero(&ndi->ndi, sizeof(ndi->ndi));
|
||||||
ndi->ndi.linkmtu = IN6_LINKMTU(ifp);
|
ndi->ndi.linkmtu = IN6_LINKMTU(ifp);
|
||||||
@ -1441,9 +1442,38 @@ nd6_ioctl(cmd, data, ifp)
|
|||||||
ndi->ndi = *ND_IFINFO(ifp);
|
ndi->ndi = *ND_IFINFO(ifp);
|
||||||
ndi->ndi.linkmtu = IN6_LINKMTU(ifp);
|
ndi->ndi.linkmtu = IN6_LINKMTU(ifp);
|
||||||
break;
|
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:
|
case SIOCSIFINFO_FLAGS:
|
||||||
ND_IFINFO(ifp)->flags = ndi->ndi.flags;
|
ND_IFINFO(ifp)->flags = ndi->ndi.flags;
|
||||||
break;
|
break;
|
||||||
|
#undef ND
|
||||||
case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */
|
case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */
|
||||||
/* flush default router list */
|
/* flush default router list */
|
||||||
/*
|
/*
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
.Op Fl nt
|
.Op Fl nt
|
||||||
.Fl i
|
.Fl i
|
||||||
.Ar interface
|
.Ar interface
|
||||||
.Op Ar flags ...
|
.Op Ar expressions ...
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl nt
|
.Op Fl nt
|
||||||
.Fl I Op Ar interface | Li delete
|
.Fl I Op Ar interface | Li delete
|
||||||
@ -153,19 +153,20 @@ The
|
|||||||
will be used as the default.
|
will be used as the default.
|
||||||
.It Fl I Li delete
|
.It Fl I Li delete
|
||||||
The current default interface will be deleted from the kernel.
|
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.
|
View ND information for the specified interface.
|
||||||
If additional arguments
|
If additional arguments
|
||||||
.Ar flags
|
.Ar expressions
|
||||||
are given,
|
are given,
|
||||||
.Nm
|
.Nm
|
||||||
sets or clears the specified flags for the interface.
|
sets or clears the flags or variables for the interface as specified in
|
||||||
Each flag should be separated by white spaces or tab characters.
|
the expression.
|
||||||
Possible flags are as follows.
|
Each expression should be separated by white spaces or tab characters.
|
||||||
All of the flags can begin with the
|
Possible expressions are as follows.
|
||||||
|
Some of the expressions can begin with the
|
||||||
special character
|
special character
|
||||||
.Ql - ,
|
.Ql - ,
|
||||||
which means the flag should be cleared.
|
which means the flag specified in the expression should be cleared.
|
||||||
Note that you need
|
Note that you need
|
||||||
.Fl -
|
.Fl -
|
||||||
before
|
before
|
||||||
@ -209,6 +210,18 @@ a certain failure of Duplicate Address Detection.
|
|||||||
While the flag can be set or cleared by hand with the
|
While the flag can be set or cleared by hand with the
|
||||||
.Nm
|
.Nm
|
||||||
command, it is not generally advisable to modify this flag manually.
|
command, it is not generally advisable to modify this flag manually.
|
||||||
|
.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
|
.El
|
||||||
.It Fl n
|
.It Fl n
|
||||||
Do not try to resolve numeric addresses to hostnames.
|
Do not try to resolve numeric addresses to hostnames.
|
||||||
|
@ -969,6 +969,27 @@ ifinfo(ifname, argc, argv)
|
|||||||
newflags |= (f);\
|
newflags |= (f);\
|
||||||
}\
|
}\
|
||||||
} while (0)
|
} 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("disabled", ND6_IFF_IFDISABLED);
|
SETFLAG("disabled", ND6_IFF_IFDISABLED);
|
||||||
SETFLAG("nud", ND6_IFF_PERFORMNUD);
|
SETFLAG("nud", ND6_IFF_PERFORMNUD);
|
||||||
#ifdef ND6_IFF_ACCEPT_RTADV
|
#ifdef ND6_IFF_ACCEPT_RTADV
|
||||||
@ -977,13 +998,17 @@ ifinfo(ifname, argc, argv)
|
|||||||
#ifdef ND6_IFF_PREFER_SOURCE
|
#ifdef ND6_IFF_PREFER_SOURCE
|
||||||
SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
|
SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
|
||||||
#endif
|
#endif
|
||||||
|
SETVALUE("basereachable", ND.basereachable);
|
||||||
|
SETVALUE("retrans", ND.retrans);
|
||||||
|
SETVALUE("curhlim", ND.chlim);
|
||||||
|
|
||||||
ND.flags = newflags;
|
ND.flags = newflags;
|
||||||
if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
|
if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd) < 0) {
|
||||||
err(1, "ioctl(SIOCSIFINFO_FLAGS)");
|
err(1, "ioctl(SIOCSIFINFO_IN6)");
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
#undef SETFLAG
|
#undef SETFLAG
|
||||||
|
#undef SETVALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ND.initialized) {
|
if (!ND.initialized) {
|
||||||
@ -991,6 +1016,10 @@ ifinfo(ifname, argc, argv)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) {
|
||||||
|
err(1, "ioctl(SIOCGIFINFO_IN6)");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
printf("linkmtu=%d", ND.linkmtu);
|
printf("linkmtu=%d", ND.linkmtu);
|
||||||
printf(", maxmtu=%d", ND.maxmtu);
|
printf(", maxmtu=%d", ND.maxmtu);
|
||||||
printf(", curhlim=%d", ND.chlim);
|
printf(", curhlim=%d", ND.chlim);
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet6/ip6_var.h>
|
#include <netinet6/ip6_var.h>
|
||||||
#include <netinet/icmp6.h>
|
#include <netinet/icmp6.h>
|
||||||
|
#include <netinet6/nd6.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
@ -407,6 +408,35 @@ getconfig(intface)
|
|||||||
exit(1);
|
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 */
|
/* route information */
|
||||||
#ifdef ROUTEINFO
|
#ifdef ROUTEINFO
|
||||||
tmp->routes = 0;
|
tmp->routes = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user