Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Aug 2013 17:30:19 +0900 (JST)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        arch@FreeBSD.org
Subject:   suspend/resume time-gap and expiration timers in network stack
Message-ID:  <20130817.173019.1478850854128616078.hrs@allbsd.org>

next in thread | raw e-mail | index | archive | help
----Security_Multipart0(Sat_Aug_17_17_30_19_2013_496)--
Content-Type: Multipart/Mixed;
 boundary="--Next_Part(Sat_Aug_17_17_30_19_2013_036)--"
Content-Transfer-Encoding: 7bit

----Next_Part(Sat_Aug_17_17_30_19_2013_036)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

 I recently committed s/time_second/time_uptime/ replacement in
 sys/netinet6 which was done in sys/netinet some years ago.  It works
 well and should be more robust against time_second deviation (by NTP,
 for example).  However, IPv6 default routers and prefixes do not
 expire as before if the machine is suspended and then resumed after a
 long time, say, 3 days.

 I think the impact is limited because suspend/resume causes to reset
 all of the physical network interfaces in some way, but in some cases
 the decayed entries can persist.  So I would like your comments about
 the following idea to solve this:

 1. Record RTC value upon suspend.

 2. Calculate the time-gap by using the recorded value and the current
    one upon resume.

 3. Store the calculated time-gap in time_uptime_gap variable and use
    (time_uptime + time_uptime_gap) for expiration timers.

 If there is no suspend/resume event, nothing happens.  If any, the
 time-gap is added to the expiration time.  The time_uptime_gap
 variable is always positive, so (time_uptime + time_uptime_gap) never
 goes backwards.

 A experimental patch is attached.  Changes include the following:

====
- Add clock_suspend_stamp() and clock_resume_fixup() functions to
  calculate suspend/resume time-gap.  clock_suspend_stamp() record
  an RTC value just before disabling timer, and clock_resume_fixup()
  store the time-gap into time_uptime_gap variable.  Ideally,
  time_uptime + time_uptime_gap becomes equal to the elapsed time
  since boottime.

- Add time-gap calculation in ACPI suspend/resume.

- Add kern.clock_suspend_stamp and kern.clock_resume_fixup sysctls to
  allow time-gap calculation from userland.  These are write-only, and
  setting them to non-zero calls the functions.  Typically,
  kern.clock_suspend_stamp should be set to 1 just before suspend,
  and kern.clock_resume_fixup should be set to 1 just after resume.
  kern.clock_resume_fixup is idempotent.

- Add TIME_UPTIME_CALED macro.  This is defined as (time_uptime +
  time_uptime_gap).

- Use TIME_UPTIME_CALED for expiration timers in sys/netinet6.
====

 It is not so smart and I do not think it is commit-ready, but it
 helps you to understand what I want to do.  While this implementation
 cares about only ACPI suspend/resume and timers in sys/netinet6, this
 can be applied to VM suspend/resume and sys/net and sys/netinet
 expiration timers like one for ARP table.

-- Hiroki

----Next_Part(Sat_Aug_17_17_30_19_2013_036)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="uptime_gap.20130817-1.diff"

- Add clock_suspend_stamp() and clock_resume_fixup() functions to
  calculate suspend/resume time-gap.  clock_suspend_stamp() record
  an RTC value just before disabling timer, and clock_resume_fixup()
  store the time-gap into time_uptime_gap variable.  Ideally,
  time_uptime + time_uptime_gap becomes equal to the elapsed time
  since boottime.

- Add time-gap calculation in ACPI suspend/resume.

- Add kern.clock_suspend_stamp and kern.clock_resume_fixup sysctls to
  allow time-gap calculation from userland.  These are write-only, and
  setting them to non-zero calls the functions.  Typically,
  kern.clock_suspend_stamp should be set to 1 just before suspend,
  and kern.clock_resume_fixup should be set to 1 just after resume.
  kern.clock_resume_fixup is idempotent.

- Add TIME_UPTIME_CALED macro.  This is defined as (time_uptime +
  time_uptime_gap).

- Use TIME_UPTIME_CALED for expiration timers in sys/netinet6.
====
Index: sys/sys/clock.h
===================================================================
--- sys/sys/clock.h	(revision 254438)
+++ sys/sys/clock.h	(working copy)
@@ -76,6 +76,8 @@ struct clocktime {
 int clock_ct_to_ts(struct clocktime *, struct timespec *);
 void clock_ts_to_ct(struct timespec *, struct clocktime *);
 void clock_register(device_t, long);
+void clock_suspend_stamp(int);
+void clock_resume_fixup(int);

 /*
  * BCD to decimal and decimal to BCD.
Index: sys/sys/time.h
===================================================================
--- sys/sys/time.h	(revision 254438)
+++ sys/sys/time.h	(working copy)
@@ -370,6 +370,8 @@ void	resettodr(void);

 extern volatile time_t	time_second;
 extern volatile time_t	time_uptime;
+extern volatile time_t	time_uptime_gap;
+#define	TIME_UPTIME_CALED	(time_uptime + time_uptime_gap)
 extern struct bintime boottimebin;
 extern struct timeval boottime;
 extern struct bintime tc_tick_bt;
Index: sys/kern/kern_tc.c
===================================================================
--- sys/kern/kern_tc.c	(revision 254438)
+++ sys/kern/kern_tc.c	(working copy)
@@ -106,6 +106,10 @@ int tc_min_ticktock_freq = 1;

 volatile time_t time_second = 1;
 volatile time_t time_uptime = 1;
+volatile time_t time_uptime_gap = 0;
+SYSCTL_LONG(_kern, OID_AUTO, uptime_gap, CTLFLAG_RD,
+    (void *)&time_uptime_gap, 0,
+    "Accumulated time-gap between system suspend and resume");

 struct bintime boottimebin;
 struct timeval boottime;
Index: sys/kern/subr_rtc.c
===================================================================
--- sys/kern/subr_rtc.c	(revision 254438)
+++ sys/kern/subr_rtc.c	(working copy)
@@ -63,10 +63,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 #include <sys/clock.h>
 #include <sys/sysctl.h>
+#include <sys/time.h>
 #ifdef FFCLOCK
 #include <sys/timeffc.h>
 #endif
 #include <sys/timetc.h>
+#include <sys/clock.h>

 #include "clock_if.h"

@@ -73,7 +75,16 @@ __FBSDID("$FreeBSD$");
 static device_t clock_dev = NULL;
 static long clock_res;
 static struct timespec clock_adj;
+static struct timespec ts_suspend;

+static int clock_suspend_stamp_sysctl(SYSCTL_HANDLER_ARGS);
+static int clock_resume_fixup_sysctl(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_kern, OID_AUTO, clock_suspend_stamp, CTLTYPE_INT | CTLFLAG_WR,
+    NULL, 0, clock_suspend_stamp_sysctl, "I",
+    "Record time for kern.uptime_gap calculation");
+SYSCTL_PROC(_kern, OID_AUTO, clock_resume_fixup, CTLTYPE_INT | CTLFLAG_WR,
+    NULL, 0, clock_resume_fixup_sysctl, "I", "Fix up kern.uptime_gap");
+
 /* XXX: should be kern. now, it's no longer machdep.  */
 static int disable_rtc_set;
 SYSCTL_INT(_machdep, OID_AUTO, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set,
@@ -106,6 +117,85 @@ clock_register(device_t dev, long res)	/* res has
 		    (intmax_t)clock_adj.tv_sec, (intmax_t)clock_adj.tv_nsec);
 }

+void
+clock_suspend_stamp(int arg)
+{
+	struct timespec ts;
+	int error;
+
+	if (arg == 0)
+		return;
+	error = CLOCK_GETTIME(clock_dev, &ts);
+	if (error) {
+		printf("warning: clock_gettime failed (%d), the system time "
+		    "upon suspend will be lost\n", error);
+		ts_suspend.tv_sec = 0;
+		ts_suspend.tv_nsec = 0;
+	} else
+		ts_suspend = ts;
+}
+
+static int
+clock_suspend_stamp_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	int error, i;
+
+	error = sysctl_wire_old_buffer(req, sizeof(int));
+	if (error == 0) {
+		i = 0;
+		error = sysctl_handle_int(oidp, &i, 0, req);
+	}
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	clock_suspend_stamp(i);
+	return (0);
+}
+
+void
+clock_resume_fixup(int arg)
+{
+	struct timespec ts;
+	int error;
+
+	if (arg == 0)
+		return;
+	/* When time upon suspend is unavailable, no calibration performed. */
+	if (ts_suspend.tv_sec == 0)
+		return;
+	error = CLOCK_GETTIME(clock_dev, &ts);
+	if (error)
+		printf("warning: clock_gettime failed (%d), the system time "
+		    "upon resume time will be lost\n", error);
+	else {
+		timespecsub(&ts, &ts_suspend);
+		if (ts.tv_sec >= 0) {
+			printf("info: %ld second time-gap detected.\n",
+			    ts.tv_sec);
+			time_uptime_gap += ts.tv_sec;
+		} else
+			printf("warning: negative time-gap (%ld) "
+			    "is detected.\n", ts.tv_sec);
+	}
+	ts_suspend.tv_sec = 0;
+	ts_suspend.tv_nsec = 0;
+}
+
+static int
+clock_resume_fixup_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	int error, i;
+
+	error = sysctl_wire_old_buffer(req, sizeof(int));
+	if (error == 0) {
+		i = 0;
+		error = sysctl_handle_int(oidp, &i, 0, req);
+	}
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	clock_resume_fixup(i);
+	return (0);
+}
+
 /*
  * inittodr and settodr derived from the i386 versions written
  * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>,  reintroduced and
Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c	(revision 254438)
+++ sys/dev/acpica/acpi.c	(working copy)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/bus.h>
+#include <sys/clock.h>
 #include <sys/conf.h>
 #include <sys/ioccom.h>
 #include <sys/reboot.h>
@@ -2742,6 +2743,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int st
 	DELAY(sc->acpi_sleep_delay * 1000000);

     intr = intr_disable();
+    clock_suspend_stamp(1);
     if (state != ACPI_STATE_S1) {
 	sleep_result = acpi_sleep_machdep(sc, state);
 	acpi_wakeup_machdep(sc, state, sleep_result, 0);
@@ -2783,6 +2785,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int st
 	    }
 	}

+	clock_resume_fixup(1);
 	intr_restore(intr);

 	/* call acpi_wakeup_machdep() again with interrupt enabled */
@@ -2797,6 +2800,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int st
     } else {
 	status = AcpiEnterSleepState(state);
 	AcpiLeaveSleepStatePrep(state);
+	clock_resume_fixup(1);
 	intr_restore(intr);
 	if (ACPI_FAILURE(status)) {
 	    device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n",
Index: sys/netinet6/icmp6.c
===================================================================
--- sys/netinet6/icmp6.c	(revision 254438)
+++ sys/netinet6/icmp6.c	(working copy)
@@ -1931,8 +1931,8 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct
 				ltime = ND6_INFINITE_LIFETIME;
 			else {
 				if (ifa6->ia6_lifetime.ia6t_expire >
-				    time_uptime)
-					ltime = htonl(ifa6->ia6_lifetime.ia6t_expire - time_uptime);
+				    TIME_UPTIME_CALED)
+					ltime = htonl(ifa6->ia6_lifetime.ia6t_expire - TIME_UPTIME_CALED);
 				else
 					ltime = 0;
 			}
Index: sys/netinet6/in6.c
===================================================================
--- sys/netinet6/in6.c	(revision 254438)
+++ sys/netinet6/in6.c	(working copy)
@@ -523,12 +523,12 @@ in6_control(struct socket *so, u_long cmd, caddr_t
 		/* sanity for overflow - beware unsigned */
 		lt = &ifr->ifr_ifru.ifru_lifetime;
 		if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME &&
-		    lt->ia6t_vltime + time_uptime < time_uptime) {
+		    lt->ia6t_vltime + TIME_UPTIME_CALED < TIME_UPTIME_CALED) {
 			error = EINVAL;
 			goto out;
 		}
 		if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME &&
-		    lt->ia6t_pltime + time_uptime < time_uptime) {
+		    lt->ia6t_pltime + TIME_UPTIME_CALED < TIME_UPTIME_CALED) {
 			error = EINVAL;
 			goto out;
 		}
@@ -631,13 +631,13 @@ in6_control(struct socket *so, u_long cmd, caddr_t
 		ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
 		/* for sanity */
 		if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
-			ia->ia6_lifetime.ia6t_expire =
-				time_uptime + ia->ia6_lifetime.ia6t_vltime;
+			ia->ia6_lifetime.ia6t_expire = TIME_UPTIME_CALED +
+			    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_uptime + ia->ia6_lifetime.ia6t_pltime;
+			ia->ia6_lifetime.ia6t_preferred = TIME_UPTIME_CALED +
+			    ia->ia6_lifetime.ia6t_pltime;
 		} else
 			ia->ia6_lifetime.ia6t_preferred = 0;
 		break;
@@ -1140,7 +1140,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_alias
 		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_uptime;
+		ia->ia6_createtime = TIME_UPTIME_CALED;
 		if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
 			/*
 			 * XXX: some functions expect that ifa_dstaddr is not
@@ -1167,7 +1167,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_alias
 	}

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

 	/* set prefix mask */
 	if (ifra->ifra_prefixmask.sin6_len) {
@@ -1217,12 +1217,12 @@ in6_update_ifa(struct ifnet *ifp, struct in6_alias
 	ia->ia6_lifetime = ifra->ifra_lifetime;
 	if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 		ia->ia6_lifetime.ia6t_expire =
-		    time_uptime + ia->ia6_lifetime.ia6t_vltime;
+		    TIME_UPTIME_CALED + 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_uptime + ia->ia6_lifetime.ia6t_pltime;
+		    TIME_UPTIME_CALED + ia->ia6_lifetime.ia6t_pltime;
 	} else
 		ia->ia6_lifetime.ia6t_preferred = 0;

@@ -1240,7 +1240,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_alias
 	 */
 	if ((ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) {
 		ia->ia6_lifetime.ia6t_pltime = 0;
-		ia->ia6_lifetime.ia6t_preferred = time_uptime;
+		ia->ia6_lifetime.ia6t_preferred = TIME_UPTIME_CALED;
 	}
 	/*
 	 * Make the address tentative before joining multicast addresses,
Index: sys/netinet6/in6.h
===================================================================
--- sys/netinet6/in6.h	(revision 254438)
+++ sys/netinet6/in6.h	(working copy)
@@ -361,11 +361,11 @@ extern const struct in6_addr in6addr_linklocal_all

 #define IFA6_IS_DEPRECATED(a) \
 	((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \
-	 (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
+	 (u_int32_t)((TIME_UPTIME_CALED - (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_uptime - (a)->ia6_updatetime)) > \
+	 (u_int32_t)((TIME_UPTIME_CALED - (a)->ia6_updatetime)) > \
 	 (a)->ia6_lifetime.ia6t_vltime)
 #endif /* _KERNEL */

Index: sys/netinet6/in6_rmx.c
===================================================================
--- sys/netinet6/in6_rmx.c	(revision 254438)
+++ sys/netinet6/in6_rmx.c	(working copy)
@@ -207,7 +207,7 @@ in6_mtuexpire(struct radix_node *rn, void *rock)
 		panic("rt == NULL in in6_mtuexpire");

 	if (rt->rt_rmx.rmx_expire && !(rt->rt_flags & RTF_PROBEMTU)) {
-		if (rt->rt_rmx.rmx_expire <= time_uptime) {
+		if (rt->rt_rmx.rmx_expire <= TIME_UPTIME_CALED) {
 			rt->rt_flags |= RTF_PROBEMTU;
 		} else {
 			ap->nextstop = lmin(ap->nextstop,
@@ -226,7 +226,7 @@ in6_mtutimo_one(struct radix_node_head *rnh)
 	struct mtuex_arg arg;

 	arg.rnh = rnh;
-	arg.nextstop = time_uptime + MTUTIMO_DEFAULT;
+	arg.nextstop = TIME_UPTIME_CALED + MTUTIMO_DEFAULT;
 	RADIX_NODE_HEAD_LOCK(rnh);
 	rnh->rnh_walktree(rnh, in6_mtuexpire, &arg);
 	RADIX_NODE_HEAD_UNLOCK(rnh);
Index: sys/netinet6/ip6_forward.c
===================================================================
--- sys/netinet6/ip6_forward.c	(revision 254438)
+++ sys/netinet6/ip6_forward.c	(working copy)
@@ -137,8 +137,8 @@ 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_uptime) {
-			V_ip6_log_time = time_uptime;
+		if (V_ip6_log_time + V_ip6_log_interval < TIME_UPTIME_CALED) {
+			V_ip6_log_time = TIME_UPTIME_CALED;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "from %s to %s nxt %d received on %s\n",
@@ -405,8 +405,8 @@ 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_uptime) {
-			V_ip6_log_time = time_uptime;
+		if (V_ip6_log_time + V_ip6_log_interval < TIME_UPTIME_CALED) {
+			V_ip6_log_time = TIME_UPTIME_CALED;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
Index: sys/netinet6/ip6_mroute.c
===================================================================
--- sys/netinet6/ip6_mroute.c	(revision 254438)
+++ sys/netinet6/ip6_mroute.c	(working copy)
@@ -1103,8 +1103,8 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *
 	 */
 	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
 		IP6STAT_INC(ip6s_cantforward);
-		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
-			V_ip6_log_time = time_uptime;
+		if (V_ip6_log_time + V_ip6_log_interval < TIME_UPTIME_CALED) {
+			V_ip6_log_time = TIME_UPTIME_CALED;
 			log(LOG_DEBUG,
 			    "cannot forward "
 			    "from %s to %s nxt %d received on %s\n",
Index: sys/netinet6/nd6.c
===================================================================
--- sys/netinet6/nd6.c	(revision 254441)
+++ sys/netinet6/nd6.c	(working copy)
@@ -428,7 +428,7 @@ nd6_llinfo_settimer_locked(struct llentry *ln, lon
 		ln->ln_ntick = 0;
 		canceled = callout_stop(&ln->ln_timer_ch);
 	} else {
-		ln->la_expire = time_uptime + tick / hz;
+		ln->la_expire = TIME_UPTIME_CALED + tick / hz;
 		LLE_ADDREF(ln);
 		if (tick > INT_MAX) {
 			ln->ln_ntick = tick - INT_MAX;
@@ -591,7 +591,7 @@ nd6_timer(void *arg)

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

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

 			/*
 			 * address expiration and prefix expiration are
@@ -1033,9 +1033,9 @@ 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_uptime)
+			if (dr->expire > TIME_UPTIME_CALED)
 				nd6_llinfo_settimer_locked(ln,
-				    (dr->expire - time_uptime) * hz);
+				    (dr->expire - TIME_UPTIME_CALED) * hz);
 			else
 				nd6_llinfo_settimer_locked(ln,
 				    (long)V_nd6_gctimer * hz);
@@ -1244,7 +1244,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *
 			drl->defrouter[i].flags = dr->flags;
 			drl->defrouter[i].rtlifetime = dr->rtlifetime;
 			drl->defrouter[i].expire = dr->expire +
-			    (time_second - time_uptime);
+			    (time_second - TIME_UPTIME_CALED);
 			drl->defrouter[i].if_index = dr->ifp->if_index;
 			i++;
 		}
@@ -1289,7 +1289,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *
 					oprl->prefix[i].expire =
 					    pr->ndpr_lastupdate +
 					    pr->ndpr_vltime +
-					    (time_second - time_uptime);
+					    (time_second - TIME_UPTIME_CALED);
 				} else
 					oprl->prefix[i].expire = maxexpire;
 			}
@@ -1512,7 +1512,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *
 			nbi->expire = 0;
 		else
 			nbi->expire = ln->la_expire +
-			    (time_second - time_uptime);
+			    (time_second - TIME_UPTIME_CALED);
 		LLE_RUNLOCK(ln);
 		break;
 	}
@@ -2292,7 +2292,7 @@ nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
 			return (error);
 		d.flags = dr->flags;
 		d.rtlifetime = dr->rtlifetime;
-		d.expire = dr->expire + (time_second - time_uptime);
+		d.expire = dr->expire + (time_second - TIME_UPTIME_CALED);
 		d.if_index = dr->ifp->if_index;
 		error = SYSCTL_OUT(req, &d, sizeof(d));
 		if (error != 0)
@@ -2345,7 +2345,7 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS)
 			if (pr->ndpr_vltime < maxexpire - pr->ndpr_lastupdate)
 				p.expire = pr->ndpr_lastupdate +
 				    pr->ndpr_vltime +
-				    (time_second - time_uptime);
+				    (time_second - TIME_UPTIME_CALED);
 			else
 				p.expire = maxexpire;
 		}
Index: sys/netinet6/nd6_rtr.c
===================================================================
--- sys/netinet6/nd6_rtr.c	(revision 254438)
+++ sys/netinet6/nd6_rtr.c	(working copy)
@@ -282,7 +282,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len
 		dr0.rtlifetime = 0;
 	else
 		dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
-	dr0.expire = time_uptime + dr0.rtlifetime;
+	dr0.expire = TIME_UPTIME_CALED + dr0.rtlifetime;
 	dr0.ifp = ifp;
 	/* unspecified or not? (RFC 2461 6.3.4) */
 	if (advreachable) {
@@ -874,7 +874,7 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd
 		free(new, M_IP6NDP);
 		return(error);
 	}
-	new->ndpr_lastupdate = time_uptime;
+	new->ndpr_lastupdate = TIME_UPTIME_CALED;
 	if (newp != NULL)
 		*newp = new;

@@ -998,7 +998,7 @@ prelist_update(struct nd_prefixctl *new, struct nd
 			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_uptime;
+			pr->ndpr_lastupdate = TIME_UPTIME_CALED;
 		}

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

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

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

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

 	return 0;
 }
@@ -2070,7 +2070,7 @@ in6_init_address_ltimes(struct nd_prefix *new, str
 	if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
 		lt6->ia6t_expire = 0;
 	else {
-		lt6->ia6t_expire = time_uptime;
+		lt6->ia6t_expire = TIME_UPTIME_CALED;
 		lt6->ia6t_expire += lt6->ia6t_vltime;
 	}

@@ -2078,7 +2078,7 @@ in6_init_address_ltimes(struct nd_prefix *new, str
 	if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
 		lt6->ia6t_preferred = 0;
 	else {
-		lt6->ia6t_preferred = time_uptime;
+		lt6->ia6t_preferred = TIME_UPTIME_CALED;
 		lt6->ia6t_preferred += lt6->ia6t_pltime;
 	}
 }

----Next_Part(Sat_Aug_17_17_30_19_2013_036)----

----Security_Multipart0(Sat_Aug_17_17_30_19_2013_496)--
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (FreeBSD)

iEYEABECAAYFAlIPNJsACgkQTyzT2CeTzy3olQCcDHleTDL5LIW8oQ/3bGtpVWJD
/hoAoJlQHiiGV+yu87eWGevWYtqKlWLt
=oTkD
-----END PGP SIGNATURE-----

----Security_Multipart0(Sat_Aug_17_17_30_19_2013_496)----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130817.173019.1478850854128616078.hrs>