Module Name: src Committed By: roy Date: Fri Jun 5 14:09:21 UTC 2015
Modified Files: src/usr.sbin/rtadvd: config.c dump.c rrenum.c rtadvd.c rtadvd.h timer.c timer.h Log Message: Use clock_gettime(2) instead of gettimeofday(2) so we can use a monotonic clock rather than the wall clock. Use timespec rather than timeval structs to make this transition easier. Kill custom timeval comparison functions in favor of timespeccmp(3). To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/usr.sbin/rtadvd/config.c cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/rtadvd/dump.c \ src/usr.sbin/rtadvd/timer.c cvs rdiff -u -r1.16 -r1.17 src/usr.sbin/rtadvd/rrenum.c cvs rdiff -u -r1.46 -r1.47 src/usr.sbin/rtadvd/rtadvd.c cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/rtadvd/rtadvd.h cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/rtadvd/timer.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/rtadvd/config.c diff -u src/usr.sbin/rtadvd/config.c:1.33 src/usr.sbin/rtadvd/config.c:1.34 --- src/usr.sbin/rtadvd/config.c:1.33 Thu Jan 24 19:55:28 2013 +++ src/usr.sbin/rtadvd/config.c Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: config.c,v 1.33 2013/01/24 19:55:28 christos Exp $ */ +/* $NetBSD: config.c,v 1.34 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: config.c,v 1.93 2005/10/17 14:40:02 suz Exp $ */ /* @@ -444,8 +444,8 @@ getconfig(const char *intface, int exith makeentry(entbuf, sizeof(entbuf), i, "vltimedecr"); if (agetflag(entbuf)) { - struct timeval now; - gettimeofday(&now, 0); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); pfx->vltimeexpire = now.tv_sec + pfx->validlifetime; } @@ -464,8 +464,8 @@ getconfig(const char *intface, int exith makeentry(entbuf, sizeof(entbuf), i, "pltimedecr"); if (agetflag(entbuf)) { - struct timeval now; - gettimeofday(&now, 0); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); pfx->pltimeexpire = now.tv_sec + pfx->preflifetime; } @@ -958,7 +958,7 @@ void invalidate_prefix(struct prefix *prefix) { char ntopbuf[INET6_ADDRSTRLEN]; - struct timeval timo; + struct timespec timo; struct rainfo *rai = prefix->rainfo; if (prefix->timer) { /* sanity check */ @@ -981,7 +981,7 @@ invalidate_prefix(struct prefix *prefix) delete_prefix(prefix); } timo.tv_sec = prefix_timo; - timo.tv_usec = 0; + timo.tv_nsec = 0; rtadvd_set_timer(&timo, prefix->timer); } @@ -1200,7 +1200,7 @@ make_packet(struct rainfo *rainfo) TAILQ_FOREACH(pfx, &rainfo->prefix, next) { uint32_t vltime, pltime; - struct timeval now; + struct timespec now; CHECKLEN(sizeof(*ndopt_pi)); ndopt_pi = (struct nd_opt_prefix_info *)buf; @@ -1218,7 +1218,7 @@ make_packet(struct rainfo *rainfo) vltime = 0; else { if (pfx->vltimeexpire || pfx->pltimeexpire) - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC, &now); if (pfx->vltimeexpire == 0) vltime = pfx->validlifetime; else Index: src/usr.sbin/rtadvd/dump.c diff -u src/usr.sbin/rtadvd/dump.c:1.11 src/usr.sbin/rtadvd/dump.c:1.12 --- src/usr.sbin/rtadvd/dump.c:1.11 Tue Jul 9 09:34:59 2013 +++ src/usr.sbin/rtadvd/dump.c Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: dump.c,v 1.11 2013/07/09 09:34:59 roy Exp $ */ +/* $NetBSD: dump.c,v 1.12 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: dump.c,v 1.34 2004/06/14 05:35:59 itojun Exp $ */ /* @@ -99,9 +99,9 @@ if_dump(void) struct dnssl_domain *dnsd; char *p, len; char prefixbuf[INET6_ADDRSTRLEN]; - struct timeval now; + struct timespec now; - gettimeofday(&now, NULL); /* XXX: unused in most cases */ + clock_gettime(CLOCK_MONOTONIC, &now); /* XXX: unused in most cases */ TAILQ_FOREACH(rai, &ralist, next) { fprintf(fp, "%s:\n", rai->ifname); @@ -198,7 +198,7 @@ if_dump(void) pfx->autoconfflg ? "A" : "", ""); if (pfx->timer) { - struct timeval *rest; + struct timespec *rest; rest = rtadvd_timer_rest(pfx->timer); if (rest) { /* XXX: what if not? */ Index: src/usr.sbin/rtadvd/timer.c diff -u src/usr.sbin/rtadvd/timer.c:1.11 src/usr.sbin/rtadvd/timer.c:1.12 --- src/usr.sbin/rtadvd/timer.c:1.11 Thu Dec 13 15:36:36 2012 +++ src/usr.sbin/rtadvd/timer.c Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: timer.c,v 1.11 2012/12/13 15:36:36 roy Exp $ */ +/* $NetBSD: timer.c,v 1.12 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: timer.c,v 1.11 2005/04/14 06:22:35 suz Exp $ */ /* @@ -33,6 +33,7 @@ #include <sys/queue.h> #include <sys/time.h> +#include <limits.h> #include <unistd.h> #include <syslog.h> #include <stdlib.h> @@ -41,13 +42,8 @@ #include "timer.h" struct rtadvd_timer_head_t ra_timer = TAILQ_HEAD_INITIALIZER(ra_timer); - -#define MILLION 1000000 -#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\ - (t1)->tv_usec == (t2)->tv_usec) - -static struct timeval tm_limit = {0x7fffffff, 0x7fffffff}; -static struct timeval tm_max; +static struct timespec tm_limit = { LONG_MAX, 1000000000L - 1 }; +static struct timespec tm_max; void rtadvd_timer_init(void) @@ -59,7 +55,7 @@ rtadvd_timer_init(void) struct rtadvd_timer * rtadvd_add_timer(struct rtadvd_timer *(*timeout) (void *), - void (*update) (void *, struct timeval *), + void (*update) (void *, struct timespec *), void *timeodata, void *updatedata) { struct rtadvd_timer *newtimer; @@ -101,20 +97,17 @@ rtadvd_remove_timer(struct rtadvd_timer } void -rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer) +rtadvd_set_timer(struct timespec *tm, struct rtadvd_timer *timer) { - struct timeval now; + struct timespec now; /* reset the timer */ - gettimeofday(&now, NULL); - - TIMEVAL_ADD(&now, tm, &timer->tm); + clock_gettime(CLOCK_MONOTONIC, &now); + timespecadd(&now, tm, &timer->tm); - /* update the next expiration time */ - if (TIMEVAL_LT(timer->tm, tm_max)) + /* upate the next expiration time */ + if (timespeccmp(&timer->tm, &tm_max, <)) tm_max = timer->tm; - - return; } /* @@ -122,89 +115,54 @@ rtadvd_set_timer(struct timeval *tm, str * call the expire function for the timer and update the timer. * Return the next interval for select() call. */ -struct timeval * +struct timespec * rtadvd_check_timer(void) { - static struct timeval returnval; - struct timeval now; + static struct timespec returnval; + struct timespec now; struct rtadvd_timer *tm, *tmn; - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC, &now); tm_max = tm_limit; TAILQ_FOREACH_SAFE(tm, &ra_timer, next, tmn) { - if (TIMEVAL_LEQ(tm->tm, now)) { + if (timespeccmp(&tm->tm, &now, <=)) { if ((*tm->expire)(tm->expire_data) == NULL) continue; /* the timer was removed */ if (tm->update) (*tm->update)(tm->update_data, &tm->tm); - TIMEVAL_ADD(&tm->tm, &now, &tm->tm); + timespecadd(&tm->tm, &now, &tm->tm); } - - if (TIMEVAL_LT(tm->tm, tm_max)) + if (timespeccmp(&tm->tm, &tm_max, <)) tm_max = tm->tm; } - if (TIMEVAL_EQUAL(&tm_max, &tm_limit)) { - /* no need to timeout */ + if (timespeccmp(&tm_max, &tm_limit, ==)) return(NULL); - } else if (TIMEVAL_LT(tm_max, now)) { + if (timespeccmp(&tm_max, &now, <)) { /* this may occur when the interval is too small */ - returnval.tv_sec = returnval.tv_usec = 0; + timespecclear(&returnval); } else - TIMEVAL_SUB(&tm_max, &now, &returnval); + timespecsub(&tm_max, &now, &returnval); return(&returnval); } -struct timeval * +struct timespec * rtadvd_timer_rest(struct rtadvd_timer *timer) { - static struct timeval returnval, now; + static struct timespec returnval; + struct timespec now; - gettimeofday(&now, NULL); - if (TIMEVAL_LEQ(timer->tm, now)) { + clock_gettime(CLOCK_MONOTONIC, &now); + if (timespeccmp(&timer->tm, &now, <=)) { syslog(LOG_DEBUG, "<%s> a timer must be expired, but not yet", __func__); - returnval.tv_sec = returnval.tv_usec = 0; + returnval.tv_sec = 0; + returnval.tv_nsec = 0; } else - TIMEVAL_SUB(&timer->tm, &now, &returnval); + timespecsub(&timer->tm, &now, &returnval); return(&returnval); } - -/* result = a + b */ -void -TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result) -{ - long l; - - if ((l = a->tv_usec + b->tv_usec) < MILLION) { - result->tv_usec = l; - result->tv_sec = a->tv_sec + b->tv_sec; - } - else { - result->tv_usec = l - MILLION; - result->tv_sec = a->tv_sec + b->tv_sec + 1; - } -} - -/* - * result = a - b - * XXX: this function assumes that a >= b. - */ -void -TIMEVAL_SUB(struct timeval *a, struct timeval *b, struct timeval *result) -{ - long l; - - if ((l = a->tv_usec - b->tv_usec) >= 0) { - result->tv_usec = l; - result->tv_sec = a->tv_sec - b->tv_sec; - } - else { - result->tv_usec = MILLION + l; - result->tv_sec = a->tv_sec - b->tv_sec - 1; - } -} Index: src/usr.sbin/rtadvd/rrenum.c diff -u src/usr.sbin/rtadvd/rrenum.c:1.16 src/usr.sbin/rtadvd/rrenum.c:1.17 --- src/usr.sbin/rtadvd/rrenum.c:1.16 Fri May 17 07:53:05 2013 +++ src/usr.sbin/rtadvd/rrenum.c Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: rrenum.c,v 1.16 2013/05/17 07:53:05 skrll Exp $ */ +/* $NetBSD: rrenum.c,v 1.17 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: rrenum.c,v 1.14 2004/06/14 05:36:00 itojun Exp $ */ /* @@ -209,7 +209,7 @@ do_use_prefix(int len, struct rr_pco_mat continue; /* non-advertising IF */ TAILQ_FOREACH(pp, &rai->prefix, next) { - struct timeval now; + struct timespec now; if (prefix_match(&pp->prefix, pp->prefixlen, &rpm->rpm_prefix, @@ -218,13 +218,15 @@ do_use_prefix(int len, struct rr_pco_mat pp->validlifetime = ntohl(rpu->rpu_vltime); pp->preflifetime = ntohl(rpu->rpu_pltime); if (irr->irr_rrf_decrvalid) { - gettimeofday(&now, 0); + clock_gettime(CLOCK_MONOTONIC, + &now); pp->vltimeexpire = now.tv_sec + pp->validlifetime; } else pp->vltimeexpire = 0; if (irr->irr_rrf_decrprefd) { - gettimeofday(&now, 0); + clock_gettime(CLOCK_MONOTONIC, + &now); pp->pltimeexpire = now.tv_sec + pp->preflifetime; } else Index: src/usr.sbin/rtadvd/rtadvd.c diff -u src/usr.sbin/rtadvd/rtadvd.c:1.46 src/usr.sbin/rtadvd/rtadvd.c:1.47 --- src/usr.sbin/rtadvd/rtadvd.c:1.46 Thu Feb 27 17:43:02 2014 +++ src/usr.sbin/rtadvd/rtadvd.c Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: rtadvd.c,v 1.46 2014/02/27 17:43:02 joerg Exp $ */ +/* $NetBSD: rtadvd.c,v 1.47 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */ /* @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) { struct pollfd set[2]; - struct timeval *timeout; + struct timespec *timeout; int i, ch; int fflag = 0, logopt; struct passwd *pw; @@ -311,20 +311,20 @@ main(int argc, char *argv[]) getconfig(*argv++, 0); } + /* timer expiration check and reset the timer */ + timeout = rtadvd_check_timer(); + if (do_die) { die(); /*NOTREACHED*/ } - /* timer expiration check and reset the timer */ - timeout = rtadvd_check_timer(); - if (timeout != NULL) { syslog(LOG_DEBUG, "<%s> set timer to %ld:%ld. waiting for " "inputs or timeout", __func__, (long int)timeout->tv_sec, - (long int)timeout->tv_usec); + (long int)timeout->tv_nsec); } else { syslog(LOG_DEBUG, "<%s> there's no timer. waiting for inputs", @@ -332,7 +332,8 @@ main(int argc, char *argv[]) } if ((i = poll(set, 2, timeout ? (timeout->tv_sec * 1000 + - timeout->tv_usec / 1000) : INFTIM)) < 0) { + (timeout->tv_nsec + 999999) / 1000000) : INFTIM)) < 0) + { /* EINTR would occur upon SIGUSR1 for status dump */ if (errno != EINTR) syslog(LOG_ERR, "<%s> poll: %s", @@ -991,7 +992,7 @@ void ra_timer_set_short_delay(struct rainfo *rai) { long delay; /* must not be greater than 1000000 */ - struct timeval interval, now, min_delay, tm_tmp, *rest; + struct timespec interval, now, min_delay, tm_tmp, *rest; /* * Compute a random delay. If the computed value @@ -1002,9 +1003,9 @@ ra_timer_set_short_delay(struct rainfo * */ delay = arc4random() % MAX_RA_DELAY_TIME; interval.tv_sec = 0; - interval.tv_usec = delay; + interval.tv_nsec = delay; rest = rtadvd_timer_rest(rai->timer); - if (TIMEVAL_LT(*rest, interval)) { + if (timespeccmp(rest, &interval, <)) { syslog(LOG_DEBUG, "<%s> random delay is larger than " "the rest of current timer", __func__); interval = *rest; @@ -1017,13 +1018,13 @@ ra_timer_set_short_delay(struct rainfo * * MIN_DELAY_BETWEEN_RAS plus the random value after the * previous advertisement was sent. */ - gettimeofday(&now, NULL); - TIMEVAL_SUB(&now, &rai->lastsent, &tm_tmp); + clock_gettime(CLOCK_MONOTONIC, &now); + timespecsub(&now, &rai->lastsent, &tm_tmp); min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS; - min_delay.tv_usec = 0; - if (TIMEVAL_LT(tm_tmp, min_delay)) { - TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay); - TIMEVAL_ADD(&min_delay, &interval, &interval); + min_delay.tv_nsec = 0; + if (timespeccmp(&tm_tmp, &min_delay, <)) { + timespecsub(&min_delay, &tm_tmp, &min_delay); + timespecadd(&min_delay, &interval, &interval); } rtadvd_set_timer(&interval, rai->timer); } @@ -1199,7 +1200,7 @@ prefix_check(struct nd_opt_prefix_info * struct prefix *pp; int inconsistent = 0; char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN]; - struct timeval now; + struct timespec now; #if 0 /* impossible */ if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION) @@ -1245,7 +1246,7 @@ prefix_check(struct nd_opt_prefix_info * * XXX: can we really expect that all routers on the link * have synchronized clocks? */ - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC, &now); preferred_time += now.tv_sec; if (!pp->timer && rai->clockskew && @@ -1281,7 +1282,7 @@ prefix_check(struct nd_opt_prefix_info * valid_time = ntohl(pinfo->nd_opt_pi_valid_time); if (pp->vltimeexpire) { - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC, &now); valid_time += now.tv_sec; if (!pp->timer && rai->clockskew && @@ -1767,7 +1768,7 @@ ra_output(struct rainfo *rai) rai->raoutput++; /* update timestamp */ - gettimeofday(&rai->lastsent, NULL); + clock_gettime(CLOCK_MONOTONIC, &rai->lastsent); /* reset waiting conter */ rai->waiting = 0; @@ -1796,7 +1797,7 @@ ra_timeout(void *data) /* update RA timer */ void -ra_timer_update(void *data, struct timeval *tm) +ra_timer_update(void *data, struct timespec *tm) { struct rainfo *rai = (struct rainfo *)data; long interval; @@ -1823,12 +1824,12 @@ ra_timer_update(void *data, struct timev interval = MAX_INITIAL_RTR_ADVERT_INTERVAL; tm->tv_sec = interval; - tm->tv_usec = 0; + tm->tv_nsec = 0; syslog(LOG_DEBUG, "<%s> RA timer on %s is set to %ld:%ld", __func__, rai->ifname, - (long int)tm->tv_sec, (long int)tm->tv_usec); + (long int)tm->tv_sec, (long int)tm->tv_nsec); return; } Index: src/usr.sbin/rtadvd/rtadvd.h diff -u src/usr.sbin/rtadvd/rtadvd.h:1.13 src/usr.sbin/rtadvd/rtadvd.h:1.14 --- src/usr.sbin/rtadvd/rtadvd.h:1.13 Tue Jul 9 09:34:59 2013 +++ src/usr.sbin/rtadvd/rtadvd.h Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: rtadvd.h,v 1.13 2013/07/09 09:34:59 roy Exp $ */ +/* $NetBSD: rtadvd.h,v 1.14 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz Exp $ */ /* @@ -63,7 +63,7 @@ extern struct sockaddr_in6 sin6_siteloca #define MAX_INITIAL_RTR_ADVERTISEMENTS 3 #define MAX_FINAL_RTR_ADVERTISEMENTS 3 #define MIN_DELAY_BETWEEN_RAS 3 -#define MAX_RA_DELAY_TIME 500000 /* usec */ +#define MAX_RA_DELAY_TIME 500000000 /* nsec */ #define PREFIX_FROM_KERNEL 1 #define PREFIX_FROM_CONFIG 2 @@ -137,7 +137,7 @@ struct rainfo { /* timer related parameters */ struct rtadvd_timer *timer; int initcounter; /* counter for the first few advertisements */ - struct timeval lastsent; /* timestamp when the latest RA was sent */ + struct timespec lastsent; /* timestamp when the latest RA was sent */ int waiting; /* number of RS waiting for RA */ struct rainfo *leaving; /* the config which is leaving */ struct rainfo *leaving_for; /* the new config to activate */ @@ -188,7 +188,7 @@ struct rainfo { extern TAILQ_HEAD(ralist_head_t, rainfo) ralist; struct rtadvd_timer *ra_timeout(void *); -void ra_timer_update(void *, struct timeval *); +void ra_timer_update(void *, struct timespec *); void ra_timer_set_short_delay(struct rainfo *); int prefix_match(struct in6_addr *, int, struct in6_addr *, int); Index: src/usr.sbin/rtadvd/timer.h diff -u src/usr.sbin/rtadvd/timer.h:1.7 src/usr.sbin/rtadvd/timer.h:1.8 --- src/usr.sbin/rtadvd/timer.h:1.7 Sat Dec 10 19:14:29 2011 +++ src/usr.sbin/rtadvd/timer.h Fri Jun 5 14:09:20 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: timer.h,v 1.7 2011/12/10 19:14:29 roy Exp $ */ +/* $NetBSD: timer.h,v 1.8 2015/06/05 14:09:20 roy Exp $ */ /* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */ /* @@ -30,36 +30,22 @@ * SUCH DAMAGE. */ -/* a < b */ -#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ - (((a).tv_sec == (b).tv_sec) && \ - ((a).tv_usec < (b).tv_usec))) - -/* a <= b */ -#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ - (((a).tv_sec == (b).tv_sec) &&\ - ((a).tv_usec <= (b).tv_usec))) - extern TAILQ_HEAD(rtadvd_timer_head_t, rtadvd_timer) ra_timer; struct rtadvd_timer { TAILQ_ENTRY(rtadvd_timer) next; struct rainfo *rai; - struct timeval tm; + struct timespec tm; struct rtadvd_timer *(*expire) (void *); /* expiration function */ void *expire_data; - void (*update) __P((void *, struct timeval *)); /* update function */ + void (*update)(void *, struct timespec *); /* update function */ void *update_data; }; void rtadvd_timer_init(void); struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*) (void *), - void (*) (void *, struct timeval *), void *, void *); -void rtadvd_set_timer(struct timeval *, struct rtadvd_timer *); + void (*) (void *, struct timespec *), void *, void *); +void rtadvd_set_timer(struct timespec *, struct rtadvd_timer *); void rtadvd_remove_timer(struct rtadvd_timer **); -struct timeval * rtadvd_check_timer(void); -struct timeval * rtadvd_timer_rest(struct rtadvd_timer *); -void TIMEVAL_ADD(struct timeval *, struct timeval *, - struct timeval *); -void TIMEVAL_SUB(struct timeval *, struct timeval *, - struct timeval *); +struct timespec * rtadvd_check_timer(void); +struct timespec * rtadvd_timer_rest(struct rtadvd_timer *);