diff options
| author | Roy Marples <roy@marples.name> | 2016-08-03 20:38:31 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2016-08-03 20:38:31 +0000 |
| commit | 6d189cb65f5fbc8898841baf86f5288ae41b70b5 (patch) | |
| tree | fb23f0fc5d8dd312a3cb8c08d2a4e177fb31752f /ipv6nd.c | |
| parent | 518f8810294b409acd596079fa70a946a8025d86 (diff) | |
| download | dhcpcd-6d189cb65f5fbc8898841baf86f5288ae41b70b5.tar.xz | |
Expire IPv6 RA Prefix routes.
Diffstat (limited to 'ipv6nd.c')
| -rw-r--r-- | ipv6nd.c | 34 |
1 files changed, 34 insertions, 0 deletions
@@ -1329,6 +1329,7 @@ ipv6nd_expirera(void *arg) 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); @@ -1362,6 +1363,39 @@ ipv6nd_expirera(void *arg) } } + /* 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. |
