]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
When deleting IPv6 addresses, remove them from our internal address state
authorRoy Marples <roy@marples.name>
Mon, 3 Mar 2014 13:56:49 +0000 (13:56 +0000)
committerRoy Marples <roy@marples.name>
Mon, 3 Mar 2014 13:56:49 +0000 (13:56 +0000)
as well so we perform DAD when rebinding.
Remove debug added with prior commit.

dhcp6.c
ipv6.c

diff --git a/dhcp6.c b/dhcp6.c
index 22c6b1f454dc0787de1e988e7c371b3879c0a1b9..6fe54a246fa5aad9c6322a7c64b1f48d8a5c8f12 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -1545,7 +1545,7 @@ dhcp6_findia(struct interface *ifp, const uint8_t *d, size_t l,
                        TAILQ_REMOVE(&state->addrs, ap, next);
                        if (ap->dadcallback)
                                eloop_q_timeout_delete(ap->iface->ctx->eloop,
-                                   0, NULL, ap->dadcallback);
+                                   0, NULL, ap);
                        free(ap);
                }
        }
@@ -2392,6 +2392,7 @@ recv:
                            dhcp6_startexpire, ifp);
                if (ifp->options->ia_type == D6_OPTION_IA_PD)
                        dhcp6_delegate_prefix(ifp);
+
                ipv6nd_probeaddrs(&state->addrs);
                if (state->state == DH6S_INFORMED)
                        syslog(has_new ? LOG_INFO : LOG_DEBUG,
@@ -2409,9 +2410,9 @@ recv:
                /* If all addresses have completed DAD run the script */
                TAILQ_FOREACH(ap, &state->addrs, next) {
                        if (ap->flags & IPV6_AF_ONLINK) {
-//                             if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
-//                                 ipv6_findaddr(ap->iface, &ap->addr))
-//                                     ap->flags |= IPV6_AF_DADCOMPLETED;
+                               if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
+                                   ipv6_findaddr(ap->iface, &ap->addr))
+                                       ap->flags |= IPV6_AF_DADCOMPLETED;
                                if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
                                        len = 0;
                                        break;
diff --git a/ipv6.c b/ipv6.c
index 8e917e64d59624968b3fdb9d7e509cb4d2cbb9a7..284c57a034129e87e9ea5145cfee77ee9625f210 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -488,6 +488,8 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
     const struct interface *ifd)
 {
        struct ipv6_addr *ap, *apn;
+       struct ipv6_state *state;
+       struct ipv6_addr_l *lap;
 
        TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
                if (ifd && ap->delegating_iface != ifd)
@@ -509,6 +511,21 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
                        if (del_address6(ap) == -1 &&
                            errno != EADDRNOTAVAIL && errno != ENXIO)
                                syslog(LOG_ERR, "del_address6 %m");
+
+                       /* Remove it from our internal state */
+                       state = IPV6_STATE(ap->iface);
+                       if (state) {
+                               TAILQ_FOREACH(lap, &state->addrs, next) {
+                                       if (IN6_ARE_ADDR_EQUAL(&lap->addr,
+                                           &ap->addr))
+                                       {
+                                               TAILQ_REMOVE(&state->addrs,
+                                                   lap, next);
+                                               free(lap);
+                                               break;
+                                       }
+                               }
+                       }
                }
                free(ap);
        }