From owner-svn-src-all@FreeBSD.ORG Wed Jun 8 16:03:29 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B48F4106566B; Wed, 8 Jun 2011 16:03:29 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A38E78FC15; Wed, 8 Jun 2011 16:03:29 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p58G3TfT037574; Wed, 8 Jun 2011 16:03:29 GMT (envelope-from hrs@svn.freebsd.org) Received: (from hrs@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p58G3TL5037569; Wed, 8 Jun 2011 16:03:29 GMT (envelope-from hrs@svn.freebsd.org) Message-Id: <201106081603.p58G3TL5037569@svn.freebsd.org> From: Hiroki Sato Date: Wed, 8 Jun 2011 16:03:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222861 - head/usr.sbin/rtsold X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2011 16:03:29 -0000 Author: hrs Date: Wed Jun 8 16:03:29 2011 New Revision: 222861 URL: http://svn.freebsd.org/changeset/base/222861 Log: - Accumulate RA options instead of replacing old ones when a new RA arrived. RFC 4861 6.3.4 clearly defines handling multiple RAs in this way. - RDNSS/DNSSL options from multiple RAs on a single link will be gathered and sent to resolvconf(8). - Call "resolvconf -d" only after at least one RDNSS or DNSSL option is received and then all of them are expired. - The rtsold.dump output now supports displaying a list of the RA options. - Use more human-readable expression for logging values of struct timeval. Discussed with: ume Modified: head/usr.sbin/rtsold/dump.c head/usr.sbin/rtsold/rtsol.c head/usr.sbin/rtsold/rtsold.c head/usr.sbin/rtsold/rtsold.h Modified: head/usr.sbin/rtsold/dump.c ============================================================================== --- head/usr.sbin/rtsold/dump.c Wed Jun 8 16:00:30 2011 (r222860) +++ head/usr.sbin/rtsold/dump.c Wed Jun 8 16:03:29 2011 (r222861) @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -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: head/usr.sbin/rtsold/rtsol.c ============================================================================== --- head/usr.sbin/rtsold/rtsol.c Wed Jun 8 16:00:30 2011 (r222860) +++ head/usr.sbin/rtsold/rtsol.c Wed Jun 8 16:03:29 2011 (r222861) @@ -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: head/usr.sbin/rtsold/rtsold.c ============================================================================== --- head/usr.sbin/rtsold/rtsold.c Wed Jun 8 16:00:30 2011 (r222860) +++ head/usr.sbin/rtsold/rtsold.c Wed Jun 8 16:03:29 2011 (r222861) @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -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: head/usr.sbin/rtsold/rtsold.h ============================================================================== --- head/usr.sbin/rtsold/rtsold.h Wed Jun 8 16:00:30 2011 (r222860) +++ head/usr.sbin/rtsold/rtsold.h Wed Jun 8 16:03:29 2011 (r222861) @@ -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);