1#ifndef _ADDRCONF_H 2#define _ADDRCONF_H 3 4#define RETRANS_TIMER HZ 5 6#define MAX_RTR_SOLICITATIONS 3 7#define RTR_SOLICITATION_INTERVAL (4*HZ) 8 9#define ADDR_CHECK_FREQUENCY (120*HZ) 10 11struct prefix_info { 12 __u8 type; 13 __u8 length; 14 __u8 prefix_len; 15 16#if defined(__BIG_ENDIAN_BITFIELD) 17 __u8 onlink : 1, 18 autoconf : 1, 19 reserved : 6; 20#elif defined(__LITTLE_ENDIAN_BITFIELD) 21 __u8 reserved : 6, 22 autoconf : 1, 23 onlink : 1; 24#else 25#error "Please fix <asm/byteorder.h>" 26#endif 27 __u32 valid; 28 __u32 prefered; 29 __u32 reserved2; 30 31 struct in6_addr prefix; 32}; 33 34 35#ifdef __KERNEL__ 36 37#include <linux/in6.h> 38#include <linux/netdevice.h> 39#include <net/if_inet6.h> 40 41#define IN6_ADDR_HSIZE 16 42 43extern void addrconf_init(void); 44extern void addrconf_cleanup(void); 45 46extern int addrconf_notify(struct notifier_block *this, 47 unsigned long event, 48 void * data); 49 50extern int addrconf_add_ifaddr(void *arg); 51extern int addrconf_del_ifaddr(void *arg); 52extern int addrconf_set_dstaddr(void *arg); 53 54extern int ipv6_chk_addr(struct in6_addr *addr, 55 struct net_device *dev); 56extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, 57 struct net_device *dev); 58extern int ipv6_get_saddr(struct dst_entry *dst, 59 struct in6_addr *daddr, 60 struct in6_addr *saddr); 61extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); 62 63/* 64 * multicast prototypes (mcast.c) 65 */ 66extern int ipv6_sock_mc_join(struct sock *sk, 67 int ifindex, 68 struct in6_addr *addr); 69extern int ipv6_sock_mc_drop(struct sock *sk, 70 int ifindex, 71 struct in6_addr *addr); 72extern void ipv6_sock_mc_close(struct sock *sk); 73extern int inet6_mc_check(struct sock *sk, struct in6_addr *addr); 74 75extern int ipv6_dev_mc_inc(struct net_device *dev, 76 struct in6_addr *addr); 77extern int ipv6_dev_mc_dec(struct net_device *dev, 78 struct in6_addr *addr); 79extern void ipv6_mc_up(struct inet6_dev *idev); 80extern void ipv6_mc_down(struct inet6_dev *idev); 81extern void ipv6_mc_init_dev(struct inet6_dev *idev); 82extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); 83extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); 84 85extern int ipv6_chk_mcast_addr(struct net_device *dev, 86 struct in6_addr *addr); 87 88extern void addrconf_prefix_rcv(struct net_device *dev, 89 u8 *opt, int len); 90 91/* Device notifier */ 92extern int register_inet6addr_notifier(struct notifier_block *nb); 93extern int unregister_inet6addr_notifier(struct notifier_block *nb); 94 95static inline struct inet6_dev * 96__in6_dev_get(struct net_device *dev) 97{ 98 return (struct inet6_dev *)dev->ip6_ptr; 99} 100 101extern rwlock_t addrconf_lock; 102 103static inline struct inet6_dev * 104in6_dev_get(struct net_device *dev) 105{ 106 struct inet6_dev *idev = NULL; 107 read_lock(&addrconf_lock); 108 idev = dev->ip6_ptr; 109 if (idev) 110 atomic_inc(&idev->refcnt); 111 read_unlock(&addrconf_lock); 112 return idev; 113} 114 115extern void in6_dev_finish_destroy(struct inet6_dev *idev); 116 117static inline void 118in6_dev_put(struct inet6_dev *idev) 119{ 120 if (atomic_dec_and_test(&idev->refcnt)) 121 in6_dev_finish_destroy(idev); 122} 123 124#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) 125#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) 126 127 128extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp); 129 130static inline void in6_ifa_put(struct inet6_ifaddr *ifp) 131{ 132 if (atomic_dec_and_test(&ifp->refcnt)) 133 inet6_ifa_finish_destroy(ifp); 134} 135 136#define __in6_ifa_put(idev) atomic_dec(&(idev)->refcnt) 137#define in6_ifa_hold(idev) atomic_inc(&(idev)->refcnt) 138 139 140extern void addrconf_forwarding_on(void); 141/* 142 * Hash function taken from net_alias.c 143 */ 144 145static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr) 146{ 147 __u32 word; 148 149 /* 150 * We perform the hash function over the last 64 bits of the address 151 * This will include the IEEE address token on links that support it. 152 */ 153 154 word = addr->s6_addr[2] ^ addr->s6_addr32[3]; 155 word ^= (word>>16); 156 word ^= (word >> 8); 157 158 return ((word ^ (word >> 4)) & 0x0f); 159} 160 161/* 162 * compute link-local solicited-node multicast address 163 */ 164 165static inline void addrconf_addr_solict_mult(struct in6_addr *addr, 166 struct in6_addr *solicited) 167{ 168 ipv6_addr_set(solicited, 169 __constant_htonl(0xFF020000), 0, 170 __constant_htonl(0x1), 171 __constant_htonl(0xFF000000) | addr->s6_addr32[3]); 172} 173 174 175static inline void ipv6_addr_all_nodes(struct in6_addr *addr) 176{ 177 ipv6_addr_set(addr, 178 __constant_htonl(0xFF020000), 0, 0, 179 __constant_htonl(0x1)); 180} 181 182static inline void ipv6_addr_all_routers(struct in6_addr *addr) 183{ 184 ipv6_addr_set(addr, 185 __constant_htonl(0xFF020000), 0, 0, 186 __constant_htonl(0x2)); 187} 188 189static inline int ipv6_addr_is_multicast(struct in6_addr *addr) 190{ 191 return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000); 192} 193 194#endif 195#endif 196