From: Roy Marples Date: Tue, 3 Mar 2015 17:27:25 +0000 (+0000) Subject: Replace timeval with timespec. X-Git-Tag: v6.8.0~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=573d048785f5996bed202b537c79ffc513433fa8;p=thirdparty%2Fdhcpcd.git Replace timeval with timespec. --- diff --git a/arp.c b/arp.c index 4caf2bd9..dced3120 100644 --- 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"); } diff --git a/common.c b/common.c index b3bca3be..804765e3 100644 --- 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; diff --git a/common.h b/common.h index 8a19f115..499dd47f 100644 --- a/common.h +++ b/common.h @@ -48,28 +48,34 @@ #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 @@ -110,7 +116,7 @@ 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 d4de3e3c..3f2b0c09 100644 --- 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 9a01e67b..6fd8229d 100644 --- 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 72c9d1d9..073294fe 100644 --- 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 37f963c2..aee627a6 100644 --- 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; diff --git a/dhcpcd.c b/dhcpcd.c index cb0d753d..76357d6e 100644 --- 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 85ba8622..da448360 100644 --- 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 563dfb00..29bf1fe1 100644 --- 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); diff --git a/if-bsd.c b/if-bsd.c index 9ac2a840..268e6b3e 100644 --- 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 143cecf3..0aa3b694 100644 --- 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 ab40a119..a22e1992 100644 --- 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) {} diff --git a/ipv6nd.c b/ipv6nd.c index a5b8df7f..140ba184 100644 --- 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, <, &expire); - if (rap->lifetime == 0 || timercmp(&now, &expire, >)) { + lt.tv_nsec = 0; + timespecadd(&rap->received, <, &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, <); - if (!timerisset(&next) || - timercmp(&next, <, >)) + timespecsub(&expire, &now, <); + if (!timespecisset(&next) || + timespeccmp(&next, <, >)) 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, <); - if (!timerisset(&next) || timercmp(&next, <, >)) + timespecsub(&rao->expire, &now, <); + if (!timespecisset(&next) || timespeccmp(&next, <, >)) 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; } diff --git a/ipv6nd.h b/ipv6nd.h index 4e85df0d..5beaacad 100644 --- 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;