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>
9f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang#include <net/ip.h>
108c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
11705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowa/* if ipv6 module registers this function is used by xfrm to force all
12705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowa * sockets to relookup their nodes - this is fairly expensive, be
13705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowa * careful
14705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowa */
15705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowavoid (*__fib6_flush_trees)(struct net *);
16705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic SowaEXPORT_SYMBOL(__fib6_flush_trees);
17705f1c869d577c8055736dd02501f26a2507dd5bHannes Frederic Sowa
188c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki#define IPV6_ADDR_SCOPE_TYPE(scope)	((scope) << 16)
198c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
2095c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazetstatic inline unsigned int ipv6_addr_scope2type(unsigned int scope)
218c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki{
22d94d34a0664b296fd1593a96ccc9c97a94dfd43dEldad Zack	switch (scope) {
238c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	case IPV6_ADDR_SCOPE_NODELOCAL:
248c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
258c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_LOOPBACK);
268c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	case IPV6_ADDR_SCOPE_LINKLOCAL:
278c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
288c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_LINKLOCAL);
298c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	case IPV6_ADDR_SCOPE_SITELOCAL:
308c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
318c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_SITELOCAL);
328c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	}
338c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	return IPV6_ADDR_SCOPE_TYPE(scope);
348c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki}
358c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
368c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideakiint __ipv6_addr_type(const struct in6_addr *addr)
378c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki{
388c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	__be32 st;
398c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
408c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	st = addr->s6_addr32[0];
418c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
428c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	/* Consider all addresses with the first three bits different of
438c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	   000 and 111 as unicasts.
448c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	 */
458c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
468c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	    (st & htonl(0xE0000000)) != htonl(0xE0000000))
478c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_UNICAST |
488c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
498c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
508c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
518c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		/* multicast */
528c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		/* addr-select 3.1 */
538c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_MULTICAST |
548c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
558c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	}
568c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
578c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
588c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
598c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));		/* addr-select 3.1 */
608c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
618c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
628c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));		/* addr-select 3.1 */
63c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson	if ((st & htonl(0xFE000000)) == htonl(0xFC000000))
64c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson		return (IPV6_ADDR_UNICAST |
65c61a7d10efbd187ab9bb54871238ebd1dfcacd44Dave Johnson			IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));			/* RFC 4193 */
668c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
678c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
688c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		if (addr->s6_addr32[2] == 0) {
698c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			if (addr->s6_addr32[3] == 0)
708c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki				return IPV6_ADDR_ANY;
718c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
728c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			if (addr->s6_addr32[3] == htonl(0x00000001))
738c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki				return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
748c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki					IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));	/* addr-select 3.4 */
758c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
768c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
778c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki				IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.3 */
788c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		}
798c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
808c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		if (addr->s6_addr32[2] == htonl(0x0000ffff))
818c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki			return (IPV6_ADDR_MAPPED |
828c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki				IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.3 */
838c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki	}
848c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
8545bb00609022ecf1d97e083666c68c74d237b799Ulrich Weber	return (IPV6_ADDR_UNICAST |
868c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki		IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));	/* addr-select 3.4 */
878c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki}
887401055b58e557362dfcaa65a581db1d1e972439David S. MillerEXPORT_SYMBOL(__ipv6_addr_type);
898c14b7ce22a7ddd9fe1b1c852c4015633ec3efecYOSHIFUJI Hideaki
90f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangstatic ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
91f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang
92f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint register_inet6addr_notifier(struct notifier_block *nb)
93f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{
94f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang	return atomic_notifier_chain_register(&inet6addr_chain, nb);
95f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang}
96f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(register_inet6addr_notifier);
97f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang
98f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint unregister_inet6addr_notifier(struct notifier_block *nb)
99f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{
100f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang	return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
101f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang}
102f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(unregister_inet6addr_notifier);
103f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang
104f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wangint inet6addr_notifier_call_chain(unsigned long val, void *v)
105f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang{
106f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang	return atomic_notifier_call_chain(&inet6addr_chain, val, v);
107f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong Wang}
108f88c91ddba958e9a5dd4a5ee8c52a0faa790f586Cong WangEXPORT_SYMBOL(inet6addr_notifier_call_chain);
1095f81bd2e5d804ca93f3ec8873451b22d2f454721Cong Wang
1105f81bd2e5d804ca93f3ec8873451b22d2f454721Cong Wangconst struct ipv6_stub *ipv6_stub __read_mostly;
1115f81bd2e5d804ca93f3ec8873451b22d2f454721Cong WangEXPORT_SYMBOL_GPL(ipv6_stub);
112034dfc5df99eb8d263211524983b1a737b25c06bCong Wang
113034dfc5df99eb8d263211524983b1a737b25c06bCong Wang/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
114034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
115034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_loopback);
116034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
117034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_any);
118034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
119034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_linklocal_allnodes);
120034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
121034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_linklocal_allrouters);
122034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
123034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_interfacelocal_allnodes);
124034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
125034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_interfacelocal_allrouters);
126034dfc5df99eb8d263211524983b1a737b25c06bCong Wangconst struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
127034dfc5df99eb8d263211524983b1a737b25c06bCong WangEXPORT_SYMBOL(in6addr_sitelocal_allrouters);
128f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang
129f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wangstatic void snmp6_free_dev(struct inet6_dev *idev)
130f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang{
131f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	kfree(idev->stats.icmpv6msgdev);
132f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	kfree(idev->stats.icmpv6dev);
133698365fa1874aa7635d51667a34a2842228e9837WANG Cong	free_percpu(idev->stats.ipv6);
134f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang}
135f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang
136f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang/* Nobody refers to this device, we may destroy it. */
137f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang
138f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wangvoid in6_dev_finish_destroy(struct inet6_dev *idev)
139f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang{
140f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	struct net_device *dev = idev->dev;
141f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang
142f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	WARN_ON(!list_empty(&idev->addr_list));
143f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	WARN_ON(idev->mc_list != NULL);
144f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	WARN_ON(timer_pending(&idev->rs_timer));
145f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang
146f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang#ifdef NET_REFCNT_DEBUG
147f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL");
148f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang#endif
149f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	dev_put(dev);
150f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	if (!idev->dead) {
151f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang		pr_warn("Freeing alive inet6 device %p\n", idev);
152f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang		return;
153f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	}
154f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	snmp6_free_dev(idev);
155f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang	kfree_rcu(idev, rcu);
156f39dc1023d6b9933528638a0c2dd618b4fdf664eCong Wang}
157f39dc1023d6b9933528638a0c2dd618b4fdf664eCong WangEXPORT_SYMBOL(in6_dev_finish_destroy);
158