continue;
if (rap->iface->options->options & DHCPCD_IPV6RA_OWN) {
TAILQ_FOREACH(addr, &rap->addrs, next) {
+ if (addr->prefix_vltime == 0)
+ continue;
rt = make_prefix(rap->iface, rap, addr);
if (rt)
TAILQ_INSERT_TAIL(dnr, rt, next);
struct ra *rap, *ran;
struct timespec now, lt, expire, next;
uint8_t expired, valid, validone;
+ struct ipv6_addr *ia;
ifp = arg;
clock_gettime(CLOCK_MONOTONIC, &now);
}
}
+ /* Not every prefix is tied to an address which
+ * the kernel can expire, so we need to handle it ourself.
+ * Also, some OS don't support address lifetimes (Solaris). */
+ TAILQ_FOREACH(ia, &rap->addrs, next) {
+ if (ia->prefix_vltime == ND6_INFINITE_LIFETIME ||
+ ia->prefix_vltime == 0)
+ continue;
+ lt.tv_sec = (time_t)ia->prefix_vltime;
+ lt.tv_nsec = 0;
+ timespecadd(&ia->acquired, <, &expire);
+ if (timespeccmp(&now, &expire, >)) {
+ if (ia->flags & IPV6_AF_ADDED) {
+ logger(ia->iface->ctx, LOG_WARNING,
+ "%s: expired address %s",
+ ia->iface->name, ia->saddr);
+ if (if_address6(RTM_DELADDR, ia)== -1 &&
+ errno != EADDRNOTAVAIL &&
+ errno != ENXIO)
+ logger(ia->iface->ctx, LOG_ERR,
+ "if_address6: %m");
+ }
+ ia->prefix_vltime = ia->prefix_pltime = 0;
+ ia->flags &=
+ ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
+ expired = 1;
+ } else {
+ timespecsub(&expire, &now, <);
+ if (!timespecisset(&next) ||
+ timespeccmp(&next, <, >))
+ next = lt;
+ }
+ }
+
/* XXX FixMe!
* We need to extract the lifetime from each option and check
* if that has expired or not.