xref: /linux/include/net/addrconf.h (revision a3b072cd180c12e8fe0ece9487b9065808327640)
11da177e4SLinus Torvalds #ifndef _ADDRCONF_H
21da177e4SLinus Torvalds #define _ADDRCONF_H
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds #define MAX_RTR_SOLICITATIONS		3
51da177e4SLinus Torvalds #define RTR_SOLICITATION_INTERVAL	(4*HZ)
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #define MIN_VALID_LIFETIME		(2*3600)	/* 2 hours */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #define TEMP_VALID_LIFETIME		(7*86400)
101da177e4SLinus Torvalds #define TEMP_PREFERRED_LIFETIME		(86400)
1176f793e3SLorenzo Colitti #define REGEN_MAX_RETRY			(3)
121da177e4SLinus Torvalds #define MAX_DESYNC_FACTOR		(600)
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #define ADDR_CHECK_FREQUENCY		(120*HZ)
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #define IPV6_MAX_ADDRESSES		16
171da177e4SLinus Torvalds 
185c766d64SJiri Pirko #define ADDRCONF_TIMER_FUZZ_MINUS	(HZ > 50 ? HZ / 50 : 1)
195c766d64SJiri Pirko #define ADDRCONF_TIMER_FUZZ		(HZ / 4)
205c766d64SJiri Pirko #define ADDRCONF_TIMER_FUZZ_MAX		(HZ)
215c766d64SJiri Pirko 
22c7dc89c0SFred L. Templin #include <linux/in.h>
236a800d45SPatrick McHardy #include <linux/in6.h>
246a800d45SPatrick McHardy 
251da177e4SLinus Torvalds struct prefix_info {
261da177e4SLinus Torvalds 	__u8			type;
271da177e4SLinus Torvalds 	__u8			length;
281da177e4SLinus Torvalds 	__u8			prefix_len;
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
311da177e4SLinus Torvalds 	__u8			onlink : 1,
321da177e4SLinus Torvalds 			 	autoconf : 1,
331da177e4SLinus Torvalds 				reserved : 6;
341da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
351da177e4SLinus Torvalds 	__u8			reserved : 6,
361da177e4SLinus Torvalds 				autoconf : 1,
371da177e4SLinus Torvalds 				onlink : 1;
381da177e4SLinus Torvalds #else
391da177e4SLinus Torvalds #error "Please fix <asm/byteorder.h>"
401da177e4SLinus Torvalds #endif
41e69a4adcSAl Viro 	__be32			valid;
42e69a4adcSAl Viro 	__be32			prefered;
43e69a4adcSAl Viro 	__be32			reserved2;
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds 	struct in6_addr		prefix;
461da177e4SLinus Torvalds };
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds #include <linux/netdevice.h>
501da177e4SLinus Torvalds #include <net/if_inet6.h>
51e4553eddSHerbert Xu #include <net/ipv6.h>
521da177e4SLinus Torvalds 
53ddbe5032SEric Dumazet #define IN6_ADDR_HSIZE_SHIFT	4
54ddbe5032SEric Dumazet #define IN6_ADDR_HSIZE		(1 << IN6_ADDR_HSIZE_SHIFT)
551da177e4SLinus Torvalds 
56e8e54d3cSJoe Perches int addrconf_init(void);
57e8e54d3cSJoe Perches void addrconf_cleanup(void);
581da177e4SLinus Torvalds 
59e8e54d3cSJoe Perches int addrconf_add_ifaddr(struct net *net, void __user *arg);
60e8e54d3cSJoe Perches int addrconf_del_ifaddr(struct net *net, void __user *arg);
61e8e54d3cSJoe Perches int addrconf_set_dstaddr(struct net *net, void __user *arg);
621da177e4SLinus Torvalds 
63e8e54d3cSJoe Perches int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
64e8e54d3cSJoe Perches 		  const struct net_device *dev, int strict);
65bfeade08SDaniel Lezcano 
6659fbb3a6SMasahide NAKAMURA #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
67e8e54d3cSJoe Perches int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
6865d4ed92SMasahide NAKAMURA #endif
6952eeeb84SYOSHIFUJI Hideaki 
707df37ff3SCatalin\(ux\) M. BOIE bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
717df37ff3SCatalin\(ux\) M. BOIE 				   const unsigned int prefix_len,
727df37ff3SCatalin\(ux\) M. BOIE 				   struct net_device *dev);
737df37ff3SCatalin\(ux\) M. BOIE 
74e8e54d3cSJoe Perches int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
7552eeeb84SYOSHIFUJI Hideaki 
76e8e54d3cSJoe Perches struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
779acd9f3aSYOSHIFUJI Hideaki 				     const struct in6_addr *addr,
78e8e54d3cSJoe Perches 				     struct net_device *dev, int strict);
791cab3da6SDaniel Lezcano 
80e8e54d3cSJoe Perches int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
81e8e54d3cSJoe Perches 		       const struct in6_addr *daddr, unsigned int srcprefs,
821da177e4SLinus Torvalds 		       struct in6_addr *saddr);
83e8e54d3cSJoe Perches int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
84479840ffSJiri Pirko 		      u32 banned_flags);
85e8e54d3cSJoe Perches int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
86479840ffSJiri Pirko 		    u32 banned_flags);
87e8e54d3cSJoe Perches int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2);
88e8e54d3cSJoe Perches void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
89e8e54d3cSJoe Perches void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
901da177e4SLinus Torvalds 
914bed72e4SYOSHIFUJI Hideaki static inline unsigned long addrconf_timeout_fixup(u32 timeout,
9295c96174SEric Dumazet 						   unsigned int unit)
934bed72e4SYOSHIFUJI Hideaki {
944bed72e4SYOSHIFUJI Hideaki 	if (timeout == 0xffffffff)
954bed72e4SYOSHIFUJI Hideaki 		return ~0UL;
964bed72e4SYOSHIFUJI Hideaki 
974bed72e4SYOSHIFUJI Hideaki 	/*
984bed72e4SYOSHIFUJI Hideaki 	 * Avoid arithmetic overflow.
994bed72e4SYOSHIFUJI Hideaki 	 * Assuming unit is constant and non-zero, this "if" statement
1004bed72e4SYOSHIFUJI Hideaki 	 * will go away on 64bit archs.
1014bed72e4SYOSHIFUJI Hideaki 	 */
1024bed72e4SYOSHIFUJI Hideaki 	if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
1034bed72e4SYOSHIFUJI Hideaki 		return LONG_MAX / unit;
1044bed72e4SYOSHIFUJI Hideaki 
1054bed72e4SYOSHIFUJI Hideaki 	return timeout;
1064bed72e4SYOSHIFUJI Hideaki }
1074bed72e4SYOSHIFUJI Hideaki 
1084bed72e4SYOSHIFUJI Hideaki static inline int addrconf_finite_timeout(unsigned long timeout)
1094bed72e4SYOSHIFUJI Hideaki {
1104bed72e4SYOSHIFUJI Hideaki 	return ~timeout;
1114bed72e4SYOSHIFUJI Hideaki }
1124bed72e4SYOSHIFUJI Hideaki 
1131da177e4SLinus Torvalds /*
1142a8cc6c8SYOSHIFUJI Hideaki  *	IPv6 Address Label subsystem (addrlabel.c)
1152a8cc6c8SYOSHIFUJI Hideaki  */
116e8e54d3cSJoe Perches int ipv6_addr_label_init(void);
117e8e54d3cSJoe Perches void ipv6_addr_label_cleanup(void);
118e8e54d3cSJoe Perches void ipv6_addr_label_rtnl_register(void);
119e8e54d3cSJoe Perches u32 ipv6_addr_label(struct net *net, const struct in6_addr *addr,
1202a8cc6c8SYOSHIFUJI Hideaki 		    int type, int ifindex);
1212a8cc6c8SYOSHIFUJI Hideaki 
1222a8cc6c8SYOSHIFUJI Hideaki /*
1231da177e4SLinus Torvalds  *	multicast prototypes (mcast.c)
1241da177e4SLinus Torvalds  */
125e8e54d3cSJoe Perches int ipv6_sock_mc_join(struct sock *sk, int ifindex,
1269acd9f3aSYOSHIFUJI Hideaki 		      const struct in6_addr *addr);
127e8e54d3cSJoe Perches int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
1289acd9f3aSYOSHIFUJI Hideaki 		      const struct in6_addr *addr);
129e8e54d3cSJoe Perches void ipv6_sock_mc_close(struct sock *sk);
130e8e54d3cSJoe Perches bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
1319acd9f3aSYOSHIFUJI Hideaki 		    const struct in6_addr *src_addr);
1321da177e4SLinus Torvalds 
133e8e54d3cSJoe Perches int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
134e8e54d3cSJoe Perches int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
135e8e54d3cSJoe Perches int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
136e8e54d3cSJoe Perches void ipv6_mc_up(struct inet6_dev *idev);
137e8e54d3cSJoe Perches void ipv6_mc_down(struct inet6_dev *idev);
138e8e54d3cSJoe Perches void ipv6_mc_unmap(struct inet6_dev *idev);
139e8e54d3cSJoe Perches void ipv6_mc_remap(struct inet6_dev *idev);
140e8e54d3cSJoe Perches void ipv6_mc_init_dev(struct inet6_dev *idev);
141e8e54d3cSJoe Perches void ipv6_mc_destroy_dev(struct inet6_dev *idev);
142e8e54d3cSJoe Perches void addrconf_dad_failure(struct inet6_ifaddr *ifp);
1431da177e4SLinus Torvalds 
144e8e54d3cSJoe Perches bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
1459acd9f3aSYOSHIFUJI Hideaki 			 const struct in6_addr *src_addr);
146daad1512SYOSHIFUJI Hideaki / 吉藤英明 
147e8e54d3cSJoe Perches void ipv6_mc_dad_complete(struct inet6_dev *idev);
1485f81bd2eSCong Wang 
1495f81bd2eSCong Wang /* A stub used by vxlan module. This is ugly, ideally these
1505f81bd2eSCong Wang  * symbols should be built into the core kernel.
1515f81bd2eSCong Wang  */
1525f81bd2eSCong Wang struct ipv6_stub {
1535f81bd2eSCong Wang 	int (*ipv6_sock_mc_join)(struct sock *sk, int ifindex,
1545f81bd2eSCong Wang 				 const struct in6_addr *addr);
1555f81bd2eSCong Wang 	int (*ipv6_sock_mc_drop)(struct sock *sk, int ifindex,
1565f81bd2eSCong Wang 				 const struct in6_addr *addr);
1575f81bd2eSCong Wang 	int (*ipv6_dst_lookup)(struct sock *sk, struct dst_entry **dst,
1585f81bd2eSCong Wang 				struct flowi6 *fl6);
1595f81bd2eSCong Wang 	void (*udpv6_encap_enable)(void);
160f564f45cSCong Wang 	void (*ndisc_send_na)(struct net_device *dev, struct neighbour *neigh,
161f564f45cSCong Wang 			      const struct in6_addr *daddr,
162f564f45cSCong Wang 			      const struct in6_addr *solicited_addr,
163f564f45cSCong Wang 			      bool router, bool solicited, bool override, bool inc_opt);
164e15a00aaSCong Wang 	struct neigh_table *nd_tbl;
1655f81bd2eSCong Wang };
1665f81bd2eSCong Wang extern const struct ipv6_stub *ipv6_stub __read_mostly;
1675f81bd2eSCong Wang 
168daad1512SYOSHIFUJI Hideaki / 吉藤英明 /*
169daad1512SYOSHIFUJI Hideaki / 吉藤英明  * identify MLD packets for MLD filter exceptions
170daad1512SYOSHIFUJI Hideaki / 吉藤英明  */
171daad1512SYOSHIFUJI Hideaki / 吉藤英明 static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
172daad1512SYOSHIFUJI Hideaki / 吉藤英明 {
173daad1512SYOSHIFUJI Hideaki / 吉藤英明 	struct icmp6hdr *hdr;
174daad1512SYOSHIFUJI Hideaki / 吉藤英明 
175daad1512SYOSHIFUJI Hideaki / 吉藤英明 	if (nexthdr != IPPROTO_ICMPV6 ||
176daad1512SYOSHIFUJI Hideaki / 吉藤英明 	    !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
177daad1512SYOSHIFUJI Hideaki / 吉藤英明 		return false;
178daad1512SYOSHIFUJI Hideaki / 吉藤英明 
179daad1512SYOSHIFUJI Hideaki / 吉藤英明 	hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
180daad1512SYOSHIFUJI Hideaki / 吉藤英明 
181daad1512SYOSHIFUJI Hideaki / 吉藤英明 	switch (hdr->icmp6_type) {
182daad1512SYOSHIFUJI Hideaki / 吉藤英明 	case ICMPV6_MGM_QUERY:
183daad1512SYOSHIFUJI Hideaki / 吉藤英明 	case ICMPV6_MGM_REPORT:
184daad1512SYOSHIFUJI Hideaki / 吉藤英明 	case ICMPV6_MGM_REDUCTION:
185daad1512SYOSHIFUJI Hideaki / 吉藤英明 	case ICMPV6_MLD2_REPORT:
186daad1512SYOSHIFUJI Hideaki / 吉藤英明 		return true;
187daad1512SYOSHIFUJI Hideaki / 吉藤英明 	default:
188daad1512SYOSHIFUJI Hideaki / 吉藤英明 		break;
189daad1512SYOSHIFUJI Hideaki / 吉藤英明 	}
190daad1512SYOSHIFUJI Hideaki / 吉藤英明 	return false;
191daad1512SYOSHIFUJI Hideaki / 吉藤英明 }
1921da177e4SLinus Torvalds 
193e8e54d3cSJoe Perches void addrconf_prefix_rcv(struct net_device *dev,
194e6bff995SNeil Horman 			 u8 *opt, int len, bool sllao);
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds /*
1971da177e4SLinus Torvalds  *	anycast prototypes (anycast.c)
1981da177e4SLinus Torvalds  */
199e8e54d3cSJoe Perches int ipv6_sock_ac_join(struct sock *sk, int ifindex,
200e8e54d3cSJoe Perches 		      const struct in6_addr *addr);
201e8e54d3cSJoe Perches int ipv6_sock_ac_drop(struct sock *sk, int ifindex,
202e8e54d3cSJoe Perches 		      const struct in6_addr *addr);
203e8e54d3cSJoe Perches void ipv6_sock_ac_close(struct sock *sk);
2041da177e4SLinus Torvalds 
205e8e54d3cSJoe Perches int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
206e8e54d3cSJoe Perches int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
207e8e54d3cSJoe Perches bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
208b71d1d42SEric Dumazet 			 const struct in6_addr *addr);
209*7c90cc2dSFX Le Bail bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
210*7c90cc2dSFX Le Bail 			     const struct in6_addr *addr);
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds /* Device notifier */
213e8e54d3cSJoe Perches int register_inet6addr_notifier(struct notifier_block *nb);
214e8e54d3cSJoe Perches int unregister_inet6addr_notifier(struct notifier_block *nb);
215e8e54d3cSJoe Perches int inet6addr_notifier_call_chain(unsigned long val, void *v);
2161da177e4SLinus Torvalds 
217e8e54d3cSJoe Perches void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
218d67b8c61SNicolas Dichtel 				  struct ipv6_devconf *devconf);
219d67b8c61SNicolas Dichtel 
22048daa3bbSEric Dumazet /**
22148daa3bbSEric Dumazet  * __in6_dev_get - get inet6_dev pointer from netdevice
22248daa3bbSEric Dumazet  * @dev: network device
22348daa3bbSEric Dumazet  *
22448daa3bbSEric Dumazet  * Caller must hold rcu_read_lock or RTNL, because this function
22548daa3bbSEric Dumazet  * does not take a reference on the inet6_dev.
22648daa3bbSEric Dumazet  */
22748daa3bbSEric Dumazet static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
2281da177e4SLinus Torvalds {
22948daa3bbSEric Dumazet 	return rcu_dereference_rtnl(dev->ip6_ptr);
2301da177e4SLinus Torvalds }
2311da177e4SLinus Torvalds 
23248daa3bbSEric Dumazet /**
23348daa3bbSEric Dumazet  * in6_dev_get - get inet6_dev pointer from netdevice
23448daa3bbSEric Dumazet  * @dev: network device
23548daa3bbSEric Dumazet  *
23648daa3bbSEric Dumazet  * This version can be used in any context, and takes a reference
23748daa3bbSEric Dumazet  * on the inet6_dev. Callers must use in6_dev_put() later to
23848daa3bbSEric Dumazet  * release this reference.
23948daa3bbSEric Dumazet  */
24048daa3bbSEric Dumazet static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
2411da177e4SLinus Torvalds {
24248daa3bbSEric Dumazet 	struct inet6_dev *idev;
24348daa3bbSEric Dumazet 
2448814c4b5SYOSHIFUJI Hideaki 	rcu_read_lock();
24548daa3bbSEric Dumazet 	idev = rcu_dereference(dev->ip6_ptr);
2461da177e4SLinus Torvalds 	if (idev)
2471da177e4SLinus Torvalds 		atomic_inc(&idev->refcnt);
2488814c4b5SYOSHIFUJI Hideaki 	rcu_read_unlock();
2491da177e4SLinus Torvalds 	return idev;
2501da177e4SLinus Torvalds }
2511da177e4SLinus Torvalds 
252bba24896SJiri Pirko static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
253bba24896SJiri Pirko {
254bba24896SJiri Pirko 	struct inet6_dev *idev = __in6_dev_get(dev);
255bba24896SJiri Pirko 
256bba24896SJiri Pirko 	return idev ? idev->nd_parms : NULL;
257bba24896SJiri Pirko }
258bba24896SJiri Pirko 
259e8e54d3cSJoe Perches void in6_dev_finish_destroy(struct inet6_dev *idev);
2601da177e4SLinus Torvalds 
26148daa3bbSEric Dumazet static inline void in6_dev_put(struct inet6_dev *idev)
2621da177e4SLinus Torvalds {
2631da177e4SLinus Torvalds 	if (atomic_dec_and_test(&idev->refcnt))
2641da177e4SLinus Torvalds 		in6_dev_finish_destroy(idev);
2651da177e4SLinus Torvalds }
2661da177e4SLinus Torvalds 
26748daa3bbSEric Dumazet static inline void __in6_dev_put(struct inet6_dev *idev)
26848daa3bbSEric Dumazet {
26948daa3bbSEric Dumazet 	atomic_dec(&idev->refcnt);
27048daa3bbSEric Dumazet }
2711da177e4SLinus Torvalds 
27248daa3bbSEric Dumazet static inline void in6_dev_hold(struct inet6_dev *idev)
27348daa3bbSEric Dumazet {
27448daa3bbSEric Dumazet 	atomic_inc(&idev->refcnt);
27548daa3bbSEric Dumazet }
2761da177e4SLinus Torvalds 
277e8e54d3cSJoe Perches void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
2801da177e4SLinus Torvalds {
2811da177e4SLinus Torvalds 	if (atomic_dec_and_test(&ifp->refcnt))
2821da177e4SLinus Torvalds 		inet6_ifa_finish_destroy(ifp);
2831da177e4SLinus Torvalds }
2841da177e4SLinus Torvalds 
28548daa3bbSEric Dumazet static inline void __in6_ifa_put(struct inet6_ifaddr *ifp)
28648daa3bbSEric Dumazet {
28748daa3bbSEric Dumazet 	atomic_dec(&ifp->refcnt);
28848daa3bbSEric Dumazet }
2891da177e4SLinus Torvalds 
29048daa3bbSEric Dumazet static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
29148daa3bbSEric Dumazet {
29248daa3bbSEric Dumazet 	atomic_inc(&ifp->refcnt);
29348daa3bbSEric Dumazet }
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 
2961da177e4SLinus Torvalds /*
2971da177e4SLinus Torvalds  *	compute link-local solicited-node multicast address
2981da177e4SLinus Torvalds  */
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
3011da177e4SLinus Torvalds 					     struct in6_addr *solicited)
3021da177e4SLinus Torvalds {
3031da177e4SLinus Torvalds 	ipv6_addr_set(solicited,
3040e7b8dcdSYOSHIFUJI Hideaki 		      htonl(0xFF020000), 0,
3050e7b8dcdSYOSHIFUJI Hideaki 		      htonl(0x1),
3060e7b8dcdSYOSHIFUJI Hideaki 		      htonl(0xFF000000) | addr->s6_addr32[3]);
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds 
309b27b28cbSYOSHIFUJI Hideaki static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
3101da177e4SLinus Torvalds {
3110e7b8dcdSYOSHIFUJI Hideaki 	return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
3121da177e4SLinus Torvalds }
3131da177e4SLinus Torvalds 
314b27b28cbSYOSHIFUJI Hideaki static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
3151da177e4SLinus Torvalds {
316d1641565SYOSHIFUJI Hideaki / 吉藤英明 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
317d1641565SYOSHIFUJI Hideaki / 吉藤英明 	__u64 *p = (__u64 *)addr;
318d1641565SYOSHIFUJI Hideaki / 吉藤英明 	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
319d1641565SYOSHIFUJI Hideaki / 吉藤英明 #else
32048daa3bbSEric Dumazet 	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
321fed85383SYOSHIFUJI Hideaki 		addr->s6_addr32[1] | addr->s6_addr32[2] |
32248daa3bbSEric Dumazet 		(addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
323d1641565SYOSHIFUJI Hideaki / 吉藤英明 #endif
3241da177e4SLinus Torvalds }
3251da177e4SLinus Torvalds 
326b27b28cbSYOSHIFUJI Hideaki static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
3271da177e4SLinus Torvalds {
328d1641565SYOSHIFUJI Hideaki / 吉藤英明 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
329d1641565SYOSHIFUJI Hideaki / 吉藤英明 	__u64 *p = (__u64 *)addr;
330d1641565SYOSHIFUJI Hideaki / 吉藤英明 	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
331d1641565SYOSHIFUJI Hideaki / 吉藤英明 #else
33248daa3bbSEric Dumazet 	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
333fed85383SYOSHIFUJI Hideaki 		addr->s6_addr32[1] | addr->s6_addr32[2] |
33448daa3bbSEric Dumazet 		(addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
335d1641565SYOSHIFUJI Hideaki / 吉藤英明 #endif
3361da177e4SLinus Torvalds }
3371da177e4SLinus Torvalds 
338b27b28cbSYOSHIFUJI Hideaki static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
339c7dc89c0SFred L. Templin {
34048daa3bbSEric Dumazet 	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
341c7dc89c0SFred L. Templin }
342c7dc89c0SFred L. Templin 
343ca97a644SYOSHIFUJI Hideaki / 吉藤英明 static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
344ca97a644SYOSHIFUJI Hideaki / 吉藤英明 {
3459d100774SYOSHIFUJI Hideaki / 吉藤英明 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
3469d100774SYOSHIFUJI Hideaki / 吉藤英明 	__u64 *p = (__u64 *)addr;
3479d100774SYOSHIFUJI Hideaki / 吉藤英明 	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
3489d100774SYOSHIFUJI Hideaki / 吉藤英明 		((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
3499d100774SYOSHIFUJI Hideaki / 吉藤英明 		 cpu_to_be64(0xffffffffff000000UL))) == 0UL;
3509d100774SYOSHIFUJI Hideaki / 吉藤英明 #else
3519d100774SYOSHIFUJI Hideaki / 吉藤英明 	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
3529d100774SYOSHIFUJI Hideaki / 吉藤英明 		addr->s6_addr32[1] |
3539d100774SYOSHIFUJI Hideaki / 吉藤英明 		(addr->s6_addr32[2] ^ htonl(0x00000001)) |
3549d100774SYOSHIFUJI Hideaki / 吉藤英明 		(addr->s6_addr[12] ^ 0xff)) == 0;
3559d100774SYOSHIFUJI Hideaki / 吉藤英明 #endif
356ca97a644SYOSHIFUJI Hideaki / 吉藤英明 }
357ca97a644SYOSHIFUJI Hideaki / 吉藤英明 
35820380731SArnaldo Carvalho de Melo #ifdef CONFIG_PROC_FS
359e8e54d3cSJoe Perches int if6_proc_init(void);
360e8e54d3cSJoe Perches void if6_proc_exit(void);
36120380731SArnaldo Carvalho de Melo #endif
36220380731SArnaldo Carvalho de Melo 
3631da177e4SLinus Torvalds #endif
364