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