]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Let arp_new take an address so we never have duplicate
authorRoy Marples <roy@marples.name>
Fri, 1 May 2015 08:10:16 +0000 (08:10 +0000)
committerRoy Marples <roy@marples.name>
Fri, 1 May 2015 08:10:16 +0000 (08:10 +0000)
ARP states.

arp.c
arp.h
dhcp.c
ipv4ll.c

diff --git a/arp.c b/arp.c
index 8abeb6073b09c1bd5f790889ce0ef65b6b6c5fab..122752b629093bdae003a106209ee6217be6be70 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -285,19 +285,37 @@ arp_probe(struct arp_state *astate)
        arp_probe1(astate);
 }
 
+static struct arp_state *
+arp_find(struct interface *ifp, const struct in_addr *addr)
+{
+       struct arp_state *astate;
+       struct dhcp_state *state;
+
+       state = D_STATE(ifp);
+       TAILQ_FOREACH(astate, &state->arp_states, next) {
+               if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
+                       return astate;
+       }
+       errno = ESRCH;
+       return NULL;
+}
+
 struct arp_state *
-arp_new(struct interface *ifp) {
+arp_new(struct interface *ifp, const struct in_addr *addr)
+{
        struct arp_state *astate;
        struct dhcp_state *state;
 
-       astate = calloc(1, sizeof(*astate));
-       if (astate == NULL) {
+       if (addr && (astate = arp_find(ifp, addr)))
+               return astate;
+
+       if ((astate = calloc(1, sizeof(*astate))) == NULL) {
                logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
                return NULL;
        }
-
-       astate->iface = ifp;
        state = D_STATE(ifp);
+       astate->iface = ifp;
+       astate->addr = *addr;
        TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
        return astate;
 }
diff --git a/arp.h b/arp.h
index 8db8c3774cc8407b7cda45ea630ebc56872f217c..d0d4ed7df844f0f5e488776b4a776bdd56904c1d 100644 (file)
--- a/arp.h
+++ b/arp.h
@@ -69,7 +69,7 @@ TAILQ_HEAD(arp_statehead, arp_state);
 void arp_report_conflicted(const struct arp_state *, const struct arp_msg *);
 void arp_announce(struct arp_state *);
 void arp_probe(struct arp_state *);
-struct arp_state *arp_new(struct interface *);
+struct arp_state *arp_new(struct interface *, const struct in_addr *);
 void arp_cancel(struct arp_state *);
 void arp_free(struct arp_state *);
 void arp_free_but(struct arp_state *);
diff --git a/dhcp.c b/dhcp.c
index 685abfc9e1bcde4b001a2e87e2360e87fa304965..1a6aeb9603eca483c028f14d4f5f57a80fd36199 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1983,8 +1983,7 @@ applyaddr:
        if (ifo->options & DHCPCD_ARP) {
                if (state->added) {
                        if (astate == NULL) {
-                               astate = arp_new(ifp);
-                               astate->addr = state->addr;
+                               astate = arp_new(ifp, &state->addr);
                                astate->announced_cb =
                                    dhcp_arp_announced;
                        }
@@ -2412,10 +2411,8 @@ dhcp_probe(struct interface *ifp)
        const struct dhcp_state *state;
        struct arp_state *astate;
 
-       astate = arp_new(ifp);
-       if (astate) {
-               state = D_CSTATE(ifp);
-               astate->addr = state->addr;
+       state = D_CSTATE(ifp);
+       if ((astate = arp_new(ifp, &state->addr))) {
                astate->probed_cb = dhcp_arp_probed;
                astate->conflicted_cb = dhcp_arp_conflicted;
                astate->announced_cb = dhcp_arp_announced;
@@ -2731,9 +2728,8 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
                if (!ipv4_iffindaddr(ifp, &addr, NULL)) {
                        struct arp_state *astate;
 
-                       astate = arp_new(ifp);
+                       astate = arp_new(ifp, &addr);
                        if (astate) {
-                               astate->addr = addr;
                                astate->probed_cb = dhcp_arp_probed;
                                astate->conflicted_cb = dhcp_arp_conflicted;
                                arp_probe(astate);
@@ -3143,7 +3139,7 @@ dhcp_start1(void *arg)
        if (state->arping_index < ifo->arping_len) {
                struct arp_state *astate;
 
-               astate = arp_new(ifp);
+               astate = arp_new(ifp, NULL);
                if (astate) {
                        astate->probed_cb = dhcp_arp_probed;
                        astate->conflicted_cb = dhcp_arp_conflicted;
index f1ab920e694631a5d231cdecda5d30b344e9dbd6..e6569faa5b163f73d427b02f230d1e2b28b72b7c 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -218,7 +218,7 @@ ipv4ll_start(void *arg)
                initstate(seed, state->randomstate, sizeof(state->randomstate));
        }
 
-       if ((astate = arp_new(ifp)) == NULL)
+       if ((astate = arp_new(ifp, NULL)) == NULL)
                return;
 
        state->arp_ipv4ll = astate;