summaryrefslogtreecommitdiffstats
path: root/ipv6rs.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2012-10-31 13:58:36 +0000
committerRoy Marples <roy@marples.name>2012-10-31 13:58:36 +0000
commit376e8b8055eda6a7458182997e7984f8b37ae309 (patch)
tree09b7fad902604fe7bbd5c52eb578d9fcc6bb21fa /ipv6rs.c
parent7c3772a86882b9cfc6436c66d2b99b365ab29007 (diff)
downloaddhcpcd-376e8b8055eda6a7458182997e7984f8b37ae309.tar.xz
Only remove IPv6 addresses when no RA's have them configured.
Diffstat (limited to 'ipv6rs.c')
-rw-r--r--ipv6rs.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/ipv6rs.c b/ipv6rs.c
index aaa5c717..155391e9 100644
--- a/ipv6rs.c
+++ b/ipv6rs.c
@@ -269,6 +269,21 @@ ipv6rs_free_opts(struct ra *rap)
}
}
+static int
+ipv6rs_addrexists(struct ipv6_addr *a)
+{
+ struct ra *rap;
+ struct ipv6_addr *ap;
+
+ TAILQ_FOREACH(rap, &ipv6_routers, next) {
+ TAILQ_FOREACH(ap, &rap->addrs, next) {
+ if (memcmp(&ap->addr, &a->addr, sizeof(a->addr)) == 0)
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
ipv6rs_freedrop_addrs(struct ra *rap, int drop)
{
@@ -276,7 +291,12 @@ ipv6rs_freedrop_addrs(struct ra *rap, int drop)
while ((ap = TAILQ_FIRST(&rap->addrs))) {
TAILQ_REMOVE(&rap->addrs, ap, next);
- if (drop && (options & DHCPCD_IPV6RA_OWN)) {
+ /* 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 && (options & DHCPCD_IPV6RA_OWN) &&
+ !ipv6rs_addrexists(ap))
+ {
syslog(LOG_INFO, "%s: deleting address %s",
rap->iface->name, ap->saddr);
if (del_address6(rap->iface, ap) == -1)