Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Jul 2012 02:54:23 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r237946 - stable/8/sys/netinet6
Message-ID:  <201207020254.q622sN1a038970@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Mon Jul  2 02:54:22 2012
New Revision: 237946
URL: http://svn.freebsd.org/changeset/base/237946

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/8/sys/netinet6/in6.c
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/netinet6/in6.c
==============================================================================
--- stable/8/sys/netinet6/in6.c	Mon Jul  2 02:50:10 2012	(r237945)
+++ stable/8/sys/netinet6/in6.c	Mon Jul  2 02:54:22 2012	(r237946)
@@ -1198,6 +1198,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;
 
 	/*
@@ -1224,6 +1225,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, 
@@ -1250,15 +1264,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 {
@@ -1300,15 +1306,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 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207020254.q622sN1a038970>