ARP states.
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;
}
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 *);
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;
}
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;
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);
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;
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;