mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-24 16:10:11 +00:00
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
This commit is contained in:
parent
c9bfe3d179
commit
3ea87cb57f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=245244
@ -420,59 +420,30 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id)
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user