changeset 5239:4507bcbe200d draft

IPv4LL: Fix for non NetBSD
author Roy Marples <roy@marples.name>
date Wed, 20 May 2020 14:07:36 +0100
parents 73659576d485
children 0281af78918f
files src/arp.c src/arp.h src/ipv4ll.c
diffstat 3 files changed, 29 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- 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 *
--- 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 *);
--- 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
 }