#ifndef timespecclear
#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
+#define timespecadd(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 timespecsub(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)
#endif
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, rt->rt_ifp->index);
#ifdef HAVE_ROUTE_LIFETIME
- if (rt->rt_lifetime != 0)
- add_attr_32(&nlm.hdr, sizeof(nlm), RTA_EXPIRES,rt->rt_lifetime);
+ if (rt->rt_lifetime != 0) {
+ uint32_t expires;
+
+ expires = lifetime_left(rt->rt_lifetime, &rt->rt_aquired, NULL);
+ add_attr_32(&nlm.hdr, sizeof(nlm), RTA_EXPIRES, expires);
+ }
#endif
if (rt->rt_metric != 0)
* The saved times will be re-applied to the ia
* before exiting this function. */
ia->prefix_vltime = ia->prefix_pltime = ND6_INFINITE_LIFETIME;
- }
-
- if (timespecisset(&ia->acquired)) {
+ } else if (timespecisset(&ia->acquired)) {
ia->prefix_pltime = lifetime_left(ia->prefix_pltime,
&ia->acquired, now);
ia->prefix_vltime = lifetime_left(ia->prefix_vltime,
const struct routeinfo *rinfo;
const struct ipv6_addr *addr;
struct in6_addr netmask;
- struct timespec now;
if (ctx->ra_routers == NULL)
return 0;
- timespecclear(&now);
-
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
if (rap->expired)
continue;
rt->rt_pref = ipv6nd_rtpref(rinfo->flags);
#endif
#ifdef HAVE_ROUTE_LIFETIME
- rt->rt_lifetime = lifetime_left(rinfo->lifetime,
- &rinfo->acquired, &now);
+ rt->rt_aquired = rinfo->acquired;
+ rt->rt_lifetime = rinfo->lifetime,
#endif
rt_proto_add(routes, rt);
}
rt->rt_pref = ipv6nd_rtpref(rap->flags);
#endif
#ifdef HAVE_ROUTE_LIFETIME
- rt->rt_lifetime =
- lifetime_left(addr->prefix_vltime,
- &addr->acquired, &now);
+ rt->rt_aquired = addr->acquired;
+ rt->rt_lifetime = addr->prefix_vltime;
#endif
rt_proto_add(routes, rt);
rt->rt_pref = ipv6nd_rtpref(rap->flags);
#endif
#ifdef HAVE_ROUTE_LIFETIME
- rt->rt_lifetime = lifetime_left(rap->lifetime,
- &rap->acquired, &now);
+ rt->rt_aquired = rap->acquired;
+ rt->rt_lifetime = rap->lifetime;
#endif
rt_proto_add(routes, rt);
if (rt == NULL)
continue;
rt->rt_dflags |= RTDF_DHCP;
+#ifdef HAVE_ROUTE_LIFETIME
+ rt->rt_aquired = ia->acquired;
+ rt->rt_lifetime = ia->prefix_vltime;
+#endif
rt_proto_add(routes, rt);
}
}
static void ipv6nd_handledata(void *, unsigned short);
static struct routeinfo *routeinfo_findalloc(struct ra *, const struct in6_addr *, uint8_t);
static void routeinfohead_free(struct routeinfohead *);
+static void ipv6nd_startrs2(void *);
/*
* Android ships buggy ICMP6 filter headers.
/* Expire should be called last as the rap object could be destroyed */
ipv6nd_expirera(ifp);
#undef FREE_RAP
+
+ eloop_timeout_add_sec(ifp->ctx->eloop, 5, ipv6nd_startrs2, ifp);
}
bool
#endif
#ifdef HAVE_ROUTE_LIFETIME
- uint32_t deviation;
-
/* There might be a minor difference between kernel route
* lifetime and our lifetime due to processing times.
* We allow a small deviation to avoid needless route changes.
- * dhcpcd will expire the route regardless of route lifetime support. */
+ * dhcpcd will expire the route regardless of route lifetime support.
+ */
+ struct timespec ts;
+ uint32_t deviation;
+
+ timespecsub(&nrt->rt_aquired, &ort->rt_aquired, &ts);
+ if (ts.tv_sec < 0)
+ ts.tv_sec = -ts.tv_sec;
+ if (ts.tv_sec > RTLIFETIME_DEV_MAX)
+ return false;
if (nrt->rt_lifetime > ort->rt_lifetime)
deviation = nrt->rt_lifetime - ort->rt_lifetime;
else
size_t rt_order;
rb_node_t rt_tree;
#ifdef HAVE_ROUTE_LIFETIME
+ struct timespec rt_aquired; /* timestamp of aquisition */
uint32_t rt_lifetime; /* current lifetime of route */
#define RTLIFETIME_DEV_MAX 2 /* max deviation for cmp */
#endif