HEADS UP: s/time_second/time_uptime/ in sys/netinet6

From: Hiroki Sato <hrs_at_FreeBSD.org>
Date: Tue, 06 Aug 2013 05:30:57 +0900 (JST)
Hi,

 I just wanted to let you know that data structures in sys/netinet6
 now uses time_uptime instead of time_second.  This should not be
 user-visible, but if you notice there is something wrong with IPv6
 after r253970, please let me know.  Please do not forget to update
 rtsold(8), rtadvd(8), and ndp(8) together when you compile a new
 kernel.

-- Hiroki

attached mail follows:


Author: hrs
Date: Mon Aug  5 20:13:02 2013
New Revision: 253970
URL: http://svnweb.freebsd.org/changeset/base/253970

Log:
  - Use time_uptime instead of time_second in data structures for
    PF_INET6 in kernel.  This fixes various malfunction when the wall time
    clock is changed.  Bump __FreeBSD_version to 1000041.

  - Use clock_gettime(CLOCK_MONOTONIC_FAST) in userland utilities.

  MFC after:	1 month

Modified:
  head/sys/netinet6/icmp6.c
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6.h
  head/sys/netinet6/ip6_forward.c
  head/sys/netinet6/ip6_id.c
  head/sys/netinet6/ip6_mroute.c
  head/sys/netinet6/nd6.c
  head/sys/netinet6/nd6_rtr.c
  head/sys/sys/param.h
  head/usr.sbin/ndp/ndp.c
  head/usr.sbin/rtadvctl/rtadvctl.c
  head/usr.sbin/rtadvd/config.c
  head/usr.sbin/rtadvd/rrenum.c
  head/usr.sbin/rtadvd/rtadvd.c
  head/usr.sbin/rtadvd/rtadvd.h
  head/usr.sbin/rtadvd/timer.c
  head/usr.sbin/rtadvd/timer.h
  head/usr.sbin/rtadvd/timer_subr.c
  head/usr.sbin/rtadvd/timer_subr.h
  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/sys/netinet6/icmp6.c
==============================================================================
--- head/sys/netinet6/icmp6.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/icmp6.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -1931,8 +1931,8 _at__at_ ni6_store_addrs(struct icmp6_nodeinfo *n
 				ltime = ND6_INFINITE_LIFETIME;
 			else {
 				if (ifa6->ia6_lifetime.ia6t_expire >
-				    time_second)
-					ltime = htonl(ifa6->ia6_lifetime.ia6t_expire - time_second);
+				    time_uptime)
+					ltime = htonl(ifa6->ia6_lifetime.ia6t_expire - time_uptime);
 				else
 					ltime = 0;
 			}

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/in6.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -523,12 +523,12 _at__at_ in6_control(struct socket *so, u_long cm
 		/* sanity for overflow - beware unsigned */
 		lt = &ifr->ifr_ifru.ifru_lifetime;
 		if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME &&
-		    lt->ia6t_vltime + time_second < time_second) {
+		    lt->ia6t_vltime + time_uptime < time_uptime) {
 			error = EINVAL;
 			goto out;
 		}
 		if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME &&
-		    lt->ia6t_pltime + time_second < time_second) {
+		    lt->ia6t_pltime + time_uptime < time_uptime) {
 			error = EINVAL;
 			goto out;
 		}
_at__at_ -632,12 +632,12 _at__at_ in6_control(struct socket *so, u_long cm
 		/* for sanity */
 		if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 			ia->ia6_lifetime.ia6t_expire =
-				time_second + ia->ia6_lifetime.ia6t_vltime;
+				time_uptime + ia->ia6_lifetime.ia6t_vltime;
 		} else
 			ia->ia6_lifetime.ia6t_expire = 0;
 		if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
 			ia->ia6_lifetime.ia6t_preferred =
-				time_second + ia->ia6_lifetime.ia6t_pltime;
+				time_uptime + ia->ia6_lifetime.ia6t_pltime;
 		} else
 			ia->ia6_lifetime.ia6t_preferred = 0;
 		break;
_at__at_ -1140,7 +1140,7 _at__at_ in6_update_ifa(struct ifnet *ifp, struct
 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
 		ia->ia_addr.sin6_family = AF_INET6;
 		ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
-		ia->ia6_createtime = time_second;
+		ia->ia6_createtime = time_uptime;
 		if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
 			/*
 			 * XXX: some functions expect that ifa_dstaddr is not
_at__at_ -1167,7 +1167,7 _at__at_ in6_update_ifa(struct ifnet *ifp, struct
 	}

 	/* update timestamp */
-	ia->ia6_updatetime = time_second;
+	ia->ia6_updatetime = time_uptime;

 	/* set prefix mask */
 	if (ifra->ifra_prefixmask.sin6_len) {
_at__at_ -1217,12 +1217,12 _at__at_ in6_update_ifa(struct ifnet *ifp, struct
 	ia->ia6_lifetime = ifra->ifra_lifetime;
 	if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 		ia->ia6_lifetime.ia6t_expire =
-		    time_second + ia->ia6_lifetime.ia6t_vltime;
+		    time_uptime + ia->ia6_lifetime.ia6t_vltime;
 	} else
 		ia->ia6_lifetime.ia6t_expire = 0;
 	if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
 		ia->ia6_lifetime.ia6t_preferred =
-		    time_second + ia->ia6_lifetime.ia6t_pltime;
+		    time_uptime + ia->ia6_lifetime.ia6t_pltime;
 	} else
 		ia->ia6_lifetime.ia6t_preferred = 0;

_at__at_ -1240,7 +1240,7 _at__at_ in6_update_ifa(struct ifnet *ifp, struct
 	 */
 	if ((ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) {
 		ia->ia6_lifetime.ia6t_pltime = 0;
-		ia->ia6_lifetime.ia6t_preferred = time_second;
+		ia->ia6_lifetime.ia6t_preferred = time_uptime;
 	}
 	/*
 	 * Make the address tentative before joining multicast addresses,

Modified: head/sys/netinet6/in6.h
==============================================================================
--- head/sys/netinet6/in6.h	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/in6.h	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -361,11 +361,11 _at__at_ extern const struct in6_addr in6addr_lin

 #define IFA6_IS_DEPRECATED(a) \
 	((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \
-	 (u_int32_t)((time_second - (a)->ia6_updatetime)) > \
+	 (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
 	 (a)->ia6_lifetime.ia6t_pltime)
 #define IFA6_IS_INVALID(a) \
 	((a)->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME && \
-	 (u_int32_t)((time_second - (a)->ia6_updatetime)) > \
+	 (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
 	 (a)->ia6_lifetime.ia6t_vltime)
 #endif /* _KERNEL */


Modified: head/sys/netinet6/ip6_forward.c
==============================================================================
--- head/sys/netinet6/ip6_forward.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/ip6_forward.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -137,8 +137,8 _at__at_ ip6_forward(struct mbuf *m, int srcrt)
 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
 		IP6STAT_INC(ip6s_cantforward);
 		/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
-		if (V_ip6_log_time + V_ip6_log_interval < time_second) {
-			V_ip6_log_time = time_second;
+		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "from %s to %s nxt %d received on %s\n",
_at__at_ -405,8 +405,8 _at__at_ skip_routing:
 		IP6STAT_INC(ip6s_badscope);
 		in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard);

-		if (V_ip6_log_time + V_ip6_log_interval < time_second) {
-			V_ip6_log_time = time_second;
+		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",

Modified: head/sys/netinet6/ip6_id.c
==============================================================================
--- head/sys/netinet6/ip6_id.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/ip6_id.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -221,7 +221,7 _at__at_ initid(struct randomtab *p)
 	p->ru_g = pmod(p->ru_gen, j, p->ru_n);
 	p->ru_counter = 0;

-	p->ru_reseed = time_second + p->ru_out;
+	p->ru_reseed = time_uptime + p->ru_out;
 	p->ru_msb = p->ru_msb ? 0 : (1U << (p->ru_bits - 1));
 }

_at__at_ -231,7 +231,7 _at__at_ randomid(struct randomtab *p)
 	int i, n;
 	u_int32_t tmp;

-	if (p->ru_counter >= p->ru_max || time_second > p->ru_reseed)
+	if (p->ru_counter >= p->ru_max || time_uptime > p->ru_reseed)
 		initid(p);

 	tmp = arc4random();

Modified: head/sys/netinet6/ip6_mroute.c
==============================================================================
--- head/sys/netinet6/ip6_mroute.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/ip6_mroute.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -1103,8 +1103,8 _at__at_ X_ip6_mforward(struct ip6_hdr *ip6, stru
 	 */
 	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
 		IP6STAT_INC(ip6s_cantforward);
-		if (V_ip6_log_time + V_ip6_log_interval < time_second) {
-			V_ip6_log_time = time_second;
+		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "from %s to %s nxt %d received on %s\n",

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/nd6.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -428,7 +428,7 _at__at_ nd6_llinfo_settimer_locked(struct llentr
 		ln->ln_ntick = 0;
 		canceled = callout_stop(&ln->ln_timer_ch);
 	} else {
-		ln->la_expire = time_second + tick / hz;
+		ln->la_expire = time_uptime + tick / hz;
 		LLE_ADDREF(ln);
 		if (tick > INT_MAX) {
 			ln->ln_ntick = tick - INT_MAX;
_at__at_ -591,7 +591,7 _at__at_ nd6_timer(void *arg)

 	/* expire default router list */
 	TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
-		if (dr->expire && dr->expire < time_second)
+		if (dr->expire && dr->expire < time_uptime)
 			defrtrlist_del(dr);
 	}

_at__at_ -675,7 +675,7 _at__at_ nd6_timer(void *arg)
 		 * prefix is not necessary.
 		 */
 		if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
-		    time_second - pr->ndpr_lastupdate > pr->ndpr_vltime) {
+		    time_uptime - pr->ndpr_lastupdate > pr->ndpr_vltime) {

 			/*
 			 * address expiration and prefix expiration are
_at__at_ -1033,9 +1033,9 _at__at_ nd6_free(struct llentry *ln, int gc)
 			 * XXX: the check for ln_state would be redundant,
 			 *      but we intentionally keep it just in case.
 			 */
-			if (dr->expire > time_second)
+			if (dr->expire > time_uptime)
 				nd6_llinfo_settimer_locked(ln,
-				    (dr->expire - time_second) * hz);
+				    (dr->expire - time_uptime) * hz);
 			else
 				nd6_llinfo_settimer_locked(ln,
 				    (long)V_nd6_gctimer * hz);

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/netinet6/nd6_rtr.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -282,7 +282,7 _at__at_ nd6_ra_input(struct mbuf *m, int off, in
 		dr0.rtlifetime = 0;
 	else
 		dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
-	dr0.expire = time_second + dr0.rtlifetime;
+	dr0.expire = time_uptime + dr0.rtlifetime;
 	dr0.ifp = ifp;
 	/* unspecified or not? (RFC 2461 6.3.4) */
 	if (advreachable) {
_at__at_ -874,7 +874,7 _at__at_ nd6_prelist_add(struct nd_prefixctl *pr,
 		free(new, M_IP6NDP);
 		return(error);
 	}
-	new->ndpr_lastupdate = time_second;
+	new->ndpr_lastupdate = time_uptime;
 	if (newp != NULL)
 		*newp = new;

_at__at_ -998,7 +998,7 _at__at_ prelist_update(struct nd_prefixctl *new,
 			pr->ndpr_vltime = new->ndpr_vltime;
 			pr->ndpr_pltime = new->ndpr_pltime;
 			(void)in6_init_prefix_ltimes(pr); /* XXX error case? */
-			pr->ndpr_lastupdate = time_second;
+			pr->ndpr_lastupdate = time_uptime;
 		}

 		if (new->ndpr_raf_onlink &&
_at__at_ -1136,7 +1136,7 _at__at_ prelist_update(struct nd_prefixctl *new,

 		if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME)
 			remaininglifetime = ND6_INFINITE_LIFETIME;
-		else if (time_second - ifa6->ia6_updatetime >
+		else if (time_uptime - ifa6->ia6_updatetime >
 			 lt6_tmp.ia6t_vltime) {
 			/*
 			 * The case of "invalid" address.  We should usually
_at__at_ -1145,7 +1145,7 _at__at_ prelist_update(struct nd_prefixctl *new,
 			remaininglifetime = 0;
 		} else
 			remaininglifetime = lt6_tmp.ia6t_vltime -
-			    (time_second - ifa6->ia6_updatetime);
+			    (time_uptime - ifa6->ia6_updatetime);

 		/* when not updating, keep the current stored lifetime. */
 		lt6_tmp.ia6t_vltime = remaininglifetime;
_at__at_ -1181,18 +1181,18 _at__at_ prelist_update(struct nd_prefixctl *new,
 			u_int32_t maxvltime, maxpltime;

 			if (V_ip6_temp_valid_lifetime >
-			    (u_int32_t)((time_second - ifa6->ia6_createtime) +
+			    (u_int32_t)((time_uptime - ifa6->ia6_createtime) +
 			    V_ip6_desync_factor)) {
 				maxvltime = V_ip6_temp_valid_lifetime -
-				    (time_second - ifa6->ia6_createtime) -
+				    (time_uptime - ifa6->ia6_createtime) -
 				    V_ip6_desync_factor;
 			} else
 				maxvltime = 0;
 			if (V_ip6_temp_preferred_lifetime >
-			    (u_int32_t)((time_second - ifa6->ia6_createtime) +
+			    (u_int32_t)((time_uptime - ifa6->ia6_createtime) +
 			    V_ip6_desync_factor)) {
 				maxpltime = V_ip6_temp_preferred_lifetime -
-				    (time_second - ifa6->ia6_createtime) -
+				    (time_uptime - ifa6->ia6_createtime) -
 				    V_ip6_desync_factor;
 			} else
 				maxpltime = 0;
_at__at_ -1207,7 +1207,7 _at__at_ prelist_update(struct nd_prefixctl *new,
 			}
 		}
 		ifa6->ia6_lifetime = lt6_tmp;
-		ifa6->ia6_updatetime = time_second;
+		ifa6->ia6_updatetime = time_uptime;
 	}
 	IF_ADDR_RUNLOCK(ifp);
 	if (ia6_match == NULL && new->ndpr_vltime) {
_at__at_ -1988,7 +1988,7 _at__at_ in6_tmpifadd(const struct in6_ifaddr *ia
 	if (ia0->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 		vltime0 = IFA6_IS_INVALID(ia0) ? 0 :
 		    (ia0->ia6_lifetime.ia6t_vltime -
-		    (time_second - ia0->ia6_updatetime));
+		    (time_uptime - ia0->ia6_updatetime));
 		if (vltime0 > V_ip6_temp_valid_lifetime)
 			vltime0 = V_ip6_temp_valid_lifetime;
 	} else
_at__at_ -1996,7 +1996,7 _at__at_ in6_tmpifadd(const struct in6_ifaddr *ia
 	if (ia0->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
 		pltime0 = IFA6_IS_DEPRECATED(ia0) ? 0 :
 		    (ia0->ia6_lifetime.ia6t_pltime -
-		    (time_second - ia0->ia6_updatetime));
+		    (time_uptime - ia0->ia6_updatetime));
 		if (pltime0 > V_ip6_temp_preferred_lifetime - V_ip6_desync_factor){
 			pltime0 = V_ip6_temp_preferred_lifetime -
 			    V_ip6_desync_factor;
_at__at_ -2054,11 +2054,11 _at__at_ in6_init_prefix_ltimes(struct nd_prefix
 	if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
 		ndpr->ndpr_preferred = 0;
 	else
-		ndpr->ndpr_preferred = time_second + ndpr->ndpr_pltime;
+		ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
 	if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
 		ndpr->ndpr_expire = 0;
 	else
-		ndpr->ndpr_expire = time_second + ndpr->ndpr_vltime;
+		ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;

 	return 0;
 }
_at__at_ -2070,7 +2070,7 _at__at_ in6_init_address_ltimes(struct nd_prefix
 	if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
 		lt6->ia6t_expire = 0;
 	else {
-		lt6->ia6t_expire = time_second;
+		lt6->ia6t_expire = time_uptime;
 		lt6->ia6t_expire += lt6->ia6t_vltime;
 	}

_at__at_ -2078,7 +2078,7 _at__at_ in6_init_address_ltimes(struct nd_prefix
 	if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
 		lt6->ia6t_preferred = 0;
 	else {
-		lt6->ia6t_preferred = time_second;
+		lt6->ia6t_preferred = time_uptime;
 		lt6->ia6t_preferred += lt6->ia6t_pltime;
 	}
 }

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/sys/sys/param.h	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -58,7 +58,7 _at__at_
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1000040	/* Master, propagated to newvers */
+#define __FreeBSD_version 1000041	/* Master, propagated to newvers */

 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

Modified: head/usr.sbin/ndp/ndp.c
==============================================================================
--- head/usr.sbin/ndp/ndp.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/ndp/ndp.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -79,7 +79,6 _at__at_
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
-#include <sys/time.h>
 #include <sys/queue.h>

 #include <net/if.h>
_at__at_ -105,6 +104,7 _at__at_
 #include <paths.h>
 #include <err.h>
 #include <stdlib.h>
+#include <time.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include "gmt2local.h"
_at__at_ -125,6 +125,7 _at__at_ static int tflag;
 static int32_t thiszone;	/* time difference with gmt */
 static int s = -1;
 static int repeat = 0;
+static struct timespec ts, ts0;

 char ntop_buf[INET6_ADDRSTRLEN];	/* inet_ntop() */
 char host_buf[NI_MAXHOST];		/* getnameinfo() */
_at__at_ -153,7 +154,7 _at__at_ static void getdefif(void);
 static void setdefif(char *);
 #endif
 static char *sec2str(time_t);
-static void ts_print(const struct timeval *);
+static void ts_print(const struct timespec *);

 #ifdef ICMPV6CTL_ND6_DRLIST
 static char *rtpref_str[] = {
_at__at_ -164,6 +165,16 _at__at_ static char *rtpref_str[] = {
 };
 #endif

+#define	TS_SUB(tsp, usp, vsp)						\
+	do {								\
+		(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;		\
+		(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec;	\
+		if ((vsp)->tv_nsec < 0) {				\
+			(vsp)->tv_sec--;				\
+			(vsp)->tv_nsec += 1000000000L;			\
+		}							\
+	} while (0)
+
 int mode = 0;
 char *arg = NULL;

_at__at_ -172,10 +183,14 _at__at_ main(argc, argv)
 	int argc;
 	char **argv;
 {
+	struct timespec now;
 	int ch;

 	pid = getpid();
 	thiszone = gmt2local(0);
+	clock_gettime(CLOCK_REALTIME_FAST, &now);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
+	TS_SUB(&now, &ts, &ts0);
 	while ((ch = getopt(argc, argv, "acd:f:Ii:nprstA:HPR")) != -1)
 		switch (ch) {
 		case 'a':
_at__at_ -367,7 +382,8 _at__at_ getsocket()
 struct	sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 };
 struct	sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m;
 struct	sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
-int	expire_time, flags, found_entry;
+static time_t expire_time;
+static int flags, found_entry;
 struct	{
 	struct	rt_msghdr m_rtm;
 	char	m_space[512];
_at__at_ -412,10 +428,10 _at__at_ set(argc, argv)
 	flags = expire_time = 0;
 	while (argc-- > 0) {
 		if (strncmp(argv[0], "temp", 4) == 0) {
-			struct timeval time;
+			struct timespec now;

-			gettimeofday(&time, 0);
-			expire_time = time.tv_sec + 20 * 60;
+			clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+			expire_time = now.tv_sec + 20 * 60;
 		} else if (strncmp(argv[0], "proxy", 5) == 0)
 			flags |= RTF_ANNOUNCE;
 		argv++;
_at__at_ -566,7 +582,7 _at__at_ dump(addr, cflag)
 	struct sockaddr_dl *sdl;
 	extern int h_errno;
 	struct in6_nbrinfo *nbi;
-	struct timeval time;
+	struct timespec now;
 	int addrwidth;
 	int llwidth;
 	int ifwidth;
_at__at_ -653,9 +669,9 _at__at_ again:;
 #endif
 			continue;
 		}
-		gettimeofday(&time, 0);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		if (tflag)
-			ts_print(&time);
+			ts_print(&now);

 		addrwidth = strlen(host_buf);
 		if (addrwidth < W_ADDR)
_at__at_ -676,9 +692,9 _at__at_ again:;
 		/* Print neighbor discovery specific informations */
 		nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index, 1);
 		if (nbi) {
-			if (nbi->expire > time.tv_sec) {
+			if (nbi->expire > now.tv_sec) {
 				printf(" %-9.9s",
-				    sec2str(nbi->expire - time.tv_sec));
+				    sec2str(nbi->expire - now.tv_sec));
 			} else if (nbi->expire == 0)
 				printf(" %-9.9s", "permanent");
 			else
_at__at_ -1075,7 +1091,7 _at__at_ rtrlist()
 	char *buf;
 	struct in6_defrouter *p, *ep;
 	size_t l;
-	struct timeval time;
+	struct timespec now;

 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) {
 		err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)");
_at__at_ -1110,18 +1126,18 _at__at_ rtrlist()
 		rtpref = ((p->flags & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff;
 		printf(", pref=%s", rtpref_str[rtpref]);

-		gettimeofday(&time, 0);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		if (p->expire == 0)
 			printf(", expire=Never\n");
 		else
 			printf(", expire=%s\n",
-			    sec2str(p->expire - time.tv_sec));
+			    sec2str(p->expire - now.tv_sec));
 	}
 	free(buf);
 #else
 	struct in6_drlist dr;
 	int s, i;
-	struct timeval time;
+	struct timespec now;

 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
 		err(1, "socket");
_at__at_ -1150,12 +1166,12 _at__at_ rtrlist()
 		printf(", flags=%s%s",
 		    DR.flags & ND_RA_FLAG_MANAGED ? "M" : "",
 		    DR.flags & ND_RA_FLAG_OTHER   ? "O" : "");
-		gettimeofday(&time, 0);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		if (DR.expire == 0)
 			printf(", expire=Never\n");
 		else
 			printf(", expire=%s\n",
-			    sec2str(DR.expire - time.tv_sec));
+			    sec2str(DR.expire - now.tv_sec));
 	}
 #undef DR
 	close(s);
_at__at_ -1171,7 +1187,7 _at__at_ plist()
 	struct in6_prefix *p, *ep, *n;
 	struct sockaddr_in6 *advrtr;
 	size_t l;
-	struct timeval time;
+	struct timespec now;
 	const int niflags = NI_NUMERICHOST;
 	int ninflags = nflag ? NI_NUMERICHOST : 0;
 	char namebuf[NI_MAXHOST];
_at__at_ -1202,7 +1218,7 _at__at_ plist()
 		printf("%s/%d if=%s\n", namebuf, p->prefixlen,
 		    if_indextoname(p->if_index, ifix_buf));

-		gettimeofday(&time, 0);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		/*
 		 * meaning of fields, especially flags, is very different
 		 * by origin.  notify the difference to the users.
_at__at_ -1228,9 +1244,9 _at__at_ plist()
 			printf(", pltime=%lu", (unsigned long)p->pltime);
 		if (p->expire == 0)
 			printf(", expire=Never");
-		else if (p->expire >= time.tv_sec)
+		else if (p->expire >= now.tv_sec)
 			printf(", expire=%s",
-			    sec2str(p->expire - time.tv_sec));
+			    sec2str(p->expire - now.tv_sec));
 		else
 			printf(", expired");
 		printf(", ref=%d", p->refcnt);
_at__at_ -1278,9 +1294,9 _at__at_ plist()
 #else
 	struct in6_prlist pr;
 	int s, i;
-	struct timeval time;
+	struct timespec now;

-	gettimeofday(&time, 0);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &now);

 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
 		err(1, "socket");
_at__at_ -1316,7 +1332,7 _at__at_ plist()
 		printf("%s/%d if=%s\n", namebuf, PR.prefixlen,
 		    if_indextoname(PR.if_index, ifix_buf));

-		gettimeofday(&time, 0);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		/*
 		 * meaning of fields, especially flags, is very different
 		 * by origin.  notify the difference to the users.
_at__at_ -1352,9 +1368,9 _at__at_ plist()
 			printf(", pltime=%lu", PR.pltime);
 		if (PR.expire == 0)
 			printf(", expire=Never");
-		else if (PR.expire >= time.tv_sec)
+		else if (PR.expire >= now.tv_sec)
 			printf(", expire=%s",
-			    sec2str(PR.expire - time.tv_sec));
+			    sec2str(PR.expire - now.tv_sec));
 		else
 			printf(", expired");
 #ifdef NDPRF_ONLINK
_at__at_ -1577,15 +1593,15 _at__at_ sec2str(total)
  * from tcpdump/util.c
  */
 static void
-ts_print(tvp)
-	const struct timeval *tvp;
+ts_print(tsp)
+	const struct timespec *tsp;
 {
 	int s;

 	/* Default */
-	s = (tvp->tv_sec + thiszone) % 86400;
+	s = (tsp->tv_sec + thiszone + ts0.tv_sec) % 86400;
 	(void)printf("%02d:%02d:%02d.%06u ",
-	    s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
+	    s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tsp->tv_nsec / 1000);
 }

 #undef NEXTADDR

Modified: head/usr.sbin/rtadvctl/rtadvctl.c
==============================================================================
--- head/usr.sbin/rtadvctl/rtadvctl.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvctl/rtadvctl.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -55,6 +55,7 _at__at_
 #include <stdlib.h>
 #include <stdarg.h>
 #include <syslog.h>
+#include <time.h>
 #include <err.h>

 #include "pathnames.h"
_at__at_ -416,6 +417,7 _at__at_ action_show(int argc, char **argv)
 	char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")];
 	char ssbuf[SSBUFLEN];

+	struct timespec now, ts0, ts;
 	struct ctrl_msg_pl cp;
 	struct ifinfo *ifi;
 	TAILQ_HEAD(, ifinfo) ifl = TAILQ_HEAD_INITIALIZER(ifl);
_at__at_ -464,6 +466,10 _at__at_ action_show(int argc, char **argv)
 		}
 	}

+	clock_gettime(CLOCK_REALTIME_FAST, &now);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
+	TS_SUB(&now, &ts, &ts0);
+
 	TAILQ_FOREACH(ifi, &ifl, ifi_next) {
 		struct ifinfo *ifi_s;
 		struct rtadvd_timer *rat;
_at__at_ -615,12 +621,20 _at__at_ action_show(int argc, char **argv)

 			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));
+		printf("\tNext RA send: ");
+		if (rat == NULL)
+			printf("never\n");
+		else {
+			ts.tv_sec = rat->rat_tm.tv_sec + ts0.tv_sec;
+			printf("%s", ctime(&ts.tv_sec));
+		}
+		printf("\tLast RA send: ");
+		if (ifi_s->ifi_ra_lastsent.tv_sec == 0)
+			printf("never\n");
+		else {
+			ts.tv_sec = ifi_s->ifi_ra_lastsent.tv_sec + ts0.tv_sec;
+			printf("%s", ctime(&ts.tv_sec));
+		}
 		if (rai->rai_clockskew)
 			printf("\tClock skew: %" PRIu16 "sec\n",
 			    rai->rai_clockskew);
_at__at_ -747,9 +761,9 _at__at_ action_show_prefix(struct prefix *pfx)
 {
 	char ntopbuf[INET6_ADDRSTRLEN];
 	char ssbuf[SSBUFLEN];
-	struct timeval now;
+	struct timespec now;

-	gettimeofday(&now, NULL);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 	printf("\t  %s/%d", inet_ntop(AF_INET6, &pfx->pfx_prefix,
 		ntopbuf, sizeof(ntopbuf)), pfx->pfx_prefixlen);

_at__at_ -800,7 +814,7 _at__at_ action_show_prefix(struct prefix *pfx)
 		printf("<none>");

 	if (pfx->pfx_timer) {
-		struct timeval *rest;
+		struct timespec *rest;

 		rest = rtadvd_timer_rest(pfx->pfx_timer);
 		if (rest) { /* XXX: what if not? */

Modified: head/usr.sbin/rtadvd/config.c
==============================================================================
--- head/usr.sbin/rtadvd/config.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvd/config.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -34,7 +34,6 _at__at_
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
-#include <sys/time.h>

 #include <net/if.h>
 #include <net/if_var.h>
_at__at_ -58,6 +57,7 _at__at_
 #include <string.h>
 #include <search.h>
 #include <stdlib.h>
+#include <time.h>
 #include <unistd.h>
 #include <ifaddrs.h>

_at__at_ -563,8 +563,9 _at__at_ getconfig(struct ifinfo *ifi)

 		makeentry(entbuf, sizeof(entbuf), i, "vltimedecr");
 		if (agetflag(entbuf)) {
-			struct timeval now;
-			gettimeofday(&now, 0);
+			struct timespec now;
+
+			clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 			pfx->pfx_vltimeexpire =
 				now.tv_sec + pfx->pfx_validlifetime;
 		}
_at__at_ -583,8 +584,9 _at__at_ getconfig(struct ifinfo *ifi)

 		makeentry(entbuf, sizeof(entbuf), i, "pltimedecr");
 		if (agetflag(entbuf)) {
-			struct timeval now;
-			gettimeofday(&now, 0);
+			struct timespec now;
+
+			clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 			pfx->pfx_pltimeexpire =
 			    now.tv_sec + pfx->pfx_preflifetime;
 		}
_at__at_ -1164,7 +1166,7 _at__at_ delete_prefix(struct prefix *pfx)
 void
 invalidate_prefix(struct prefix *pfx)
 {
-	struct timeval timo;
+	struct timespec timo;
 	struct rainfo *rai;
 	struct ifinfo *ifi;
 	char ntopbuf[INET6_ADDRSTRLEN];
_at__at_ -1191,7 +1193,7 _at__at_ invalidate_prefix(struct prefix *pfx)
 		delete_prefix(pfx);
 	}
 	timo.tv_sec = prefix_timo;
-	timo.tv_usec = 0;
+	timo.tv_nsec = 0;
 	rtadvd_set_timer(&timo, pfx->pfx_timer);
 }

_at__at_ -1415,7 +1417,7 _at__at_ make_packet(struct rainfo *rai)

 	TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
 		uint32_t vltime, pltime;
-		struct timeval now;
+		struct timespec now;

 		ndopt_pi = (struct nd_opt_prefix_info *)buf;
 		ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
_at__at_ -1432,7 +1434,7 _at__at_ make_packet(struct rainfo *rai)
 			vltime = 0;
 		else {
 			if (pfx->pfx_vltimeexpire || pfx->pfx_pltimeexpire)
-				gettimeofday(&now, NULL);
+				clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 			if (pfx->pfx_vltimeexpire == 0)
 				vltime = pfx->pfx_validlifetime;
 			else

Modified: head/usr.sbin/rtadvd/rrenum.c
==============================================================================
--- head/usr.sbin/rtadvd/rrenum.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvd/rrenum.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -49,6 +49,7 _at__at_
 #include <netdb.h>
 #include <string.h>
 #include <stdlib.h>
+#include <time.h>
 #include <syslog.h>
 #include "rtadvd.h"
 #include "rrenum.h"
_at__at_ -215,7 +216,7 _at__at_ do_use_prefix(int len, struct rr_pco_mat
 			rai = ifi->ifi_rainfo;

 			TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
-				struct timeval now;
+				struct timespec now;

 				if (prefix_match(&pfx->pfx_prefix,
 				    pfx->pfx_prefixlen, &rpm->rpm_prefix,
_at__at_ -226,14 +227,16 _at__at_ do_use_prefix(int len, struct rr_pco_mat
 					pfx->pfx_preflifetime =
 					    ntohl(rpu->rpu_pltime);
 					if (irr->irr_rrf_decrvalid) {
-						gettimeofday(&now, 0);
+						clock_gettime(CLOCK_MONOTONIC_FAST,
+						    &now);
 						pfx->pfx_vltimeexpire =
 						    now.tv_sec +
 						    pfx->pfx_validlifetime;
 					} else
 						pfx->pfx_vltimeexpire = 0;
 					if (irr->irr_rrf_decrprefd) {
-						gettimeofday(&now, 0);
+						clock_gettime(CLOCK_MONOTONIC_FAST,
+						    &now);
 						pfx->pfx_pltimeexpire =
 						    now.tv_sec +
 						    pfx->pfx_preflifetime;

Modified: head/usr.sbin/rtadvd/rtadvd.c
==============================================================================
--- head/usr.sbin/rtadvd/rtadvd.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvd/rtadvd.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -35,7 +35,6 _at__at_
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
-#include <sys/time.h>
 #include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
_at__at_ -179,7 +178,7 _at__at_ int
 main(int argc, char *argv[])
 {
 	struct pollfd set[PFD_MAX];
-	struct timeval *timeout;
+	struct timespec *timeout;
 	int i, ch;
 	int fflag = 0, logopt;
 	int error;
_at__at_ -331,7 +330,7 _at__at_ main(int argc, char *argv[])
 			    "<%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 / 1000);
 		} else {
 			syslog(LOG_DEBUG,
 			    "<%s> there's no timer. waiting for inputs",
_at__at_ -339,7 +338,7 _at__at_ main(int argc, char *argv[])
 		}
 		if ((i = poll(set, sizeof(set)/sizeof(set[0]),
 			    timeout ? (timeout->tv_sec * 1000 +
-				timeout->tv_usec / 1000) : INFTIM)) < 0) {
+				timeout->tv_nsec / 1000 / 1000) : INFTIM)) < 0) {

 			/* EINTR would occur if a signal was delivered */
 			if (errno != EINTR)
_at__at_ -432,7 +431,7 _at__at_ rtadvd_shutdown(void)
 		if (ifi->ifi_ra_timer == NULL)
 			continue;
 		if (ifi->ifi_ra_lastsent.tv_sec == 0 &&
-		    ifi->ifi_ra_lastsent.tv_usec == 0 &&
+		    ifi->ifi_ra_lastsent.tv_nsec == 0 &&
 		    ifi->ifi_ra_timer != NULL) {
 			/*
 			 * When RA configured but never sent,
_at__at_ -1006,7 +1005,7 _at__at_ static void
 set_short_delay(struct ifinfo *ifi)
 {
 	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;

 	if (ifi->ifi_ra_timer == NULL)
 		return;
_at__at_ -1023,9 +1022,9 _at__at_ set_short_delay(struct ifinfo *ifi)
 	delay = random() % MAX_RA_DELAY_TIME;
 #endif
 	interval.tv_sec = 0;
-	interval.tv_usec = delay;
+	interval.tv_nsec = delay * 1000;
 	rest = rtadvd_timer_rest(ifi->ifi_ra_timer);
-	if (TIMEVAL_LT(rest, &interval)) {
+	if (TS_CMP(rest, &interval, <)) {
 		syslog(LOG_DEBUG, "<%s> random delay is larger than "
 		    "the rest of the current timer", __func__);
 		interval = *rest;
_at__at_ -1038,13 +1037,13 _at__at_ set_short_delay(struct ifinfo *ifi)
 	 * MIN_DELAY_BETWEEN_RAS plus the random value after the
 	 * previous advertisement was sent.
 	 */
-	gettimeofday(&now, NULL);
-	TIMEVAL_SUB(&now, &ifi->ifi_ra_lastsent, &tm_tmp);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+	TS_SUB(&now, &ifi->ifi_ra_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 (TS_CMP(&tm_tmp, &min_delay, <)) {
+		TS_SUB(&min_delay, &tm_tmp, &min_delay);
+		TS_ADD(&min_delay, &interval, &interval);
 	}
 	rtadvd_set_timer(&interval, ifi->ifi_ra_timer);
 }
_at__at_ -1242,7 +1241,7 _at__at_ prefix_check(struct nd_opt_prefix_info *
 	int inconsistent = 0;
 	char ntopbuf[INET6_ADDRSTRLEN];
 	char prefixbuf[INET6_ADDRSTRLEN];
-	struct timeval now;
+	struct timespec now;

 #if 0				/* impossible */
 	if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
_at__at_ -1285,7 +1284,7 _at__at_ 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_FAST, &now);
 		preferred_time += now.tv_sec;

 		if (!pfx->pfx_timer && rai->rai_clockskew &&
_at__at_ -1318,7 +1317,7 _at__at_ prefix_check(struct nd_opt_prefix_info *

 	valid_time = ntohl(pinfo->nd_opt_pi_valid_time);
 	if (pfx->pfx_vltimeexpire) {
-		gettimeofday(&now, NULL);
+		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
 		valid_time += now.tv_sec;

 		if (!pfx->pfx_timer && rai->rai_clockskew &&
_at__at_ -1784,7 +1783,7 _at__at_ ra_output(struct ifinfo *ifi)
 	}

 	/* update timestamp */
-	gettimeofday(&ifi->ifi_ra_lastsent, NULL);
+	clock_gettime(CLOCK_MONOTONIC_FAST, &ifi->ifi_ra_lastsent);

 	/* update counter */
 	ifi->ifi_rs_waitcount = 0;
_at__at_ -1866,7 +1865,7 _at__at_ ra_timeout(void *arg)

 /* update RA timer */
 void
-ra_timer_update(void *arg, struct timeval *tm)
+ra_timer_update(void *arg, struct timespec *tm)
 {
 	uint16_t interval;
 	struct rainfo *rai;
_at__at_ -1916,12 +1915,12 _at__at_ ra_timer_update(void *arg, struct timeva
 	}

 	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__, ifi->ifi_ifname,
-	    (long int)tm->tv_sec, (long int)tm->tv_usec);
+	    (long int)tm->tv_sec, (long int)tm->tv_nsec / 1000);

 	return;
 }

Modified: head/usr.sbin/rtadvd/rtadvd.h
==============================================================================
--- head/usr.sbin/rtadvd/rtadvd.h	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvd/rtadvd.h	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -270,7 +270,7 _at__at_ struct	ifinfo {
 	uint32_t	ifi_burstinterval;
 	struct rtadvd_timer	*ifi_ra_timer;
 	/* timestamp when the latest RA was sent */
-	struct timeval		ifi_ra_lastsent;
+	struct timespec		ifi_ra_lastsent;
 	uint16_t	ifi_rs_waitcount;

 	/* statistics */
_at__at_ -286,7 +286,7 _at__at_ extern TAILQ_HEAD(ifilist_head_t, ifinfo
 extern char *mcastif;

 struct rtadvd_timer	*ra_timeout(void *);
-void			ra_timer_update(void *, struct timeval *);
+void			ra_timer_update(void *, struct timespec *);
 void			ra_output(struct ifinfo *);

 int			prefix_match(struct in6_addr *, int,

Modified: head/usr.sbin/rtadvd/timer.c
==============================================================================
--- head/usr.sbin/rtadvd/timer.c	Mon Aug  5 19:42:03 2013	(r253969)
+++ head/usr.sbin/rtadvd/timer.c	Mon Aug  5 20:13:02 2013	(r253970)
_at__at_ -31,7 +31,6 _at__at_
  * SUCH DAMAGE.
  */

-#include <sys/time.h>
 #include <sys/queue.h>
 #include <sys/socket.h>

_at__at_ -44,6 +43,7 _at__at_
 #include <stdlib.h>
 #include <string.h>
 #include <search.h>
+#include <time.h>
 #include <netdb.h>

 #include "rtadvd.h"
_at__at_ -52,12 +52,17 _at__at_

 struct rtadvd_timer_head_t ra_timer =
     TAILQ_HEAD_INITIALIZER(ra_timer);
-static struct timeval tm_limit = {0x7fffffff, 0x7fffffff};
-static struct timeval tm_max;
+static struct timespec tm_limit;
+static struct timespec tm_max;

 void
 rtadvd_timer_init(void)
 {
+	/* Generate maximum time in timespec. */
+	memset(&tm_limit.tv_sec, 0xff, sizeof(tm_limit.tv_sec));
+	memset(&tm_limit.tv_nsec, 0xff, sizeof(tm_limit.tv_nsec));
+	tm_limit.tv_sec &= ~(1UL << (sizeof(tm_limit.tv_sec) * 8 - 1));
+	tm_limit.tv_nsec &= ~(1UL << (sizeof(tm_limit.tv_nsec) * 8 - 1));

 	tm_max = tm_limit;
 	TAILQ_INIT(&ra_timer);
_at__at_ -102,7 +107,7 _at__at_ rtadvd_update_timeout_handler(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)
 {

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


Received on Mon Aug 05 2013 - 18:32:06 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:40 UTC