# HG changeset patch # User Roy Marples # Date 1589980056 -3600 # Node ID 4507bcbe200deccd4515abc627ca9d4212ecfa77 # Parent 73659576d4850a038289691286d94b031c0a7559 IPv4LL: Fix for non NetBSD diff -r 73659576d485 -r 4507bcbe200d src/arp.c --- a/src/arp.c Wed May 20 12:23:25 2020 +0100 +++ b/src/arp.c Wed May 20 14:07:36 2020 +0100 @@ -478,25 +478,26 @@ arp_announce1(astate); } -void +struct arp_state * arp_ifannounceaddr(struct interface *ifp, const struct in_addr *ia) { struct arp_state *astate; if (ifp->flags & IFF_NOARP) - return; + return NULL; astate = arp_find(ifp, ia); if (astate == NULL) { astate = arp_new(ifp, ia); if (astate == NULL) - return; + return NULL; astate->announced_cb = arp_free; } arp_announce(astate); + return astate; } -void +struct arp_state * arp_announceaddr(struct dhcpcd_ctx *ctx, const struct in_addr *ia) { struct interface *ifp, *iff = NULL; @@ -517,9 +518,9 @@ iff = ifp; } if (iff == NULL) - return; + return NULL; - arp_ifannounceaddr(iff, ia); + return arp_ifannounceaddr(iff, ia); } struct arp_state * diff -r 73659576d485 -r 4507bcbe200d src/arp.h --- a/src/arp.h Wed May 20 12:23:25 2020 +0100 +++ b/src/arp.h Wed May 20 14:07:36 2020 +0100 @@ -97,8 +97,8 @@ struct arp_state *arp_new(struct interface *, const struct in_addr *); void arp_probe(struct arp_state *); void arp_announce(struct arp_state *); -void arp_announceaddr(struct dhcpcd_ctx *, const struct in_addr *); -void arp_ifannounceaddr(struct interface *, const struct in_addr *); +struct arp_state *arp_announceaddr(struct dhcpcd_ctx *, const struct in_addr *); +struct arp_state *arp_ifannounceaddr(struct interface *, const struct in_addr *); void arp_cancel(struct arp_state *); struct arp_state * arp_find(struct interface *, const struct in_addr *); void arp_free(struct arp_state *); diff -r 73659576d485 -r 4507bcbe200d src/ipv4ll.c --- a/src/ipv4ll.c Wed May 20 12:23:25 2020 +0100 +++ b/src/ipv4ll.c Wed May 20 14:07:36 2020 +0100 @@ -57,10 +57,10 @@ .s_addr = HTONL(LINKLOCAL_BCAST) }; -static in_addr_t +static void ipv4ll_pickaddr(struct interface *ifp) { - struct in_addr addr; + struct in_addr addr = { .s_addr = 0 }; struct ipv4ll_state *state; state = IPV4LL_STATE(ifp); @@ -86,7 +86,7 @@ /* Restore the original random state */ setstate(ifp->ctx->randomstate); - return addr.s_addr; + state->pickedaddr = addr; } int @@ -168,21 +168,18 @@ return 5; } -#ifndef KERNEL_RFC5227 static void ipv4ll_announced_arp(struct arp_state *astate) { struct ipv4ll_state *state = IPV4LL_STATE(astate->iface); state->conflicts = 0; - arp_free(astate); - if (state->arp == astate) - state->arp = NULL; } +#ifndef KERNEL_RFC5227 /* This is the callback by ARP freeing */ static void -ipv4ll_arpfree(struct arp_state *astate) +ipv4ll_free_arp(struct arp_state *astate) { struct ipv4ll_state *state; @@ -214,6 +211,7 @@ { struct ipv4ll_state *state; struct ipv4_addr *ia; + struct arp_state *astate; state = IPV4LL_STATE(ifp); ia = ipv4_iffindaddr(ifp, &state->pickedaddr, &inaddr_llmask); @@ -246,7 +244,9 @@ return; } rt_build(ifp->ctx, AF_INET); - arp_announceaddr(ifp->ctx, &ia->addr); + astate = arp_announceaddr(ifp->ctx, &ia->addr); + if (astate != NULL) + astate->announced_cb = ipv4ll_announced_arp; script_runreason(ifp, "IPV4LL"); dhcpcd_daemonise(ifp->ctx); } @@ -260,7 +260,7 @@ if (++state->conflicts == MAX_CONFLICTS) logerrx("%s: failed to acquire an IPv4LL address", ifp->name); - state->pickedaddr.s_addr = ipv4ll_pickaddr(ifp); + ipv4ll_pickaddr(ifp); eloop_timeout_add_sec(ifp->ctx->eloop, state->conflicts >= MAX_CONFLICTS ? RATE_LIMIT_INTERVAL : PROBE_WAIT, @@ -277,7 +277,7 @@ state->addr = NULL; rt_build(ifp->ctx, AF_INET); script_runreason(ifp, "IPV4LL"); - state->pickedaddr.s_addr = ipv4ll_pickaddr(ifp); + ipv4ll_pickaddr(ifp); ipv4ll_start(ifp); } @@ -384,17 +384,17 @@ #ifdef IN_IFF_DUPLICATED loginfox("%s: using IPv4LL address %s", ifp->name, ia->saddr); #endif - ipv4ll_not_found(ifp); - return; + } else { + loginfox("%s: probing for an IPv4LL address", ifp->name); + if (repick || state->pickedaddr.s_addr == INADDR_ANY) + ipv4ll_pickaddr(ifp); } - loginfox("%s: probing for an IPv4LL address", ifp->name); - if (repick || state->pickedaddr.s_addr == INADDR_ANY) - state->pickedaddr.s_addr = ipv4ll_pickaddr(ifp); - -#ifndef KERNEL_RFC5227 +#ifdef KERNEL_RFC5227 + ipv4ll_not_found(ifp); +#else ipv4ll_freearp(ifp); - state->arp = astate = arp_new(ifp, NULL); + state->arp = astate = arp_new(ifp, &state->pickedaddr); if (state->arp == NULL) return; @@ -402,12 +402,7 @@ astate->not_found_cb = ipv4ll_not_found_arp; astate->announced_cb = ipv4ll_announced_arp; astate->defend_failed_cb = ipv4ll_defend_failed_arp; - astate->free_cb = ipv4ll_arpfree; -#endif - -#ifdef IN_IFF_DUPLICATED - ipv4ll_not_found(ifp); -#else + astate->free_cb = ipv4ll_free_arp; arp_probe(astate); #endif }