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