]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add an free callback to ARP states so that they can notify their parents they
authorRoy Marples <roy@marples.name>
Thu, 25 Jun 2015 15:36:28 +0000 (15:36 +0000)
committerRoy Marples <roy@marples.name>
Thu, 25 Jun 2015 15:36:28 +0000 (15:36 +0000)
are gone to avoid any double frees.
Fixes [5fdd9b8d08].

arp.c
arp.h
ipv4ll.c

diff --git a/arp.c b/arp.c
index 70dd324a02f6178045bf973148ef2ba82faf230a..f4369047fb4387c242f177057ac1746db8bd168d 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -98,7 +98,7 @@ void
 arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
 {
 
-       if (amsg) {
+       if (amsg != NULL) {
                char buf[HWADDR_LEN * 3];
 
                logger(astate->iface->ctx, LOG_ERR,
@@ -362,6 +362,8 @@ arp_free(struct arp_state *astate)
                eloop_timeout_delete(ifp->ctx->eloop, NULL, astate);
                state = ARP_STATE(ifp);
                TAILQ_REMOVE(&state->arp_states, astate, next);
+               if (astate->free_cb)
+                       astate->free_cb(astate);
                free(astate);
 
                /* If there are no more ARP states, close the socket. */
diff --git a/arp.h b/arp.h
index ce0e91fdce390993158a24dd7dabb9f9e3519ecb..6eb3808cc99c9a58ff0339d4d4cef7ab9f3e84a0 100644 (file)
--- a/arp.h
+++ b/arp.h
@@ -57,6 +57,7 @@ struct arp_state {
        void (*probed_cb)(struct arp_state *);
        void (*announced_cb)(struct arp_state *);
        void (*conflicted_cb)(struct arp_state *, const struct arp_msg *);
+       void (*free_cb)(struct arp_state *);
 
        struct in_addr addr;
        int probes;
index fee857f6cef63f4142781abf5ba0d37fe20990e2..e18bb5ef3d2cfba39d501eddd38aee2382ff1c40 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -243,6 +243,16 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
                ipv4ll_probe, astate);
 }
 
+static void
+ipv4ll_arpfree(struct arp_state *astate)
+{
+       struct ipv4ll_state *state;
+
+       state = IPV4LL_STATE(astate->iface);
+       if (state->arp == astate)
+               state->arp = NULL;
+}
+
 void
 ipv4ll_start(void *arg)
 {
@@ -289,6 +299,7 @@ ipv4ll_start(void *arg)
        astate->probed_cb = ipv4ll_probed;
        astate->announced_cb = ipv4ll_announced;
        astate->conflicted_cb = ipv4ll_conflicted;
+       astate->free_cb = ipv4ll_arpfree;
 
        /* Find an existing IPv4LL address and ensure we can work with it. */
        ia = ipv4_iffindlladdr(ifp);