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>