2 * IPv6 library code, needed by static components when full IPv6 support is
3 * not configured or static.
6 #include <linux/export.h>
8 #include <net/addrconf.h>
10 #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
12 static inline unsigned int ipv6_addr_scope2type(unsigned int scope
)
15 case IPV6_ADDR_SCOPE_NODELOCAL
:
16 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL
) |
18 case IPV6_ADDR_SCOPE_LINKLOCAL
:
19 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL
) |
21 case IPV6_ADDR_SCOPE_SITELOCAL
:
22 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL
) |
25 return IPV6_ADDR_SCOPE_TYPE(scope
);
28 int __ipv6_addr_type(const struct in6_addr
*addr
)
32 st
= addr
->s6_addr32
[0];
34 /* Consider all addresses with the first three bits different of
35 000 and 111 as unicasts.
37 if ((st
& htonl(0xE0000000)) != htonl(0x00000000) &&
38 (st
& htonl(0xE0000000)) != htonl(0xE0000000))
39 return (IPV6_ADDR_UNICAST
|
40 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL
));
42 if ((st
& htonl(0xFF000000)) == htonl(0xFF000000)) {
45 return (IPV6_ADDR_MULTICAST
|
46 ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr
)));
49 if ((st
& htonl(0xFFC00000)) == htonl(0xFE800000))
50 return (IPV6_ADDR_LINKLOCAL
| IPV6_ADDR_UNICAST
|
51 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL
)); /* addr-select 3.1 */
52 if ((st
& htonl(0xFFC00000)) == htonl(0xFEC00000))
53 return (IPV6_ADDR_SITELOCAL
| IPV6_ADDR_UNICAST
|
54 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL
)); /* addr-select 3.1 */
55 if ((st
& htonl(0xFE000000)) == htonl(0xFC000000))
56 return (IPV6_ADDR_UNICAST
|
57 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL
)); /* RFC 4193 */
59 if ((addr
->s6_addr32
[0] | addr
->s6_addr32
[1]) == 0) {
60 if (addr
->s6_addr32
[2] == 0) {
61 if (addr
->s6_addr32
[3] == 0)
64 if (addr
->s6_addr32
[3] == htonl(0x00000001))
65 return (IPV6_ADDR_LOOPBACK
| IPV6_ADDR_UNICAST
|
66 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL
)); /* addr-select 3.4 */
68 return (IPV6_ADDR_COMPATv4
| IPV6_ADDR_UNICAST
|
69 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL
)); /* addr-select 3.3 */
72 if (addr
->s6_addr32
[2] == htonl(0x0000ffff))
73 return (IPV6_ADDR_MAPPED
|
74 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL
)); /* addr-select 3.3 */
77 return (IPV6_ADDR_UNICAST
|
78 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL
)); /* addr-select 3.4 */
80 EXPORT_SYMBOL(__ipv6_addr_type
);
82 static ATOMIC_NOTIFIER_HEAD(inet6addr_chain
);
84 int register_inet6addr_notifier(struct notifier_block
*nb
)
86 return atomic_notifier_chain_register(&inet6addr_chain
, nb
);
88 EXPORT_SYMBOL(register_inet6addr_notifier
);
90 int unregister_inet6addr_notifier(struct notifier_block
*nb
)
92 return atomic_notifier_chain_unregister(&inet6addr_chain
, nb
);
94 EXPORT_SYMBOL(unregister_inet6addr_notifier
);
96 int inet6addr_notifier_call_chain(unsigned long val
, void *v
)
98 return atomic_notifier_call_chain(&inet6addr_chain
, val
, v
);
100 EXPORT_SYMBOL(inet6addr_notifier_call_chain
);