summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtadvctl
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rtadvctl')
-rw-r--r--usr.sbin/rtadvctl/Makefile4
-rw-r--r--usr.sbin/rtadvctl/rtadvctl.863
-rw-r--r--usr.sbin/rtadvctl/rtadvctl.c227
3 files changed, 199 insertions, 95 deletions
diff --git a/usr.sbin/rtadvctl/Makefile b/usr.sbin/rtadvctl/Makefile
index 3200288..a66db84c4 100644
--- a/usr.sbin/rtadvctl/Makefile
+++ b/usr.sbin/rtadvctl/Makefile
@@ -7,7 +7,7 @@ MAN= rtadvctl.8
SRCS= rtadvctl.c control.c control_client.c if.c timer_subr.c
-CFLAGS+= -DROUTEINFO -I${.CURDIR} -I${.CURDIR}/../rtadvd
-WARNS?= 3
+CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../rtadvd
+WARNS?= 1
.include <bsd.prog.mk>
diff --git a/usr.sbin/rtadvctl/rtadvctl.8 b/usr.sbin/rtadvctl/rtadvctl.8
index 81cfa07..b9c0f2e 100644
--- a/usr.sbin/rtadvctl/rtadvctl.8
+++ b/usr.sbin/rtadvctl/rtadvctl.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 14, 2011
+.Dd July 16, 2011
.Dt RTADVCTL 8
.Os
.Sh NAME
@@ -39,54 +39,65 @@
.Op Ar interface ...
.Sh DESCRIPTION
.Nm
-is a utility that communicates
+is a utility that communicates with
.Xr rtadvd 8
-daemon and displays information on Router Advertisement messages being
-sent on each interfaces.
+daemon and displays information about Router Advertisement messages being
+sent on each interface.
.Pp
This utility provides several options and subcommands.
The options are as follows:
.Bl -tag -width indent
.\"
.It Fl v
-Increase verbose level. When specified once, the
+Increase verbosity level.
+When specified once, the
.Nm
-utility shows additional information on prefixes, RDNSS, and DNSSL
+utility shows additional information about prefixes, RDNSS, and DNSSL
options.
-When twice, it shows information on inactive interfaces and
-some statistics.
+When given twice, it additionally shows information about
+inactive interfaces and some statistics.
.El
.Pp
The subcommands are as follows:
.Bl -tag -width indent
.\"
-.It reload
-Specifies reloading the configuration file.
+.It reload Op interfaces...
+Specifies to reload the configuration file. If one or more
+.Ar interface
+is specified, configuration entries for the interfaces will be reloaded
+selectively.
+.It enable interfaces...
+Specifies to mark the interface as enable and to try to reload the
+configuration entry.
+This subcommand is useful for dynamically-added interfaces.
+.Pp
+The
+.Xr rtadvd 8
+daemon marks an interface as enable if the interface exists and the
+configuration file has a valid entry for that when it is invoked.
+.It disable interfaces...
+Specifies to mark the interface as disable.
.It shutdown
-Makes
+Makes the
+.Xr rtadvd 8
+daemon shut down.
+Note that the
.Xr rtadvd 8
-daemon shut down immediately.
+daemon will send several RAs with zero lifetime to invalidate the old
+information on each interface.
+It will take at most nine seconds.
.It show Op interfaces...
Displays information on Router Advertisement messages being sent
-on each interfaces.
+on each interface.
.Sh SEE ALSO
-.Xr rtadv 8 ,
+.Xr rtadvd 8 ,
.Xr rtadvd.conf 5
.Sh HISTORY
The
.Nm
command first appeared in
.Fx 9.0 .
-.Sh BUGS
-The
-.Xr rtadvd 8
-daemon stops responding to
-.Nm
-for a while just after reloading the configuration file by the reload
-subcommand.
-This is because in the current implementation it cannot communicate
-with
+.Sh AUTHORS
.Nm
-during sending some additional RAs for graceful transition from one
-configuration to another.
-It will take at most nine seconds for each interface.
+was written by
+.An "Hiroki Sato" Aq hrs@FreeBSD.org .
diff --git a/usr.sbin/rtadvctl/rtadvctl.c b/usr.sbin/rtadvctl/rtadvctl.c
index e5be355..26bf11d 100644
--- a/usr.sbin/rtadvctl/rtadvctl.c
+++ b/usr.sbin/rtadvctl/rtadvctl.c
@@ -46,6 +46,7 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
+#include <inttypes.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
@@ -60,6 +61,7 @@
#include "rtadvd.h"
#include "if.h"
#include "timer_subr.h"
+#include "timer.h"
#include "control.h"
#include "control_client.h"
@@ -84,9 +86,7 @@ static int action_shutdown(int, char **);
static int action_show(int, char **);
static int action_show_prefix(struct prefix *);
-#ifdef ROUTEINFO
static int action_show_rtinfo(struct rtinfo *);
-#endif
static int action_show_rdnss(void *);
static int action_show_dnssl(void *);
@@ -108,14 +108,17 @@ static struct dispatch_table {
{ "show", action_show },
{ "reload", action_reload },
{ "shutdown", action_shutdown },
- { NULL, NULL },
{ "enable", action_enable },
{ "disable", action_disable },
+ { NULL, NULL },
{ "echo", action_echo },
{ "version", action_version },
{ NULL, NULL },
};
+static char errmsgbuf[1024];
+static char *errmsg = NULL;
+
static void
mysyslog(int priority, const char * restrict fmt, ...)
{
@@ -177,13 +180,17 @@ main(int argc, char *argv[])
}
}
- if (action != NULL) {
- error = (dtable[i].dt_act)(--argc, ++argv);
- if (error)
- fprintf(stderr, "%s failed.\n", dtable[i].dt_comm);
- } else
+ if (action == NULL)
usage();
+ error = (dtable[i].dt_act)(--argc, ++argv);
+ if (error) {
+ fprintf(stderr, "%s failed", dtable[i].dt_comm);
+ if (errmsg != NULL)
+ fprintf(stderr, ": %s", errmsg);
+ fprintf(stderr, ".\n");
+ }
+
return (error);
}
@@ -295,33 +302,69 @@ action_propset(char *argv)
return (action_plgeneric(CM_TYPE_REQ_SET_PROP, argv, buf));
}
-/* XXX */
static int
-action_enable(int argc, char **argv)
+action_disable(int argc, char **argv)
{
- argc = argc;
- argv = argv;
+ char *action_argv;
+ char argv_disable[IFNAMSIZ + sizeof(":disable=")];
+ int i;
+ int error;
- return (0);
+ if (argc < 1)
+ return (1);
+
+ error = 0;
+ for (i = 0; i < argc; i++) {
+ sprintf(argv_disable, "%s:disable=", argv[i]);
+ action_argv = argv_disable;
+ error += action_propset(action_argv);
+ }
+
+ return (error);
}
-/* XXX */
static int
-action_disable(int argc, char **argv)
+action_enable(int argc, char **argv)
{
- argc = argc;
- argv = argv;
+ char *action_argv;
+ char argv_enable[IFNAMSIZ + sizeof(":enable=")];
+ int i;
+ int error;
- return (0);
+ if (argc < 1)
+ return (1);
+
+ error = 0;
+ for (i = 0; i < argc; i++) {
+ sprintf(argv_enable, "%s:enable=", argv[i]);
+ action_argv = argv_enable;
+ error += action_propset(action_argv);
+ }
+
+ return (error);
}
static int
-action_reload(int argc __unused, char **argv __unused)
+action_reload(int argc, char **argv)
{
char *action_argv;
+ char argv_reload[IFNAMSIZ + sizeof(":reload=")];
+ int i;
+ int error;
+
+ if (argc == 0) {
+ action_argv = strdup(":reload=");
+ return (action_propset(action_argv));
+ }
+
+ error = 0;
+ for (i = 0; i < argc; i++) {
+ sprintf(argv_reload, "%s:reload=", argv[i]);
+ action_argv = argv_reload;
+ error += action_propset(action_argv);
+ }
- action_argv = strdup("reload");
- return(action_propset(action_argv));
+ return (error);
}
static int
@@ -330,7 +373,7 @@ action_echo(int argc __unused, char **argv __unused)
char *action_argv;
action_argv = strdup("echo");
- return(action_propset(action_argv));
+ return (action_propset(action_argv));
}
static int
@@ -339,7 +382,7 @@ action_shutdown(int argc __unused, char **argv __unused)
char *action_argv;
action_argv = strdup("shutdown");
- return(action_propset(action_argv));
+ return (action_propset(action_argv));
}
/* XXX */
@@ -366,10 +409,9 @@ action_show(int argc, char **argv)
char argv_ifilist[sizeof(":ifilist=")] = ":ifilist=";
char argv_ifi[IFNAMSIZ + sizeof(":ifi=")];
char argv_rai[IFNAMSIZ + sizeof(":rai=")];
-#ifdef ROUTEINFO
char argv_rti[IFNAMSIZ + sizeof(":rti=")];
-#endif
char argv_pfx[IFNAMSIZ + sizeof(":pfx=")];
+ char argv_ifi_ra_timer[IFNAMSIZ + sizeof(":ifi_ra_timer=")];
char argv_rdnss[IFNAMSIZ + sizeof(":rdnss=")];
char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")];
char ssbuf[SSBUFLEN];
@@ -394,7 +436,7 @@ action_show(int argc, char **argv)
while (p < endp) {
ifi = malloc(sizeof(*ifi));
if (ifi == NULL)
- exit(1);
+ return (1);
memset(ifi, 0, sizeof(*ifi));
strcpy(ifi->ifi_ifname, p);
@@ -406,23 +448,27 @@ action_show(int argc, char **argv)
for (i = 0; i < argc; i++) {
ifi = malloc(sizeof(*ifi));
if (ifi == NULL)
- exit(1);
+ return (1);
memset(ifi, 0, sizeof(*ifi));
strcpy(ifi->ifi_ifname, argv[i]);
ifi->ifi_ifindex = if_nametoindex(ifi->ifi_ifname);
- if (ifi->ifi_ifindex == 0)
- exit(1);
+ if (ifi->ifi_ifindex == 0) {
+ sprintf(errmsgbuf, "invalid interface %s",
+ ifi->ifi_ifname);
+ errmsg = errmsgbuf;
+ return (1);
+ }
+
TAILQ_INSERT_TAIL(&ifl, ifi, ifi_next);
}
}
TAILQ_FOREACH(ifi, &ifl, ifi_next) {
struct ifinfo *ifi_s;
+ struct rtadvd_timer *rat;
struct rainfo *rai;
-#ifdef ROUTEINFO
struct rtinfo *rti;
-#endif
struct prefix *pfx;
int c;
int ra_ifstatus;
@@ -439,33 +485,52 @@ action_show(int argc, char **argv)
printf("%s: flags=<", ifi->ifi_ifname);
- /*
- * RA_RECV = UP + CONFIGURED + ACCEPT_RTADV
- * RA_SEND = UP + CONFIGURED + IPV6FORWARDING
- */
-
c = 0;
if (ifi_s->ifi_ifindex == 0)
c += printf("NONEXISTENT");
else
c += printf("%s", (ifi_s->ifi_flags & IFF_UP) ?
"UP" : "DOWN");
- if (ifi_s->ifi_state == IFI_STATE_CONFIGURED)
+ switch (ifi_s->ifi_state) {
+ case IFI_STATE_CONFIGURED:
c += printf("%s%s", (c) ? "," : "", "CONFIGURED");
-
+ break;
+ case IFI_STATE_TRANSITIVE:
+ c += printf("%s%s", (c) ? "," : "", "TRANSITIVE");
+ break;
+ }
if (ifi_s->ifi_persist)
c += printf("%s%s", (c) ? "," : "", "PERSIST");
printf(">");
ra_ifstatus = RA_IFSTATUS_INACTIVE;
if ((ifi_s->ifi_flags & IFF_UP) &&
- (ifi_s->ifi_state == IFI_STATE_CONFIGURED)) {
+ ((ifi_s->ifi_state == IFI_STATE_CONFIGURED) ||
+ (ifi_s->ifi_state == IFI_STATE_TRANSITIVE))) {
+#if (__FreeBSD_version < 900000)
+ /*
+ * RA_RECV: !ip6.forwarding && ip6.accept_rtadv
+ * RA_SEND: ip6.forwarding
+ */
+ if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
+ if (getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
+ ra_ifstatus = RA_IFSTATUS_RA_RECV;
+ else
+ ra_ifstatus = RA_IFSTATUS_INACTIVE;
+ } else
+ ra_ifstatus = RA_IFSTATUS_RA_SEND;
+#else
+ /*
+ * RA_RECV: ND6_IFF_ACCEPT_RTADV
+ * RA_SEND: ip6.forwarding
+ */
if (ifi_s->ifi_nd_flags & ND6_IFF_ACCEPT_RTADV)
ra_ifstatus = RA_IFSTATUS_RA_RECV;
else if (getinet6sysctl(IPV6CTL_FORWARDING))
ra_ifstatus = RA_IFSTATUS_RA_SEND;
else
ra_ifstatus = RA_IFSTATUS_INACTIVE;
+#endif
}
c = 0;
@@ -478,7 +543,11 @@ action_show(int argc, char **argv)
printf("%s%s", (c) ? "," : "", "RA_SEND");
printf("> ");
- if (ifi_s->ifi_state != IFI_STATE_CONFIGURED) {
+ switch (ifi_s->ifi_state) {
+ case IFI_STATE_CONFIGURED:
+ case IFI_STATE_TRANSITIVE:
+ break;
+ default:
printf("\n");
continue;
}
@@ -533,14 +602,33 @@ action_show(int argc, char **argv)
rai->rai_hoplimit);
printf("\tAdvIfPrefixes: %s\n",
rai->rai_advifprefix ? "yes" : "no");
+
+ /* RA timer */
+ rat = NULL;
+ if (ifi_s->ifi_ra_timer != NULL) {
+ sprintf(argv_ifi_ra_timer, "%s:ifi_ra_timer=",
+ ifi->ifi_ifname);
+ action_argv = argv_ifi_ra_timer;
+
+ error = action_propget(action_argv, &cp);
+ if (error)
+ return (error);
+
+ rat = (struct rtadvd_timer *)cp.cp_val;
+ }
+ printf("\tNext RA send: %s",
+ (rat == NULL) ? "never\n" :
+ ctime((time_t *)&rat->rat_tm.tv_sec));
+ printf("\tLast RA sent: %s",
+ (ifi_s->ifi_ra_lastsent.tv_sec == 0) ? "never\n" :
+ ctime((time_t *)&ifi_s->ifi_ra_lastsent.tv_sec));
if (rai->rai_clockskew)
- printf("\tClock skew: %ldsec\n",
+ printf("\tClock skew: %" PRIu16 "sec\n",
rai->rai_clockskew);
if (vflag < LOG_WARNING)
continue;
-#ifdef ROUTEINFO
/* route information */
sprintf(argv_rti, "%s:rti=", ifi->ifi_ifname);
action_argv = argv_rti;
@@ -556,7 +644,7 @@ action_show(int argc, char **argv)
for (i = 0; i < len; i++)
action_show_rtinfo(&rti[i]);
}
-#endif
+
/* prefix information */
sprintf(argv_pfx, "%s:pfx=", ifi->ifi_ifname);
action_argv = argv_pfx;
@@ -583,7 +671,7 @@ action_show(int argc, char **argv)
if (error)
continue;
- len = *((u_int16_t *)cp.cp_val);
+ len = *((uint16_t *)cp.cp_val);
if (len > 0) {
printf("\tRDNSS entries:\n");
@@ -598,7 +686,7 @@ action_show(int argc, char **argv)
if (error)
continue;
- len = *((u_int16_t *)cp.cp_val);
+ len = *((uint16_t *)cp.cp_val);
if (len > 0) {
printf("\tDNSSL entries:\n");
@@ -610,28 +698,34 @@ action_show(int argc, char **argv)
printf("\n");
- printf("\tLast RA sent: %s",
- (rai->rai_lastsent.tv_sec == 0) ? "never\n" :
- ctime((time_t *)&rai->rai_lastsent.tv_sec));
- printf("\tRA initcounts/waits: %d/%d\n",
- rai->rai_initcounter,
- rai->rai_waiting);
- printf("\tRA out/in/inconsistent: %llu/%llu/%llu\n",
- ifi_s->ifi_raoutput,
+ printf("\tCounters\n"
+ "\t RA burst counts: %" PRIu16 " (interval: %s)\n"
+ "\t RS wait counts: %" PRIu16 "\n",
+ ifi_s->ifi_burstcount,
+ sec2str(ifi_s->ifi_burstinterval, ssbuf),
+ ifi_s->ifi_rs_waitcount);
+
+ printf("\tOutputs\n"
+ "\t RA: %" PRIu64 "\n", ifi_s->ifi_raoutput);
+
+ printf("\tInputs\n"
+ "\t RA: %" PRIu64 " (normal)\n"
+ "\t RA: %" PRIu64 " (inconsistent)\n"
+ "\t RS: %" PRIu64 "\n",
ifi_s->ifi_rainput,
- ifi_s->ifi_rainconsistent);
- printf("\tRS in: %llu\n",
+ ifi_s->ifi_rainconsistent,
ifi_s->ifi_rsinput);
printf("\n");
+#if 0 /* Not implemented yet */
printf("\tReceived RAs:\n");
+#endif
}
return (0);
}
-#ifdef ROUTEINFO
static int
action_show_rtinfo(struct rtinfo *rti)
{
@@ -648,7 +742,6 @@ action_show_rtinfo(struct rtinfo *rti)
return (0);
}
-#endif
static int
action_show_prefix(struct prefix *pfx)
@@ -726,17 +819,17 @@ action_show_rdnss(void *msg)
{
struct rdnss *rdn;
struct rdnss_addr *rda;
- u_int16_t *rdn_cnt;
- u_int16_t *rda_cnt;
+ uint16_t *rdn_cnt;
+ uint16_t *rda_cnt;
int i;
int j;
char *p;
- u_int32_t ltime;
+ uint32_t ltime;
char ntopbuf[INET6_ADDRSTRLEN];
char ssbuf[SSBUFLEN];
p = msg;
- rdn_cnt = (u_int16_t *)p;
+ rdn_cnt = (uint16_t *)p;
p += sizeof(*rdn_cnt);
if (*rdn_cnt > 0) {
@@ -745,7 +838,7 @@ action_show_rdnss(void *msg)
ltime = rdn->rd_ltime;
p += sizeof(*rdn);
- rda_cnt = (u_int16_t *)p;
+ rda_cnt = (uint16_t *)p;
p += sizeof(*rda_cnt);
if (*rda_cnt > 0)
for (j = 0; j < *rda_cnt; j++) {
@@ -769,17 +862,17 @@ action_show_dnssl(void *msg)
{
struct dnssl *dns;
struct dnssl_addr *dna;
- u_int16_t *dns_cnt;
- u_int16_t *dna_cnt;
+ uint16_t *dns_cnt;
+ uint16_t *dna_cnt;
int i;
int j;
char *p;
- u_int32_t ltime;
+ uint32_t ltime;
char hbuf[NI_MAXHOST];
char ssbuf[SSBUFLEN];
p = msg;
- dns_cnt = (u_int16_t *)p;
+ dns_cnt = (uint16_t *)p;
p += sizeof(*dns_cnt);
if (*dns_cnt > 0) {
@@ -788,7 +881,7 @@ action_show_dnssl(void *msg)
ltime = dns->dn_ltime;
p += sizeof(*dns);
- dna_cnt = (u_int16_t *)p;
+ dna_cnt = (uint16_t *)p;
p += sizeof(*dna_cnt);
if (*dna_cnt > 0)
for (j = 0; j < *dna_cnt; j++) {
OpenPOWER on IntegriCloud