Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/scope6.c
Show First 20 Lines • Show All 537 Lines • ▼ Show 20 Lines | in6_splitscope(const struct in6_addr *src, struct in6_addr *dst, | ||||
*dst = *src; | *dst = *src; | ||||
zoneid = ntohs(in6_getscope(dst)); | zoneid = ntohs(in6_getscope(dst)); | ||||
in6_clearscope(dst); | in6_clearscope(dst); | ||||
*scopeid = zoneid; | *scopeid = zoneid; | ||||
} | } | ||||
/* | /* | ||||
* Checks that @addr_zone of @addr scope spans across @ifp. | |||||
* Returns true on success. | |||||
* | |||||
* @addr - Specified (non ::) valid IPv6 address, w/o embedded scope, used only to determine scope | |||||
* @addr_zone - zone id (host format) of an @addr zone | |||||
* @check_multi - if true, verify @addr_zone against the relevant @ifp zone, otherwise pass | |||||
* @ifp - interface to check scope against (if @addr is a local address, then @ifp is the addr iface) | |||||
*/ | |||||
bool | |||||
in6_checkscope(const struct in6_addr *addr, uint32_t addr_zone, bool check_multi, const struct ifnet *ifp) | |||||
{ | |||||
NET_EPOCH_ASSERT(); | |||||
if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_LOOPBACK(addr)) { | |||||
return (addr_zone == ifp->if_index); | |||||
} | |||||
if (__predict_false(IN6_IS_ADDR_MULTICAST(addr) && check_multi)) { | |||||
switch (IPV6_ADDR_MC_SCOPE(addr)) { | |||||
case 0x0F: | |||||
bz: That probably wants a #define elsewhere? But then GLOBAL is 0xe ... so either the 0xf or the… | |||||
return (true); // IPV6_ADDR_SCOPE_GLOBAL | |||||
case IPV6_ADDR_SCOPE_INTFACELOCAL: | |||||
case IPV6_ADDR_SCOPE_LINKLOCAL: | |||||
return (addr_zone == ifp->if_index); | |||||
default: | |||||
if (ifp->if_afdata[AF_INET6] != NULL) { | |||||
return (addr_zone == SID(ifp)->s6id_list[IPV6_ADDR_MC_SCOPE(addr)]); | |||||
} | |||||
return false; | |||||
} | |||||
} | |||||
// Explicitly pass check for global unicast & site-local addresses | |||||
return (true); | |||||
} | |||||
/* | |||||
* Checks that the zoneid potentially embedded in @addr spans across @ifp. | |||||
* Returns true on success. | |||||
*/ | |||||
bool | |||||
in6_checkscope_embedded(const struct in6_addr *addr, const struct ifnet *ifp) | |||||
{ | |||||
uint32_t zone; | |||||
if (!IN6_IS_ADDR_LOOPBACK(addr)) | |||||
zone = ntohs(addr->s6_addr16[1]); | |||||
else | |||||
zone = (ifp->if_flags & IFF_LOOPBACK) ? ifp->if_index : 0; | |||||
return (in6_checkscope(addr, zone, false, ifp)); | |||||
} | |||||
/* | |||||
* This function is for checking sockaddr_in6 structure passed | * This function is for checking sockaddr_in6 structure passed | ||||
* from the application level (usually). | * from the application level (usually). | ||||
* | * | ||||
* sin6_scope_id should be set for link-local unicast, link-local and | * sin6_scope_id should be set for link-local unicast, link-local and | ||||
* interface-local multicast addresses. | * interface-local multicast addresses. | ||||
* | * | ||||
* If it is zero, then look into default zone ids. If default zone id is | * If it is zero, then look into default zone ids. If default zone id is | ||||
* not set or disabled, then return error. | * not set or disabled, then return error. | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |
That probably wants a #define elsewhere? But then GLOBAL is 0xe ... so either the 0xf or the comment are misleading...