svn commit: r245244 - head/sys/netinet6

Andrey V. Elsukov ae at FreeBSD.org
Thu Jan 10 00:10:25 UTC 2013


Author: ae
Date: Thu Jan 10 00:10:24 2013
New Revision: 245244
URL: http://svnweb.freebsd.org/changeset/base/245244

Log:
  Simplify in6_setscope() function to get better performance.
  Currently we use interface indeces as zone IDs for link-local and
  interface-local scopes, and since we don't have any tool to configure
  zone IDs, there is no need to acquire the afdata lock several times per
  packet only to read if_index value.
  So, now in6_setscope reads zone IDs for interface-local, link-local and
  global scopes without a lock.
  
  Sponsored by:	Yandex LLC
  MFC after:	2 weeks

Modified:
  head/sys/netinet6/scope6.c

Modified: head/sys/netinet6/scope6.c
==============================================================================
--- head/sys/netinet6/scope6.c	Wed Jan  9 21:27:14 2013	(r245243)
+++ head/sys/netinet6/scope6.c	Thu Jan 10 00:10:24 2013	(r245244)
@@ -420,59 +420,30 @@ in6_setscope(struct in6_addr *in6, struc
 	 * interface.
 	 */
 	if (IN6_IS_ADDR_LOOPBACK(in6)) {
-		if (!(ifp->if_flags & IFF_LOOPBACK)) {
+		if (!(ifp->if_flags & IFF_LOOPBACK))
 			return (EINVAL);
-		} else {
-			if (ret_id != NULL)
-				*ret_id = 0; /* there's no ambiguity */
-			return (0);
+	} else {
+		scope = in6_addrscope(in6);
+		if (scope == IPV6_ADDR_SCOPE_INTFACELOCAL ||
+		    scope == IPV6_ADDR_SCOPE_LINKLOCAL) {
+			/*
+			 * Currently we use interface indeces as the
+			 * zone IDs for interface-local and link-local
+			 * scopes.
+			 */
+			zoneid = ifp->if_index;
+			in6->s6_addr16[1] = htons(zoneid & 0xffff); /* XXX */
+		} else if (scope != IPV6_ADDR_SCOPE_GLOBAL) {
+			IF_AFDATA_RLOCK(ifp);
+			sid = SID(ifp);
+			zoneid = sid->s6id_list[scope];
+			IF_AFDATA_RUNLOCK(ifp);
 		}
 	}
 
-	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 */
-		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_INTFACELOCAL];
-		break;
-
-	case IPV6_ADDR_SCOPE_LINKLOCAL:
-		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL];
-		break;
-
-	case IPV6_ADDR_SCOPE_SITELOCAL:
-		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL];
-		break;
-
-	case IPV6_ADDR_SCOPE_ORGLOCAL:
-		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL];
-		break;
-
-	default:
-		zoneid = 0;	/* XXX: treat as global. */
-		break;
-	}
-	IF_AFDATA_RUNLOCK(ifp);
-
 	if (ret_id != NULL)
 		*ret_id = zoneid;
 
-	if (IN6_IS_SCOPE_EMBED(in6))
-		in6->s6_addr16[1] = htons(zoneid & 0xffff); /* XXX */
-
 	return (0);
 }
 


More information about the svn-src-all mailing list