]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Replace timeval with timespec.
authorRoy Marples <roy@marples.name>
Tue, 3 Mar 2015 17:27:25 +0000 (17:27 +0000)
committerRoy Marples <roy@marples.name>
Tue, 3 Mar 2015 17:27:25 +0000 (17:27 +0000)
15 files changed:
arp.c
common.c
common.h
dhcp.c
dhcp.h
dhcp6.c
dhcp6.h
dhcpcd.c
eloop.c
eloop.h
if-bsd.c
ipv6.c
ipv6.h
ipv6nd.c
ipv6nd.h

diff --git a/arp.c b/arp.c
index 4caf2bd9fcc50f75514e5a1e70ff2736ac4ccd09..dced312027ffa0f47949283bb8a866562485348e 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -253,24 +253,24 @@ arp_probe1(void *arg)
 {
        struct arp_state *astate = arg;
        struct interface *ifp = astate->iface;
-       struct timeval tv;
+       struct timespec tv;
 
        if (++astate->probes < PROBE_NUM) {
                tv.tv_sec = PROBE_MIN;
-               tv.tv_usec = (suseconds_t)arc4random_uniform(
-                   (PROBE_MAX - PROBE_MIN) * 1000000);
-               timernorm(&tv);
+               tv.tv_nsec = (suseconds_t)arc4random_uniform(
+                   (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
+               timespecnorm(&tv);
                eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
        } else {
                tv.tv_sec = ANNOUNCE_WAIT;
-               tv.tv_usec = 0;
+               tv.tv_nsec = 0;
                eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
        }
        syslog(LOG_DEBUG,
            "%s: ARP probing %s (%d of %d), next in %0.1f seconds",
            ifp->name, inet_ntoa(astate->addr),
            astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
-           timeval_to_double(&tv));
+           timespec_to_double(&tv));
        if (arp_send(ifp, ARPOP_REQUEST, 0, astate->addr.s_addr) == -1)
                syslog(LOG_ERR, "send_arp: %m");
 }
index b3bca3be86b2f67609dd0b0aa2d746efb27967c6..804765e388b67c0863402965b4b34a88c4c9b6a2 100644 (file)
--- a/common.c
+++ b/common.c
@@ -89,18 +89,13 @@ get_hostname(char *buf, size_t buflen, int short_hostname)
  */
 #define NO_MONOTONIC "host does not support a monotonic clock - timing can skew"
 int
-get_monotonic(struct timeval *tp)
+get_monotonic(struct timespec *ts)
 {
-#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
-       struct timespec ts;
 
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
-               tp->tv_sec = ts.tv_sec;
-               tp->tv_usec = (suseconds_t)(ts.tv_nsec / 1000);
+#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
+       return clock_gettime(CLOCK_MONOTONIC, ts);
                return 0;
-       }
 #elif defined(__APPLE__)
-#define NSEC_PER_SEC 1000000000
        /* We can use mach kernel functions here.
         * This is crap though - why can't they implement clock_gettime?*/
        static struct mach_timebase_info info = { 0, 0 };
@@ -118,13 +113,12 @@ get_monotonic(struct timeval *tp)
                nano = mach_absolute_time();
                if ((info.denom != 1 || info.numer != 1) && factor != 0.0)
                        nano *= factor;
-               tp->tv_sec = nano / NSEC_PER_SEC;
-               rem = nano % NSEC_PER_SEC;
-               if (rem < 0) {
-                       tp->tv_sec--;
-                       rem += NSEC_PER_SEC;
+               ts->tv_sec = nano / NSEC_PER_SEC;
+               ts->tv_nsec = nano % NSEC_PER_SEC;
+               if (ts->tv_nsec < 0) {
+                       ts->tv_sec--;
+                       ts->tv_nsec += NSEC_PER_SEC;
                }
-               tp->tv_usec = rem / 1000;
                return 0;
        }
 #endif
@@ -136,7 +130,15 @@ get_monotonic(struct timeval *tp)
                posix_clock_set = 1;
        }
 #endif
-       return gettimeofday(tp, NULL);
+       {
+               struct timeval tv;
+               if (gettimeofday(&tv, NULL) == 0) {
+                       TIMEVAL_TO_TIMESPEC(&tv, ts);
+                       return 0;
+               }
+       }
+
+       return -1;
 }
 
 ssize_t
@@ -172,7 +174,7 @@ setvard(char ***e, const char *prefix, const char *var, size_t value)
 time_t
 uptime(void)
 {
-       struct timeval tv;
+       struct timespec tv;
 
        if (get_monotonic(&tv) == -1)
                return -1;
index 8a19f115d9155f5d43b61b07ad5f006117358a44..499dd47f4000dc84da3056a4b27ea18ec8282dc3 100644 (file)
--- a/common.h
+++ b/common.h
 #define STRINGIFY(a)           #a
 #define TOSTRING(a)            STRINGIFY(a)
 
-#define USECINSEC              1000000
-#define timeval_to_double(tv)                                          \
-       ((double)(tv)->tv_sec + (double)((tv)->tv_usec) * 1.0e-6)
-#define timernorm(tv) do {                                             \
-       while ((tv)->tv_usec >=  USECINSEC) {                           \
-               (tv)->tv_sec++;                                         \
-               (tv)->tv_usec -= USECINSEC;                             \
-       }                                                               \
+#define USEC_PER_SEC           1000000L
+#define USEC_PER_NSEC          1000L
+#define NSEC_PER_SEC           1000000000L
+#define MSEC_PER_SEC           1000L
+#define MSEC_PER_NSEC          1000000L
+
+#define timespec_to_double(tv)                                              \
+       ((double)(tv)->tv_sec + (double)((tv)->tv_nsec) / 1000000000.0)
+#define timespecnorm(tv) do {                                               \
+       while ((tv)->tv_nsec >=  NSEC_PER_SEC) {                             \
+               (tv)->tv_sec++;                                              \
+               (tv)->tv_nsec -= NSEC_PER_SEC;                               \
+       }                                                                    \
 } while (0 /* CONSTCOND */);
-#define tv_to_ms(ms, tv) do {                                          \
-       ms = (tv)->tv_sec * 1000;                                       \
-       ms += (tv)->tv_usec / 1000;                                     \
+#define ts_to_ms(ms, tv) do {                                               \
+       ms = (tv)->tv_sec * MSEC_PER_SEC;                                    \
+       ms += (tv)->tv_nsec / MSEC_PER_NSEC;                                 \
 } while (0 /* CONSTCOND */);
-#define ms_to_tv(tv, ms) do {                                                \
-       (tv)->tv_sec = ms / 1000;                                             \
-       (tv)->tv_usec = (suseconds_t)(ms - ((tv)->tv_sec * 1000)) * 1000;     \
+#define ms_to_ts(tv, ms) do {                                               \
+       (tv)->tv_sec = ms / MSEC_PER_SEC;                                    \
+       (tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC))    \
+           * MSEC_PER_NSEC;                                                 \
 } while (0 /* CONSTCOND */);
 
 #ifndef TIMEVAL_TO_TIMESPEC
 #define        TIMEVAL_TO_TIMESPEC(tv, ts) do {                                \
        (ts)->tv_sec = (tv)->tv_sec;                                    \
-       (ts)->tv_nsec = (tv)->tv_usec * 1000;                           \
+       (ts)->tv_nsec = (tv)->tv_usec * USEC_PER_NSEC;                  \
 } while (0 /* CONSTCOND */)
 #endif
 
 void get_line_free(void);
 const char *get_hostname(char *, size_t, int);
 extern int clock_monotonic;
-int get_monotonic(struct timeval *);
+int get_monotonic(struct timespec *);
 ssize_t setvar(char ***, const char *, const char *, const char *);
 ssize_t setvard(char ***, const char *, const char *, size_t);
 time_t uptime(void);
diff --git a/dhcp.c b/dhcp.c
index d4de3e3c7e18b8368141fa2efcd064f93fbfb18d..3f2b0c09d9b4602e33fbc37db57dad681469f014 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1569,7 +1569,7 @@ send_message(struct interface *iface, uint8_t type,
        ssize_t r;
        struct in_addr from, to;
        in_addr_t a = INADDR_ANY;
-       struct timeval tv;
+       struct timespec tv;
        int s;
 
        if (!callback)
@@ -1584,13 +1584,13 @@ send_message(struct interface *iface, uint8_t type,
                                state->interval = 64;
                }
                tv.tv_sec = state->interval + DHCP_RAND_MIN;
-               tv.tv_usec = (suseconds_t)arc4random_uniform(
-                   (DHCP_RAND_MAX - DHCP_RAND_MIN) * 1000000);
-               timernorm(&tv);
+               tv.tv_nsec = (suseconds_t)arc4random_uniform(
+                   (DHCP_RAND_MAX - DHCP_RAND_MIN) * NSEC_PER_SEC);
+               timespecnorm(&tv);
                syslog(LOG_DEBUG,
                    "%s: sending %s (xid 0x%x), next in %0.1f seconds",
                    iface->name, get_dhcp_op(type), state->xid,
-                   timeval_to_double(&tv));
+                   timespec_to_double(&tv));
        }
 
        if (dhcp_open(iface) == -1)
@@ -1829,7 +1829,6 @@ dhcp_bind(struct interface *ifp, struct arp_state *astate)
        struct dhcp_state *state = D_STATE(ifp);
        struct if_options *ifo = ifp->options;
        struct dhcp_lease *lease = &state->lease;
-       struct timeval tv;
        uint8_t ipv4ll = 0;
 
        if (state->state == DHS_BOUND)
@@ -1862,9 +1861,7 @@ dhcp_bind(struct interface *ifp, struct arp_state *astate)
                lease->leasetime = ~0U;
                state->reason = "INFORM";
        } else {
-               if (gettimeofday(&tv, NULL) == 0)
-                       lease->leasedfrom = tv.tv_sec;
-               else if (lease->frominfo)
+               if (lease->frominfo)
                        state->reason = "TIMEOUT";
                if (lease->leasetime == ~0U) {
                        lease->renewaltime =
@@ -3071,7 +3068,6 @@ dhcp_start1(void *arg)
        struct if_options *ifo = ifp->options;
        struct dhcp_state *state;
        struct stat st;
-       struct timeval now;
        uint32_t l;
        int nolease;
 
@@ -3167,10 +3163,12 @@ dhcp_start1(void *arg)
                } else if (state->lease.leasetime != ~0U &&
                    stat(state->leasefile, &st) == 0)
                {
+                       time_t now;
+
                        /* Offset lease times and check expiry */
-                       gettimeofday(&now, NULL);
-                       if ((time_t)state->lease.leasetime <
-                           now.tv_sec - st.st_mtime)
+                       now = time(NULL);
+                       if (now == -1 ||
+                           (time_t)state->lease.leasetime < now - st.st_mtime)
                        {
                                syslog(LOG_DEBUG,
                                    "%s: discarding expired lease",
@@ -3195,7 +3193,7 @@ dhcp_start1(void *arg)
                                        dhcp_drop(ifp, "EXPIRE");
 #endif
                        } else {
-                               l = (uint32_t)(now.tv_sec - st.st_mtime);
+                               l = (uint32_t)(now - st.st_mtime);
                                state->lease.leasetime -= l;
                                state->lease.renewaltime -= l;
                                state->lease.rebindtime -= l;
@@ -3223,19 +3221,19 @@ dhcp_start1(void *arg)
 void
 dhcp_start(struct interface *ifp)
 {
-       struct timeval tv;
+       struct timespec tv;
 
        if (!(ifp->options->options & DHCPCD_IPV4))
                return;
 
        /* No point in delaying a static configuration */
        tv.tv_sec = DHCP_MIN_DELAY;
-       tv.tv_usec = (suseconds_t)arc4random_uniform(
-           (DHCP_MAX_DELAY - DHCP_MIN_DELAY) * 1000000);
-       timernorm(&tv);
+       tv.tv_nsec = (suseconds_t)arc4random_uniform(
+           (DHCP_MAX_DELAY - DHCP_MIN_DELAY) * NSEC_PER_SEC);
+       timespecnorm(&tv);
        syslog(LOG_DEBUG,
            "%s: delaying IPv4 for %0.1f seconds",
-           ifp->name, timeval_to_double(&tv));
+           ifp->name, timespec_to_double(&tv));
 
        eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
 }
diff --git a/dhcp.h b/dhcp.h
index 9a01e67b4bbac16038a46129a34478f2493574e6..6fd8229ddaac0cbc5b037c879832623359a51efd 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -181,7 +181,6 @@ struct dhcp_lease {
        uint32_t renewaltime;
        uint32_t rebindtime;
        struct in_addr server;
-       time_t leasedfrom;
        uint8_t frominfo;
        uint32_t cookie;
 };
diff --git a/dhcp6.c b/dhcp6.c
index 72c9d1d99fb85aa4c7854a8365093d7560295b60..073294fee89f621e252fe41584d714024e927fff 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -990,7 +990,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
        struct sockaddr_in6 dst;
        struct cmsghdr *cm;
        struct in6_pktinfo pi;
-       struct timeval RTprev;
+       struct timespec RTprev;
        double rnd;
        time_t ms;
        uint8_t neg;
@@ -1037,49 +1037,49 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
                                state->RT.tv_sec = 1;
                        else
                                state->RT.tv_sec = 0;
-                       state->RT.tv_usec = (suseconds_t)arc4random_uniform(
-                           state->IMD * 1000000);
-                       timernorm(&state->RT);
+                       state->RT.tv_nsec = (suseconds_t)arc4random_uniform(
+                           state->IMD * NSEC_PER_SEC);
+                       timespecnorm(&state->RT);
                        broad_uni = "delaying";
                        goto logsend;
                }
                if (state->RTC == 0) {
                        RTprev.tv_sec = state->IRT;
-                       RTprev.tv_usec = 0;
+                       RTprev.tv_nsec = 0;
                        state->RT.tv_sec = RTprev.tv_sec;
-                       state->RT.tv_usec = 0;
+                       state->RT.tv_nsec = 0;
                } else {
                        RTprev = state->RT;
-                       timeradd(&state->RT, &state->RT, &state->RT);
+                       timespecadd(&state->RT, &state->RT, &state->RT);
                }
 
                rnd = DHCP6_RAND_MIN;
                rnd += (suseconds_t)arc4random_uniform(
                    DHCP6_RAND_MAX - DHCP6_RAND_MIN);
-               rnd /= 1000;
+               rnd /= MSEC_PER_SEC;
                neg = (rnd < 0.0);
                if (neg)
                        rnd = -rnd;
-               tv_to_ms(ms, &RTprev);
+               ts_to_ms(ms, &RTprev);
                ms *= rnd;
-               ms_to_tv(&RTprev, ms);
+               ms_to_ts(&RTprev, ms);
                if (neg)
-                       timersub(&state->RT, &RTprev, &state->RT);
+                       timespecsub(&state->RT, &RTprev, &state->RT);
                else
-                       timeradd(&state->RT, &RTprev, &state->RT);
+                       timespecadd(&state->RT, &RTprev, &state->RT);
 
                if (state->RT.tv_sec > state->MRT) {
                        RTprev.tv_sec = state->MRT;
-                       RTprev.tv_usec = 0;
+                       RTprev.tv_nsec = 0;
                        state->RT.tv_sec = state->MRT;
-                       state->RT.tv_usec = 0;
-                       tv_to_ms(ms, &RTprev);
+                       state->RT.tv_nsec = 0;
+                       ts_to_ms(ms, &RTprev);
                        ms *= rnd;
-                       ms_to_tv(&RTprev, ms);
+                       ms_to_ts(&RTprev, ms);
                        if (neg)
-                               timersub(&state->RT, &RTprev, &state->RT);
+                               timespecsub(&state->RT, &RTprev, &state->RT);
                        else
-                               timeradd(&state->RT, &RTprev, &state->RT);
+                               timespecadd(&state->RT, &RTprev, &state->RT);
                }
 
 logsend:
@@ -1092,7 +1092,7 @@ logsend:
                    state->send->xid[0],
                    state->send->xid[1],
                    state->send->xid[2],
-                   timeval_to_double(&state->RT));
+                   timespec_to_double(&state->RT));
 
                /* Wait the initial delay */
                if (state->IMD) {
@@ -1695,7 +1695,7 @@ dhcp6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
 
 static int
 dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
-    const uint8_t *d, size_t l, const struct timeval *acquired)
+    const uint8_t *d, size_t l, const struct timespec *acquired)
 {
        struct dhcp6_state *state;
        const struct dhcp6_option *o;
@@ -1776,7 +1776,7 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
 
 static int
 dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
-    const uint8_t *d, size_t l, const struct timeval *acquired)
+    const uint8_t *d, size_t l, const struct timespec *acquired)
 {
        struct dhcp6_state *state;
        const struct dhcp6_option *o, *ex;
@@ -1902,7 +1902,7 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
 
 static int
 dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
-    const char *sfrom, const struct timeval *acquired)
+    const char *sfrom, const struct timespec *acquired)
 {
        struct dhcp6_state *state;
        const struct if_options *ifo;
@@ -2051,11 +2051,11 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
 static int
 dhcp6_validatelease(struct interface *ifp,
     const struct dhcp6_message *m, size_t len,
-    const char *sfrom, const struct timeval *acquired)
+    const char *sfrom, const struct timespec *acquired)
 {
        struct dhcp6_state *state;
        int nia;
-       struct timeval aq;
+       struct timespec aq;
 
        if (len <= sizeof(*m)) {
                syslog(LOG_ERR, "%s: DHCPv6 lease truncated", ifp->name);
@@ -2109,9 +2109,9 @@ dhcp6_readlease(struct interface *ifp)
        struct stat st;
        int fd;
        ssize_t bytes;
-       struct timeval now;
        const struct dhcp6_option *o;
-       struct timeval acquired;
+       struct timespec acquired;
+       time_t now;
 
        state = D6_STATE(ifp);
        if (stat(state->leasefile, &st) == -1) {
@@ -2145,9 +2145,13 @@ dhcp6_readlease(struct interface *ifp)
                goto ex;
        }
 
-       gettimeofday(&now, NULL);
+       if ((now = time(NULL)) == -1) {
+               syslog(LOG_ERR, "%s: time: %m", __func__);
+               goto ex;
+       }
+
        get_monotonic(&acquired);
-       acquired.tv_sec -= now.tv_sec - st.st_mtime;
+       acquired.tv_sec -= now - st.st_mtime;
 
        /* Check to see if the lease is still valid */
        fd = dhcp6_validatelease(ifp, state->new, state->new_len, NULL,
@@ -2158,7 +2162,7 @@ dhcp6_readlease(struct interface *ifp)
        if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) &&
            state->expire != ND6_INFINITE_LIFETIME)
        {
-               if ((time_t)state->expire < now.tv_sec - st.st_mtime) {
+               if ((time_t)state->expire < now - st.st_mtime) {
                        syslog(LOG_DEBUG,"%s: discarding expired lease",
                            ifp->name);
                        goto ex;
diff --git a/dhcp6.h b/dhcp6.h
index 37f963c23f8c47ead1a1dc11058b5c0dc3f2948b..aee627a64d7860fd93fbdfaf037f0a837f18daa4 100644 (file)
--- a/dhcp6.h
+++ b/dhcp6.h
@@ -172,7 +172,7 @@ struct dhcp6_state {
        time_t start_uptime;
 
        /* Message retransmission timings */
-       struct timeval RT;
+       struct timespec RT;
        unsigned int IMD;
        unsigned int RTC;
        time_t IRT;
index cb0d753d0c17575b54e2b6ab8962de4597e56fad..76357d6efea6d52b6d366497f5a23857cf4ef73a 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -550,10 +550,10 @@ dhcpcd_pollup(void *arg)
 
        carrier = if_carrier(ifp); /* will set ifp->flags */
        if (carrier == LINK_UP && !(ifp->flags & IFF_UP)) {
-               struct timeval tv;
+               struct timespec tv;
 
                tv.tv_sec = 0;
-               tv.tv_usec = IF_POLL_UP * 1000;
+               tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
                eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcpcd_pollup, ifp);
                return;
        }
@@ -681,7 +681,7 @@ dhcpcd_startinterface(void *arg)
        size_t i;
        char buf[DUID_LEN * 3];
        int carrier;
-       struct timeval tv;
+       struct timespec tv;
 
        if (ifo->options & DHCPCD_LINK) {
                switch (ifp->carrier) {
@@ -695,7 +695,7 @@ dhcpcd_startinterface(void *arg)
                         * Loop until both IFF_UP and IFF_RUNNING are set */
                        if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
                                tv.tv_sec = 0;
-                               tv.tv_usec = IF_POLL_UP * 1000;
+                               tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
                                eloop_timeout_add_tv(ifp->ctx->eloop,
                                    &tv, dhcpcd_startinterface, ifp);
                        } else
@@ -1508,7 +1508,7 @@ main(int argc, char **argv)
         * eloop removals as well, so init here. */
        ctx.eloop = eloop_init();
        if (ctx.eloop == NULL) {
-               syslog(LOG_ERR, "%s: %m", __func__);
+               syslog(LOG_ERR, "%s: eloop_init: %m", __func__);
                goto exit_failure;
        }
 
diff --git a/eloop.c b/eloop.c
index 85ba8622f35ff4ccd0f8d7a190ab99cde4e9c8de..da4483601866c4d84283924a698da957fcd4868c 100644 (file)
--- a/eloop.c
+++ b/eloop.c
@@ -153,16 +153,15 @@ eloop_event_delete(struct eloop_ctx *ctx, int fd, int write_only)
 
 int
 eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
-    const struct timeval *when, void (*callback)(void *), void *arg)
+    const struct timespec *when, void (*callback)(void *), void *arg)
 {
-       struct timeval now;
-       struct timeval w;
+       struct timespec now, w;
        struct eloop_timeout *t, *tt = NULL;
 
        get_monotonic(&now);
-       timeradd(&now, when, &w);
+       timespecadd(&now, when, &w);
        /* Check for time_t overflow. */
-       if (timercmp(&w, &now, <)) {
+       if (timespeccmp(&w, &now, <)) {
                errno = ERANGE;
                return -1;
        }
@@ -188,8 +187,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
                }
        }
 
-       t->when.tv_sec = w.tv_sec;
-       t->when.tv_usec = w.tv_usec;
+       t->when = w;
        t->callback = callback;
        t->arg = arg;
        t->queue = queue;
@@ -197,7 +195,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
        /* The timeout list should be in chronological order,
         * soonest first. */
        TAILQ_FOREACH(tt, &ctx->timeouts, next) {
-               if (timercmp(&t->when, &tt->when, <)) {
+               if (timespeccmp(&t->when, &tt->when, <)) {
                        TAILQ_INSERT_BEFORE(tt, t, next);
                        return 0;
                }
@@ -210,10 +208,10 @@ int
 eloop_q_timeout_add_sec(struct eloop_ctx *ctx, int queue, time_t when,
     void (*callback)(void *), void *arg)
 {
-       struct timeval tv;
+       struct timespec tv;
 
        tv.tv_sec = when;
-       tv.tv_usec = 0;
+       tv.tv_nsec = 0;
        return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
 }
 
@@ -261,6 +259,11 @@ struct eloop_ctx *
 eloop_init(void)
 {
        struct eloop_ctx *ctx;
+       struct timespec now;
+
+       /* Check we have a working monotonic clock. */
+       if (get_monotonic(&now) == -1)
+               return NULL;
 
        ctx = calloc(1, sizeof(*ctx));
        if (ctx) {
@@ -306,12 +309,10 @@ int
 eloop_start(struct dhcpcd_ctx *dctx)
 {
        struct eloop_ctx *ctx;
-       struct timeval now;
        int n;
        struct eloop_event *e;
        struct eloop_timeout *t;
-       struct timeval tv;
-       struct timespec ts, *tsp;
+       struct timespec now, ts, *tsp;
        void (*t0)(void *);
 #ifndef USE_SIGNALS
        int timeout;
@@ -331,14 +332,13 @@ eloop_start(struct dhcpcd_ctx *dctx)
                }
                if ((t = TAILQ_FIRST(&ctx->timeouts))) {
                        get_monotonic(&now);
-                       if (timercmp(&now, &t->when, >)) {
+                       if (timespeccmp(&now, &t->when, >)) {
                                TAILQ_REMOVE(&ctx->timeouts, t, next);
                                t->callback(t->arg);
                                TAILQ_INSERT_TAIL(&ctx->free_timeouts, t, next);
                                continue;
                        }
-                       timersub(&t->when, &now, &tv);
-                       TIMEVAL_TO_TIMESPEC(&tv, &ts);
+                       timespecsub(&t->when, &now, &ts);
                        tsp = &ts;
                } else
                        /* No timeouts, so wait forever */
diff --git a/eloop.h b/eloop.h
index 563dfb008b78a12e17d7dac7e586516059ca80a8..29bf1fe17acb4323d3e25b55d942f372ffab19da 100644 (file)
--- a/eloop.h
+++ b/eloop.h
@@ -50,7 +50,7 @@ struct eloop_event {
 
 struct eloop_timeout {
        TAILQ_ENTRY(eloop_timeout) next;
-       struct timeval when;
+       struct timespec when;
        void (*callback)(void *);
        void *arg;
        int queue;
@@ -88,7 +88,7 @@ void eloop_event_delete(struct eloop_ctx *, int, int);
 int eloop_q_timeout_add_sec(struct eloop_ctx *, int queue,
     time_t, void (*)(void *), void *);
 int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue,
-    const struct timeval *, void (*)(void *), void *);
+    const struct timespec *, void (*)(void *), void *);
 int eloop_timeout_add_now(struct eloop_ctx *, void (*)(void *), void *);
 void eloop_q_timeout_delete(struct eloop_ctx *, int, void (*)(void *), void *);
 struct eloop_ctx * eloop_init(void);
index 9ac2a8404878c09b6e345f454f2068b474db7c5b..268e6b3e38e80f7f79a21b94994d02762a3c1080 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -599,6 +599,9 @@ if_route(unsigned char cmd, const struct rt *rt, struct rt *srt)
                else {
 #ifdef RTF_CLONING
                        rtm.hdr.rtm_flags |= RTF_CLONING;
+#endif
+#ifdef RTP_CONNECTED
+                       rtm.hdr.rtm_priority = RTP_CONNECTED;
 #endif
                }
        }
@@ -952,6 +955,9 @@ if_route6(unsigned char cmd, const struct rt6 *rt, struct rt6 *srt)
        if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
 #ifdef RTF_CLONING
                rtm.hdr.rtm_flags |= RTF_CLONING;
+#endif
+#ifdef RTP_CONNECTED
+               rtm.hdr.rtm_priority = RTP_CONNECTED;
 #endif
        } else
                rtm.hdr.rtm_flags |= RTF_GATEWAY | RTF_STATIC;
diff --git a/ipv6.c b/ipv6.c
index 143cecf387547d96ca9202959a13a4dd4a37aa19..0aa3b694f3263695c8c290f2f913ca8566674002 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -594,9 +594,9 @@ ipv6_checkaddrflags(void *arg)
                    ap->iface->ctx->ifaces, ap->iface->name,
                    &ap->addr, ap->prefix_len, ifa_flags);
        } else {
-               struct timeval tv;
+               struct timespec tv;
 
-               ms_to_tv(&tv, RETRANS_TIMER / 2);
+               ms_to_ts(&tv, RETRANS_TIMER / 2);
                eloop_timeout_add_tv(ap->iface->ctx->eloop, &tv,
                    ipv6_checkaddrflags, ap);
        }
@@ -627,7 +627,7 @@ ipv6_deleteaddr(struct ipv6_addr *addr)
 }
 
 int
-ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
+ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
 {
        struct interface *ifp;
        struct ipv6_state *state;
@@ -676,17 +676,17 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
        /* Adjust plftime and vltime based on acquired time */
        pltime = ap->prefix_pltime;
        vltime = ap->prefix_vltime;
-       if (timerisset(&ap->acquired) &&
+       if (timespecisset(&ap->acquired) &&
            (ap->prefix_pltime != ND6_INFINITE_LIFETIME ||
            ap->prefix_vltime != ND6_INFINITE_LIFETIME))
        {
-               struct timeval n;
+               struct timespec n;
 
                if (now == NULL) {
                        get_monotonic(&n);
                        now = &n;
                }
-               timersub(now, &ap->acquired, &n);
+               timespecsub(now, &ap->acquired, &n);
                if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
                        ap->prefix_pltime -= (uint32_t)n.tv_sec;
                if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
@@ -732,9 +732,9 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
        eloop_timeout_delete(ap->iface->ctx->eloop,
                ipv6_checkaddrflags, ap);
        if (!(ap->flags & IPV6_AF_DADCOMPLETED)) {
-               struct timeval tv;
+               struct timespec tv;
 
-               ms_to_tv(&tv, RETRANS_TIMER / 2);
+               ms_to_ts(&tv, RETRANS_TIMER / 2);
                eloop_timeout_add_tv(ap->iface->ctx->eloop,
                    &tv, ipv6_checkaddrflags, ap);
        }
@@ -766,10 +766,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
 {
        struct ipv6_addr *ap, *apn, *apf;
        ssize_t i;
-       struct timeval now;
+       struct timespec now;
 
        i = 0;
-       timerclear(&now);
+       timespecclear(&now);
        TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
                if (ap->prefix_vltime == 0) {
                        if (ap->flags & IPV6_AF_ADDED) {
@@ -814,7 +814,7 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
                                apf->flags &= ~IPV6_AF_ADDED;
                        if (ap->flags & IPV6_AF_NEW)
                                i++;
-                       if (!timerisset(&now))
+                       if (!timespecisset(&now))
                                get_monotonic(&now);
                        ipv6_addaddr(ap, &now);
                }
@@ -836,9 +836,9 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
     const struct interface *ifd)
 {
        struct ipv6_addr *ap, *apn, *apf;
-       struct timeval now;
+       struct timespec now;
 
-       timerclear(&now);
+       timespecclear(&now);
        TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
                if (ifd && ap->delegating_iface != ifd)
                        continue;
@@ -860,7 +860,7 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
                        if (!(ap->iface->options->options &
                            DHCPCD_EXITING) && apf)
                        {
-                               if (!timerisset(&now))
+                               if (!timespecisset(&now))
                                        get_monotonic(&now);
                                ipv6_addaddr(apf, &now);
                        }
@@ -997,9 +997,9 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
                        if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
 #ifdef IPV6_POLLADDRFLAG
                                if (ap->addr_flags & IN6_IFF_TENTATIVE) {
-                                       struct timeval tv;
+                                       struct timespec tv;
 
-                                       ms_to_tv(&tv, RETRANS_TIMER / 2);
+                                       ms_to_ts(&tv, RETRANS_TIMER / 2);
                                        eloop_timeout_add_tv(
                                            ap->iface->ctx->eloop,
                                            &tv, ipv6_checkaddrflags, ap);
@@ -1437,7 +1437,7 @@ ipv6_tempdadcallback(void *arg)
 
        if (ia->flags & IPV6_AF_DUPLICATED) {
                struct ipv6_addr *ia1;
-               struct timeval tv;
+               struct timespec tv;
 
                if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
                        syslog(LOG_ERR,
@@ -1457,7 +1457,7 @@ ipv6_tempdadcallback(void *arg)
 }
 
 struct ipv6_addr *
-ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timeval *now)
+ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now)
 {
        struct ipv6_state *state;
        const struct ipv6_state *cstate;
@@ -1649,7 +1649,7 @@ valid:
 }
 
 void
-ipv6_addtempaddrs(struct interface *ifp, const struct timeval *now)
+ipv6_addtempaddrs(struct interface *ifp, const struct timespec *now)
 {
        struct ipv6_state *state;
        struct ipv6_addr *ia;
@@ -1666,7 +1666,7 @@ static void
 ipv6_regentempaddr(void *arg)
 {
        struct ipv6_addr *ia = arg, *ia1;
-       struct timeval tv;
+       struct timespec tv;
 
        syslog(LOG_DEBUG, "%s: regen temp addr %s",
            ia->iface->name, ia->saddr);
diff --git a/ipv6.h b/ipv6.h
index ab40a1199ca124d5db7bc820b19cca4434c540a3..a22e19926856eac9a88a51fc2c4b787730db1ef0 100644 (file)
--- a/ipv6.h
+++ b/ipv6.h
@@ -104,8 +104,8 @@ struct ipv6_addr {
        uint8_t prefix_len;
        uint32_t prefix_vltime;
        uint32_t prefix_pltime;
-       struct timeval created;
-       struct timeval acquired;
+       struct timespec created;
+       struct timespec acquired;
        struct in6_addr addr;
        int addr_flags;
        short flags;
@@ -238,7 +238,7 @@ uint8_t ipv6_prefixlen(const struct in6_addr *);
 int ipv6_userprefix( const struct in6_addr *, short prefix_len,
     uint64_t user_number, struct in6_addr *result, short result_len);
 void ipv6_checkaddrflags(void *);
-int ipv6_addaddr(struct ipv6_addr *, const struct timeval *);
+int ipv6_addaddr(struct ipv6_addr *, const struct timespec *);
 ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
 void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
     const struct interface *);
@@ -261,9 +261,9 @@ void ipv6_freedrop(struct interface *, int);
 void ipv6_gentempifid(struct interface *);
 void ipv6_settempstale(struct interface *);
 struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *,
-    const struct timeval *);
+    const struct timespec *);
 struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int);
-void ipv6_addtempaddrs(struct interface *, const struct timeval *);
+void ipv6_addtempaddrs(struct interface *, const struct timespec *);
 #else
 #define ipv6_gentempifid(a) {}
 #define ipv6_settempstale(a) {}
index a5b8df7f934b83cc5f16902fe912611616f6fee3..140ba184b4105ab88164a340debec53c2254cc27 100644 (file)
--- a/ipv6nd.c
+++ b/ipv6nd.c
@@ -519,7 +519,7 @@ ipv6nd_scriptrun(struct ra *rap)
                TAILQ_FOREACH(rao, &rap->options, next) {
                        if (rao->type == ND_OPT_RDNSS &&
                            rao->option &&
-                           timerisset(&rao->expire))
+                           timespecisset(&rao->expire))
                        {
                                hasdns = 1;
                                break;
@@ -578,7 +578,7 @@ ipv6nd_dadcallback(void *arg)
        struct interface *ifp;
        struct ra *rap;
        int wascompleted, found;
-       struct timeval tv;
+       struct timespec tv;
        char buf[INET6_ADDRSTRLEN];
        const char *p;
        int dadcounter;
@@ -630,9 +630,9 @@ ipv6nd_dadcallback(void *arg)
                        else
                                ap->saddr[0] = '\0';
                        tv.tv_sec = 0;
-                       tv.tv_usec = (suseconds_t)arc4random_uniform(
-                           IDGEN_DELAY * USECINSEC);
-                       timernorm(&tv);
+                       tv.tv_nsec = (suseconds_t)
+                           arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC);
+                       timespecnorm(&tv);
                        eloop_timeout_add_tv(ifp->ctx->eloop, &tv,
                            ipv6nd_addaddr, ap);
                        return;
@@ -690,7 +690,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
        struct ra_opt *rao;
        struct ipv6_addr *ap;
        char *opt, *opt2, *tmp;
-       struct timeval expire;
+       struct timespec expire;
        uint8_t new_rap, new_data;
 #ifdef IPV6_MANAGETEMPADDR
        uint8_t new_ap;
@@ -1094,11 +1094,11 @@ extra_opt:
                } else
                        free(opt);
                if (lifetime == ~0U)
-                       timerclear(&rao->expire);
+                       timespecclear(&rao->expire);
                else {
                        expire.tv_sec = (time_t)lifetime;
-                       expire.tv_usec = 0;
-                       timeradd(&rap->received, &expire, &rao->expire);
+                       expire.tv_nsec = 0;
+                       timespecadd(&rap->received, &expire, &rao->expire);
                }
                if (rao && rao->type == ND_OPT_PREFIX_INFORMATION && opt2) {
                        n = _ND_OPT_PREFIX_ADDR;
@@ -1316,13 +1316,13 @@ ipv6nd_expirera(void *arg)
        struct interface *ifp;
        struct ra *rap, *ran;
        struct ra_opt *rao, *raon;
-       struct timeval now, lt, expire, next;
+       struct timespec now, lt, expire, next;
        int expired, valid;
 
        ifp = arg;
        get_monotonic(&now);
        expired = 0;
-       timerclear(&next);
+       timespecclear(&next);
 
        TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
                if (rap->iface != ifp)
@@ -1330,9 +1330,10 @@ ipv6nd_expirera(void *arg)
                valid = 0;
                if (rap->lifetime) {
                        lt.tv_sec = (time_t)rap->lifetime;
-                       lt.tv_usec = 0;
-                       timeradd(&rap->received, &lt, &expire);
-                       if (rap->lifetime == 0 || timercmp(&now, &expire, >)) {
+                       lt.tv_nsec = 0;
+                       timespecadd(&rap->received, &lt, &expire);
+                       if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
+                       {
                                if (!rap->expired) {
                                        syslog(LOG_WARNING,
                                            "%s: %s: router expired",
@@ -1341,9 +1342,9 @@ ipv6nd_expirera(void *arg)
                                }
                        } else {
                                valid = 1;
-                               timersub(&expire, &now, &lt);
-                               if (!timerisset(&next) ||
-                                   timercmp(&next, &lt, >))
+                               timespecsub(&expire, &now, &lt);
+                               if (!timespecisset(&next) ||
+                                   timespeccmp(&next, &lt, >))
                                        next = lt;
                        }
                }
@@ -1366,9 +1367,9 @@ ipv6nd_expirera(void *arg)
                                        continue;
                                }
                        }
-                       if (!timerisset(&rao->expire))
+                       if (!timespecisset(&rao->expire))
                                continue;
-                       if (timercmp(&now, &rao->expire, >)) {
+                       if (timespeccmp(&now, &rao->expire, >)) {
                                /* Expired prefixes are logged above */
                                if (rao->type != ND_OPT_PREFIX_INFORMATION)
                                        syslog(LOG_WARNING,
@@ -1381,8 +1382,8 @@ ipv6nd_expirera(void *arg)
                                continue;
                        }
                        valid = 1;
-                       timersub(&rao->expire, &now, &lt);
-                       if (!timerisset(&next) || timercmp(&next, &lt, >))
+                       timespecsub(&rao->expire, &now, &lt);
+                       if (!timespecisset(&next) || timespeccmp(&next, &lt, >))
                                next = lt;
                }
 
@@ -1392,7 +1393,7 @@ ipv6nd_expirera(void *arg)
                        ipv6nd_free_ra(rap);
        }
 
-       if (timerisset(&next))
+       if (timespecisset(&next))
                eloop_timeout_add_tv(ifp->ctx->eloop,
                    &next, ipv6nd_expirera, ifp);
        if (expired) {
@@ -1624,16 +1625,16 @@ ipv6nd_startrs1(void *arg)
 void
 ipv6nd_startrs(struct interface *ifp)
 {
-       struct timeval tv;
+       struct timespec tv;
 
        eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
        tv.tv_sec = 0;
-       tv.tv_usec = (suseconds_t)arc4random_uniform(
-           MAX_RTR_SOLICITATION_DELAY * 1000000);
-       timernorm(&tv);
+       tv.tv_nsec = (suseconds_t)arc4random_uniform(
+           MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
+       timespecnorm(&tv);
        syslog(LOG_DEBUG,
            "%s: delaying IPv6 router solicitation for %0.1f seconds",
-           ifp->name, timeval_to_double(&tv));
+           ifp->name, timespec_to_double(&tv));
        eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
        return;
 }
index 4e85df0d395b919cd4ed82ee10c5cadb9f9d424a..5beaacad12781271691a4bc08b227f80345a51bf 100644 (file)
--- a/ipv6nd.h
+++ b/ipv6nd.h
@@ -37,7 +37,7 @@
 struct ra_opt {
        TAILQ_ENTRY(ra_opt) next;
        uint16_t type;
-       struct timeval expire;
+       struct timespec expire;
        char *option;
 };
 
@@ -48,7 +48,7 @@ struct ra {
        char sfrom[INET6_ADDRSTRLEN];
        unsigned char *data;
        size_t data_len;
-       struct timeval received;
+       struct timespec received;
        unsigned char flags;
        uint32_t lifetime;
        uint32_t reachable;