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
Archive administrator: postmaster@marples.name