diff options
| author | Roy Marples <roy@marples.name> | 2015-05-06 15:21:56 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2015-05-06 15:21:56 +0000 |
| commit | 474ba00c161e950a39111c7d3b37b3176d898b69 (patch) | |
| tree | 5e330c923985da7f4672f1fc909aaf02747f6a4f /ipv6.c | |
| parent | bbba67d0f8a0b70dca42e43841e52f1ec0ea2d85 (diff) | |
| download | dhcpcd-474ba00c161e950a39111c7d3b37b3176d898b69.tar.xz | |
Fix IPv6 prefix underflow when confirming deprecated but valid leases.
Diffstat (limited to 'ipv6.c')
| -rw-r--r-- | ipv6.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -689,20 +689,32 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now) now = &n; } timespecsub(now, &ap->acquired, &n); - if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) + if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) { ap->prefix_pltime -= (uint32_t)n.tv_sec; + /* This can happen when confirming a + * deprecated but still valid lease. */ + if (ap->prefix_pltime > pltime) + ap->prefix_pltime = 0; + } if (ap->prefix_vltime != ND6_INFINITE_LIFETIME) ap->prefix_vltime -= (uint32_t)n.tv_sec; - } - if (if_addaddress6(ap) == -1) { - logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m"); #if 0 logger(ap->iface->ctx, LOG_DEBUG, + "%s: acquired %lld.%.9ld, now %lld.%.9ld, diff %lld.%.9ld", + ap->iface->name, + (long long)ap->acquired.tv_sec, ap->acquired.tv_nsec, + (long long)now->tv_sec, now->tv_nsec, + (long long)n.tv_sec, n.tv_nsec); + logger(ap->iface->ctx, LOG_DEBUG, "%s: adj pltime %"PRIu32" seconds, " "vltime %"PRIu32" seconds", ap->iface->name, ap->prefix_pltime, ap->prefix_vltime); #endif + } + + if (if_addaddress6(ap) == -1) { + logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m"); /* Restore real pltime and vltime */ ap->prefix_pltime = pltime; ap->prefix_vltime = vltime; |
