diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index de1b0e6a8a27..28e731244e72 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1931,8 +1931,8 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, 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; } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index a8930d79d7fe..9d9993091c7c 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -523,12 +523,12 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, /* 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; } @@ -632,12 +632,12 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, /* 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; @@ -1140,7 +1140,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, 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 @@ -1167,7 +1167,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, } /* update timestamp */ - ia->ia6_updatetime = time_second; + ia->ia6_updatetime = time_uptime; /* set prefix mask */ if (ifra->ifra_prefixmask.sin6_len) { @@ -1217,12 +1217,12 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, 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; @@ -1240,7 +1240,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, */ 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, diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 616f1009ad3f..07ba2901bfe2 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -361,11 +361,11 @@ extern const struct in6_addr in6addr_linklocal_allv2routers; #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 */ diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index fa54fe43fc09..2cc274167be3 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -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_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", @@ -405,8 +405,8 @@ ip6_forward(struct mbuf *m, int srcrt) 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", diff --git a/sys/netinet6/ip6_id.c b/sys/netinet6/ip6_id.c index fa7bc64fb0da..cf808061e85c 100644 --- a/sys/netinet6/ip6_id.c +++ b/sys/netinet6/ip6_id.c @@ -221,7 +221,7 @@ 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)); } @@ -231,7 +231,7 @@ 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(); diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index db614ecef198..194aaf5d3d66 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1103,8 +1103,8 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) */ 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", diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 2c27c714cec6..6ad787fd890f 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -428,7 +428,7 @@ nd6_llinfo_settimer_locked(struct llentry *ln, long tick) 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; @@ -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_second) + if (dr->expire && dr->expire < time_uptime) defrtrlist_del(dr); } @@ -675,7 +675,7 @@ 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 @@ -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_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); diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 03d06b423eba..0c8b58765954 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -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_second + dr0.rtlifetime; + dr0.expire = time_uptime + 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_defrouter *dr, free(new, M_IP6NDP); return(error); } - new->ndpr_lastupdate = time_second; + new->ndpr_lastupdate = time_uptime; if (newp != NULL) *newp = new; @@ -998,7 +998,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, 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 && @@ -1136,7 +1136,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, 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 @@ -1145,7 +1145,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, 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; @@ -1181,18 +1181,18 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, 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; @@ -1207,7 +1207,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, } } 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) { @@ -1988,7 +1988,7 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay) 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 @@ -1996,7 +1996,7 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay) 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; @@ -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_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; } @@ -2070,7 +2070,7 @@ in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6) 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; } @@ -2078,7 +2078,7 @@ in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6) 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; } } diff --git a/sys/sys/param.h b/sys/sys/param.h index 20fa2c887844..d425fdc6fa74 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * 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, diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 0449c123841d..ae1fbca78f97 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include @@ -105,6 +104,7 @@ #include #include #include +#include #include #include #include "gmt2local.h" @@ -125,6 +125,7 @@ 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() */ @@ -153,7 +154,7 @@ 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[] = { @@ -164,6 +165,16 @@ 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; @@ -172,10 +183,14 @@ 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': @@ -367,7 +382,8 @@ 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]; @@ -412,10 +428,10 @@ 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++; @@ -566,7 +582,7 @@ 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; @@ -653,9 +669,9 @@ 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) @@ -676,9 +692,9 @@ 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 @@ -1075,7 +1091,7 @@ 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)"); @@ -1110,18 +1126,18 @@ 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"); @@ -1150,12 +1166,12 @@ 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); @@ -1171,7 +1187,7 @@ 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]; @@ -1202,7 +1218,7 @@ 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. @@ -1228,9 +1244,9 @@ 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); @@ -1278,9 +1294,9 @@ 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"); @@ -1316,7 +1332,7 @@ 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. @@ -1352,9 +1368,9 @@ 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 @@ -1577,15 +1593,15 @@ 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 diff --git a/usr.sbin/rtadvctl/rtadvctl.c b/usr.sbin/rtadvctl/rtadvctl.c index adc87b593455..3f225187129a 100644 --- a/usr.sbin/rtadvctl/rtadvctl.c +++ b/usr.sbin/rtadvctl/rtadvctl.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "pathnames.h" @@ -416,6 +417,7 @@ 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); @@ -464,6 +466,10 @@ 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; @@ -615,12 +621,20 @@ 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); @@ -747,9 +761,9 @@ 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); @@ -800,7 +814,7 @@ action_show_prefix(struct prefix *pfx) printf(""); if (pfx->pfx_timer) { - struct timeval *rest; + struct timespec *rest; rest = rtadvd_timer_rest(pfx->pfx_timer); if (rest) { /* XXX: what if not? */ diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index d10829a79be6..bb4aaecf84a7 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include #include @@ -563,8 +563,9 @@ 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; } @@ -583,8 +584,9 @@ 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; } @@ -1164,7 +1166,7 @@ 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]; @@ -1191,7 +1193,7 @@ 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); } @@ -1415,7 +1417,7 @@ 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; @@ -1432,7 +1434,7 @@ 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 diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c index a8fbbf2a3bb0..0c97d98cdc44 100644 --- a/usr.sbin/rtadvd/rrenum.c +++ b/usr.sbin/rtadvd/rrenum.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include "rtadvd.h" #include "rrenum.h" @@ -215,7 +216,7 @@ do_use_prefix(int len, struct rr_pco_match *rpm, 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, @@ -226,14 +227,16 @@ do_use_prefix(int len, struct rr_pco_match *rpm, 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; diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index c3420eff71e3..ba71954085e9 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -179,7 +178,7 @@ 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; @@ -331,7 +330,7 @@ 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", @@ -339,7 +338,7 @@ 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) @@ -432,7 +431,7 @@ 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, @@ -1006,7 +1005,7 @@ 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; @@ -1023,9 +1022,9 @@ 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; @@ -1038,13 +1037,13 @@ 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); } @@ -1242,7 +1241,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo, 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) @@ -1285,7 +1284,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo, * 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 && @@ -1318,7 +1317,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo, 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 && @@ -1784,7 +1783,7 @@ 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; @@ -1866,7 +1865,7 @@ 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; @@ -1916,12 +1915,12 @@ ra_timer_update(void *arg, struct timeval *tm) } 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; } diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h index ac8ce9985a1f..e7ed87fece02 100644 --- a/usr.sbin/rtadvd/rtadvd.h +++ b/usr.sbin/rtadvd/rtadvd.h @@ -270,7 +270,7 @@ 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 */ @@ -286,7 +286,7 @@ extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist; 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, diff --git a/usr.sbin/rtadvd/timer.c b/usr.sbin/rtadvd/timer.c index 2ea77b5c95bd..faa541dc738e 100644 --- a/usr.sbin/rtadvd/timer.c +++ b/usr.sbin/rtadvd/timer.c @@ -31,7 +31,6 @@ * SUCH DAMAGE. */ -#include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include "rtadvd.h" @@ -52,12 +52,17 @@ 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); @@ -102,7 +107,7 @@ 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) { struct rtadvd_timer *rat; @@ -149,48 +154,48 @@ rtadvd_remove_timer(struct rtadvd_timer *rat) * 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 *rat; - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); tm_max = tm_limit; TAILQ_FOREACH(rat, &ra_timer, rat_next) { - if (TIMEVAL_LEQ(&rat->rat_tm, &now)) { + if (TS_CMP(&rat->rat_tm, &now, <=)) { if (((*rat->rat_expire)(rat->rat_expire_data) == NULL)) continue; /* the timer was removed */ if (rat->rat_update) (*rat->rat_update)(rat->rat_update_data, &rat->rat_tm); - TIMEVAL_ADD(&rat->rat_tm, &now, &rat->rat_tm); + TS_ADD(&rat->rat_tm, &now, &rat->rat_tm); } - if (TIMEVAL_LT(&rat->rat_tm, &tm_max)) + if (TS_CMP(&rat->rat_tm, &tm_max, <)) tm_max = rat->rat_tm; } - if (TIMEVAL_EQUAL(&tm_max, &tm_limit)) { + if (TS_CMP(&tm_max, &tm_limit, ==)) { /* no need to timeout */ return (NULL); - } else if (TIMEVAL_LT(&tm_max, &now)) { + } else if (TS_CMP(&tm_max, &now, <)) { /* this may occur when the interval is too small */ - returnval.tv_sec = returnval.tv_usec = 0; + returnval.tv_sec = returnval.tv_nsec = 0; } else - TIMEVAL_SUB(&tm_max, &now, &returnval); + TS_SUB(&tm_max, &now, &returnval); return (&returnval); } void -rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *rat) +rtadvd_set_timer(struct timespec *tm, struct rtadvd_timer *rat) { - struct timeval now; + struct timespec now; /* reset the timer */ - gettimeofday(&now, NULL); - TIMEVAL_ADD(&now, tm, &rat->rat_tm); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); + TS_ADD(&now, tm, &rat->rat_tm); /* update the next expiration time */ - if (TIMEVAL_LT(&rat->rat_tm, &tm_max)) + if (TS_CMP(&rat->rat_tm, &tm_max, <)) tm_max = rat->rat_tm; return; diff --git a/usr.sbin/rtadvd/timer.h b/usr.sbin/rtadvd/timer.h index f70e0d1fdc98..4498aaff073a 100644 --- a/usr.sbin/rtadvd/timer.h +++ b/usr.sbin/rtadvd/timer.h @@ -35,18 +35,18 @@ struct rtadvd_timer { TAILQ_ENTRY(rtadvd_timer) rat_next; struct rainfo *rat_rai; - struct timeval rat_tm; + struct timespec rat_tm; struct rtadvd_timer *(*rat_expire)(void *); void *rat_expire_data; - void (*rat_update)(void *, struct timeval *); + void (*rat_update)(void *, struct timespec *); void *rat_update_data; }; void rtadvd_timer_init(void); void rtadvd_update_timeout_handler(void); struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*)(void *), - void (*)(void *, struct timeval *), void *, void *); -void rtadvd_set_timer(struct timeval *, + 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 timespec *rtadvd_check_timer(void); diff --git a/usr.sbin/rtadvd/timer_subr.c b/usr.sbin/rtadvd/timer_subr.c index 2bebdd3f5685..0ddf0a433f96 100644 --- a/usr.sbin/rtadvd/timer_subr.c +++ b/usr.sbin/rtadvd/timer_subr.c @@ -30,69 +30,34 @@ * SUCH DAMAGE. */ -#include #include #include #include #include #include +#include #include "timer.h" #include "timer_subr.h" -struct timeval * +struct timespec * rtadvd_timer_rest(struct rtadvd_timer *rat) { - static struct timeval returnval, now; + static struct timespec returnval, now; - gettimeofday(&now, NULL); - if (TIMEVAL_LEQ(&rat->rat_tm, &now)) { + clock_gettime(CLOCK_MONOTONIC_FAST, &now); + if (TS_CMP(&rat->rat_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 = returnval.tv_nsec = 0; } else - TIMEVAL_SUB(&rat->rat_tm, &now, &returnval); + TS_SUB(&rat->rat_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; - } -} - char * sec2str(uint32_t s, char *buf) { diff --git a/usr.sbin/rtadvd/timer_subr.h b/usr.sbin/rtadvd/timer_subr.h index 9ceddad76958..32e1bb163afb 100644 --- a/usr.sbin/rtadvd/timer_subr.h +++ b/usr.sbin/rtadvd/timer_subr.h @@ -31,27 +31,29 @@ */ #define SSBUFLEN 1024 -#define MILLION 1000000 -/* 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))) +#define TS_CMP(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#define TS_ADD(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 >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (0) +#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) -/* 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))) - -#define TIMEVAL_EQUAL(a,b) \ - (((a)->tv_sec == (b)->tv_sec) && \ - ((a)->tv_usec == (b)->tv_usec)) - -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_timer_rest(struct rtadvd_timer *); char *sec2str(uint32_t, char *buf); diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c index 52d4b62e1390..ddf0d3c0d533 100644 --- a/usr.sbin/rtsold/dump.c +++ b/usr.sbin/rtsold/dump.c @@ -32,7 +32,6 @@ */ #include -#include #include #include @@ -62,10 +61,10 @@ dump_interface_status(void) struct ifinfo *ifi; struct rainfo *rai; struct ra_opt *rao; - struct timeval now; + struct timespec now; char ntopbuf[INET6_ADDRSTRLEN]; - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) { fprintf(fp, "Interface %s\n", ifi->ifname); @@ -87,12 +86,12 @@ dump_interface_status(void) fprintf(fp, " probes: %d, dadcount = %d\n", ifi->probes, ifi->dadcount); if (ifi->timer.tv_sec == tm_max.tv_sec && - ifi->timer.tv_usec == tm_max.tv_usec) + ifi->timer.tv_nsec == tm_max.tv_nsec) fprintf(fp, " no timer\n"); else { fprintf(fp, " timer: interval=%d:%d, expire=%s\n", (int)ifi->timer.tv_sec, - (int)ifi->timer.tv_usec, + (int)ifi->timer.tv_nsec / 1000, (ifi->expire.tv_sec < now.tv_sec) ? "expired" : sec2str(&ifi->expire)); } @@ -137,7 +136,7 @@ rtsold_dump_file(const char *dumpfile) } const char * -sec2str(const struct timeval *total) +sec2str(const struct timespec *total) { static char result[256]; int days, hours, mins, secs; @@ -145,14 +144,14 @@ sec2str(const struct timeval *total) char *p = result; char *ep = &result[sizeof(result)]; int n; - struct timeval now; + struct timespec now; time_t tsec; - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); tsec = total->tv_sec; - tsec += total->tv_usec / 1000000; + tsec += total->tv_nsec / 1000 / 1000000; tsec -= now.tv_sec; - tsec -= now.tv_usec / 1000000; + tsec -= now.tv_nsec / 1000 / 1000000; days = tsec / 3600 / 24; hours = (tsec / 3600) % 24; diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c index 181012c52fb3..f7210f666693 100644 --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -256,8 +256,8 @@ rtsol_input(int s) size_t len; char nsbuf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ + 1]; char dname[NI_MAXHOST]; - struct timeval now; - struct timeval lifetime; + struct timespec now; + struct timespec lifetime; int newent_rai; int newent_rao; @@ -376,7 +376,7 @@ rtsol_input(int s) ifi->otherconfig = 1; CALL_SCRIPT(OTHER, NULL); } - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); newent_rai = 0; rai = find_rainfo(ifi, &from); if (rai == NULL) { @@ -472,7 +472,7 @@ rtsol_input(int s) memset(&lifetime, 0, sizeof(lifetime)); lifetime.tv_sec = ntohl(rdnss->nd_opt_rdnss_lifetime); - timeradd(&now, &lifetime, &rao->rao_expire); + TS_ADD(&now, &lifetime, &rao->rao_expire); if (newent_rao) TAILQ_INSERT_TAIL(&rai->rai_ra_opt, @@ -531,7 +531,7 @@ rtsol_input(int s) memset(&lifetime, 0, sizeof(lifetime)); lifetime.tv_sec = ntohl(dnssl->nd_opt_dnssl_lifetime); - timeradd(&now, &lifetime, &rao->rao_expire); + TS_ADD(&now, &lifetime, &rao->rao_expire); if (newent_rao) TAILQ_INSERT_TAIL(&rai->rai_ra_opt, @@ -574,7 +574,7 @@ ra_opt_handler(struct ifinfo *ifi) struct ra_opt *rao; struct rainfo *rai; struct script_msg *smp1, *smp2, *smp3; - struct timeval now; + struct timespec now; struct script_msg_head_t sm_rdnss_head = TAILQ_HEAD_INITIALIZER(sm_rdnss_head); struct script_msg_head_t sm_dnssl_head = @@ -584,7 +584,7 @@ ra_opt_handler(struct ifinfo *ifi) dcount = 0; dlen = strlen(resstr_sh_prefix) + strlen(resstr_nl); - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); /* * All options from multiple RAs with the same or different @@ -595,7 +595,7 @@ ra_opt_handler(struct ifinfo *ifi) TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) { switch (rao->rao_type) { case ND_OPT_RDNSS: - if (timercmp(&now, &rao->rao_expire, >)) { + if (TS_CMP(&now, &rao->rao_expire, >)) { warnmsg(LOG_INFO, __func__, "expired rdnss entry: %s", (char *)rao->rao_msg); @@ -617,7 +617,7 @@ ra_opt_handler(struct ifinfo *ifi) break; case ND_OPT_DNSSL: - if (timercmp(&now, &rao->rao_expire, >)) { + if (TS_CMP(&now, &rao->rao_expire, >)) { warnmsg(LOG_INFO, __func__, "expired dnssl entry: %s", (char *)rao->rao_msg); diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index d3d1289aa562..2826c2cc43e5 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -54,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -68,7 +68,7 @@ #define RTSOL_PIDFILE "/var/run/rtsold.pid"; struct ifinfo *iflist; -struct timeval tm_max = {0x7fffffff, 0x7fffffff}; +struct timespec tm_max; static int log_upto = 999; static int fflag = 0; @@ -105,7 +105,7 @@ static int ifreconfig(char *); #endif static int make_packet(struct ifinfo *); -static struct timeval *rtsol_check_timer(void); +static struct timespec *rtsol_check_timer(void); #ifndef SMALL static void rtsold_set_dump_file(int); @@ -116,7 +116,7 @@ int main(int argc, char **argv) { int s, ch, once = 0; - struct timeval *timeout; + struct timespec *timeout; const char *opts; #ifdef HAVE_POLL_H struct pollfd set[2]; @@ -187,6 +187,12 @@ main(int argc, char **argv) exit(1); } + /* Generate maximum time in timespec. */ + memset(&tm_max.tv_sec, 0xff, sizeof(tm_max.tv_sec)); + memset(&tm_max.tv_nsec, 0xff, sizeof(tm_max.tv_nsec)); + tm_max.tv_sec &= ~(1UL << (sizeof(tm_max.tv_sec) * 8 - 1)); + tm_max.tv_nsec &= ~(1UL << (sizeof(tm_max.tv_nsec) * 8 - 1)); + /* set log level */ if (dflag > 1) log_upto = LOG_DEBUG; @@ -363,7 +369,7 @@ main(int argc, char **argv) break; } #ifdef HAVE_POLL_H - e = poll(set, 2, timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFTIM); + e = poll(set, 2, timeout ? (timeout->tv_sec * 1000 + timeout->tv_nsec / 1000 / 1000) : INFTIM); #else e = select(maxfd + 1, selectfdp, NULL, NULL, timeout); #endif @@ -603,22 +609,22 @@ make_packet(struct ifinfo *ifi) return (0); } -static struct timeval * +static struct timespec * rtsol_check_timer(void) { - static struct timeval returnval; - struct timeval now, rtsol_timer; + static struct timespec returnval; + struct timespec now, rtsol_timer; struct ifinfo *ifi; struct rainfo *rai; struct ra_opt *rao; int flags; - gettimeofday(&now, NULL); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); rtsol_timer = tm_max; TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) { - if (timercmp(&ifi->expire, &now, <=)) { + if (TS_CMP(&ifi->expire, &now, <=)) { warnmsg(LOG_DEBUG, __func__, "timer expiration on %s, " "state = %d", ifi->ifname, ifi->state); @@ -711,7 +717,7 @@ rtsol_check_timer(void) "type=%d, msg=%s, expire=%s", rao->rao_type, (char *)rao->rao_msg, sec2str(&rao->rao_expire)); - if (timercmp(&now, &rao->rao_expire, + if (TS_CMP(&now, &rao->rao_expire, >=)) { warnmsg(LOG_DEBUG, __func__, "RA expiration timer: " @@ -728,21 +734,21 @@ rtsol_check_timer(void) if (expire) ra_opt_handler(ifi); } - if (timercmp(&ifi->expire, &rtsol_timer, <)) + if (TS_CMP(&ifi->expire, &rtsol_timer, <)) rtsol_timer = ifi->expire; } - if (timercmp(&rtsol_timer, &tm_max, ==)) { + if (TS_CMP(&rtsol_timer, &tm_max, ==)) { warnmsg(LOG_DEBUG, __func__, "there is no timer"); return (NULL); - } else if (timercmp(&rtsol_timer, &now, <)) + } else if (TS_CMP(&rtsol_timer, &now, <)) /* this may occur when the interval is too small */ - returnval.tv_sec = returnval.tv_usec = 0; + returnval.tv_sec = returnval.tv_nsec = 0; else - timersub(&rtsol_timer, &now, &returnval); + TS_SUB(&rtsol_timer, &now, &returnval); now.tv_sec += returnval.tv_sec; - now.tv_usec += returnval.tv_usec; + now.tv_nsec += returnval.tv_nsec; warnmsg(LOG_DEBUG, __func__, "New timer is %s", sec2str(&now)); @@ -755,7 +761,7 @@ rtsol_timer_update(struct ifinfo *ifi) #define MILLION 1000000 #define DADRETRY 10 /* XXX: adhoc */ long interval; - struct timeval now; + struct timespec now; bzero(&ifi->timer, sizeof(ifi->timer)); @@ -783,7 +789,7 @@ rtsol_timer_update(struct ifinfo *ifi) interval = arc4random_uniform(MAX_RTR_SOLICITATION_DELAY * MILLION); #endif ifi->timer.tv_sec = interval / MILLION; - ifi->timer.tv_usec = interval % MILLION; + ifi->timer.tv_nsec = (interval % MILLION) * 1000; break; case IFS_PROBE: if (ifi->probes < MAX_RTR_SOLICITATIONS) @@ -807,16 +813,16 @@ rtsol_timer_update(struct ifinfo *ifi) } /* reset the timer */ - if (timercmp(&ifi->timer, &tm_max, ==)) { + if (TS_CMP(&ifi->timer, &tm_max, ==)) { ifi->expire = tm_max; warnmsg(LOG_DEBUG, __func__, "stop timer for %s", ifi->ifname); } else { - gettimeofday(&now, NULL); - timeradd(&now, &ifi->timer, &ifi->expire); + clock_gettime(CLOCK_MONOTONIC_FAST, &now); + TS_ADD(&now, &ifi->timer, &ifi->expire); now.tv_sec += ifi->timer.tv_sec; - now.tv_usec += ifi->timer.tv_usec; + now.tv_nsec += ifi->timer.tv_nsec; warnmsg(LOG_DEBUG, __func__, "set timer for %s to %s", ifi->ifname, sec2str(&now)); } diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h index 3ab010f1914a..69f9c352fe9e 100644 --- a/usr.sbin/rtsold/rtsold.h +++ b/usr.sbin/rtsold/rtsold.h @@ -43,7 +43,7 @@ struct ra_opt { TAILQ_ENTRY(ra_opt) rao_next; u_int8_t rao_type; - struct timeval rao_expire; + struct timespec rao_expire; size_t rao_len; void *rao_msg; }; @@ -73,8 +73,8 @@ struct ifinfo { int state; int probes; int dadcount; - struct timeval timer; - struct timeval expire; + struct timespec timer; + struct timespec expire; int errors; /* # of errors we've got - detect wedge */ #define IFI_DNSOPT_STATE_NOINFO 0 #define IFI_DNSOPT_STATE_RECEIVED 1 @@ -124,8 +124,31 @@ extern TAILQ_HEAD(ifinfo_head_t, ifinfo) ifinfo_head; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}} #endif +#define TS_CMP(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#define TS_ADD(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 >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (0) +#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) + /* rtsold.c */ -extern struct timeval tm_max; +extern struct timespec tm_max; extern int dflag; extern int aflag; extern int Fflag; @@ -163,7 +186,7 @@ extern void defrouter_probe(struct ifinfo *); /* dump.c */ extern void rtsold_dump_file(const char *); -extern const char *sec2str(const struct timeval *); +extern const char *sec2str(const struct timespec *); /* rtsock.c */ extern int rtsock_open(void);