Always start IPv6 DAD asynchronously.

Otherwise we transmit the first neighbour solicitation in the context of the
caller of nd6_dad_start(), which can easily result in lock recursion. When
DAD is to be started after some delay, we send the first NS from the DAD
callout handler, so just change the implementation to do this in the
non-delayed case as well.

Reviewed by:	ae, hrs
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D6639
This commit is contained in:
markj 2016-06-02 17:17:15 +00:00
parent 0c382ea647
commit 71ff51c027

View File

@ -1216,7 +1216,6 @@ nd6_dad_start(struct ifaddr *ifa, int delay)
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
struct dadq *dp;
char ip6buf[INET6_ADDRSTRLEN];
int send_ns;
/*
* If we don't need DAD, don't do it.
@ -1290,12 +1289,7 @@ nd6_dad_start(struct ifaddr *ifa, int delay)
dp->dad_ns_lcount = dp->dad_loopbackprobe = 0;
refcount_init(&dp->dad_refcnt, 1);
nd6_dad_add(dp);
send_ns = 0;
if (delay == 0) {
send_ns = 1;
delay = (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000;
}
nd6_dad_starttimer(dp, delay, send_ns);
nd6_dad_starttimer(dp, delay, 0);
}
/*