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);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to