svn commit: r222862 - user/hrs/ipv6/usr.sbin/rtsold

Hiroki Sato hrs at FreeBSD.org
Wed Jun 8 16:06:27 UTC 2011


Author: hrs
Date: Wed Jun  8 16:06:27 2011
New Revision: 222862
URL: http://svn.freebsd.org/changeset/base/222862

Log:
  Merge from HEAD at 222861.

Modified:
  user/hrs/ipv6/usr.sbin/rtsold/dump.c
  user/hrs/ipv6/usr.sbin/rtsold/rtsol.c
  user/hrs/ipv6/usr.sbin/rtsold/rtsold.c
  user/hrs/ipv6/usr.sbin/rtsold/rtsold.h
Directory Properties:
  user/hrs/ipv6/usr.sbin/rtsold/   (props changed)

Modified: user/hrs/ipv6/usr.sbin/rtsold/dump.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/dump.c	Wed Jun  8 16:03:29 2011	(r222861)
+++ user/hrs/ipv6/usr.sbin/rtsold/dump.c	Wed Jun  8 16:06:27 2011	(r222862)
@@ -39,6 +39,7 @@
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/icmp6.h>
+#include <arpa/inet.h>
 
 #include <syslog.h>
 #include <time.h>
@@ -53,14 +54,16 @@ static FILE *fp;
 extern struct ifinfo *iflist;
 
 static void dump_interface_status(void);
-static const char *sec2str(time_t);
 static const char * const ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"};
 
 static void
 dump_interface_status(void)
 {
 	struct ifinfo *ifi;
+	struct rainfo *rai;
+	struct ra_opt *rao;
 	struct timeval now;
+	char ntopbuf[INET6_ADDRSTRLEN];
 
 	gettimeofday(&now, NULL);
 
@@ -91,9 +94,33 @@ dump_interface_status(void)
 			    (int)ifi->timer.tv_sec,
 			    (int)ifi->timer.tv_usec,
 			    (ifi->expire.tv_sec < now.tv_sec) ? "expired"
-			    : sec2str(ifi->expire.tv_sec - now.tv_sec));
+			    : sec2str(&ifi->expire));
 		}
 		fprintf(fp, "  number of valid RAs: %d\n", ifi->racnt);
+
+		TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) {
+			fprintf(fp, "   RA from %s\n",
+			    inet_ntop(AF_INET6, &rai->rai_saddr.sin6_addr,
+				ntopbuf, sizeof(ntopbuf)));
+			TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) {
+				fprintf(fp, "    option: ");
+				switch (rao->rao_type) {
+				case ND_OPT_RDNSS:
+					fprintf(fp, "RDNSS: %s (expire: %s)\n",
+					    (char *)rao->rao_msg,
+					    sec2str(&rao->rao_expire));
+					break;
+				case ND_OPT_DNSSL:
+					fprintf(fp, "DNSSL: %s (expire: %s)\n",
+					    (char *)rao->rao_msg,
+					    sec2str(&rao->rao_expire));
+					break;
+				default:
+					break;
+				}
+			}
+			fprintf(fp, "\n");
+		}
 	}
 }
 
@@ -109,8 +136,8 @@ rtsold_dump_file(const char *dumpfile)
 	fclose(fp);
 }
 
-static const char *
-sec2str(time_t total)
+const char *
+sec2str(const struct timeval *total)
 {
 	static char result[256];
 	int days, hours, mins, secs;
@@ -118,11 +145,19 @@ sec2str(time_t total)
 	char *p = result;
 	char *ep = &result[sizeof(result)];
 	int n;
+	struct timeval now;
+	time_t tsec;
 
-	days = total / 3600 / 24;
-	hours = (total / 3600) % 24;
-	mins = (total / 60) % 60;
-	secs = total % 60;
+	gettimeofday(&now, NULL);
+	tsec  = total->tv_sec;
+	tsec += total->tv_usec / 1000000;
+	tsec -= now.tv_sec;
+	tsec -= now.tv_usec / 1000000;
+
+	days = tsec / 3600 / 24;
+	hours = (tsec / 3600) % 24;
+	mins = (tsec / 60) % 60;
+	secs = tsec % 60;
 
 	if (days) {
 		first = 0;

Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsol.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/rtsol.c	Wed Jun  8 16:03:29 2011	(r222861)
+++ user/hrs/ipv6/usr.sbin/rtsold/rtsol.c	Wed Jun  8 16:06:27 2011	(r222862)
@@ -85,6 +85,7 @@ static const struct sockaddr_in6 sin6_al
 static void call_script(const int, const char *const *, void *);
 static size_t dname_labeldec(char *, size_t, const char *);
 static int safefile(const char *);
+static struct ra_opt *find_raopt(struct rainfo *, int, void *, size_t);
 
 #define	_ARGS_OTHER	otherconf_script, ifi->ifname
 #define	_ARGS_RESADD	resolvconf_script, "-a", ifi->ifname
@@ -240,6 +241,7 @@ rtsol_input(int s)
 	struct icmp6_hdr *icp;
 	struct nd_router_advert *nd_ra;
 	struct cmsghdr *cm;
+	struct rainfo *rai;
 	char *raoptp;
 	char *p;
 	struct in6_addr *addr;
@@ -251,6 +253,8 @@ rtsol_input(int s)
 	char dname[NI_MAXHOST];
 	struct timeval now;
 	struct timeval lifetime;
+	int newent_rai;
+	int newent_rao;
 
 	/* get message.  namelen and controllen must always be initialized. */
 	rcvmhdr.msg_namelen = sizeof(from);
@@ -367,22 +371,20 @@ rtsol_input(int s)
 		ifi->otherconfig = 1;
 		CALL_SCRIPT(OTHER, NULL);
 	}
-
-	/* Initialize ra_opt per-interface structure. */
 	gettimeofday(&now, NULL);
-	if (!TAILQ_EMPTY(&ifi->ifi_ra_opt))
-		while ((rao = TAILQ_FIRST(&ifi->ifi_ra_opt)) != NULL) {
-			if (rao->rao_msg != NULL)
-				free(rao->rao_msg);
-			TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next);
-			free(rao);
-		}
-	else
-		TAILQ_INIT(&ifi->ifi_ra_opt);
+	newent_rai = 0;
+	rai = find_rainfo(ifi, &from);
+	if (rai == NULL) {
+		ELM_MALLOC(rai, exit(1));
+		rai->rai_ifinfo = ifi;
+		TAILQ_INIT(&rai->rai_ra_opt);
+		memcpy(&rai->rai_saddr.sin6_addr, &from.sin6_addr,
+		    sizeof(rai->rai_saddr.sin6_addr));
+		newent_rai = 1;
+	}
 
 #define	RA_OPT_NEXT_HDR(x)	(struct nd_opt_hdr *)((char *)x + \
 				(((struct nd_opt_hdr *)x)->nd_opt_len * 8))
-
 	/* Process RA options. */
 	warnmsg(LOG_DEBUG, __func__, "Processing RA");
 	raoptp = (char *)icp + sizeof(struct nd_router_advert);
@@ -439,25 +441,35 @@ rtsol_input(int s)
 				warnmsg(LOG_DEBUG, __func__, "nsbuf = %s",
 				    nsbuf);
 
-				ELM_MALLOC(rao, break);
-				rao->rao_type = ndo->nd_opt_type;
-				rao->rao_len = strlen(nsbuf);
-				rao->rao_msg = strdup(nsbuf);
-				if (rao->rao_msg == NULL) {
-					warnmsg(LOG_ERR, __func__,
-					    "strdup failed: %s",
-					    strerror(errno));
-					free(rao);
-					addr++;
-					continue;
+				newent_rao = 0;
+				rao = find_raopt(rai, ndo->nd_opt_type, nsbuf,
+				    strlen(nsbuf));
+				if (rao == NULL) {
+					ELM_MALLOC(rao, break);
+					rao->rao_type = ndo->nd_opt_type;
+					rao->rao_len = strlen(nsbuf);
+					rao->rao_msg = strdup(nsbuf);
+					if (rao->rao_msg == NULL) {
+						warnmsg(LOG_ERR, __func__,
+						    "strdup failed: %s",
+						    strerror(errno));
+						free(rao);
+						addr++;
+						continue;
+					}
+					newent_rao = 1;
 				}
 				/* Set expiration timer */
-				memset(&rao->rao_expire, 0, sizeof(rao->rao_expire));
+				memset(&rao->rao_expire, 0,
+				    sizeof(rao->rao_expire));
 				memset(&lifetime, 0, sizeof(lifetime));
-				lifetime.tv_sec = ntohl(rdnss->nd_opt_rdnss_lifetime);
+				lifetime.tv_sec =
+				    ntohl(rdnss->nd_opt_rdnss_lifetime);
 				timeradd(&now, &lifetime, &rao->rao_expire);
 
-				TAILQ_INSERT_TAIL(&ifi->ifi_ra_opt, rao, rao_next);
+				if (newent_rao)
+					TAILQ_INSERT_TAIL(&rai->rai_ra_opt,
+					    rao, rao_next);
 				addr++;
 			}
 			break;
@@ -488,24 +500,35 @@ rtsol_input(int s)
 				warnmsg(LOG_DEBUG, __func__, "dname = %s",
 				    dname);
 
-				ELM_MALLOC(rao, break);
-				rao->rao_type = ndo->nd_opt_type;
-				rao->rao_len = strlen(dname);
-				rao->rao_msg = strdup(dname);
-				if (rao->rao_msg == NULL) {
-					warnmsg(LOG_ERR, __func__,
-					    "strdup failed: %s",
-					    strerror(errno));
-					free(rao);
-					break;
+				newent_rao = 0;
+				rao = find_raopt(rai, ndo->nd_opt_type, dname,
+				    strlen(dname));
+				if (rao == NULL) {
+					ELM_MALLOC(rao, break);
+					rao->rao_type = ndo->nd_opt_type;
+					rao->rao_len = strlen(dname);
+					rao->rao_msg = strdup(dname);
+					if (rao->rao_msg == NULL) {
+						warnmsg(LOG_ERR, __func__,
+						    "strdup failed: %s",
+						    strerror(errno));
+						free(rao);
+						addr++;
+						continue;
+					}
+					newent_rao = 1;
 				}
 				/* Set expiration timer */
-				memset(&rao->rao_expire, 0, sizeof(rao->rao_expire));
+				memset(&rao->rao_expire, 0,
+				    sizeof(rao->rao_expire));
 				memset(&lifetime, 0, sizeof(lifetime));
-				lifetime.tv_sec = ntohl(dnssl->nd_opt_dnssl_lifetime);
+				lifetime.tv_sec =
+				    ntohl(dnssl->nd_opt_dnssl_lifetime);
 				timeradd(&now, &lifetime, &rao->rao_expire);
 
-				TAILQ_INSERT_TAIL(&ifi->ifi_ra_opt, rao, rao_next);
+				if (newent_rao)
+					TAILQ_INSERT_TAIL(&rai->rai_ra_opt,
+					    rao, rao_next);
 				p += len;
 			}
 			break;
@@ -515,6 +538,9 @@ rtsol_input(int s)
 		}
 		raoptp = (char *)RA_OPT_NEXT_HDR(raoptp);
 	}
+	if (newent_rai)
+		TAILQ_INSERT_TAIL(&ifi->ifi_rainfo, rai, rai_next);
+
 	ra_opt_handler(ifi);
 	ifi->racnt++;
 
@@ -539,6 +565,7 @@ int
 ra_opt_handler(struct ifinfo *ifi)
 {
 	struct ra_opt *rao;
+	struct rainfo *rai;
 	struct script_msg *smp1, *smp2, *smp3;
 	struct timeval now;
 	TAILQ_HEAD(, script_msg) sm_rdnss_head =
@@ -550,70 +577,87 @@ ra_opt_handler(struct ifinfo *ifi)
 	dcount = 0;
 	dlen = strlen(resstr_sh_prefix) + strlen(resstr_nl);
 	gettimeofday(&now, NULL);
-	TAILQ_FOREACH(rao, &ifi->ifi_ra_opt, rao_next) {
-		switch (rao->rao_type) {
-		case ND_OPT_RDNSS:
-			if (timercmp(&now, &rao->rao_expire, >)) {
-				warnmsg(LOG_INFO, __func__,
-					"expired rdnss entry: %s",
-					(char *)rao->rao_msg);
-				break;
-			}
-			ELM_MALLOC(smp1, continue);
-			ELM_MALLOC(smp2, goto free1);
-			ELM_MALLOC(smp3, goto free2);
-			smp1->sm_msg = resstr_ns_prefix;
-			TAILQ_INSERT_TAIL(&sm_rdnss_head, smp1, sm_next);
-			smp2->sm_msg = rao->rao_msg;
-			TAILQ_INSERT_TAIL(&sm_rdnss_head, smp2, sm_next);
-			smp3->sm_msg = resstr_nl;
-			TAILQ_INSERT_TAIL(&sm_rdnss_head, smp3, sm_next);
 
-			break;
-		case ND_OPT_DNSSL:
-			if (timercmp(&now, &rao->rao_expire, >)) {
-				warnmsg(LOG_INFO, __func__,
-					"expired dnssl entry: %s",
-					(char *)rao->rao_msg);
+	/*
+	 * All options from multiple RAs with the same or different
+	 * source addresses on a single interface will be gathered and
+	 * handled, not overridden.  [RFC 4861 6.3.4]
+	 */
+	TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) {
+		TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) {
+			switch (rao->rao_type) {
+			case ND_OPT_RDNSS:
+				if (timercmp(&now, &rao->rao_expire, >)) {
+					warnmsg(LOG_INFO, __func__,
+					    "expired rdnss entry: %s",
+					    (char *)rao->rao_msg);
+					break;
+				}
+				ELM_MALLOC(smp1, continue);
+				ELM_MALLOC(smp2, goto free1);
+				ELM_MALLOC(smp3, goto free2);
+				smp1->sm_msg = resstr_ns_prefix;
+				TAILQ_INSERT_TAIL(&sm_rdnss_head, smp1,
+				    sm_next);
+				smp2->sm_msg = rao->rao_msg;
+				TAILQ_INSERT_TAIL(&sm_rdnss_head, smp2,
+				    sm_next);
+				smp3->sm_msg = resstr_nl;
+				TAILQ_INSERT_TAIL(&sm_rdnss_head, smp3,
+				    sm_next);
+				ifi->ifi_rdnss = IFI_DNSOPT_STATE_RECEIVED;
+
 				break;
-			}
-			dcount++;
-			/* Check resolv.conf(5) restrictions. */
-			if (dcount > 6) {
-				warnmsg(LOG_INFO, __func__,
-				    "dnssl entry exceeding maximum count (%d>6)"
-				    ": %s", dcount, (char *)rao->rao_msg);
+			case ND_OPT_DNSSL:
+				if (timercmp(&now, &rao->rao_expire, >)) {
+					warnmsg(LOG_INFO, __func__,
+					    "expired dnssl entry: %s",
+					    (char *)rao->rao_msg);
+					break;
+				}
+				dcount++;
+				/* Check resolv.conf(5) restrictions. */
+				if (dcount > 6) {
+					warnmsg(LOG_INFO, __func__,
+					    "dnssl entry exceeding maximum count (%d>6)"
+					    ": %s", dcount, (char *)rao->rao_msg);
+					break;
+				}
+				if (256 < dlen + strlen(rao->rao_msg) +
+				    strlen(resstr_sp)) {
+					warnmsg(LOG_INFO, __func__,
+					    "dnssl entry exceeding maximum length "
+					    "(>256): %s", (char *)rao->rao_msg);
+					break;
+				}
+				ELM_MALLOC(smp1, continue);
+				ELM_MALLOC(smp2, goto free1);
+				if (TAILQ_EMPTY(&sm_dnssl_head)) {
+					ELM_MALLOC(smp3, goto free2);
+					smp3->sm_msg = resstr_sh_prefix;
+					TAILQ_INSERT_TAIL(&sm_dnssl_head, smp3,
+					    sm_next);
+				}
+				smp1->sm_msg = rao->rao_msg;
+				TAILQ_INSERT_TAIL(&sm_dnssl_head, smp1,
+				    sm_next);
+				smp2->sm_msg = resstr_sp;
+				TAILQ_INSERT_TAIL(&sm_dnssl_head, smp2,
+				    sm_next);
+				dlen += strlen(rao->rao_msg) +
+				    strlen(resstr_sp);
 				break;
-			}
-			if (256 < dlen + strlen(rao->rao_msg) +
-			    strlen(resstr_sp)) {
-				warnmsg(LOG_INFO, __func__,
-				    "dnssl entry exceeding maximum length "
-				    "(>256): %s", (char *)rao->rao_msg);
+
+				ifi->ifi_dnssl = IFI_DNSOPT_STATE_RECEIVED;
+			default:
 				break;
 			}
-			ELM_MALLOC(smp1, continue);
-			ELM_MALLOC(smp2, goto free1);
-			if (TAILQ_EMPTY(&sm_dnssl_head)) {
-				ELM_MALLOC(smp3, goto free2);
-				smp3->sm_msg = resstr_sh_prefix;
-				TAILQ_INSERT_TAIL(&sm_dnssl_head, smp3,
-				    sm_next);
-			}
-			smp1->sm_msg = rao->rao_msg;
-			TAILQ_INSERT_TAIL(&sm_dnssl_head, smp1, sm_next);
-			smp2->sm_msg = resstr_sp;
-			TAILQ_INSERT_TAIL(&sm_dnssl_head, smp2, sm_next);
-			dlen += strlen(rao->rao_msg) + strlen(resstr_sp);
-			break;
-		default:
-			break;
-		}
-		continue;
+			continue;
 free2:
-		free(smp2);
+			free(smp2);
 free1:
-		free(smp1);
+			free(smp1);
+		}
 	}
 	/* Add \n for DNSSL list. */
 	if (!TAILQ_EMPTY(&sm_dnssl_head)) {
@@ -625,10 +669,12 @@ free1:
 
 	if (!TAILQ_EMPTY(&sm_rdnss_head))
 		CALL_SCRIPT(RESADD, &sm_rdnss_head);
-#if 0
-	else
+	else if (ifi->ifi_rdnss == IFI_DNSOPT_STATE_RECEIVED ||
+	    ifi->ifi_dnssl == IFI_DNSOPT_STATE_RECEIVED) {
 		CALL_SCRIPT(RESDEL, NULL);
-#endif
+		ifi->ifi_rdnss = IFI_DNSOPT_STATE_NOINFO;
+		ifi->ifi_dnssl = IFI_DNSOPT_STATE_NOINFO;
+	}
 
 ra_opt_handler_freeit:
 	/* Clear script message queue. */
@@ -638,9 +684,30 @@ ra_opt_handler_freeit:
 			free(smp1);
 		}
 	}
+	if (!TAILQ_EMPTY(&sm_dnssl_head)) {
+		while ((smp1 = TAILQ_FIRST(&sm_dnssl_head)) != NULL) {
+			TAILQ_REMOVE(&sm_dnssl_head, smp1, sm_next);
+			free(smp1);
+		}
+	}
 	return (0);
 }
 
+static struct ra_opt *
+find_raopt(struct rainfo *rai, int type, void *msg, size_t len)
+{
+	struct ra_opt *rao;
+
+	TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) {
+		if (rao->rao_type == type &&
+		    rao->rao_len == strlen(msg) &&
+		    memcmp(rao->rao_msg, msg, len) == 0)
+			break;
+	}
+
+	return (rao);
+}
+
 static void
 call_script(const int argc, const char *const argv[], void *head)
 {

Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsold.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/rtsold.c	Wed Jun  8 16:03:29 2011	(r222861)
+++ user/hrs/ipv6/usr.sbin/rtsold/rtsold.c	Wed Jun  8 16:06:27 2011	(r222862)
@@ -44,6 +44,7 @@
 #include <netinet/in.h>
 #include <netinet/icmp6.h>
 #include <netinet/in_var.h>
+#include <arpa/inet.h>
 
 #include <netinet6/nd6.h>
 
@@ -408,7 +409,9 @@ ifconfig(char *ifname)
 	}
 	memset(ifi, 0, sizeof(*ifi));
 	ifi->sdl = sdl;
-
+	ifi->ifi_rdnss = IFI_DNSOPT_STATE_NOINFO;
+	ifi->ifi_dnssl = IFI_DNSOPT_STATE_NOINFO;
+	TAILQ_INIT(&ifi->ifi_rainfo);
 	strlcpy(ifi->ifname, ifname, sizeof(ifi->ifname));
 
 	/* construct a router solicitation message */
@@ -500,6 +503,19 @@ ifreconfig(char *ifname)
 }
 #endif
 
+struct rainfo *
+find_rainfo(struct ifinfo *ifi, struct sockaddr_in6 *sin6)
+{
+	struct rainfo *rai;
+
+	TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next)
+		if (memcmp(&rai->rai_saddr.sin6_addr, &sin6->sin6_addr,
+		    sizeof(rai->rai_saddr.sin6_addr)) == 0)
+			return (rai);
+
+	return (NULL);
+}
+
 struct ifinfo *
 find_ifinfo(int ifindex)
 {
@@ -556,6 +572,7 @@ rtsol_check_timer(void)
 	static struct timeval returnval;
 	struct timeval now, rtsol_timer;
 	struct ifinfo *ifi;
+	struct rainfo *rai;
 	struct ra_opt *rao;
 	int flags;
 
@@ -565,18 +582,21 @@ rtsol_check_timer(void)
 
 	TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) {
 		if (timercmp(&ifi->expire, &now, <=)) {
-			if (dflag > 1)
-				warnmsg(LOG_DEBUG, __func__,
-				    "timer expiration on %s, "
-				    "state = %d", ifi->ifname,
-				    ifi->state);
-
-			/* Remove all RA options. */
-			while ((rao = TAILQ_FIRST(&ifi->ifi_ra_opt)) != NULL) {
-				if (rao->rao_msg != NULL)
-					free(rao->rao_msg);
-				TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next);
-				free(rao);
+			warnmsg(LOG_DEBUG, __func__, "timer expiration on %s, "
+			    "state = %d", ifi->ifname, ifi->state);
+
+			while((rai = TAILQ_FIRST(&ifi->ifi_rainfo)) != NULL) {
+				/* Remove all RA options. */
+				TAILQ_REMOVE(&ifi->ifi_rainfo, rai, rai_next);
+				while ((rao = TAILQ_FIRST(&rai->rai_ra_opt)) !=
+				    NULL) {
+					TAILQ_REMOVE(&rai->rai_ra_opt, rao,
+					    rao_next);
+					if (rao->rao_msg != NULL)
+						free(rao->rao_msg);
+					free(rao);
+				}
+				free(rai);
 			}
 			switch (ifi->state) {
 			case IFS_DOWN:
@@ -645,21 +665,27 @@ rtsol_check_timer(void)
 			rtsol_timer_update(ifi);
 		} else {
 			/* Expiration check for RA options. */
-			struct ra_opt *rao_tmp;
 			int expire = 0;
 
-			TAILQ_FOREACH_SAFE(rao, &ifi->ifi_ra_opt, rao_next, rao_tmp) {
-				warnmsg(LOG_DEBUG, __func__,
-					"RA expiration timer: "
-					"type=%d, msg=%s, timer=%ld:%08ld",
-					rao->rao_type, (char *)rao->rao_msg,
-					(long)rao->rao_expire.tv_sec,
-					(long)rao->rao_expire.tv_usec);
-				if (timercmp(&now, &rao->rao_expire, >=)) {
+			TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) {
+				TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) {
 					warnmsg(LOG_DEBUG, __func__,
-						"RA expiration timer: expired.");
-					TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next);
-					expire = 1;
+					    "RA expiration timer: "
+					    "type=%d, msg=%s, expire=%s",
+					    rao->rao_type, (char *)rao->rao_msg,
+						sec2str(&rao->rao_expire));
+					if (timercmp(&now, &rao->rao_expire,
+					    >=)) {
+						warnmsg(LOG_DEBUG, __func__,
+						    "RA expiration timer: "
+						    "expired.");
+						TAILQ_REMOVE(&rai->rai_ra_opt,
+						    rao, rao_next);
+						if (rao->rao_msg != NULL)
+							free(rao->rao_msg);
+						free(rao);
+						expire = 1;
+					}
 				}
 			}
 			if (expire)
@@ -678,9 +704,10 @@ rtsol_check_timer(void)
 	else
 		timersub(&rtsol_timer, &now, &returnval);
 
-	if (dflag > 1)
-		warnmsg(LOG_DEBUG, __func__, "New timer is %ld:%08ld",
-		    (long)returnval.tv_sec, (long)returnval.tv_usec);
+	now.tv_sec += returnval.tv_sec;
+	now.tv_usec += returnval.tv_usec;
+	warnmsg(LOG_DEBUG, __func__, "New timer is %s",
+	    sec2str(&now));
 
 	return (&returnval);
 }
@@ -751,11 +778,10 @@ rtsol_timer_update(struct ifinfo *ifi)
 		gettimeofday(&now, NULL);
 		timeradd(&now, &ifi->timer, &ifi->expire);
 
-		if (dflag > 1)
-			warnmsg(LOG_DEBUG, __func__,
-			    "set timer for %s to %d:%d", ifi->ifname,
-			    (int)ifi->timer.tv_sec,
-			    (int)ifi->timer.tv_usec);
+		now.tv_sec += ifi->timer.tv_sec;
+		now.tv_usec += ifi->timer.tv_usec;
+		warnmsg(LOG_DEBUG, __func__, "set timer for %s to %s",
+		    ifi->ifname, sec2str(&now));
 	}
 
 #undef MILLION

Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsold.h
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/rtsold.h	Wed Jun  8 16:03:29 2011	(r222861)
+++ user/hrs/ipv6/usr.sbin/rtsold/rtsold.h	Wed Jun  8 16:06:27 2011	(r222862)
@@ -46,6 +46,16 @@ struct ra_opt {
 	void		*rao_msg;
 };
 
+TAILQ_HEAD(rainfo_head, ra_opt);
+
+struct rainfo {
+	TAILQ_ENTRY(rainfo)	rai_next;
+
+	struct ifinfo		*rai_ifinfo;
+	struct sockaddr_in6	rai_saddr;
+	TAILQ_HEAD(, ra_opt)	rai_ra_opt;
+};
+
 struct ifinfo {
 	TAILQ_ENTRY(ifinfo)	ifi_next;	/* pointer to the next interface */
 
@@ -64,13 +74,16 @@ struct ifinfo {
 	struct timeval timer;
 	struct timeval expire;
 	int errors;		/* # of errors we've got - detect wedge */
+#define IFI_DNSOPT_STATE_NOINFO		0
+#define IFI_DNSOPT_STATE_RECEIVED     	1
+	int ifi_rdnss;		/* RDNSS option state */
+	int ifi_dnssl;		/* DNSSL option state */
 
 	int racnt;		/* total # of valid RAs it have got */
+	TAILQ_HEAD(, rainfo)	ifi_rainfo;
 
 	size_t rs_datalen;
 	u_char *rs_data;
-
-	TAILQ_HEAD(, ra_opt)   ifi_ra_opt;
 };
 
 /* per interface status */
@@ -118,6 +131,7 @@ extern const char *resolvconf_script;
 extern int ifconfig(char *);
 extern void iflist_init(void);
 struct ifinfo *find_ifinfo(int);
+struct rainfo *find_rainfo(struct ifinfo *, struct sockaddr_in6 *);
 void rtsol_timer_update(struct ifinfo *);
 extern void warnmsg(int, const char *, const char *, ...)
      __attribute__((__format__(__printf__, 3, 4)));
@@ -145,6 +159,7 @@ extern void defrouter_probe(struct ifinf
 
 /* dump.c */
 extern void rtsold_dump_file(const char *);
+extern const char *sec2str(const struct timeval *);
 
 /* rtsock.c */
 extern int rtsock_open(void);


More information about the svn-src-user mailing list