}
dhcp_close(astate->iface);
- /* Stop IPv4LL now we have a working DHCP address */
- ipv4ll_drop(astate->iface);
-
eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
#ifdef IN_IFF_TENTATIVE
logger(astate->iface->ctx, LOG_DEBUG, "%s: DAD completed for %s",
#else
dhcp_bind(astate->iface, astate);
#endif
+
+ /* Stop IPv4LL now we have a working DHCP address */
+ ipv4ll_drop(astate->iface);
}
static void
fail = astate->addr.s_addr;
/* RFC 3927 2.5, Conflict Defense */
- if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
+ if (IN_LINKLOCAL(ntohl(state->addr.s_addr)) &&
amsg && amsg->sip.s_addr == state->addr.s_addr)
fail = state->addr.s_addr;
struct ipv4ll_state *state;
assert(ifp != NULL);
- if ((state = IPV4LL_STATE(ifp)) == NULL)
- return;
+ state = IPV4LL_STATE(ifp);
/* Free ARP state first because ipv4_deladdr might also ... */
- if (state->arp) {
+ if (state && state->arp) {
eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp);
arp_free(state->arp);
state->arp = NULL;
/* Unlike other protocols, we don't run a script on stopping IPv4LL
* because we piggy back on the state of DHCP. */
if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) {
- if (state->addr.s_addr != INADDR_ANY) {
+ struct ipv4_state *istate;
+ struct ipv4_addr *ia, *ian;
+
+ if (state && state->addr.s_addr != INADDR_ANY) {
ipv4_deladdr(ifp, &state->addr, &inaddr_llmask);
state->addr.s_addr = INADDR_ANY;
}
+
+ /* Free any other link local addresses that might exist. */
+ istate = IPV4_STATE(ifp);
+ TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
+ if (IN_LINKLOCAL(ntohl(ia->addr.s_addr)))
+ ipv4_deladdr(ifp, &ia->addr, &ia->net);
+ }
+ }
+
+ if (state) {
+ free(state);
+ ifp->if_data[IF_DATA_IPV4LL] = NULL;
}
- free(state);
- ifp->if_data[IF_DATA_IPV4LL] = NULL;
}