svn commit: r353461 - head/sys/netinet6

Gleb Smirnoff glebius at FreeBSD.org
Sun Oct 13 04:25:17 UTC 2019


Author: glebius
Date: Sun Oct 13 04:25:16 2019
New Revision: 353461
URL: https://svnweb.freebsd.org/changeset/base/353461

Log:
  Don't cover in6_ifattach() with network epoch, as it may call into
  network drivers ioctls, that may sleep.
  
  PR:		241223

Modified:
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_ifattach.c
  head/sys/netinet6/nd6.c

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Sun Oct 13 00:08:17 2019	(r353460)
+++ head/sys/netinet6/in6.c	Sun Oct 13 04:25:16 2019	(r353461)
@@ -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

Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c	Sun Oct 13 00:08:17 2019	(r353460)
+++ head/sys/netinet6/in6_ifattach.c	Sun Oct 13 04:25:16 2019	(r353461)
@@ -423,6 +423,7 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet
 	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
 		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
 		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

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Sun Oct 13 00:08:17 2019	(r353460)
+++ head/sys/netinet6/nd6.c	Sun Oct 13 04:25:16 2019	(r353461)
@@ -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


More information about the svn-src-head mailing list