[PATCH] timer initialization cleanup: DEFINE_TIMER
[deliverable/linux.git] / net / ipv6 / addrconf.c
CommitLineData
1da177e4
LT
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *
9 * $Id: addrconf.c,v 1.69 2001/10/31 21:55:54 davem Exp $
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17/*
18 * Changes:
19 *
20 * Janos Farkas : delete timer on ifdown
21 * <chexum@bankinf.banki.hu>
22 * Andi Kleen : kill double kfree on module
23 * unload.
24 * Maciej W. Rozycki : FDDI support
25 * sekiya@USAGI : Don't send too many RS
26 * packets.
27 * yoshfuji@USAGI : Fixed interval between DAD
28 * packets.
29 * YOSHIFUJI Hideaki @USAGI : improved accuracy of
30 * address validation timer.
31 * YOSHIFUJI Hideaki @USAGI : Privacy Extensions (RFC3041)
32 * support.
33 * Yuji SEKIYA @USAGI : Don't assign a same IPv6
34 * address on a same interface.
35 * YOSHIFUJI Hideaki @USAGI : ARCnet support
36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
37 * seq_file.
38 */
39
40#include <linux/config.h>
41#include <linux/errno.h>
42#include <linux/types.h>
43#include <linux/socket.h>
44#include <linux/sockios.h>
45#include <linux/sched.h>
46#include <linux/net.h>
47#include <linux/in6.h>
48#include <linux/netdevice.h>
49#include <linux/if_arp.h>
50#include <linux/if_arcnet.h>
51#include <linux/if_infiniband.h>
52#include <linux/route.h>
53#include <linux/inetdevice.h>
54#include <linux/init.h>
55#ifdef CONFIG_SYSCTL
56#include <linux/sysctl.h>
57#endif
58#include <linux/delay.h>
59#include <linux/notifier.h>
543537bd 60#include <linux/string.h>
1da177e4
LT
61
62#include <net/sock.h>
63#include <net/snmp.h>
64
65#include <net/ipv6.h>
66#include <net/protocol.h>
67#include <net/ndisc.h>
68#include <net/ip6_route.h>
69#include <net/addrconf.h>
70#include <net/tcp.h>
71#include <net/ip.h>
72#include <linux/if_tunnel.h>
73#include <linux/rtnetlink.h>
74
75#ifdef CONFIG_IPV6_PRIVACY
76#include <linux/random.h>
77#include <linux/crypto.h>
78#include <asm/scatterlist.h>
79#endif
80
81#include <asm/uaccess.h>
82
83#include <linux/proc_fs.h>
84#include <linux/seq_file.h>
85
86/* Set to 3 to get tracing... */
87#define ACONF_DEBUG 2
88
89#if ACONF_DEBUG >= 3
90#define ADBG(x) printk x
91#else
92#define ADBG(x)
93#endif
94
95#define INFINITY_LIFE_TIME 0xFFFFFFFF
96#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
97
98#ifdef CONFIG_SYSCTL
99static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p);
100static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
101#endif
102
103#ifdef CONFIG_IPV6_PRIVACY
104static int __ipv6_regen_rndid(struct inet6_dev *idev);
105static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
106static void ipv6_regen_rndid(unsigned long data);
107
108static int desync_factor = MAX_DESYNC_FACTOR * HZ;
109static struct crypto_tfm *md5_tfm;
110static DEFINE_SPINLOCK(md5_tfm_lock);
111#endif
112
113static int ipv6_count_addresses(struct inet6_dev *idev);
114
115/*
116 * Configured unicast address hash table
117 */
118static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE];
119static DEFINE_RWLOCK(addrconf_hash_lock);
120
121/* Protects inet6 devices */
122DEFINE_RWLOCK(addrconf_lock);
123
124static void addrconf_verify(unsigned long);
125
8d06afab 126static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
1da177e4
LT
127static DEFINE_SPINLOCK(addrconf_verify_lock);
128
129static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
130static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
131
132static int addrconf_ifdown(struct net_device *dev, int how);
133
e431b8c0 134static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
1da177e4
LT
135static void addrconf_dad_timer(unsigned long data);
136static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
137static void addrconf_rs_timer(unsigned long data);
138static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
139static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
140
141static void inet6_prefix_notify(int event, struct inet6_dev *idev,
142 struct prefix_info *pinfo);
143static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
144
145static struct notifier_block *inet6addr_chain;
146
147struct ipv6_devconf ipv6_devconf = {
148 .forwarding = 0,
149 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
150 .mtu6 = IPV6_MIN_MTU,
151 .accept_ra = 1,
152 .accept_redirects = 1,
153 .autoconf = 1,
154 .force_mld_version = 0,
155 .dad_transmits = 1,
156 .rtr_solicits = MAX_RTR_SOLICITATIONS,
157 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
158 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
159#ifdef CONFIG_IPV6_PRIVACY
160 .use_tempaddr = 0,
161 .temp_valid_lft = TEMP_VALID_LIFETIME,
162 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
163 .regen_max_retry = REGEN_MAX_RETRY,
164 .max_desync_factor = MAX_DESYNC_FACTOR,
165#endif
166 .max_addresses = IPV6_MAX_ADDRESSES,
167};
168
169static struct ipv6_devconf ipv6_devconf_dflt = {
170 .forwarding = 0,
171 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
172 .mtu6 = IPV6_MIN_MTU,
173 .accept_ra = 1,
174 .accept_redirects = 1,
175 .autoconf = 1,
176 .dad_transmits = 1,
177 .rtr_solicits = MAX_RTR_SOLICITATIONS,
178 .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
179 .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
180#ifdef CONFIG_IPV6_PRIVACY
181 .use_tempaddr = 0,
182 .temp_valid_lft = TEMP_VALID_LIFETIME,
183 .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
184 .regen_max_retry = REGEN_MAX_RETRY,
185 .max_desync_factor = MAX_DESYNC_FACTOR,
186#endif
187 .max_addresses = IPV6_MAX_ADDRESSES,
188};
189
190/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
191#if 0
192const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
193#endif
194const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
195
196int ipv6_addr_type(const struct in6_addr *addr)
197{
198 int type;
199 u32 st;
200
201 st = addr->s6_addr32[0];
202
203 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
204 type = IPV6_ADDR_MULTICAST;
205
206 switch((st & htonl(0x00FF0000))) {
207 case __constant_htonl(0x00010000):
208 type |= IPV6_ADDR_LOOPBACK;
209 break;
210
211 case __constant_htonl(0x00020000):
212 type |= IPV6_ADDR_LINKLOCAL;
213 break;
214
215 case __constant_htonl(0x00050000):
216 type |= IPV6_ADDR_SITELOCAL;
217 break;
218 };
219 return type;
220 }
221
222 type = IPV6_ADDR_UNICAST;
223
224 /* Consider all addresses with the first three bits different of
225 000 and 111 as finished.
226 */
227 if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
228 (st & htonl(0xE0000000)) != htonl(0xE0000000))
229 return type;
230
231 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
232 return (IPV6_ADDR_LINKLOCAL | type);
233
234 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
235 return (IPV6_ADDR_SITELOCAL | type);
236
237 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
238 if (addr->s6_addr32[2] == 0) {
239 if (addr->s6_addr32[3] == 0)
240 return IPV6_ADDR_ANY;
241
242 if (addr->s6_addr32[3] == htonl(0x00000001))
243 return (IPV6_ADDR_LOOPBACK | type);
244
245 return (IPV6_ADDR_COMPATv4 | type);
246 }
247
248 if (addr->s6_addr32[2] == htonl(0x0000ffff))
249 return IPV6_ADDR_MAPPED;
250 }
251
252 st &= htonl(0xFF000000);
253 if (st == 0)
254 return IPV6_ADDR_RESERVED;
255 st &= htonl(0xFE000000);
256 if (st == htonl(0x02000000))
257 return IPV6_ADDR_RESERVED; /* for NSAP */
258 if (st == htonl(0x04000000))
259 return IPV6_ADDR_RESERVED; /* for IPX */
260 return type;
261}
262
263static void addrconf_del_timer(struct inet6_ifaddr *ifp)
264{
265 if (del_timer(&ifp->timer))
266 __in6_ifa_put(ifp);
267}
268
269enum addrconf_timer_t
270{
271 AC_NONE,
272 AC_DAD,
273 AC_RS,
274};
275
276static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
277 enum addrconf_timer_t what,
278 unsigned long when)
279{
280 if (!del_timer(&ifp->timer))
281 in6_ifa_hold(ifp);
282
283 switch (what) {
284 case AC_DAD:
285 ifp->timer.function = addrconf_dad_timer;
286 break;
287 case AC_RS:
288 ifp->timer.function = addrconf_rs_timer;
289 break;
290 default:;
291 }
292 ifp->timer.expires = jiffies + when;
293 add_timer(&ifp->timer);
294}
295
296/* Nobody refers to this device, we may destroy it. */
297
298void in6_dev_finish_destroy(struct inet6_dev *idev)
299{
300 struct net_device *dev = idev->dev;
301 BUG_TRAP(idev->addr_list==NULL);
302 BUG_TRAP(idev->mc_list==NULL);
303#ifdef NET_REFCNT_DEBUG
304 printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL");
305#endif
306 dev_put(dev);
307 if (!idev->dead) {
308 printk("Freeing alive inet6 device %p\n", idev);
309 return;
310 }
311 snmp6_free_dev(idev);
312 kfree(idev);
313}
314
315static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
316{
317 struct inet6_dev *ndev;
318
319 ASSERT_RTNL();
320
321 if (dev->mtu < IPV6_MIN_MTU)
322 return NULL;
323
324 ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL);
325
326 if (ndev) {
327 memset(ndev, 0, sizeof(struct inet6_dev));
328
329 rwlock_init(&ndev->lock);
330 ndev->dev = dev;
331 memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
332 ndev->cnf.mtu6 = dev->mtu;
333 ndev->cnf.sysctl = NULL;
334 ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
335 if (ndev->nd_parms == NULL) {
336 kfree(ndev);
337 return NULL;
338 }
339 /* We refer to the device */
340 dev_hold(dev);
341
342 if (snmp6_alloc_dev(ndev) < 0) {
343 ADBG((KERN_WARNING
344 "%s(): cannot allocate memory for statistics; dev=%s.\n",
345 __FUNCTION__, dev->name));
346 neigh_parms_release(&nd_tbl, ndev->nd_parms);
347 ndev->dead = 1;
348 in6_dev_finish_destroy(ndev);
349 return NULL;
350 }
351
352 if (snmp6_register_dev(ndev) < 0) {
353 ADBG((KERN_WARNING
354 "%s(): cannot create /proc/net/dev_snmp6/%s\n",
355 __FUNCTION__, dev->name));
356 neigh_parms_release(&nd_tbl, ndev->nd_parms);
357 ndev->dead = 1;
358 in6_dev_finish_destroy(ndev);
359 return NULL;
360 }
361
362 /* One reference from device. We must do this before
363 * we invoke __ipv6_regen_rndid().
364 */
365 in6_dev_hold(ndev);
366
367#ifdef CONFIG_IPV6_PRIVACY
368 get_random_bytes(ndev->rndid, sizeof(ndev->rndid));
369 get_random_bytes(ndev->entropy, sizeof(ndev->entropy));
370 init_timer(&ndev->regen_timer);
371 ndev->regen_timer.function = ipv6_regen_rndid;
372 ndev->regen_timer.data = (unsigned long) ndev;
373 if ((dev->flags&IFF_LOOPBACK) ||
374 dev->type == ARPHRD_TUNNEL ||