]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Revert part of the prior patch and only free IPv6 if state when
authorRoy Marples <roy@marples.name>
Tue, 20 Jan 2015 12:04:42 +0000 (12:04 +0000)
committerRoy Marples <roy@marples.name>
Tue, 20 Jan 2015 12:04:42 +0000 (12:04 +0000)
freeing and not dropping so we retain IPv6 addresses we don't
generally control on carrier down.

if.c
ipv6.c

diff --git a/if.c b/if.c
index b41a2eb21e164afb5e2ab12429566aeb3a41b24e..78bc27f4d24dde212ed640eb924d71c728069293 100644 (file)
--- a/if.c
+++ b/if.c
@@ -83,9 +83,9 @@ if_free(struct interface *ifp)
                return;
        ipv4_free(ifp);
        dhcp_free(ifp);
-       ipv6_free(ifp);
        dhcp6_free(ifp);
        ipv6nd_free(ifp);
+       ipv6_free(ifp);
        free_options(ifp->options);
        free(ifp);
 }
diff --git a/ipv6.c b/ipv6.c
index bb17cb3737b2af88d8be5c618bbde233f292c320..bf9de6b5248b13aabaa553d6c4aafe85b53f0c58 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -835,13 +835,16 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
        TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
                if (ifd && ap->delegating_iface != ifd)
                        continue;
-               TAILQ_REMOVE(addrs, ap, next);
+               if (drop != 2)
+                       TAILQ_REMOVE(addrs, ap, next);
                eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap);
                if (drop && ap->flags & IPV6_AF_ADDED &&
                    (ap->iface->options->options &
                    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
                    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
                {
+                       if (drop == 2)
+                               TAILQ_REMOVE(addrs, ap, next);
                        /* Find the same address somewhere else */
                        apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0);
                        if (apf == NULL ||
@@ -855,8 +858,11 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
                                        get_monotonic(&now);
                                ipv6_addaddr(apf, &now);
                        }
+                       if (drop == 2)
+                               free(ap);
                }
-               free(ap);
+               if (drop != 2)
+                       free(ap);
        }
 }
 
@@ -1227,18 +1233,24 @@ ipv6_freedrop(struct interface *ifp, int drop)
        struct ipv6_state *state;
        struct ll_callback *cb;
 
-       if (ifp) {
-               state = IPV6_STATE(ifp);
-               if (state) {
-                       while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
-                               TAILQ_REMOVE(&state->ll_callbacks, cb, next);
-                               free(cb);
-                       }
-                       ipv6_freedrop_addrs(&state->addrs, drop, NULL);
-                       free(state);
-                       ifp->if_data[IF_DATA_IPV6] = NULL;
-                       eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+       if (ifp == NULL)
+               return;
+
+       if ((state = IPV6_STATE(ifp)) == NULL)
+               return;
+
+       ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
+
+       /* Becuase we need to cache the addresses we don't control,
+        * we only free the state on when NOT dropping addresses. */
+       if (drop == 0) {
+               while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
+                       TAILQ_REMOVE(&state->ll_callbacks, cb, next);
+                       free(cb);
                }
+               free(state);
+               ifp->if_data[IF_DATA_IPV6] = NULL;
+               eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
        }
 }