send_rebind(ifp);
}
-#ifdef ARP
static void
-dhcp_arp_probed(struct arp_state *astate)
+dhcp_finish_dad(struct interface *ifp, struct in_addr *ia)
{
- struct interface *ifp;
- struct dhcp_state *state;
- struct if_options *ifo;
+ struct dhcp_state *state = D_STATE(ifp);
- ifp = astate->iface;
- state = D_STATE(ifp);
- ifo = ifp->options;
-#ifdef ARPING
- if (ifo->arping_len && state->arping_index < ifo->arping_len) {
- /* We didn't find a profile for this
- * address or hwaddr, so move to the next
- * arping profile */
- if (++state->arping_index < ifo->arping_len) {
- astate->addr.s_addr =
- ifo->arping[state->arping_index];
- arp_probe(astate);
- return;
- }
- arp_free(astate);
- dhcpcd_startinterface(ifp);
+ if (state->state != DHS_PROBE)
return;
- }
-#endif
-
- /* Already bound so DAD has worked */
- if (state->state == DHS_BOUND)
+ if (state->offer == NULL || state->offer->yiaddr != ia->s_addr)
return;
- logdebugx("%s: DAD completed for %s",
- ifp->name, inet_ntoa(astate->addr));
- if (!(ifo->options & DHCPCD_INFORM))
+ logdebugx("%s: DAD completed for %s", ifp->name, inet_ntoa(*ia));
+ if (!(ifp->options->options & DHCPCD_INFORM))
dhcp_bind(ifp);
- #ifndef IN_IFF_TENTATIVE
+ #ifndef IN_IFF_DUPLICATED
else {
struct bootp *bootp;
size_t len;
/* If the interface already has the address configured
* then we can't ARP for duplicate detection. */
ia = ipv4_iffindaddr(ifp, &addr, NULL);
- #ifdef IN_IFF_TENTATIVE
- astate = dhcp_arp_new(ifp, &addr);
- if (astate == NULL)
- return -1;
-
+ #ifdef IN_IFF_NOTUSEABLE
if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) {
state->state = DHS_PROBE;
if (ia == NULL) {
if (ia == NULL)
ia = ipv4_iffindlladdr(ifp);
- #ifdef IN_IFF_TENTATIVE
+ repick = false;
+ #ifdef IN_IFF_DUPLICATED
if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
+ state->pickedaddr = ia->addr; /* So it's not picked again. */
+ repick = true;
ipv4_deladdr(ia, 0);
ia = NULL;
}
ifp->name, inet_ntoa(ia->addr));
return;
}
+ #endif
+ #ifdef IN_IFF_DUPLICATED
loginfox("%s: using IPv4LL address %s", ifp->name, ia->saddr);
#endif
- ipv4ll_probed(astate);
+ ipv4ll_not_found(ifp);
return;
}
loginfox("%s: probing for an IPv4LL address", ifp->name);
- if (state->pickedaddr.s_addr == INADDR_ANY)
- state->pickedaddr.s_addr = ipv4ll_pickaddr(astate);
+ if (repick || state->pickedaddr.s_addr == INADDR_ANY)
+ state->pickedaddr.s_addr = ipv4ll_pickaddr(ifp);
+#ifndef KERNEL_RFC5227
astate->addr = state->pickedaddr;
- #ifdef IN_IFF_TENTATIVE
+#endif
- ipv4ll_probed(astate);
+ #ifdef IN_IFF_DUPLICATED
+ ipv4ll_not_found(ifp);
#else
arp_probe(astate);
#endif