dhcpcd-discuss

Re: dhcp6_listen: Address already in use

Roy Marples

Thu May 17 21:08:49 2018

On 17/05/2018 21:42, Moritz Warning wrote:
I think you forgot to append the patch.

diff --git a/src/dhcp6.c b/src/dhcp6.c
index 399f3785..01170336 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -1468,15 +1468,15 @@ dhcp6_dadcompleted(const struct interface *ifp)
 	return 1;
 }
 
-static void
+static int
 dhcp6_dadcallback(void *arg)
 {
-	struct ipv6_addr *ia = arg;
+	struct ipv6_addr *ia = arg, *ia2;
 	struct interface *ifp;
 	struct dhcp6_state *state;
-	int wascompleted, valid;
+	bool wascompleted, valid;
 
-	wascompleted = (ia->flags & IPV6_AF_DADCOMPLETED);
+	wascompleted = (ia->flags & IPV6_AF_DADCOMPLETED) ? true : false;
 	ia->flags |= IPV6_AF_DADCOMPLETED;
 	if (ia->flags & IPV6_AF_DUPLICATED) {
 		/* XXX FIXME
@@ -1484,41 +1484,39 @@ dhcp6_dadcallback(void *arg)
 		logwarnx("%s: DAD detected %s", ia->iface->name, ia->saddr);
 	}
 
-	if (!wascompleted) {
-		ifp = ia->iface;
+	if (wascompleted)
+		return 0;
 
-		state = D6_STATE(ifp);
-		if (state->state == DH6S_BOUND ||
-		    state->state == DH6S_DELEGATED)
-		{
-			struct ipv6_addr *ia2;
+	ifp = ia->iface;
+	state = D6_STATE(ifp);
+	if (state->state != DH6S_BOUND && state->state != DH6S_DELEGATED)
+		return 0;
 
 #ifdef SMALL
-			valid = true;
+	valid = true;
 #else
-			valid = (ia->delegating_prefix == NULL);
-#endif
-			TAILQ_FOREACH(ia2, &state->addrs, next) {
-				if (ia2->flags & IPV6_AF_ADDED &&
-				    !(ia2->flags & IPV6_AF_DADCOMPLETED))
-				{
-					wascompleted = 1;
-					break;
-				}
-			}
-			if (!wascompleted) {
-				logdebugx("%s: DHCPv6 DAD completed",
-				    ifp->name);
-				script_runreason(ifp,
-#ifndef SMALL
-				    ia->delegating_prefix ? "DELEGATED6" :
+	valid = (ia->delegating_prefix == NULL);
 #endif
-				    state->reason);
-				if (valid)
-					dhcpcd_daemonise(ifp->ctx);
-			}
+	TAILQ_FOREACH(ia2, &state->addrs, next) {
+		if (ia2->flags & IPV6_AF_ADDED &&
+		    !(ia2->flags & IPV6_AF_DADCOMPLETED))
+		{
+			wascompleted = true;
+			break;
 		}
 	}
+	if (wascompleted)
+		return 0;
+
+	logdebugx("%s: DHCPv6 DAD completed", ifp->name);
+	script_runreason(ifp,
+#ifndef SMALL
+	    ia->delegating_prefix ? "DELEGATED6" :
+#endif
+	    state->reason);
+	if (valid && dhcpcd_daemonise(ifp->ctx) != 0)
+		return 1;
+	return 0;
 }
 
 static void
@@ -3611,6 +3609,8 @@ dhcp6_listen(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
 	struct sockaddr_in6 sa;
 	int n, s;
 
+	loginfox("LISTENING TO %s", ia == NULL ? NULL : ia->saddr);
+
 #define SOCK_FLAGS	SOCK_CLOEXEC | SOCK_NONBLOCK
 	s = xsocket(PF_INET6, SOCK_DGRAM | SOCK_FLAGS, IPPROTO_UDP);
 #undef SOCK_FLAGS
@@ -3651,6 +3651,7 @@ errexit:
 	logerr(__func__);
 	if (s != -1)
 		close(s);
+	abort();
 	return -1;
 }
 
diff --git a/src/ipv6.c b/src/ipv6.c
index 82cf71b6..c72a195a 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1152,8 +1152,10 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 			}
 #endif
 
-			if (ia->dadcallback)
-				ia->dadcallback(ia);
+			if (ia->dadcallback) {
+				if (ia->dadcallback(ia))
+					return;
+			}
 
 			if (IN6_IS_ADDR_LINKLOCAL(&ia->addr) &&
 			    !(ia->addr_flags & IN6_IFF_NOTUSEABLE))
@@ -1174,14 +1176,15 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 		break;
 	}
 
-	if (ia != NULL) {
-		ipv6nd_handleifa(cmd, ia, pid);
-		dhcp6_handleifa(cmd, ia, pid);
+	if (ia == NULL)
+		return;
 
-		/* Done with the ia now, so free it. */
-		if (cmd == RTM_DELADDR)
-			ipv6_freeaddr(ia);
-	}
+	ipv6nd_handleifa(cmd, ia, pid);
+	dhcp6_handleifa(cmd, ia, pid);
+
+	/* Done with the ia now, so free it. */
+	if (cmd == RTM_DELADDR)
+		ipv6_freeaddr(ia);
 }
 
 int
@@ -1506,11 +1509,13 @@ err:
 	return NULL;
 }
 
-static void
+static int
 ipv6_staticdadcallback(void *arg)
 {
 	struct ipv6_addr *ia = arg;
 	int wascompleted;
+	struct interface *ifp;
+	struct ipv6_state *state;
 
 	wascompleted = (ia->flags & IPV6_AF_DADCOMPLETED);
 	ia->flags |= IPV6_AF_DADCOMPLETED;
@@ -1522,25 +1527,25 @@ ipv6_staticdadcallback(void *arg)
 		    ia->iface->name);
 	}
 
-#define FINISHED (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)
-	if (!wascompleted) {
-		struct interface *ifp;
-		struct ipv6_state *state;
+	if (wascompleted)
+		return 0;
 
-		ifp = ia->iface;
-		state = IPV6_STATE(ifp);
-		TAILQ_FOREACH(ia, &state->addrs, next) {
-			if (ia->flags & IPV6_AF_STATIC &&
-			    (ia->flags & FINISHED) != FINISHED)
-			{
-				wascompleted = 1;
-				break;
-			}
+#define FINISHED (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)
+	ifp = ia->iface;
+	state = IPV6_STATE(ifp);
+	TAILQ_FOREACH(ia, &state->addrs, next) {
+		if (ia->flags & IPV6_AF_STATIC &&
+		    (ia->flags & FINISHED) != FINISHED)
+		{
+			wascompleted = 1;
+			break;
 		}
-		if (!wascompleted)
-			script_runreason(ifp, "STATIC6");
 	}
+	if (!wascompleted)
+		script_runreason(ifp, "STATIC6");
 #undef FINISHED
+
+	return 0;
 }
 
 ssize_t
@@ -1744,8 +1749,10 @@ ipv6_handleifa_addrs(int cmd,
 					ia->flags |= IPV6_AF_DUPLICATED;
 				else
 					ia->flags &= ~IPV6_AF_DUPLICATED;
-				if (ia->dadcallback)
-					ia->dadcallback(ia);
+				if (ia->dadcallback) {
+					if (ia->dadcallback(ia))
+						goto out;
+				}
 				/* We need to set this here in-case the
 				 * dadcallback function checks it */
 				ia->flags |= IPV6_AF_DADCOMPLETED;
@@ -1754,6 +1761,7 @@ ipv6_handleifa_addrs(int cmd,
 		}
 	}
 
+out:
 	return alldadcompleted ? found : 0;
 }
 
@@ -1862,29 +1870,30 @@ again:
 }
 
 /* RFC4941 Section 3.3.7 */
-static void
+static int
 ipv6_tempdadcallback(void *arg)
 {
 	struct ipv6_addr *ia = arg;
+	struct ipv6_addr *ia1;
+	struct timespec tv;
 
-	if (ia->flags & IPV6_AF_DUPLICATED) {
-		struct ipv6_addr *ia1;
-		struct timespec tv;
+	if (!(ia->flags & IPV6_AF_DUPLICATED))
+		return 0;
 
-		if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
-			logerrx("%s: too many duplicate temporary addresses",
-			    ia->iface->name);
-			return;
-		}
-		clock_gettime(CLOCK_MONOTONIC, &tv);
-		if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
-			logerr(__func__);
-		else
-			ia1->dadcounter = ia->dadcounter;
-		ipv6_deleteaddr(ia);
-		if (ia1)
-			ipv6_addaddr(ia1, &ia1->acquired);
+	if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
+		logerrx("%s: too many duplicate temporary addresses",
+		    ia->iface->name);
+		return 0;
 	}
+	clock_gettime(CLOCK_MONOTONIC, &tv);
+	if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
+		logerr(__func__);
+	else
+		ia1->dadcounter = ia->dadcounter;
+	ipv6_deleteaddr(ia);
+	if (ia1)
+		ipv6_addaddr(ia1, &ia1->acquired);
+	return 0;
 }
 
 struct ipv6_addr *
diff --git a/src/ipv6.h b/src/ipv6.h
index 2b6eb5cc..80ff9b93 100644
--- a/src/ipv6.h
+++ b/src/ipv6.h
@@ -166,7 +166,7 @@ struct ipv6_addr {
 	struct in6_addr prefix_exclude;
 #endif
 
-	void (*dadcallback)(void *);
+	int (*dadcallback)(void *);
 	int dadcounter;
 
 #ifdef ALIAS_ADDR

Follow-Ups:
Re: dhcp6_listen: Address already in useMoritz Warning
References:
dhcp6_listen: Address already in useMoritz Warning
Re: dhcp6_listen: Address already in useRoy Marples
Re: dhcp6_listen: Address already in useMoritz Warning
Re: dhcp6_listen: Address already in useRoy Marples
Re: dhcp6_listen: Address already in useMoritz Warning
Re: dhcp6_listen: Address already in useRoy Marples
Re: dhcp6_listen: Address already in useMoritz Warning
Re: dhcp6_listen: Address already in useRoy Marples
Re: dhcp6_listen: Address already in useMoritz Warning
Re: dhcp6_listen: Address already in useRoy Marples
Re: dhcp6_listen: Address already in useMoritz Warning
Archive administrator: postmaster@marples.name