Don't cover in6_ifattach() with network epoch, as it may call into

network drivers ioctls, that may sleep.

PR:		241223
This commit is contained in:
Gleb Smirnoff 2019-10-13 04:25:16 +00:00
parent bff630d1dc
commit ef2e580e56
3 changed files with 18 additions and 6 deletions

View File

@ -1930,12 +1930,12 @@ in6_if_up(struct ifnet *ifp)
arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz));
}
}
NET_EPOCH_EXIT(et);
/*
* special cases, like 6to4, are handled in in6_ifattach
*/
in6_ifattach(ifp, NULL);
NET_EPOCH_EXIT(et);
}
int

View File

@ -423,6 +423,7 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
struct in6_ifaddr *ia;
struct in6_aliasreq ifra;
struct nd_prefixctl pr0;
struct epoch_tracker et;
struct nd_prefix *pr;
int error;
@ -437,7 +438,10 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0;
ifra.ifra_addr.sin6_addr.s6_addr32[3] = htonl(1);
} else {
if (get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr) != 0) {
NET_EPOCH_ENTER(et);
error = get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr);
NET_EPOCH_EXIT(et);
if (error != 0) {
nd6log((LOG_ERR,
"%s: no ifid available\n", if_name(ifp)));
return (-1);
@ -472,7 +476,9 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
return (-1);
}
NET_EPOCH_ENTER(et);
ia = in6ifa_ifpforlinklocal(ifp, 0);
NET_EPOCH_EXIT(et);
if (ia == NULL) {
/*
* Another thread removed the address that we just added.
@ -667,8 +673,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
{
struct in6_ifaddr *ia;
NET_EPOCH_ASSERT();
if (ifp->if_afdata[AF_INET6] == NULL)
return;
/*
@ -718,7 +722,11 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
*/
if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) {
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
ia = in6ifa_ifpforlinklocal(ifp, 0);
NET_EPOCH_EXIT(et);
if (ia == NULL)
in6_ifattach_linklocal(ifp, altifp);
else

View File

@ -1691,7 +1691,6 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
struct ifaddr *ifa;
struct in6_ifaddr *ia;
NET_EPOCH_ENTER(et);
if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
!(ND.flags & ND6_IFF_IFDISABLED)) {
/* ifdisabled 1->0 transision */
@ -1702,6 +1701,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
* do not clear ND6_IFF_IFDISABLED.
* See RFC 4862, Section 5.4.5.
*/
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1710,6 +1710,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
break;
}
NET_EPOCH_EXIT(et);
if (ifa != NULL) {
/* LLA is duplicated. */
@ -1730,6 +1731,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
if (V_ip6_dad_count > 0 &&
(ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) {
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
ifa_link) {
if (ifa->ifa_addr->sa_family !=
@ -1738,6 +1740,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
ia = (struct in6_ifaddr *)ifa;
ia->ia6_flags |= IN6_IFF_TENTATIVE;
}
NET_EPOCH_EXIT(et);
}
}
@ -1756,6 +1759,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
* address is assigned, and IFF_UP, try to
* assign one.
*/
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
ifa_link) {
if (ifa->ifa_addr->sa_family !=
@ -1765,13 +1769,13 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
break;
}
NET_EPOCH_EXIT(et);
if (ifa != NULL)
/* No LLA is configured. */
in6_ifattach(ifp, NULL);
}
}
ND_IFINFO(ifp)->flags = ND.flags;
NET_EPOCH_EXIT(et);
break;
}
#undef ND