]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
IPv4LL: Fix for non NetBSD
authorRoy Marples <roy@marples.name>
Wed, 20 May 2020 13:07:36 +0000 (14:07 +0100)
committerRoy Marples <roy@marples.name>
Wed, 20 May 2020 13:07:36 +0000 (14:07 +0100)
src/arp.c
src/arp.h
src/ipv4ll.c

index b458e4512e01b1ad820e4dd6c47bcdce065e7e00..ee06a057d43656881cdf98900ce2dbaac97ddb7c 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -478,25 +478,26 @@ arp_announce(struct arp_state *astate)
        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 @@ arp_announceaddr(struct dhcpcd_ctx *ctx, const struct in_addr *ia)
                iff = ifp;
        }
        if (iff == NULL)
-               return;
+               return NULL;
 
-       arp_ifannounceaddr(iff, ia);
+       return arp_ifannounceaddr(iff, ia);
 }
 
 struct arp_state *
index f1074fa3527e0fb5b932cf82ecdad9b4c291c944..602317ca151794ffd3f8cdf51377aa26ca43b06b 100644 (file)
--- a/src/arp.h
+++ b/src/arp.h
@@ -97,8 +97,8 @@ void arp_packet(struct interface *, uint8_t *, size_t, unsigned int);
 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 *);
index efddc2a3afc917604af23064b2a400c0177b7b3f..e058f5aa2d73861ea30d15505bc3a26fcef674f9 100644 (file)
@@ -57,10 +57,10 @@ static const struct in_addr inaddr_llbcast = {
        .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 @@ again:
 
        /* Restore the original random state */
        setstate(ifp->ctx->randomstate);
-       return addr.s_addr;
+       state->pickedaddr = addr;
 }
 
 int
@@ -168,21 +168,18 @@ ipv4ll_env(FILE *fp, const char *prefix, const struct interface *ifp)
        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 @@ ipv4ll_not_found(struct interface *ifp)
 {
        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 @@ test:
                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 @@ ipv4ll_found(struct interface *ifp)
        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 @@ ipv4ll_defend_failed(struct interface *ifp)
        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 @@ ipv4ll_start(void *arg)
 #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 @@ ipv4ll_start(void *arg)
        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
 }