From: Roy Marples Date: Fri, 1 May 2015 08:10:16 +0000 (+0000) Subject: Let arp_new take an address so we never have duplicate X-Git-Tag: v6.8.2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb5825b3e2ceaebb6764adfa978c56d707da03d5;p=thirdparty%2Fdhcpcd.git Let arp_new take an address so we never have duplicate ARP states. --- diff --git a/arp.c b/arp.c index 8abeb607..122752b6 100644 --- 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 8db8c377..d0d4ed7d 100644 --- 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 685abfc9..1a6aeb96 100644 --- 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; diff --git a/ipv4ll.c b/ipv4ll.c index f1ab920e..e6569faa 100644 --- 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;