diff options
| author | Roy Marples <roy@marples.name> | 2014-12-16 20:20:01 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2014-12-16 20:20:01 +0000 |
| commit | 0b3255ac875375112d273cca8223c22dfe3af12d (patch) | |
| tree | 09c83f35a829d35bcba36be230b15ac3e3c449b8 /ipv6.c | |
| parent | 3852009b98d8a5f3447c95e45cdcf7e995a22613 (diff) | |
| download | dhcpcd-0b3255ac875375112d273cca8223c22dfe3af12d.tar.xz | |
Store acquired time for each IPv6 address so we can correctly offset
pltime and vltime if we need to re-add them.
Diffstat (limited to 'ipv6.c')
| -rw-r--r-- | ipv6.c | 45 |
1 files changed, 41 insertions, 4 deletions
@@ -602,11 +602,13 @@ ipv6_deleteaddr(struct ipv6_addr *addr) } int -ipv6_addaddr(struct ipv6_addr *ap) +ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now) { struct interface *ifp; struct ipv6_state *state; struct ipv6_addr *nap; + struct timeval n; + uint32_t pltime, vltime; /* Ensure no other interface has this address */ TAILQ_FOREACH(ifp, ap->iface->ctx->ifaces, next) { @@ -623,6 +625,24 @@ ipv6_addaddr(struct ipv6_addr *ap) } } + /* Adjust plftime and vltime based on acquired time */ + pltime = ap->prefix_pltime; + vltime = ap->prefix_vltime; + if (timerisset(&ap->acquired) && + (ap->prefix_pltime != ND6_INFINITE_LIFETIME || + ap->prefix_vltime != ND6_INFINITE_LIFETIME)) + { + if (now == NULL) { + get_monotonic(&n); + now = &n; + } + timersub(now, &ap->acquired, &n); + if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) + ap->prefix_pltime -= n.tv_sec; + if (ap->prefix_vltime != ND6_INFINITE_LIFETIME) + ap->prefix_vltime -= n.tv_sec; + } + syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG, "%s: adding address %s", ap->iface->name, ap->saddr); if (!(ap->flags & IPV6_AF_DADCOMPLETED) && @@ -630,8 +650,15 @@ ipv6_addaddr(struct ipv6_addr *ap) ap->flags |= IPV6_AF_DADCOMPLETED; if (if_addaddress6(ap) == -1) { syslog(LOG_ERR, "if_addaddress6: %m"); + /* Restore real pltime and vltime */ + ap->prefix_pltime = pltime; + ap->prefix_vltime = vltime; return -1; } + + /* Restore real pltime and vltime */ + ap->prefix_pltime = pltime; + ap->prefix_vltime = vltime; ap->flags &= ~IPV6_AF_NEW; ap->flags |= IPV6_AF_ADDED; if (ap->delegating_iface) @@ -695,8 +722,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs) { struct ipv6_addr *ap, *apn, *apf; ssize_t i; + struct timeval now; i = 0; + timerclear(&now); TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { if (ap->prefix_vltime == 0) { if (ap->flags & IPV6_AF_ADDED) { @@ -741,7 +770,9 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs) apf->flags &= ~IPV6_AF_ADDED; if (ap->flags & IPV6_AF_NEW) i++; - ipv6_addaddr(ap); + if (!timerisset(&now)) + get_monotonic(&now); + ipv6_addaddr(ap, &now); } } @@ -753,7 +784,9 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop, const struct interface *ifd) { struct ipv6_addr *ap, *apn, *apf; + struct timeval now; + timerclear(&now); TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { if (ifd && ap->delegating_iface != ifd) continue; @@ -772,7 +805,11 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop, ipv6_deleteaddr(ap); if (!(ap->iface->options->options & DHCPCD_EXITING) && apf) - ipv6_addaddr(apf); + { + if (!timerisset(&now)) + get_monotonic(&now); + ipv6_addaddr(apf, &now); + } } free(ap); } @@ -1078,7 +1115,7 @@ nextslaacprivate: inet_ntop(AF_INET6, &ap->addr, ap->saddr, sizeof(ap->saddr)); TAILQ_INSERT_TAIL(&state->addrs, ap, next); - ipv6_addaddr(ap); + ipv6_addaddr(ap, NULL); return 1; } |
