Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Jun 2012 20:56:32 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r237571 - head/sys/netinet6
Message-ID:  <201206252056.q5PKuW6M094972@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Mon Jun 25 20:56:32 2012
New Revision: 237571
URL: http://svn.freebsd.org/changeset/base/237571

Log:
  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
  MFC after:	1 week

Modified:
  head/sys/netinet6/in6.c

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Mon Jun 25 19:59:08 2012	(r237570)
+++ head/sys/netinet6/in6.c	Mon Jun 25 20:56:32 2012	(r237571)
@@ -1330,6 +1330,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;
 
 	/*
@@ -1356,6 +1357,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, 
@@ -1382,15 +1396,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 {
@@ -1432,15 +1438,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?201206252056.q5PKuW6M094972>