svn commit: r237945 - stable/9/sys/netinet6

Xin LI delphij at FreeBSD.org
Mon Jul 2 02:50:11 UTC 2012


Author: delphij
Date: Mon Jul  2 02:50:10 2012
New Revision: 237945
URL: http://svn.freebsd.org/changeset/base/237945

Log:
  MFC r237571:
  
  Fix a LOR acquiring the if_afdata lock while holding an rtentry lock.
  Possibly do some entra work in case we would not get into the
  ifa0 != NULL paths later as we already do for the mltaddr before.
  
  XXX We should possibly error in case in6_setscope fails.
  
  Reference: http://lists.freebsd.org/pipermail/freebsd-net/2011-September/029829.html
  
  Submitted by:	bz

Modified:
  stable/9/sys/netinet6/in6.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/netinet6/in6.c
==============================================================================
--- stable/9/sys/netinet6/in6.c	Mon Jul  2 02:45:33 2012	(r237944)
+++ stable/9/sys/netinet6/in6.c	Mon Jul  2 02:50:10 2012	(r237945)
@@ -1304,6 +1304,7 @@ in6_purgeaddr_mc(struct ifnet *ifp, stru
 	struct sockaddr_in6 mltaddr, mltmask;
 	struct in6_multi_mship *imm;
 	struct rtentry *rt;
+	struct sockaddr_in6 sin6;
 	int error;
 
 	/*
@@ -1330,6 +1331,19 @@ in6_purgeaddr_mc(struct ifnet *ifp, stru
 	if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
 		return (error);
 
+	/*
+	 * As for the mltaddr above, proactively prepare the sin6 to avoid
+	 * rtentry un- and re-locking.
+	 */
+	if (ifa0 != NULL) {
+		bzero(&sin6, sizeof(sin6));
+		sin6.sin6_len = sizeof(sin6);
+		sin6.sin6_family = AF_INET6;
+		memcpy(&sin6.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr, 
+		    sizeof(sin6.sin6_addr));
+		in6_setscope(&sin6.sin6_addr, ifa0->ifa_ifp, NULL);
+	}
+
 	rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
 	if (rt != NULL && rt->rt_gateway != NULL &&
 	    (memcmp(&satosin6(rt->rt_gateway)->sin6_addr, 
@@ -1356,15 +1370,7 @@ in6_purgeaddr_mc(struct ifnet *ifp, stru
 			/*
 			 * Replace the gateway of the route.
 			 */
-			struct sockaddr_in6 sa;
-
-			bzero(&sa, sizeof(sa));
-			sa.sin6_len = sizeof(struct sockaddr_in6);
-			sa.sin6_family = AF_INET6;
-			memcpy(&sa.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr, 
-			       sizeof(sa.sin6_addr));
-			in6_setscope(&sa.sin6_addr, ifa0->ifa_ifp, NULL);
-			memcpy(rt->rt_gateway, &sa, sizeof(sa));
+			memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
 			RTFREE_LOCKED(rt);
 		}
 	} else {
@@ -1406,15 +1412,7 @@ in6_purgeaddr_mc(struct ifnet *ifp, stru
 			/*
 			 * Replace the gateway of the route.
 			 */
-			struct sockaddr_in6 sa;
-
-			bzero(&sa, sizeof(sa));
-			sa.sin6_len = sizeof(struct sockaddr_in6);
-			sa.sin6_family = AF_INET6;
-			memcpy(&sa.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr, 
-			       sizeof(sa.sin6_addr));
-			in6_setscope(&sa.sin6_addr, ifa0->ifa_ifp, NULL);
-			memcpy(rt->rt_gateway, &sa, sizeof(sa));
+			memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
 			RTFREE_LOCKED(rt);
 		}
 	} else {


More information about the svn-src-stable-9 mailing list