]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Only remove IPv6 addresses when no RA's have them configured.
authorRoy Marples <roy@marples.name>
Wed, 14 Nov 2012 10:16:30 +0000 (10:16 +0000)
committerRoy Marples <roy@marples.name>
Wed, 14 Nov 2012 10:16:30 +0000 (10:16 +0000)
ipv6rs.c

index 3737d91c2ef09b25b9c1f9254b80adde1bb7a242..31a5230984138b8da2f88e013989f18d20b35479 100644 (file)
--- a/ipv6rs.c
+++ b/ipv6rs.c
@@ -262,6 +262,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)
 {
@@ -269,7 +284,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)