Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jan 2013 00:36:06 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r245199 - head/sys/netinet6
Message-ID:  <201301090036.r090a6va065525@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Jan  9 00:36:06 2013
New Revision: 245199
URL: http://svnweb.freebsd.org/changeset/base/245199

Log:
  The in6_setscope() function determines the scope zone id of an address
  and embeds it into address. Inside the kernel we keep addresses with
  embedded zone id only for two scopes: link-local and interface-local.
  
  For other scopes this function is nop in most cases. To reduce an
  overhead of locking, first check that address is capable for embedding.
  Also, handle the loopback address before acquire the lock.
  
  Sponsored by:	Yandex LLC
  MFC after:	1 week

Modified:
  head/sys/netinet6/scope6.c

Modified: head/sys/netinet6/scope6.c
==============================================================================
--- head/sys/netinet6/scope6.c	Wed Jan  9 00:22:53 2013	(r245198)
+++ head/sys/netinet6/scope6.c	Wed Jan  9 00:36:06 2013	(r245199)
@@ -420,33 +420,34 @@ in6_setscope(struct in6_addr *in6, struc
 	u_int32_t zoneid = 0;
 	struct scope6_id *sid;
 
-	IF_AFDATA_RLOCK(ifp);
-
-	sid = SID(ifp);
-
-#ifdef DIAGNOSTIC
-	if (sid == NULL) { /* should not happen */
-		panic("in6_setscope: scope array is NULL");
-		/* NOTREACHED */
-	}
-#endif
-
 	/*
 	 * special case: the loopback address can only belong to a loopback
 	 * interface.
 	 */
 	if (IN6_IS_ADDR_LOOPBACK(in6)) {
 		if (!(ifp->if_flags & IFF_LOOPBACK)) {
-			IF_AFDATA_RUNLOCK(ifp);
 			return (EINVAL);
 		} else {
 			if (ret_id != NULL)
 				*ret_id = 0; /* there's no ambiguity */
-			IF_AFDATA_RUNLOCK(ifp);
 			return (0);
 		}
 	}
 
+	if (ret_id == NULL && !IN6_IS_SCOPE_EMBED(in6))
+		return (0);
+
+	IF_AFDATA_RLOCK(ifp);
+
+	sid = SID(ifp);
+
+#ifdef DIAGNOSTIC
+	if (sid == NULL) { /* should not happen */
+		panic("in6_setscope: scope array is NULL");
+		/* NOTREACHED */
+	}
+#endif
+
 	scope = in6_addrscope(in6);
 	switch (scope) {
 	case IPV6_ADDR_SCOPE_INTFACELOCAL: /* should be interface index */
@@ -474,7 +475,7 @@ in6_setscope(struct in6_addr *in6, struc
 	if (ret_id != NULL)
 		*ret_id = zoneid;
 
-	if (IN6_IS_SCOPE_LINKLOCAL(in6) || IN6_IS_ADDR_MC_INTFACELOCAL(in6))
+	if (IN6_IS_SCOPE_EMBED(in6))
 		in6->s6_addr16[1] = htons(zoneid & 0xffff); /* XXX */
 
 	return (0);



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