addrconf_core.c revision 034dfc5df99eb8d263211524983b1a737b25c06b
18c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki/* 28c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki * IPv6 library code, needed by static components when full IPv6 support is 38c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki * not configured or static. 48c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki */ 58c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 6bc3b2d7fb9b014d75ebb79ba371a763dbab5e8cfPaul Gortmaker#include <linux/export.h> 78c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki#include <net/ipv6.h> 86da334ee0c101fc5ecf62f2b1e11b1524be7b159Eric Dumazet#include <net/addrconf.h> 98c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 108c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16) 118c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 1295c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazetstatic inline unsigned int ipv6_addr_scope2type(unsigned int scope) 138c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki{ 14d94d34a0664b296fd1593a96ccc9c97a94dfd43dEldad Zack switch (scope) { 158c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki case IPV6_ADDR_SCOPE_NODELOCAL: 168c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) | 178c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_LOOPBACK); 188c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki case IPV6_ADDR_SCOPE_LINKLOCAL: 198c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) | 208c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_LINKLOCAL); 218c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki case IPV6_ADDR_SCOPE_SITELOCAL: 228c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) | 238c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SITELOCAL); 248c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki } 258c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return IPV6_ADDR_SCOPE_TYPE(scope); 268c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki} 278c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 288c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideakiint __ipv6_addr_type(const struct in6_addr *addr) 298c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki{ 308c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki __be32 st; 318c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 328c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki st = addr->s6_addr32[0]; 338c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 348c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki /* Consider all addresses with the first three bits different of 358c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 000 and 111 as unicasts. 368c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki */ 378c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if ((st & htonl(0xE0000000)) != htonl(0x00000000) && 388c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki (st & htonl(0xE0000000)) != htonl(0xE0000000)) 398c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_UNICAST | 408c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); 418c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 428c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) { 438c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki /* multicast */ 448c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki /* addr-select 3.1 */ 458c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_MULTICAST | 468c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr))); 478c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki } 488c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 498c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if ((st & htonl(0xFFC00000)) == htonl(0xFE800000)) 508c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST | 518c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */ 528c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000)) 538c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST | 548c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */ 55c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson if ((st & htonl(0xFE000000)) == htonl(0xFC000000)) 56c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson return (IPV6_ADDR_UNICAST | 57c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* RFC 4193 */ 588c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 598c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) { 608c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if (addr->s6_addr32[2] == 0) { 618c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if (addr->s6_addr32[3] == 0) 628c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return IPV6_ADDR_ANY; 638c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 648c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if (addr->s6_addr32[3] == htonl(0x00000001)) 658c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST | 668c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */ 678c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 688c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST | 698c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */ 708c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki } 718c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 728c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki if (addr->s6_addr32[2] == htonl(0x0000ffff)) 738c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki return (IPV6_ADDR_MAPPED | 748c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */ 758c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki } 768c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 7745bb00609022ecf1d97e083666c68c74d237b799Ulrich Weber return (IPV6_ADDR_UNICAST | 788c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */ 798c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki} 807401055b58e557362dfcaa65a581db1d1e972439David S. MillerEXPORT_SYMBOL(__ipv6_addr_type); 818c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki 82f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangstatic ATOMIC_NOTIFIER_HEAD(inet6addr_chain); 83f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang 84f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint register_inet6addr_notifier(struct notifier_block *nb) 85f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{ 86f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang return atomic_notifier_chain_register(&inet6addr_chain, nb); 87f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang} 88f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(register_inet6addr_notifier); 89f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang 90f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint unregister_inet6addr_notifier(struct notifier_block *nb) 91f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{ 92f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang return atomic_notifier_chain_unregister(&inet6addr_chain, nb); 93f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang} 94f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(unregister_inet6addr_notifier); 95f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang 96f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint inet6addr_notifier_call_chain(unsigned long val, void *v) 97f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{ 98f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang return atomic_notifier_call_chain(&inet6addr_chain, val, v); 99f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang} 100f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(inet6addr_notifier_call_chain); 1015f81bd2e5d804ca93f3ec8873451b22d2f454721Cong Wang 1025f81bd2e5d804ca93f3ec8873451b22d2f454721Cong Wangconst struct ipv6_stub *ipv6_stub __read_mostly; 1035f81bd2e5d804ca93f3ec8873451b22d2f454721Cong WangEXPORT_SYMBOL_GPL(ipv6_stub); 104034dfc5df99eb8d263211524983b1a737b25c06bCong Wang 105034dfc5df99eb8d263211524983b1a737b25c06bCong Wang/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ 106034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; 107034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_loopback); 108034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; 109034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_any); 110034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; 111034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_linklocal_allnodes); 112034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; 113034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_linklocal_allrouters); 114034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT; 115034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_interfacelocal_allnodes); 116034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT; 117034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_interfacelocal_allrouters); 118034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT; 119034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_sitelocal_allrouters); 120