summaryrefslogtreecommitdiffstats
path: root/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-06-12 10:58:28 +0000
committerRoy Marples <roy@marples.name>2013-06-12 10:58:28 +0000
commit8fdedf593b1b7bfa89a04975381462addd3b5e57 (patch)
tree00c6720db21e679ad0aa49783859564207819ad6 /ipv6.c
parent37028d2c8166747cc8f78fd1b92882311429096b (diff)
downloaddhcpcd-8fdedf593b1b7bfa89a04975381462addd3b5e57.tar.xz
Ensure we have the correct type to send in our saved lease as the
user could change from IA_PD to IA_NA. Re-send INFORM_REQUEST at each ROUTERADVERT. Save some code by sharing the drop addrs loop.
Diffstat (limited to 'ipv6.c')
-rw-r--r--ipv6.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/ipv6.c b/ipv6.c
index b706ab2f..de5513e8 100644
--- a/ipv6.c
+++ b/ipv6.c
@@ -443,6 +443,34 @@ ipv6_addaddr(struct ipv6_addr *ap)
return 0;
}
+void
+ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
+ const struct interface *ifd)
+{
+ struct ipv6_addr *ap, *apn;
+
+ TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
+ if (ifd && ap->delegating_iface != ifd)
+ continue;
+ TAILQ_REMOVE(addrs, ap, next);
+ if (ap->dadcallback)
+ eloop_q_timeout_delete(0, NULL, ap->dadcallback);
+ /* Only drop the address if no other RAs have assigned it.
+ * This is safe because the RA is removed from the list
+ * before we are called. */
+ if (drop && ap->flags & IPV6_AF_ADDED &&
+ !ipv6rs_addrexists(ap) && !dhcp6_addrexists(ap))
+ {
+ syslog(LOG_INFO, "%s: deleting address %s",
+ ap->iface->name, ap->saddr);
+ if (del_address6(ap) == -1 &&
+ errno != EADDRNOTAVAIL && errno != ENXIO)
+ syslog(LOG_ERR, "del_address6 %m");
+ }
+ free(ap);
+ }
+}
+
static struct ipv6_state *
ipv6_getstate(struct interface *ifp)
{