svn commit: r224144 - in head/usr.sbin: . rtadvctl rtadvd

Hiroki Sato hrs at FreeBSD.org
Sun Jul 17 19:24:54 UTC 2011


Author: hrs
Date: Sun Jul 17 19:24:54 2011
New Revision: 224144
URL: http://svn.freebsd.org/changeset/base/224144

Log:
  - Improve interface list handling.  The rtadvd(8) now supports dynamically-
    added/removed interfaces in a more consistent manner and reloading the
    configuration file.
  
  - Implement burst unsolicited RA sending into the internal RA timer framework
    when AdvSendAdvertisements and/or configuration entries are changed as
    described in RFC 4861 6.2.4.  This fixes issues that make termination of the
    rtadvd(8) daemon take very long time.
  
    An interface now has three internal states, UNCONFIGURED, TRANSITIVE, or
    CONFIGURED, and the burst unsolicited sending happens in TRANSITIVE.
    See rtadvd.h for the details.
  
  - rtadvd(8) now accepts non-existent interfaces as well in the command line.
  
  - Add control socket support and rtadvctl(8) utility to show the RA information
    in rtadvd(8).  Dumping by SIGUSR1 has been removed in favor of it.

Added:
     - copied from r224006, user/hrs/ipv6/usr.sbin/rtadvctl/
  head/usr.sbin/rtadvd/control.c   (contents, props changed)
     - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control.c
     - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control.h
     - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_client.c
     - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_client.h
  head/usr.sbin/rtadvd/control_server.c   (contents, props changed)
     - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_server.c
  head/usr.sbin/rtadvd/control_server.h   (contents, props changed)
     - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_server.h
  head/usr.sbin/rtadvd/timer_subr.c   (contents, props changed)
     - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/timer_subr.c
  head/usr.sbin/rtadvd/timer_subr.h   (contents, props changed)
     - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/timer_subr.h
Directory Properties:
  head/usr.sbin/rtadvctl/   (props changed)
  head/usr.sbin/rtadvd/control.h   (props changed)
  head/usr.sbin/rtadvd/control_client.c   (props changed)
  head/usr.sbin/rtadvd/control_client.h   (props changed)
Deleted:
  head/usr.sbin/rtadvd/dump.c
  head/usr.sbin/rtadvd/dump.h
Modified:
  head/usr.sbin/Makefile
  head/usr.sbin/rtadvctl/Makefile   (contents, props changed)
  head/usr.sbin/rtadvctl/rtadvctl.8   (contents, props changed)
  head/usr.sbin/rtadvctl/rtadvctl.c   (contents, props changed)
  head/usr.sbin/rtadvd/Makefile
  head/usr.sbin/rtadvd/config.c
  head/usr.sbin/rtadvd/config.h
  head/usr.sbin/rtadvd/if.c
  head/usr.sbin/rtadvd/if.h
  head/usr.sbin/rtadvd/pathnames.h
  head/usr.sbin/rtadvd/rrenum.c
  head/usr.sbin/rtadvd/rtadvd.8
  head/usr.sbin/rtadvd/rtadvd.c
  head/usr.sbin/rtadvd/rtadvd.h
  head/usr.sbin/rtadvd/timer.c
  head/usr.sbin/rtadvd/timer.h
Directory Properties:
  head/usr.sbin/rtadvd/   (props changed)

Modified: head/usr.sbin/Makefile
==============================================================================
--- head/usr.sbin/Makefile	Sun Jul 17 18:51:51 2011	(r224143)
+++ head/usr.sbin/Makefile	Sun Jul 17 19:24:54 2011	(r224144)
@@ -178,6 +178,7 @@ SUBDIR+=	ndp
 SUBDIR+=	rip6query
 SUBDIR+=	route6d
 SUBDIR+=	rrenumd
+SUBDIR+=	rtadvctl
 SUBDIR+=	rtadvd
 SUBDIR+=	rtsold
 SUBDIR+=	traceroute6

Modified: head/usr.sbin/rtadvctl/Makefile
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvctl/Makefile	Thu Jul 14 10:09:58 2011	(r224006)
+++ head/usr.sbin/rtadvctl/Makefile	Sun Jul 17 19:24:54 2011	(r224144)
@@ -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>

Modified: head/usr.sbin/rtadvctl/rtadvctl.8
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvctl/rtadvctl.8	Thu Jul 14 10:09:58 2011	(r224006)
+++ head/usr.sbin/rtadvctl/rtadvctl.8	Sun Jul 17 19:24:54 2011	(r224144)
@@ -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 at FreeBSD.org .

Modified: head/usr.sbin/rtadvctl/rtadvctl.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvctl/rtadvctl.c	Thu Jul 14 10:09:58 2011	(r224006)
+++ head/usr.sbin/rtadvctl/rtadvctl.c	Sun Jul 17 19:24:54 2011	(r224144)
@@ -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;
 
-	action_argv = strdup("reload");
-	return(action_propset(action_argv));
+	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);
+	}
+
+	return (error);
 }
 
 static int
@@ -330,7 +373,7 @@ action_echo(int argc __unused, char **ar
 	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 
 	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++) {

Modified: head/usr.sbin/rtadvd/Makefile
==============================================================================
--- head/usr.sbin/rtadvd/Makefile	Sun Jul 17 18:51:51 2011	(r224143)
+++ head/usr.sbin/rtadvd/Makefile	Sun Jul 17 19:24:54 2011	(r224144)
@@ -16,12 +16,13 @@
 
 PROG=	rtadvd
 MAN=	rtadvd.conf.5 rtadvd.8
-SRCS=	rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
+SRCS=	rtadvd.c rrenum.c advcap.c if.c config.c timer.c timer_subr.c	\
+	control.c control_server.c
 
 DPADD=	${LIBUTIL}
 LDADD=	-lutil
 
-CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H -DROUTEINFO
+CFLAGS+= -DHAVE_ARC4RANDOM
 
 WARNS?=	1
 

Modified: head/usr.sbin/rtadvd/config.c
==============================================================================
--- head/usr.sbin/rtadvd/config.c	Sun Jul 17 18:51:51 2011	(r224143)
+++ head/usr.sbin/rtadvd/config.c	Sun Jul 17 19:24:54 2011	(r224144)
@@ -3,6 +3,7 @@
 
 /*
  * Copyright (C) 1998 WIDE Project.
+ * Copyright (C) 2011 Hiroki Sato <hrs at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,6 +53,7 @@
 #include <stdio.h>
 #include <syslog.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <netdb.h>
 #include <string.h>
 #include <search.h>
@@ -130,48 +132,153 @@ dname_labelenc(char *dst, const char *sr
 		var = def;						\
      } while (0)
 
-#define	ELM_MALLOC(p,error_action)					\
-	do {								\
-		p = malloc(sizeof(*p));					\
-		if (p == NULL) {					\
-			syslog(LOG_ERR, "<%s> malloc failed: %s",	\
-			    __func__, strerror(errno));			\
-			error_action;					\
-		}							\
-		memset(p, 0, sizeof(*p));				\
-	} while(0)
+int
+loadconfig_index(int idx)
+{
+	char ifname[IFNAMSIZ];
+
+	syslog(LOG_DEBUG, "<%s> enter", __func__);
+
+	if (if_indextoname(idx, ifname) != NULL)
+		return (loadconfig_ifname(ifname));
+	else
+		return (1);
+}
 
 int
-loadconfig(char *ifl_names[], const int ifl_len)
+loadconfig_ifname(char *ifname)
 {
-	int i;
-	int idx;
-	int error;
+	struct ifinfo *ifi;
+
+	syslog(LOG_DEBUG, "<%s> enter", __func__);
+
+	update_ifinfo(&ifilist, UPDATE_IFINFO_ALL);
+	TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
+		/* NULL means all IFs will be processed. */
+		if (ifname != NULL &&
+		    strcmp(ifi->ifi_ifname, ifname) != 0)
+			continue;
+
+		if (!ifi->ifi_persist) {
+			syslog(LOG_INFO,
+			    "<%s> %s is not a target interface.  "
+			    "Ignored at this moment.", __func__,
+			    ifi->ifi_ifname);
+			continue;
 
-	for (i = 0; i < ifl_len; i++) {
-		idx = if_nametoindex(ifl_names[i]);
-		if (idx == 0) {
+		}
+		if (ifi->ifi_ifindex == 0) {
 			syslog(LOG_ERR,
-			    "<%s> interface %s not found.  "
-			    "Ignored at this moment.", __func__, ifl_names[i]);
+			    "<%s> %s not found.  "
+			    "Ignored at this moment.", __func__,
+			    ifi->ifi_ifname);
 			continue;
 		}
-		syslog(LOG_INFO,
-		    "<%s> loading config for %s.", __func__, ifl_names[i]);
-		error = getconfig(idx);
-		if (error)
+		if (getconfig(ifi) == NULL) {
 			syslog(LOG_ERR,
 			    "<%s> invalid configuration for %s.  "
-			    "Ignored at this moment.", __func__, ifl_names[i]);
+			    "Ignored at this moment.", __func__,
+			    ifi->ifi_ifname);
+			continue;
+		}
 	}
+	return (0);
+}
+
+int
+rm_ifinfo_index(int idx)
+{
+	struct ifinfo *ifi;
 
+	ifi = if_indextoifinfo(idx);
+	if (ifi == NULL) {
+		syslog(LOG_ERR, "<%s>: ifinfo not found (idx=%d)",
+		    __func__, idx);
+		return (-1);
+	}
+
+	return (rm_ifinfo(ifi));
+}
+
+int
+rm_ifinfo(struct ifinfo *ifi)
+{
+	int error;
+
+	syslog(LOG_DEBUG, "<%s> enter (%s).", __func__, ifi->ifi_ifname);
+	switch (ifi->ifi_state) {
+	case IFI_STATE_UNCONFIGURED:
+		return (0);
+		break;
+	default:
+		ifi->ifi_state = IFI_STATE_UNCONFIGURED;
+		syslog(LOG_DEBUG,
+		    "<%s> ifname=%s marked as UNCONFIGURED.",
+		    __func__, ifi->ifi_ifname);
+
+		/* XXX: No MC leaving here becasue index is disappeared */
+
+		/* Inactivate timer */
+		rtadvd_remove_timer(ifi->ifi_ra_timer);
+		ifi->ifi_ra_timer = NULL;
+		break;
+	}
+
+	/* clean up ifi */
+	if (!ifi->ifi_persist) {
+		TAILQ_REMOVE(&ifilist, ifi, ifi_next);
+		syslog(LOG_DEBUG, "<%s>: ifinfo (idx=%d) removed.",
+		    __func__, ifi->ifi_ifindex);
+		free(ifi);
+	} else {
+		/* recreate an empty entry */
+		update_persist_ifinfo(&ifilist, ifi->ifi_ifname);
+		syslog(LOG_DEBUG, "<%s>: ifname=%s is persistent.",
+		    __func__, ifi->ifi_ifname);
+	}
+
+	/* clean up rai if any */
+	switch (ifi->ifi_state) {
+	case IFI_STATE_CONFIGURED:
+		if (ifi->ifi_rainfo != NULL) {
+			error = rm_rainfo(ifi->ifi_rainfo);
+			if (error)
+				return (error);
+			ifi->ifi_rainfo = NULL;
+		}
+		break;
+	case IFI_STATE_TRANSITIVE:
+		if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) {
+			if (ifi->ifi_rainfo != NULL) {
+				error = rm_rainfo(ifi->ifi_rainfo);
+				if (error)
+					return (error);
+				ifi->ifi_rainfo = NULL;
+				ifi->ifi_rainfo_trans = NULL;
+			}
+		} else {
+			if (ifi->ifi_rainfo != NULL) {
+				error = rm_rainfo(ifi->ifi_rainfo);
+				if (error)
+					return (error);
+				ifi->ifi_rainfo = NULL;
+			}
+			if (ifi->ifi_rainfo_trans != NULL) {
+				error = rm_rainfo(ifi->ifi_rainfo_trans);
+				if (error)
+					return (error);
+				ifi->ifi_rainfo_trans = NULL;
+			}
+		}
+	}
+
+	syslog(LOG_DEBUG, "<%s> leave (%s).", __func__, ifi->ifi_ifname);
 	return (0);
 }
 
 int
-rmconfig(int idx)
+rm_rainfo(struct rainfo *rai)
 {
-	struct rainfo *rai;
 	struct prefix *pfx;
 	struct soliciter *sol;
 	struct rdnss *rdn;
@@ -179,26 +286,16 @@ rmconfig(int idx)
 	struct dnssl *dns;
 	struct rtinfo *rti;
 
-	rai = if_indextorainfo(idx);
-	if (rai == NULL) {
-		syslog(LOG_ERR, "<%s>: rainfo not found (idx=%d)",
-		    __func__, idx);
-		return (-1);
-	}
+	syslog(LOG_DEBUG, "<%s>: enter",  __func__);
 
 	TAILQ_REMOVE(&railist, rai, rai_next);
-	syslog(LOG_DEBUG, "<%s>: rainfo (idx=%d) removed.",
-	    __func__, idx);
-
-	/* Free all of allocated memories for this entry. */
-	rtadvd_remove_timer(rai->rai_timer);
+	if (rai->rai_ifinfo != NULL)
+		syslog(LOG_DEBUG, "<%s>: rainfo (idx=%d) removed.",
+		    __func__, rai->rai_ifinfo->ifi_ifindex);
 
 	if (rai->rai_ra_data != NULL)
 		free(rai->rai_ra_data);
 
-	if (rai->rai_sdl != NULL)
-		free(rai->rai_sdl);
-
 	while ((pfx = TAILQ_FIRST(&rai->rai_prefix)) != NULL) {
 		TAILQ_REMOVE(&rai->rai_prefix, pfx, pfx_next);
 		free(pfx);
@@ -224,51 +321,51 @@ rmconfig(int idx)
 		free(rti);
 	}
 	free(rai);
-	
+	syslog(LOG_DEBUG, "<%s>: leave",  __func__);
+
 	return (0);
 }
 
-int
-getconfig(int idx)
+struct ifinfo *
+getconfig(struct ifinfo *ifi)
 {
 	int stat, i;
+	int error;
 	char tbuf[BUFSIZ];
 	struct rainfo *rai;
 	struct rainfo *rai_old;
-	long val;
+	int32_t val;
 	int64_t val64;
 	char buf[BUFSIZ];
 	char *bp = buf;
 	char *addr, *flagstr;
-	char intface[IFNAMSIZ];
 
-	if (if_indextoname(idx, intface) == NULL) {
-		syslog(LOG_ERR, "<%s> invalid index number (%d)",
-		    __func__, idx);
-		return (-1);
-	}
+	if (ifi == NULL)	/* if does not exist */
+		return (NULL);
 
-	TAILQ_FOREACH(rai_old, &railist, rai_next)
-		if (idx == rai_old->rai_ifindex)
-			break;
+	if (ifi->ifi_state == IFI_STATE_TRANSITIVE &&
+	    ifi->ifi_rainfo == NULL) {
+		syslog(LOG_INFO, "<%s> %s is shutting down.  Skipped.",
+		    __func__, ifi->ifi_ifname);
+		return (NULL);
+	}
 
-	if ((stat = agetent(tbuf, intface)) <= 0) {
+	if ((stat = agetent(tbuf, ifi->ifi_ifname)) <= 0) {
 		memset(tbuf, 0, sizeof(tbuf));
 		syslog(LOG_INFO,
 		    "<%s> %s isn't defined in the configuration file"
 		    " or the configuration file doesn't exist."
 		    " Treat it as default",
-		     __func__, intface);
+		     __func__, ifi->ifi_ifname);
 	}
 
 	ELM_MALLOC(rai, exit(1));
 	TAILQ_INIT(&rai->rai_prefix);
-#ifdef ROUTEINFO
 	TAILQ_INIT(&rai->rai_route);
-#endif
 	TAILQ_INIT(&rai->rai_rdnss);
 	TAILQ_INIT(&rai->rai_dnssl);
 	TAILQ_INIT(&rai->rai_soliciter);
+	rai->rai_ifinfo = ifi;
 
 	/* gather on-link prefixes from the network interfaces. */
 	if (agetflag("noifprefix"))
@@ -282,25 +379,12 @@ getconfig(int idx)
 	else
 		rai->rai_advlinkopt = 1;
 	if (rai->rai_advlinkopt) {
-		if ((rai->rai_sdl = if_nametosdl(intface)) == NULL) {
+		if (ifi->ifi_sdl.sdl_type == 0) {
 			syslog(LOG_ERR,
 			    "<%s> can't get information of %s",
-			    __func__, intface);
+			    __func__, ifi->ifi_ifname);
 			goto getconfig_free_rai;
 		}
-		rai->rai_ifindex = rai->rai_sdl->sdl_index;
-	} else
-		rai->rai_ifindex = if_nametoindex(intface);
-	strncpy(rai->rai_ifname, intface, sizeof(rai->rai_ifname));
-	syslog(LOG_DEBUG,
-	    "<%s> ifindex = %d on %s", __func__, rai->rai_ifindex,
-	    rai->rai_ifname);
-
-	if ((rai->rai_phymtu = if_getmtu(intface)) == 0) {
-		rai->rai_phymtu = IPV6_MMTU;
-		syslog(LOG_WARNING,
-		    "<%s> can't get interface mtu of %s. Treat as %d",
-		    __func__, intface, IPV6_MMTU);
 	}
 
 	/*
@@ -309,24 +393,24 @@ getconfig(int idx)
 	MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL);
 	if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) {
 		syslog(LOG_ERR,
-		    "<%s> maxinterval (%ld) on %s is invalid "
+		    "<%s> maxinterval (%" PRIu32 ") on %s is invalid "
 		    "(must be between %u and %u)", __func__, val,
-		    intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
+		    ifi->ifi_ifname, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
 		goto getconfig_free_rai;
 	}
-	rai->rai_maxinterval = (u_int)val;
+	rai->rai_maxinterval = (uint16_t)val;
 
 	MAYHAVE(val, "mininterval", rai->rai_maxinterval/3);
-	if ((u_int)val < MIN_MININTERVAL ||
-	    (u_int)val > (rai->rai_maxinterval * 3) / 4) {
+	if ((uint16_t)val < MIN_MININTERVAL ||
+	    (uint16_t)val > (rai->rai_maxinterval * 3) / 4) {
 		syslog(LOG_ERR,
-		    "<%s> mininterval (%ld) on %s is invalid "
+		    "<%s> mininterval (%" PRIu32 ") on %s is invalid "
 		    "(must be between %d and %d)",
-		    __func__, val, intface, MIN_MININTERVAL,
+		    __func__, val, ifi->ifi_ifname, MIN_MININTERVAL,
 		    (rai->rai_maxinterval * 3) / 4);
 		goto getconfig_free_rai;
 	}
-	rai->rai_mininterval = (u_int)val;
+	rai->rai_mininterval = (uint16_t)val;
 
 	MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
 	rai->rai_hoplimit = val & 0xff;
@@ -359,17 +443,17 @@ getconfig(int idx)
 	rai->rai_rtpref = val & ND_RA_FLAG_RTPREF_MASK;
 	if (rai->rai_rtpref == ND_RA_FLAG_RTPREF_RSV) {
 		syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s",
-		    __func__, rai->rai_rtpref, intface);
+		    __func__, rai->rai_rtpref, ifi->ifi_ifname);
 		goto getconfig_free_rai;
 	}
 
 	MAYHAVE(val, "rltime", rai->rai_maxinterval * 3);
-	if ((u_int)val && ((u_int)val < rai->rai_maxinterval ||
-	    (u_int)val > MAXROUTERLIFETIME)) {
+	if ((uint16_t)val && ((uint16_t)val < rai->rai_maxinterval ||
+	    (uint16_t)val > MAXROUTERLIFETIME)) {
 		syslog(LOG_ERR,
-		    "<%s> router lifetime (%ld) on %s is invalid "
+		    "<%s> router lifetime (%" PRIu32 ") on %s is invalid "
 		    "(must be 0 or between %d and %d)",
-		    __func__, val, intface, rai->rai_maxinterval,
+		    __func__, val, ifi->ifi_ifname, rai->rai_maxinterval,
 		    MAXROUTERLIFETIME);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list