diff options
| author | Roy Marples <roy@marples.name> | 2019-12-17 22:16:26 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2019-12-17 22:21:25 +0000 |
| commit | 8ea376efd27bef6b9be26faca1838ebcb927a073 (patch) | |
| tree | 9635c51a881259c65bc0fd924cf4c27ad9f024ab /src/ipv6.c | |
| parent | 0e0af1e67a3045c78afee348e398e889a597bfed (diff) | |
| download | dhcpcd-8ea376efd27bef6b9be26faca1838ebcb927a073.tar.xz | |
DHCP6: Rework delegation deprecation
Split ipv6_addaddrs out so ipv6_doaddr can operate on a single address.
Call this when deprecating delegated addresses to avoid calling
ipv6_addaddrs.
This allows a more simple ipv6_addaddrs that doesn't need to test
which address collection we are deleting from and removes DHCPv6
specific code from the generic IPv6 module.
Diffstat (limited to 'src/ipv6.c')
| -rw-r--r-- | src/ipv6.c | 78 |
1 files changed, 40 insertions, 38 deletions
@@ -923,52 +923,54 @@ ipv6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, unsigned int #endif } +int +ipv6_doaddr(struct ipv6_addr *ia, struct timespec *now) +{ + + /* A delegated prefix is not an address. */ + if (ia->flags & IPV6_AF_DELEGATEDPFX) + return 0; + + if (ia->prefix_vltime == 0) { + if (ia->flags & IPV6_AF_ADDED) + ipv6_deleteaddr(ia); + eloop_q_timeout_delete(ia->iface->ctx->eloop, + 0, NULL, ia); + if (ia->flags & IPV6_AF_REQUEST) { + ia->flags &= ~IPV6_AF_ADDED; + return 0; + } + return -1; + } + + if (ia->flags & IPV6_AF_STALE || + IN6_IS_ADDR_UNSPECIFIED(&ia->addr)) + return 0; + + if (!timespecisset(now)) + clock_gettime(CLOCK_MONOTONIC, now); + ipv6_addaddr(ia, now); + return ia->flags & IPV6_AF_NEW ? 1 : 0; +} + ssize_t -ipv6_addaddrs(struct ipv6_addrhead *addrs) +ipv6_addaddrs(struct ipv6_addrhead *iaddrs) { - struct ipv6_addr *ap, *apn; - ssize_t i; struct timespec now; + struct ipv6_addr *ia, *ian; + ssize_t i, r; i = 0; timespecclear(&now); - TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { - /* A delegated prefix is not an address. */ - if (ap->flags & IPV6_AF_DELEGATEDPFX) - continue; - if (ap->prefix_vltime == 0) { - if (ap->flags & IPV6_AF_ADDED) { - ipv6_deleteaddr(ap); - i++; - } - eloop_q_timeout_delete(ap->iface->ctx->eloop, - 0, NULL, ap); - if (ap->flags & IPV6_AF_REQUEST) { - ap->flags &= ~IPV6_AF_ADDED; - } else { -#ifndef SMALL - if (ap->delegating_prefix != NULL && - addrs == &ap->delegating_prefix->pd_pfxs) { - TAILQ_REMOVE(addrs, ap, pd_next); - ap->delegating_prefix = NULL; - } else -#endif - { - TAILQ_REMOVE(addrs, ap, next); - ipv6_freeaddr(ap); - } - } - } else if (!(ap->flags & IPV6_AF_STALE) && - !IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) - { - if (ap->flags & IPV6_AF_NEW) - i++; - if (!timespecisset(&now)) - clock_gettime(CLOCK_MONOTONIC, &now); - ipv6_addaddr(ap, &now); + TAILQ_FOREACH_SAFE(ia, iaddrs, next, ian) { + r = ipv6_doaddr(ia, &now); + if (r != 0) + i++; + if (r == -1) { + TAILQ_REMOVE(iaddrs, ia, next); + ipv6_freeaddr(ia); } } - return i; } |
