[IPV6] ADDRCONF: Uninline ipv6_isatap_eui64().
[linux-block.git] / net / ipv6 / ndisc.c
CommitLineData
1da177e4
LT
1/*
2 * Neighbour Discovery for IPv6
1ab1457c 3 * Linux INET6 implementation
1da177e4
LT
4 *
5 * Authors:
1ab1457c 6 * Pedro Roque <roque@di.fc.ul.pt>
1da177e4
LT
7 * Mike Shaver <shaver@ingenia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15/*
16 * Changes:
17 *
31910575
PY
18 * Pierre Ynard : export userland ND options
19 * through netlink (RDNSS support)
1da177e4
LT
20 * Lars Fenneberg : fixed MTU setting on receipt
21 * of an RA.
1da177e4
LT
22 * Janos Farkas : kmalloc failure checks
23 * Alexey Kuznetsov : state machine reworked
24 * and moved to net/core.
25 * Pekka Savola : RFC2461 validation
26 * YOSHIFUJI Hideaki @USAGI : Verify ND options properly
27 */
28
29/* Set to 3 to get tracing... */
30#define ND_DEBUG 1
31
32#define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0)
33#define ND_NOPRINTK(x...) do { ; } while(0)
34#define ND_PRINTK0 ND_PRINTK
35#define ND_PRINTK1 ND_NOPRINTK
36#define ND_PRINTK2 ND_NOPRINTK
37#define ND_PRINTK3 ND_NOPRINTK
38#if ND_DEBUG >= 1
39#undef ND_PRINTK1
40#define ND_PRINTK1 ND_PRINTK
41#endif
42#if ND_DEBUG >= 2
43#undef ND_PRINTK2
44#define ND_PRINTK2 ND_PRINTK
45#endif
46#if ND_DEBUG >= 3
47#undef ND_PRINTK3
48#define ND_PRINTK3 ND_PRINTK
49#endif
50
51#include <linux/module.h>
1da177e4
LT
52#include <linux/errno.h>
53#include <linux/types.h>
54#include <linux/socket.h>
55#include <linux/sockios.h>
56#include <linux/sched.h>
57#include <linux/net.h>
58#include <linux/in6.h>
59#include <linux/route.h>
60#include <linux/init.h>
61#include <linux/rcupdate.h>
62#ifdef CONFIG_SYSCTL
63#include <linux/sysctl.h>
64#endif
65
1823730f 66#include <linux/if_addr.h>
1da177e4
LT
67#include <linux/if_arp.h>
68#include <linux/ipv6.h>
69#include <linux/icmpv6.h>
70#include <linux/jhash.h>
71
72#include <net/sock.h>
73#include <net/snmp.h>
74
75#include <net/ipv6.h>
76#include <net/protocol.h>
77#include <net/ndisc.h>
78#include <net/ip6_route.h>
79#include <net/addrconf.h>
80#include <net/icmp.h>
81
31910575
PY
82#include <net/netlink.h>
83#include <linux/rtnetlink.h>
84
1da177e4
LT
85#include <net/flow.h>
86#include <net/ip6_checksum.h>
1ed8516f 87#include <net/inet_common.h>
1da177e4
LT
88#include <linux/proc_fs.h>
89
90#include <linux/netfilter.h>
91#include <linux/netfilter_ipv6.h>
92
1da177e4
LT
93static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
94static int ndisc_constructor(struct neighbour *neigh);
95static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
96static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
97static int pndisc_constructor(struct pneigh_entry *n);
98static void pndisc_destructor(struct pneigh_entry *n);
99static void pndisc_redo(struct sk_buff *skb);
100
101static struct neigh_ops ndisc_generic_ops = {
102 .family = AF_INET6,
103 .solicit = ndisc_solicit,
104 .error_report = ndisc_error_report,
105 .output = neigh_resolve_output,
106 .connected_output = neigh_connected_output,
107 .hh_output = dev_queue_xmit,
108 .queue_xmit = dev_queue_xmit,
109};
110
111static struct neigh_ops ndisc_hh_ops = {
112 .family = AF_INET6,
113 .solicit = ndisc_solicit,
114 .error_report = ndisc_error_report,
115 .output = neigh_resolve_output,
116 .connected_output = neigh_resolve_output,
117 .hh_output = dev_queue_xmit,
118 .queue_xmit = dev_queue_xmit,
119};
120
121
122static struct neigh_ops ndisc_direct_ops = {
123 .family = AF_INET6,
124 .output = dev_queue_xmit,
125 .connected_output = dev_queue_xmit,
126 .hh_output = dev_queue_xmit,
127 .queue_xmit = dev_queue_xmit,
128};
129
130struct neigh_table nd_tbl = {
131 .family = AF_INET6,
132 .entry_size = sizeof(struct neighbour) + sizeof(struct in6_addr),
133 .key_len = sizeof(struct in6_addr),
134 .hash = ndisc_hash,
135 .constructor = ndisc_constructor,
136 .pconstructor = pndisc_constructor,
137 .pdestructor = pndisc_destructor,
138 .proxy_redo = pndisc_redo,
139 .id = "ndisc_cache",
140 .parms = {
141 .tbl = &nd_tbl,
142 .base_reachable_time = 30 * HZ,
143 .retrans_time = 1 * HZ,
144 .gc_staletime = 60 * HZ,
145 .reachable_time = 30 * HZ,
146 .delay_probe_time = 5 * HZ,
147 .queue_len = 3,
148 .ucast_probes = 3,
149 .mcast_probes = 3,
150 .anycast_delay = 1 * HZ,
151 .proxy_delay = (8 * HZ) / 10,
152 .proxy_qlen = 64,
153 },
154 .gc_interval = 30 * HZ,
155 .gc_thresh1 = 128,
156 .gc_thresh2 = 512,
157 .gc_thresh3 = 1024,
158};
159
160/* ND options */
161struct ndisc_options {
70ceb4f5
YH
162 struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
163#ifdef CONFIG_IPV6_ROUTE_INFO
164 struct nd_opt_hdr *nd_opts_ri;
165 struct nd_opt_hdr *nd_opts_ri_end;
166#endif
31910575
PY
167 struct nd_opt_hdr *nd_useropts;
168 struct nd_opt_hdr *nd_useropts_end;
1da177e4
LT
169};
170
171#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
172#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
173#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
174#define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
175#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
176#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
177
178#define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
179
180/*
181 * Return the padding between the option length and the start of the
182 * link addr. Currently only IP-over-InfiniBand needs this, although
183 * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
184 * also need a pad of 2.
185 */
186static int ndisc_addr_option_pad(unsigned short type)
187{
188 switch (type) {
189 case ARPHRD_INFINIBAND: return 2;
190 default: return 0;
191 }
192}
193
194static inline int ndisc_opt_addr_space(struct net_device *dev)
195{
196 return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
197}
198
199static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
200 unsigned short addr_type)
201{
202 int space = NDISC_OPT_SPACE(data_len);
203 int pad = ndisc_addr_option_pad(addr_type);
204
205 opt[0] = type;
206 opt[1] = space>>3;
207
208 memset(opt + 2, 0, pad);
209 opt += pad;
210 space -= pad;
211
212 memcpy(opt+2, data, data_len);
213 data_len += 2;
214 opt += data_len;
215 if ((space -= data_len) > 0)
216 memset(opt, 0, space);
217 return opt + space;
218}
219
220static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
221 struct nd_opt_hdr *end)
222{
223 int type;
224 if (!cur || !end || cur >= end)
225 return NULL;
226 type = cur->nd_opt_type;
227 do {
228 cur = ((void *)cur) + (cur->nd_opt_len << 3);
229 } while(cur < end && cur->nd_opt_type != type);
230 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
231}
232
31910575
PY
233static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
234{
235 return (opt->nd_opt_type == ND_OPT_RDNSS);
236}
237
238static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
239 struct nd_opt_hdr *end)
240{
241 if (!cur || !end || cur >= end)
242 return NULL;
243 do {
244 cur = ((void *)cur) + (cur->nd_opt_len << 3);
245 } while(cur < end && !ndisc_is_useropt(cur));
246 return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL);
247}
248
1da177e4
LT
249static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
250 struct ndisc_options *ndopts)
251{
252 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
253
254 if (!nd_opt || opt_len < 0 || !ndopts)
255 return NULL;
256 memset(ndopts, 0, sizeof(*ndopts));
257 while (opt_len) {
258 int l;
259 if (opt_len < sizeof(struct nd_opt_hdr))
260 return NULL;
261 l = nd_opt->nd_opt_len << 3;
262 if (opt_len < l || l == 0)
263 return NULL;
264 switch (nd_opt->nd_opt_type) {
265 case ND_OPT_SOURCE_LL_ADDR:
266 case ND_OPT_TARGET_LL_ADDR:
267 case ND_OPT_MTU:
268 case ND_OPT_REDIRECT_HDR:
269 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
270 ND_PRINTK2(KERN_WARNING
271 "%s(): duplicated ND6 option found: type=%d\n",
0dc47877 272 __func__,
1da177e4
LT
273 nd_opt->nd_opt_type);
274 } else {
275 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
276 }
277 break;
278 case ND_OPT_PREFIX_INFO:
279 ndopts->nd_opts_pi_end = nd_opt;
cfcabdcc 280 if (!ndopts->nd_opt_array[nd_opt->nd_opt_type])
1da177e4
LT
281 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
282 break;
70ceb4f5
YH
283#ifdef CONFIG_IPV6_ROUTE_INFO
284 case ND_OPT_ROUTE_INFO:
285 ndopts->nd_opts_ri_end = nd_opt;
286 if (!ndopts->nd_opts_ri)
287 ndopts->nd_opts_ri = nd_opt;
288 break;
289#endif
1da177e4 290 default:
31910575
PY
291 if (ndisc_is_useropt(nd_opt)) {
292 ndopts->nd_useropts_end = nd_opt;
293 if (!ndopts->nd_useropts)
294 ndopts->nd_useropts = nd_opt;
295 } else {
296 /*
297 * Unknown options must be silently ignored,
298 * to accommodate future extension to the
299 * protocol.
300 */
301 ND_PRINTK2(KERN_NOTICE
302 "%s(): ignored unsupported option; type=%d, len=%d\n",
0dc47877 303 __func__,
31910575
PY
304 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
305 }
1da177e4
LT
306 }
307 opt_len -= l;
308 nd_opt = ((void *)nd_opt) + l;
309 }
310 return ndopts;
311}
312
313static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
314 struct net_device *dev)
315{
316 u8 *lladdr = (u8 *)(p + 1);
317 int lladdrlen = p->nd_opt_len << 3;
318 int prepad = ndisc_addr_option_pad(dev->type);
319 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
320 return NULL;
321 return (lladdr + prepad);
322}
323
324int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
325{
326 switch (dev->type) {
327 case ARPHRD_ETHER:
328 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
329 case ARPHRD_FDDI:
330 ipv6_eth_mc_map(addr, buf);
331 return 0;
332 case ARPHRD_IEEE802_TR:
333 ipv6_tr_mc_map(addr,buf);
334 return 0;
335 case ARPHRD_ARCNET:
336 ipv6_arcnet_mc_map(addr, buf);
337 return 0;
338 case ARPHRD_INFINIBAND:
a9e527e3 339 ipv6_ib_mc_map(addr, dev->broadcast, buf);
1da177e4
LT
340 return 0;
341 default:
342 if (dir) {
343 memcpy(buf, dev->broadcast, dev->addr_len);
344 return 0;
345 }
346 }
347 return -EINVAL;
348}
349
7159039a
YH
350EXPORT_SYMBOL(ndisc_mc_map);
351
1da177e4
LT
352static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
353{
354 const u32 *p32 = pkey;
355 u32 addr_hash, i;
356
357 addr_hash = 0;
358 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
359 addr_hash ^= *p32++;
360
361 return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
362}
363
364static int ndisc_constructor(struct neighbour *neigh)
365{
366 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
367 struct net_device *dev = neigh->dev;
368 struct inet6_dev *in6_dev;
369 struct neigh_parms *parms;
370 int is_multicast = ipv6_addr_is_multicast(addr);
371
372 rcu_read_lock();
373 in6_dev = in6_dev_get(dev);
374 if (in6_dev == NULL) {
375 rcu_read_unlock();
376 return -EINVAL;
377 }
378
379 parms = in6_dev->nd_parms;
380 __neigh_parms_put(neigh->parms);
381 neigh->parms = neigh_parms_clone(parms);
382 rcu_read_unlock();
383
384 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
3b04ddde 385 if (!dev->header_ops) {
1da177e4
LT
386 neigh->nud_state = NUD_NOARP;
387 neigh->ops = &ndisc_direct_ops;
388 neigh->output = neigh->ops->queue_xmit;
389 } else {
390 if (is_multicast) {
391 neigh->nud_state = NUD_NOARP;
392 ndisc_mc_map(addr, neigh->ha, dev, 1);
393 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
394 neigh->nud_state = NUD_NOARP;
395 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
396 if (dev->flags&IFF_LOOPBACK)
397 neigh->type = RTN_LOCAL;
398 } else if (dev->flags&IFF_POINTOPOINT) {
399 neigh->nud_state = NUD_NOARP;
400 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
401 }
3b04ddde 402 if (dev->header_ops->cache)
1da177e4
LT
403 neigh->ops = &ndisc_hh_ops;
404 else
405 neigh->ops = &ndisc_generic_ops;
406 if (neigh->nud_state&NUD_VALID)
407 neigh->output = neigh->ops->connected_output;
408 else
409 neigh->output = neigh->ops->output;
410 }
411 in6_dev_put(in6_dev);
412 return 0;
413}
414
415static int pndisc_constructor(struct pneigh_entry *n)
416{
417 struct in6_addr *addr = (struct in6_addr*)&n->key;
418 struct in6_addr maddr;
419 struct net_device *dev = n->dev;
420
421 if (dev == NULL || __in6_dev_get(dev) == NULL)
422 return -EINVAL;
423 addrconf_addr_solict_mult(addr, &maddr);
424 ipv6_dev_mc_inc(dev, &maddr);
425 return 0;
426}
427
428static void pndisc_destructor(struct pneigh_entry *n)
429{
430 struct in6_addr *addr = (struct in6_addr*)&n->key;
431 struct in6_addr maddr;
432 struct net_device *dev = n->dev;
433
434 if (dev == NULL || __in6_dev_get(dev) == NULL)
435 return;
436 addrconf_addr_solict_mult(addr, &maddr);
437 ipv6_dev_mc_dec(dev, &maddr);
438}
439
440/*
441 * Send a Neighbour Advertisement
442 */
e1ec7842
YH
443static void __ndisc_send(struct net_device *dev,
444 struct neighbour *neigh,
445 struct in6_addr *daddr, struct in6_addr *saddr,
446 struct icmp6hdr *icmp6h, struct in6_addr *target,
14878f75 447 int llinfo)
1da177e4 448{
1da177e4 449 struct flowi fl;
e1ec7842 450 struct dst_entry *dst;
c346dca1 451 struct net *net = dev_net(dev);
1762f7e8 452 struct sock *sk = net->ipv6.ndisc_sk;
1ab1457c 453 struct sk_buff *skb;
e1ec7842
YH
454 struct icmp6hdr *hdr;
455 struct inet6_dev *idev;
456 int len;
1da177e4 457 int err;
14878f75
DS
458 u8 *opt, type;
459
460 type = icmp6h->icmp6_type;
1da177e4 461
1762f7e8 462 icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
1da177e4 463
3b00944c 464 dst = icmp6_dst_alloc(dev, neigh, daddr);
1da177e4
LT
465 if (!dst)
466 return;
467
468 err = xfrm_lookup(&dst, &fl, NULL, 0);
e104411b 469 if (err < 0)
1da177e4 470 return;
1da177e4 471
e1ec7842
YH
472 if (!dev->addr_len)
473 llinfo = 0;
474
475 len = sizeof(struct icmp6hdr) + (target ? sizeof(*target) : 0);
476 if (llinfo)
477 len += ndisc_opt_addr_space(dev);
1da177e4 478
d54a81d3
DM
479 skb = sock_alloc_send_skb(sk,
480 (MAX_HEADER + sizeof(struct ipv6hdr) +
481 len + LL_RESERVED_SPACE(dev)),
1da177e4 482 1, &err);
e1ec7842 483 if (!skb) {
1da177e4 484 ND_PRINTK0(KERN_ERR
e1ec7842 485 "ICMPv6 ND: %s() failed to allocate an skb.\n",
0dc47877 486 __func__);
1da177e4
LT
487 dst_release(dst);
488 return;
489 }
490
491 skb_reserve(skb, LL_RESERVED_SPACE(dev));
e1ec7842 492 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
1da177e4 493
27a884dc 494 skb->transport_header = skb->tail;
d10ba34b 495 skb_put(skb, len);
1da177e4 496
e1ec7842
YH
497 hdr = (struct icmp6hdr *)skb_transport_header(skb);
498 memcpy(hdr, icmp6h, sizeof(*hdr));
1da177e4 499
e1ec7842
YH
500 opt = skb_transport_header(skb) + sizeof(struct icmp6hdr);
501 if (target) {
502 ipv6_addr_copy((struct in6_addr *)opt, target);
503 opt += sizeof(*target);
504 }
1da177e4 505
e1ec7842
YH
506 if (llinfo)
507 ndisc_fill_addr_option(opt, llinfo, dev->dev_addr,
1da177e4
LT
508 dev->addr_len, dev->type);
509
e1ec7842
YH
510 hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len,
511 IPPROTO_ICMPV6,
512 csum_partial((__u8 *) hdr,
513 len, 0));
1da177e4
LT
514
515 skb->dst = dst;
e1ec7842 516
1da177e4 517 idev = in6_dev_get(dst->dev);
a11d206d 518 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
e1ec7842 519
6e23ae2a
PM
520 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
521 dst_output);
1da177e4 522 if (!err) {
14878f75 523 ICMP6MSGOUT_INC_STATS(idev, type);
1da177e4
LT
524 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
525 }
526
527 if (likely(idev != NULL))
528 in6_dev_put(idev);
1ab1457c 529}
1da177e4 530
e1ec7842
YH
531static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
532 struct in6_addr *daddr, struct in6_addr *solicited_addr,
533 int router, int solicited, int override, int inc_opt)
534{
535 struct in6_addr tmpaddr;
536 struct inet6_ifaddr *ifp;
537 struct in6_addr *src_addr;
538 struct icmp6hdr icmp6h = {
539 .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
540 };
541
542 /* for anycast or proxy, solicited_addr != src_addr */
c346dca1 543 ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
e1ec7842
YH
544 if (ifp) {
545 src_addr = solicited_addr;
546 if (ifp->flags & IFA_F_OPTIMISTIC)
547 override = 0;
548 in6_ifa_put(ifp);
549 } else {
7cbca67c 550 if (ipv6_dev_get_saddr(dev, daddr,
c346dca1 551 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
7cbca67c 552 &tmpaddr))
e1ec7842
YH
553 return;
554 src_addr = &tmpaddr;
555 }
556
557 icmp6h.icmp6_router = router;
558 icmp6h.icmp6_solicited = solicited;
559 icmp6h.icmp6_override = override;
560
561 __ndisc_send(dev, neigh, daddr, src_addr,
562 &icmp6h, solicited_addr,
14878f75 563 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
e1ec7842
YH
564}
565
1da177e4
LT
566void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
567 struct in6_addr *solicit,
1ab1457c 568 struct in6_addr *daddr, struct in6_addr *saddr)
1da177e4 569{
1da177e4 570 struct in6_addr addr_buf;
e1ec7842
YH
571 struct icmp6hdr icmp6h = {
572 .icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
573 };
1da177e4
LT
574
575 if (saddr == NULL) {
95c385b4
NH
576 if (ipv6_get_lladdr(dev, &addr_buf,
577 (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
1da177e4
LT
578 return;
579 saddr = &addr_buf;
580 }
581
e1ec7842
YH
582 __ndisc_send(dev, neigh, daddr, saddr,
583 &icmp6h, solicit,
14878f75 584 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
1da177e4
LT
585}
586
587void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
588 struct in6_addr *daddr)
589{
e1ec7842
YH
590 struct icmp6hdr icmp6h = {
591 .icmp6_type = NDISC_ROUTER_SOLICITATION,
592 };
95c385b4 593 int send_sllao = dev->addr_len;
95c385b4
NH
594
595#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
596 /*
597 * According to section 2.2 of RFC 4429, we must not
598 * send router solicitations with a sllao from
599 * optimistic addresses, but we may send the solicitation
600 * if we don't include the sllao. So here we check
601 * if our address is optimistic, and if so, we
bea85195 602 * suppress the inclusion of the sllao.
95c385b4
NH
603 */
604 if (send_sllao) {
c346dca1 605 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(dev_net(dev), saddr,
1cab3da6 606 dev, 1);
95c385b4
NH
607 if (ifp) {
608 if (ifp->flags & IFA_F_OPTIMISTIC) {
ca043569 609 send_sllao = 0;
95c385b4 610 }
ca043569 611 in6_ifa_put(ifp);
95c385b4
NH
612 } else {
613 send_sllao = 0;
614 }
615 }
616#endif
e1ec7842
YH
617 __ndisc_send(dev, NULL, daddr, saddr,
618 &icmp6h, NULL,
14878f75 619 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
1da177e4 620}
1ab1457c 621
1da177e4
LT
622
623static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
624{
625 /*
626 * "The sender MUST return an ICMP
627 * destination unreachable"
628 */
629 dst_link_failure(skb);
630 kfree_skb(skb);
631}
632
633/* Called with locked neigh: either read or both */
634
635static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
636{
637 struct in6_addr *saddr = NULL;
638 struct in6_addr mcaddr;
639 struct net_device *dev = neigh->dev;
640 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
641 int probes = atomic_read(&neigh->probes);
642
c346dca1 643 if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
0660e03f 644 saddr = &ipv6_hdr(skb)->saddr;
1da177e4
LT
645
646 if ((probes -= neigh->parms->ucast_probes) < 0) {
647 if (!(neigh->nud_state & NUD_VALID)) {
648 ND_PRINTK1(KERN_DEBUG
649 "%s(): trying to ucast probe in NUD_INVALID: "
46b86a2d 650 NIP6_FMT "\n",
0dc47877 651 __func__,
1da177e4
LT
652 NIP6(*target));
653 }
654 ndisc_send_ns(dev, neigh, target, target, saddr);
655 } else if ((probes -= neigh->parms->app_probes) < 0) {
656#ifdef CONFIG_ARPD
657 neigh_app_ns(neigh);
658#endif
659 } else {
660 addrconf_addr_solict_mult(target, &mcaddr);
661 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
662 }
663}
664
0736ffc0
YH
665static int pndisc_is_router(const void *pkey,
666 struct net_device *dev)
fa86d322
PE
667{
668 struct pneigh_entry *n;
0736ffc0 669 int ret = -1;
fa86d322
PE
670
671 read_lock_bh(&nd_tbl.lock);
0736ffc0
YH
672 n = __pneigh_lookup(&nd_tbl, dev_net(dev), pkey, dev);
673 if (n)
674 ret = !!(n->flags & NTF_ROUTER);
fa86d322
PE
675 read_unlock_bh(&nd_tbl.lock);
676
0736ffc0 677 return ret;
fa86d322
PE
678}
679
1da177e4
LT
680static void ndisc_recv_ns(struct sk_buff *skb)
681{
9c70220b 682 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
0660e03f
ACM
683 struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
684 struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
1da177e4 685 u8 *lladdr = NULL;
27a884dc
ACM
686 u32 ndoptlen = skb->tail - (skb->transport_header +
687 offsetof(struct nd_msg, opt));
1da177e4
LT
688 struct ndisc_options ndopts;
689 struct net_device *dev = skb->dev;
690 struct inet6_ifaddr *ifp;
691 struct inet6_dev *idev = NULL;
692 struct neighbour *neigh;
693 int dad = ipv6_addr_any(saddr);
694 int inc;
0736ffc0 695 int is_router = -1;
1da177e4
LT
696
697 if (ipv6_addr_is_multicast(&msg->target)) {
1ab1457c 698 ND_PRINTK2(KERN_WARNING
1da177e4
LT
699 "ICMPv6 NS: multicast target address");
700 return;
701 }
702
703 /*
704 * RFC2461 7.1.1:
705 * DAD has to be destined for solicited node multicast address.
706 */
707 if (dad &&
708 !(daddr->s6_addr32[0] == htonl(0xff020000) &&
709 daddr->s6_addr32[1] == htonl(0x00000000) &&
710 daddr->s6_addr32[2] == htonl(0x00000001) &&
711 daddr->s6_addr [12] == 0xff )) {
712 ND_PRINTK2(KERN_WARNING
713 "ICMPv6 NS: bad DAD packet (wrong destination)\n");
714 return;
715 }
716
717 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
1ab1457c 718 ND_PRINTK2(KERN_WARNING
1da177e4
LT
719 "ICMPv6 NS: invalid ND options\n");
720 return;
721 }
722
723 if (ndopts.nd_opts_src_lladdr) {
724 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
725 if (!lladdr) {
726 ND_PRINTK2(KERN_WARNING
727 "ICMPv6 NS: invalid link-layer address length\n");
728 return;
729 }
730
731 /* RFC2461 7.1.1:
1ab1457c
YH
732 * If the IP source address is the unspecified address,
733 * there MUST NOT be source link-layer address option
1da177e4
LT
734 * in the message.
735 */
736 if (dad) {
1ab1457c 737 ND_PRINTK2(KERN_WARNING
1da177e4
LT
738 "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
739 return;
740 }
741 }
742
743 inc = ipv6_addr_is_multicast(daddr);
744
c346dca1 745 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
a18bc695 746 if (ifp) {
95c385b4
NH
747
748 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
749 if (dad) {
750 if (dev->type == ARPHRD_IEEE802_TR) {
98e399f8
ACM
751 const unsigned char *sadr;
752 sadr = skb_mac_header(skb);
95c385b4
NH
753 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
754 sadr[9] == dev->dev_addr[1] &&
755 sadr[10] == dev->dev_addr[2] &&
756 sadr[11] == dev->dev_addr[3] &&
757 sadr[12] == dev->dev_addr[4] &&
758 sadr[13] == dev->dev_addr[5]) {
759 /* looped-back to us */
760 goto out;
761 }
762 }
763
764 /*
765 * We are colliding with another node
766 * who is doing DAD
767 * so fail our DAD process
768 */
769 addrconf_dad_failure(ifp);
9e3be4b3 770 return;
95c385b4
NH
771 } else {
772 /*
773 * This is not a dad solicitation.
774 * If we are an optimistic node,
775 * we should respond.
776 * Otherwise, we should ignore it.
777 */
778 if (!(ifp->flags & IFA_F_OPTIMISTIC))
1da177e4 779 goto out;
1da177e4 780 }
1da177e4
LT
781 }
782
783 idev = ifp->idev;
784 } else {
785 idev = in6_dev_get(dev);
786 if (!idev) {
787 /* XXX: count this drop? */
788 return;
789 }
790
6ab57e7e 791 if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) ||
1ab1457c 792 (idev->cnf.forwarding &&
fbea49e1 793 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
0736ffc0 794 (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
a61bbcf2 795 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
1da177e4
LT
796 skb->pkt_type != PACKET_HOST &&
797 inc != 0 &&
798 idev->nd_parms->proxy_delay != 0) {
799 /*
800 * for anycast or proxy,
1ab1457c
YH
801 * sender should delay its response
802 * by a random time between 0 and
1da177e4
LT
803 * MAX_ANYCAST_DELAY_TIME seconds.
804 * (RFC2461) -- yoshfuji
805 */
806 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
807 if (n)
808 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
809 goto out;
810 }
811 } else
812 goto out;
813 }
814
0736ffc0
YH
815 if (is_router < 0)
816 is_router = !!idev->cnf.forwarding;
62dd9318 817
1da177e4
LT
818 if (dad) {
819 struct in6_addr maddr;
820
821 ipv6_addr_all_nodes(&maddr);
822 ndisc_send_na(dev, NULL, &maddr, &msg->target,
62dd9318 823 is_router, 0, (ifp != NULL), 1);
1da177e4
LT
824 goto out;
825 }
826
827 if (inc)
828 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
829 else
830 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
831
1ab1457c 832 /*
1da177e4
LT
833 * update / create cache entry
834 * for the source address
835 */
836 neigh = __neigh_lookup(&nd_tbl, saddr, dev,
837 !inc || lladdr || !dev->addr_len);
838 if (neigh)
1ab1457c 839 neigh_update(neigh, lladdr, NUD_STALE,
1da177e4
LT
840 NEIGH_UPDATE_F_WEAK_OVERRIDE|
841 NEIGH_UPDATE_F_OVERRIDE);
3b04ddde 842 if (neigh || !dev->header_ops) {
1da177e4 843 ndisc_send_na(dev, neigh, saddr, &msg->target,
62dd9318 844 is_router,
1da177e4
LT
845 1, (ifp != NULL && inc), inc);
846 if (neigh)
847 neigh_release(neigh);
848 }
849
850out:
851 if (ifp)
852 in6_ifa_put(ifp);
853 else
854 in6_dev_put(idev);
855
856 return;
857}
858
859static void ndisc_recv_na(struct sk_buff *skb)
860{
9c70220b 861 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
0660e03f
ACM
862 struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
863 struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
1da177e4 864 u8 *lladdr = NULL;
27a884dc
ACM
865 u32 ndoptlen = skb->tail - (skb->transport_header +
866 offsetof(struct nd_msg, opt));
1da177e4
LT
867 struct ndisc_options ndopts;
868 struct net_device *dev = skb->dev;
869 struct inet6_ifaddr *ifp;
870 struct neighbour *neigh;
871
872 if (skb->len < sizeof(struct nd_msg)) {
873 ND_PRINTK2(KERN_WARNING
874 "ICMPv6 NA: packet too short\n");
875 return;
876 }
877
878 if (ipv6_addr_is_multicast(&msg->target)) {
879 ND_PRINTK2(KERN_WARNING
880 "ICMPv6 NA: target address is multicast.\n");
881 return;
882 }
883
884 if (ipv6_addr_is_multicast(daddr) &&
885 msg->icmph.icmp6_solicited) {
886 ND_PRINTK2(KERN_WARNING
887 "ICMPv6 NA: solicited NA is multicasted.\n");
888 return;
889 }
1ab1457c 890
1da177e4
LT
891 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
892 ND_PRINTK2(KERN_WARNING
893 "ICMPv6 NS: invalid ND option\n");
894 return;
895 }
896 if (ndopts.nd_opts_tgt_lladdr) {
897 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
898 if (!lladdr) {
899 ND_PRINTK2(KERN_WARNING
900 "ICMPv6 NA: invalid link-layer address length\n");
901 return;
902 }
903 }
c346dca1 904 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
a18bc695 905 if (ifp) {
1da177e4
LT
906 if (ifp->flags & IFA_F_TENTATIVE) {
907 addrconf_dad_failure(ifp);
908 return;
909 }
910 /* What should we make now? The advertisement
911 is invalid, but ndisc specs say nothing
912 about it. It could be misconfiguration, or
913 an smart proxy agent tries to help us :-)
914 */
915 ND_PRINTK1(KERN_WARNING
916 "ICMPv6 NA: someone advertises our address on %s!\n",
917 ifp->idev->dev->name);
918 in6_ifa_put(ifp);
919 return;
920 }
921 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
922
923 if (neigh) {
924 u8 old_flags = neigh->flags;
925
926 if (neigh->nud_state & NUD_FAILED)
927 goto out;
928
5f3e6e9e
VN
929 /*
930 * Don't update the neighbor cache entry on a proxy NA from
931 * ourselves because either the proxied node is off link or it
932 * has already sent a NA to us.
933 */
934 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
fbea49e1 935 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
c346dca1 936 pneigh_lookup(&nd_tbl, dev_net(dev), &msg->target, dev, 0)) {
fbea49e1 937 /* XXX: idev->cnf.prixy_ndp */
5f3e6e9e 938 goto out;
fbea49e1 939 }
5f3e6e9e 940
1da177e4
LT
941 neigh_update(neigh, lladdr,
942 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
943 NEIGH_UPDATE_F_WEAK_OVERRIDE|
944 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
945 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
946 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
947
948 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
949 /*
950 * Change: router to host
951 */
952 struct rt6_info *rt;
953 rt = rt6_get_dflt_router(saddr, dev);
954 if (rt)
e0a1ad73 955 ip6_del_rt(rt);
1da177e4
LT
956 }
957
958out:
959 neigh_release(neigh);
960 }
961}
962
963static void ndisc_recv_rs(struct sk_buff *skb)
964{
9c70220b 965 struct rs_msg *rs_msg = (struct rs_msg *)skb_transport_header(skb);
1da177e4
LT
966 unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
967 struct neighbour *neigh;
968 struct inet6_dev *idev;
0660e03f 969 struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
1da177e4
LT
970 struct ndisc_options ndopts;
971 u8 *lladdr = NULL;
972
973 if (skb->len < sizeof(*rs_msg))
974 return;
975
976 idev = in6_dev_get(skb->dev);
977 if (!idev) {
978 if (net_ratelimit())
979 ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
980 return;
981 }
982
983 /* Don't accept RS if we're not in router mode */
984 if (!idev->cnf.forwarding)
985 goto out;
986
987 /*
988 * Don't update NCE if src = ::;
989 * this implies that the source node has no ip address assigned yet.
990 */
991 if (ipv6_addr_any(saddr))
992 goto out;
993
994 /* Parse ND options */
995 if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
996 if (net_ratelimit())
997 ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
998 goto out;
999 }
1000
1001 if (ndopts.nd_opts_src_lladdr) {
1002 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1003 skb->dev);
1004 if (!lladdr)
1005 goto out;
1006 }
1007
1008 neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1009 if (neigh) {
1010 neigh_update(neigh, lladdr, NUD_STALE,
1011 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1012 NEIGH_UPDATE_F_OVERRIDE|
1013 NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1014 neigh_release(neigh);
1015 }
1016out:
1017 in6_dev_put(idev);
1018}
1019
31910575
PY
1020static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
1021{
1022 struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
1023 struct sk_buff *skb;
1024 struct nlmsghdr *nlh;
1025 struct nduseroptmsg *ndmsg;
c346dca1 1026 struct net *net = dev_net(ra->dev);
31910575
PY
1027 int err;
1028 int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
1029 + (opt->nd_opt_len << 3));
1030 size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr));
1031
1032 skb = nlmsg_new(msg_size, GFP_ATOMIC);
1033 if (skb == NULL) {
1034 err = -ENOBUFS;
1035 goto errout;
1036 }
1037
1038 nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0);
1039 if (nlh == NULL) {
1040 goto nla_put_failure;
1041 }
1042
1043 ndmsg = nlmsg_data(nlh);
1044 ndmsg->nduseropt_family = AF_INET6;
dbb2ed24 1045 ndmsg->nduseropt_ifindex = ra->dev->ifindex;
31910575
PY
1046 ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
1047 ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
1048 ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
1049
1050 memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
1051
1052 NLA_PUT(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
1053 &ipv6_hdr(ra)->saddr);
1054 nlmsg_end(skb, nlh);
1055
a18bc695 1056 err = rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL,
97c53cac 1057 GFP_ATOMIC);
31910575
PY
1058 if (err < 0)
1059 goto errout;
1060
1061 return;
1062
1063nla_put_failure:
1064 nlmsg_free(skb);
1065 err = -EMSGSIZE;
1066errout:
a18bc695 1067 rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
31910575
PY
1068}
1069
1da177e4
LT
1070static void ndisc_router_discovery(struct sk_buff *skb)
1071{
9c70220b 1072 struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
1da177e4
LT
1073 struct neighbour *neigh = NULL;
1074 struct inet6_dev *in6_dev;
65f5c7c1 1075 struct rt6_info *rt = NULL;
1da177e4
LT
1076 int lifetime;
1077 struct ndisc_options ndopts;
1078 int optlen;
ebacaaa0 1079 unsigned int pref = 0;
1da177e4
LT
1080
1081 __u8 * opt = (__u8 *)(ra_msg + 1);
1082
27a884dc 1083 optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg);
1da177e4 1084
0660e03f 1085 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1da177e4
LT
1086 ND_PRINTK2(KERN_WARNING
1087 "ICMPv6 RA: source address is not link-local.\n");
1088 return;
1089 }
1090 if (optlen < 0) {
1ab1457c 1091 ND_PRINTK2(KERN_WARNING
1da177e4
LT
1092 "ICMPv6 RA: packet too short\n");
1093 return;
1094 }
1095
de357cc0 1096#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1097 if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
1098 ND_PRINTK2(KERN_WARNING
1099 "ICMPv6 RA: from host or unauthorized router\n");
1100 return;
1101 }
de357cc0 1102#endif
fadf6bf0 1103
1da177e4
LT
1104 /*
1105 * set the RA_RECV flag in the interface
1106 */
1107
1108 in6_dev = in6_dev_get(skb->dev);
1109 if (in6_dev == NULL) {
1110 ND_PRINTK0(KERN_ERR
1111 "ICMPv6 RA: can't find inet6 device for %s.\n",
1112 skb->dev->name);
1113 return;
1114 }
1115 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1116 in6_dev_put(in6_dev);
1117 return;
1118 }
1119
1120 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1121 in6_dev_put(in6_dev);
1122 ND_PRINTK2(KERN_WARNING
1123 "ICMP6 RA: invalid ND options\n");
1124 return;
1125 }
1126
de357cc0 1127#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1128 /* skip link-specific parameters from interior routers */
1129 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1130 goto skip_linkparms;
de357cc0 1131#endif
fadf6bf0 1132
1da177e4
LT
1133 if (in6_dev->if_flags & IF_RS_SENT) {
1134 /*
1135 * flag that an RA was received after an RS was sent
1136 * out on this interface.
1137 */
1138 in6_dev->if_flags |= IF_RA_RCVD;
1139 }
1140
1141 /*
1142 * Remember the managed/otherconf flags from most recently
1143 * received RA message (RFC 2462) -- yoshfuji
1144 */
1145 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1146 IF_RA_OTHERCONF)) |
1147 (ra_msg->icmph.icmp6_addrconf_managed ?
1148 IF_RA_MANAGED : 0) |
1149 (ra_msg->icmph.icmp6_addrconf_other ?
1150 IF_RA_OTHERCONF : 0);
1151
65f5c7c1
YH
1152 if (!in6_dev->cnf.accept_ra_defrtr)
1153 goto skip_defrtr;
1154
1da177e4
LT
1155 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1156
ebacaaa0
YH
1157#ifdef CONFIG_IPV6_ROUTER_PREF
1158 pref = ra_msg->icmph.icmp6_router_pref;
1159 /* 10b is handled as if it were 00b (medium) */
930d6ff2 1160 if (pref == ICMPV6_ROUTER_PREF_INVALID ||
6d5b78cd 1161 !in6_dev->cnf.accept_ra_rtr_pref)
ebacaaa0
YH
1162 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1163#endif
1164
0660e03f 1165 rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
1da177e4
LT
1166
1167 if (rt)
1168 neigh = rt->rt6i_nexthop;
1169
1170 if (rt && lifetime == 0) {
1171 neigh_clone(neigh);
e0a1ad73 1172 ip6_del_rt(rt);
1da177e4
LT
1173 rt = NULL;
1174 }
1175
1176 if (rt == NULL && lifetime) {
1177 ND_PRINTK3(KERN_DEBUG
1178 "ICMPv6 RA: adding default router.\n");
1179
0660e03f 1180 rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);
1da177e4
LT
1181 if (rt == NULL) {
1182 ND_PRINTK0(KERN_ERR
1183 "ICMPv6 RA: %s() failed to add default route.\n",
0dc47877 1184 __func__);
1da177e4
LT
1185 in6_dev_put(in6_dev);
1186 return;
1187 }
1188
1189 neigh = rt->rt6i_nexthop;
1190 if (neigh == NULL) {
1191 ND_PRINTK0(KERN_ERR
1192 "ICMPv6 RA: %s() got default router without neighbour.\n",
0dc47877 1193 __func__);
1da177e4
LT
1194 dst_release(&rt->u.dst);
1195 in6_dev_put(in6_dev);
1196 return;
1197 }
1198 neigh->flags |= NTF_ROUTER;
ebacaaa0
YH
1199 } else if (rt) {
1200 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1da177e4
LT
1201 }
1202
1203 if (rt)
1204 rt->rt6i_expires = jiffies + (HZ * lifetime);
1205
1206 if (ra_msg->icmph.icmp6_hop_limit) {
1207 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1208 if (rt)
1209 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1210 }
1211
65f5c7c1
YH
1212skip_defrtr:
1213
1da177e4
LT
1214 /*
1215 * Update Reachable Time and Retrans Timer
1216 */
1217
1218 if (in6_dev->nd_parms) {
1219 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1220
1221 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1222 rtime = (rtime*HZ)/1000;
1223 if (rtime < HZ/10)
1224 rtime = HZ/10;
1225 in6_dev->nd_parms->retrans_time = rtime;
1226 in6_dev->tstamp = jiffies;
1227 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1228 }
1229
1230 rtime = ntohl(ra_msg->reachable_time);
1231 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1232 rtime = (rtime*HZ)/1000;
1233
1234 if (rtime < HZ/10)
1235 rtime = HZ/10;
1236
1237 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1238 in6_dev->nd_parms->base_reachable_time = rtime;
1239 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1240 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1241 in6_dev->tstamp = jiffies;
1242 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1243 }
1244 }
1245 }
1246
de357cc0 1247#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0 1248skip_linkparms:
de357cc0 1249#endif
fadf6bf0 1250
1da177e4
LT
1251 /*
1252 * Process options.
1253 */
1254
1255 if (!neigh)
0660e03f 1256 neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr,
1da177e4
LT
1257 skb->dev, 1);
1258 if (neigh) {
1259 u8 *lladdr = NULL;
1260 if (ndopts.nd_opts_src_lladdr) {
1261 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1262 skb->dev);
1263 if (!lladdr) {
1264 ND_PRINTK2(KERN_WARNING
1265 "ICMPv6 RA: invalid link-layer address length\n");
1266 goto out;
1267 }
1268 }
1269 neigh_update(neigh, lladdr, NUD_STALE,
1270 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1271 NEIGH_UPDATE_F_OVERRIDE|
1272 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1273 NEIGH_UPDATE_F_ISROUTER);
1274 }
1275
70ceb4f5 1276#ifdef CONFIG_IPV6_ROUTE_INFO
09c884d4 1277 if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
70ceb4f5
YH
1278 struct nd_opt_hdr *p;
1279 for (p = ndopts.nd_opts_ri;
1280 p;
1281 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
6294e000
YH
1282 struct route_info *ri = (struct route_info *)p;
1283#ifdef CONFIG_IPV6_NDISC_NODETYPE
1284 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
1285 ri->prefix_len == 0)
1286 continue;
1287#endif
1288 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
09c884d4 1289 continue;
70ceb4f5 1290 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
0660e03f 1291 &ipv6_hdr(skb)->saddr);
70ceb4f5
YH
1292 }
1293 }
1294#endif
1295
de357cc0 1296#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1297 /* skip link-specific ndopts from interior routers */
1298 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1299 goto out;
de357cc0 1300#endif
fadf6bf0 1301
c4fd30eb 1302 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1da177e4
LT
1303 struct nd_opt_hdr *p;
1304 for (p = ndopts.nd_opts_pi;
1305 p;
1306 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1307 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1308 }
1309 }
1310
1311 if (ndopts.nd_opts_mtu) {
e69a4adc 1312 __be32 n;
1da177e4
LT
1313 u32 mtu;
1314
e69a4adc
AV
1315 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1316 mtu = ntohl(n);
1da177e4
LT
1317
1318 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1319 ND_PRINTK2(KERN_WARNING
1320 "ICMPv6 RA: invalid mtu: %d\n",
1321 mtu);
1322 } else if (in6_dev->cnf.mtu6 != mtu) {
1323 in6_dev->cnf.mtu6 = mtu;
1324
1325 if (rt)
1326 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1327
1328 rt6_mtu_change(skb->dev, mtu);
1329 }
1330 }
1ab1457c 1331
31910575 1332 if (ndopts.nd_useropts) {
61cf46ad
YH
1333 struct nd_opt_hdr *p;
1334 for (p = ndopts.nd_useropts;
1335 p;
1336 p = ndisc_next_useropt(p, ndopts.nd_useropts_end)) {
1337 ndisc_ra_useropt(skb, p);
31910575
PY
1338 }
1339 }
1340
1da177e4
LT
1341 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1342 ND_PRINTK2(KERN_WARNING
1343 "ICMPv6 RA: invalid RA options");
1344 }
1345out:
1346 if (rt)
1347 dst_release(&rt->u.dst);
1348 else if (neigh)
1349 neigh_release(neigh);
1350 in6_dev_put(in6_dev);
1351}
1352
1353static void ndisc_redirect_rcv(struct sk_buff *skb)
1354{
1355 struct inet6_dev *in6_dev;
1356 struct icmp6hdr *icmph;
1357 struct in6_addr *dest;
1358 struct in6_addr *target; /* new first hop to destination */
1359 struct neighbour *neigh;
1360 int on_link = 0;
1361 struct ndisc_options ndopts;
1362 int optlen;
1363 u8 *lladdr = NULL;
1364
de357cc0 1365#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1366 switch (skb->ndisc_nodetype) {
1367 case NDISC_NODETYPE_HOST:
1368 case NDISC_NODETYPE_NODEFAULT:
1369 ND_PRINTK2(KERN_WARNING
1370 "ICMPv6 Redirect: from host or unauthorized router\n");
1371 return;
1372 }
de357cc0 1373#endif
fadf6bf0 1374
0660e03f 1375 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1da177e4
LT
1376 ND_PRINTK2(KERN_WARNING
1377 "ICMPv6 Redirect: source address is not link-local.\n");
1378 return;
1379 }
1380
27a884dc 1381 optlen = skb->tail - skb->transport_header;
1da177e4
LT
1382 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1383
1384 if (optlen < 0) {
1385 ND_PRINTK2(KERN_WARNING
1386 "ICMPv6 Redirect: packet too short\n");
1387 return;
1388 }
1389
cc70ab26 1390 icmph = icmp6_hdr(skb);
1da177e4
LT
1391 target = (struct in6_addr *) (icmph + 1);
1392 dest = target + 1;
1393
1394 if (ipv6_addr_is_multicast(dest)) {
1395 ND_PRINTK2(KERN_WARNING
1396 "ICMPv6 Redirect: destination address is multicast.\n");
1397 return;
1398 }
1399
1400 if (ipv6_addr_equal(dest, target)) {
1401 on_link = 1;
bf0b48df
BH
1402 } else if (ipv6_addr_type(target) !=
1403 (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
1ab1457c 1404 ND_PRINTK2(KERN_WARNING
bf0b48df 1405 "ICMPv6 Redirect: target address is not link-local unicast.\n");
1da177e4
LT
1406 return;
1407 }
1408
1409 in6_dev = in6_dev_get(skb->dev);
1410 if (!in6_dev)
1411 return;
1412 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1413 in6_dev_put(in6_dev);
1414 return;
1415 }
1416
1ab1457c 1417 /* RFC2461 8.1:
1da177e4
LT
1418 * The IP source address of the Redirect MUST be the same as the current
1419 * first-hop router for the specified ICMP Destination Address.
1420 */
1ab1457c 1421
1da177e4
LT
1422 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1423 ND_PRINTK2(KERN_WARNING
1424 "ICMPv6 Redirect: invalid ND options\n");
1425 in6_dev_put(in6_dev);
1426 return;
1427 }
1428 if (ndopts.nd_opts_tgt_lladdr) {
1429 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1430 skb->dev);
1431 if (!lladdr) {
1432 ND_PRINTK2(KERN_WARNING
1433 "ICMPv6 Redirect: invalid link-layer address length\n");
1434 in6_dev_put(in6_dev);
1435 return;
1436 }
1437 }
1438
1439 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1440 if (neigh) {
0660e03f
ACM
1441 rt6_redirect(dest, &ipv6_hdr(skb)->daddr,
1442 &ipv6_hdr(skb)->saddr, neigh, lladdr,
1da177e4
LT
1443 on_link);
1444 neigh_release(neigh);
1445 }
1446 in6_dev_put(in6_dev);
1447}
1448
1449void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1450 struct in6_addr *target)
1451{
1762f7e8 1452 struct net_device *dev = skb->dev;
c346dca1 1453 struct net *net = dev_net(dev);
1762f7e8 1454 struct sock *sk = net->ipv6.ndisc_sk;
1da177e4
LT
1455 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1456 struct sk_buff *buff;
1457 struct icmp6hdr *icmph;
1458 struct in6_addr saddr_buf;
1459 struct in6_addr *addrp;
1da177e4
LT
1460 struct rt6_info *rt;
1461 struct dst_entry *dst;
1462 struct inet6_dev *idev;
1463 struct flowi fl;
1464 u8 *opt;
1465 int rd_len;
1466 int err;
1da177e4
LT
1467 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1468
95c385b4 1469 if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
1da177e4
LT
1470 ND_PRINTK2(KERN_WARNING
1471 "ICMPv6 Redirect: no link-local address on %s\n",
1472 dev->name);
1ab1457c
YH
1473 return;
1474 }
1da177e4 1475
0660e03f 1476 if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
bf0b48df 1477 ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
29556526 1478 ND_PRINTK2(KERN_WARNING
bf0b48df 1479 "ICMPv6 Redirect: target address is not link-local unicast.\n");
29556526
LY
1480 return;
1481 }
1482
1762f7e8 1483 icmpv6_flow_init(sk, &fl, NDISC_REDIRECT,
95e41e93 1484 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
1da177e4 1485
1762f7e8 1486 dst = ip6_route_output(net, NULL, &fl);
1da177e4
LT
1487 if (dst == NULL)
1488 return;
1489
1490 err = xfrm_lookup(&dst, &fl, NULL, 0);
e104411b 1491 if (err)
1da177e4 1492 return;
1da177e4
LT
1493
1494 rt = (struct rt6_info *) dst;
1495
1496 if (rt->rt6i_flags & RTF_GATEWAY) {
1497 ND_PRINTK2(KERN_WARNING
1498 "ICMPv6 Redirect: destination is not a neighbour.\n");
1499 dst_release(dst);
1500 return;
1501 }
1502 if (!xrlim_allow(dst, 1*HZ)) {
1503 dst_release(dst);
1504 return;
1505 }
1506
1507 if (dev->addr_len) {
1508 read_lock_bh(&neigh->lock);
1509 if (neigh->nud_state & NUD_VALID) {
1510 memcpy(ha_buf, neigh->ha, dev->addr_len);
1511 read_unlock_bh(&neigh->lock);
1512 ha = ha_buf;
1513 len += ndisc_opt_addr_space(dev);
1514 } else
1515 read_unlock_bh(&neigh->lock);
1516 }
1517
1518 rd_len = min_t(unsigned int,
1519 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1520 rd_len &= ~0x7;
1521 len += rd_len;
1522
d54a81d3
DM
1523 buff = sock_alloc_send_skb(sk,
1524 (MAX_HEADER + sizeof(struct ipv6hdr) +
1525 len + LL_RESERVED_SPACE(dev)),
1da177e4
LT
1526 1, &err);
1527 if (buff == NULL) {
1528 ND_PRINTK0(KERN_ERR
1529 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
0dc47877 1530 __func__);
1da177e4
LT
1531 dst_release(dst);
1532 return;
1533 }
1534
1da177e4 1535 skb_reserve(buff, LL_RESERVED_SPACE(dev));
0660e03f 1536 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
1da177e4
LT
1537 IPPROTO_ICMPV6, len);
1538
27a884dc 1539 skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
d10ba34b
ACM
1540 skb_put(buff, len);
1541 icmph = icmp6_hdr(buff);
1da177e4
LT
1542
1543 memset(icmph, 0, sizeof(struct icmp6hdr));
1544 icmph->icmp6_type = NDISC_REDIRECT;
1545
1546 /*
1547 * copy target and destination addresses
1548 */
1549
1550 addrp = (struct in6_addr *)(icmph + 1);
1551 ipv6_addr_copy(addrp, target);
1552 addrp++;
0660e03f 1553 ipv6_addr_copy(addrp, &ipv6_hdr(skb)->daddr);
1da177e4
LT
1554
1555 opt = (u8*) (addrp + 1);
1556
1557 /*
1558 * include target_address option
1559 */
1560
1561 if (ha)
1562 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1563 dev->addr_len, dev->type);
1564
1565 /*
1566 * build redirect option and copy skb over to the new packet.
1567 */
1568
1ab1457c 1569 memset(opt, 0, 8);
1da177e4
LT
1570 *(opt++) = ND_OPT_REDIRECT_HDR;
1571 *(opt++) = (rd_len >> 3);
1572 opt += 6;
1573
0660e03f 1574 memcpy(opt, ipv6_hdr(skb), rd_len - 8);
1da177e4 1575
0660e03f 1576 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
1da177e4
LT
1577 len, IPPROTO_ICMPV6,
1578 csum_partial((u8 *) icmph, len, 0));
1579
1580 buff->dst = dst;
1581 idev = in6_dev_get(dst->dev);
a11d206d 1582 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
6e23ae2a
PM
1583 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
1584 dst_output);
1da177e4 1585 if (!err) {
14878f75 1586 ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT);
1da177e4
LT
1587 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1588 }
1589
1590 if (likely(idev != NULL))
1591 in6_dev_put(idev);
1592}
1593
1594static void pndisc_redo(struct sk_buff *skb)
1595{
140e26fc 1596 ndisc_recv_ns(skb);
1da177e4
LT
1597 kfree_skb(skb);
1598}
1599
1600int ndisc_rcv(struct sk_buff *skb)
1601{
1602 struct nd_msg *msg;
1603
1604 if (!pskb_may_pull(skb, skb->len))
1605 return 0;
1606
9c70220b 1607 msg = (struct nd_msg *)skb_transport_header(skb);
1da177e4 1608
9c70220b 1609 __skb_push(skb, skb->data - skb_transport_header(skb));
1da177e4 1610
0660e03f 1611 if (ipv6_hdr(skb)->hop_limit != 255) {
1da177e4
LT
1612 ND_PRINTK2(KERN_WARNING
1613 "ICMPv6 NDISC: invalid hop-limit: %d\n",
0660e03f 1614 ipv6_hdr(skb)->hop_limit);
1da177e4
LT
1615 return 0;
1616 }
1617
1618 if (msg->icmph.icmp6_code != 0) {
1ab1457c 1619 ND_PRINTK2(KERN_WARNING
1da177e4
LT
1620 "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1621 msg->icmph.icmp6_code);
1622 return 0;
1623 }
1624
a61bbcf2
PM
1625 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1626
1da177e4
LT
1627 switch (msg->icmph.icmp6_type) {
1628 case NDISC_NEIGHBOUR_SOLICITATION:
1629 ndisc_recv_ns(skb);
1630 break;
1631
1632 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1633 ndisc_recv_na(skb);
1634 break;
1635
1636 case NDISC_ROUTER_SOLICITATION:
1637 ndisc_recv_rs(skb);
1638 break;
1639
1640 case NDISC_ROUTER_ADVERTISEMENT:
1641 ndisc_router_discovery(skb);
1642 break;
1643
1644 case NDISC_REDIRECT:
1645 ndisc_redirect_rcv(skb);
1646 break;
3ff50b79 1647 }
1da177e4
LT
1648
1649 return 0;
1650}
1651
1652static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1653{
1654 struct net_device *dev = ptr;
c346dca1 1655 struct net *net = dev_net(dev);
1da177e4
LT
1656
1657 switch (event) {
1658 case NETDEV_CHANGEADDR:
1659 neigh_changeaddr(&nd_tbl, dev);
5b7c931d 1660 fib6_run_gc(~0UL, net);
1da177e4
LT
1661 break;
1662 case NETDEV_DOWN:
1663 neigh_ifdown(&nd_tbl, dev);
5b7c931d 1664 fib6_run_gc(~0UL, net);
1da177e4
LT
1665 break;
1666 default:
1667 break;
1668 }
1669
1670 return NOTIFY_DONE;
1671}
1672
1673static struct notifier_block ndisc_netdev_notifier = {
1674 .notifier_call = ndisc_netdev_event,
1675};
1676
1677#ifdef CONFIG_SYSCTL
1678static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1679 const char *func, const char *dev_name)
1680{
1681 static char warncomm[TASK_COMM_LEN];
1682 static int warned;
1683 if (strcmp(warncomm, current->comm) && warned < 5) {
1684 strcpy(warncomm, current->comm);
1685 printk(KERN_WARNING
1686 "process `%s' is using deprecated sysctl (%s) "
1687 "net.ipv6.neigh.%s.%s; "
1688 "Use net.ipv6.neigh.%s.%s_ms "
1689 "instead.\n",
1690 warncomm, func,
1691 dev_name, ctl->procname,
1692 dev_name, ctl->procname);
1693 warned++;
1694 }
1695}
1696
1697int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1698{
1699 struct net_device *dev = ctl->extra1;
1700 struct inet6_dev *idev;
1701 int ret;
1702
d12af679
EB
1703 if ((strcmp(ctl->procname, "retrans_time") == 0) ||
1704 (strcmp(ctl->procname, "base_reachable_time") == 0))
1da177e4
LT
1705 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1706
d12af679 1707 if (strcmp(ctl->procname, "retrans_time") == 0)
1da177e4 1708 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
d12af679
EB
1709
1710 else if (strcmp(ctl->procname, "base_reachable_time") == 0)
1da177e4
LT
1711 ret = proc_dointvec_jiffies(ctl, write,
1712 filp, buffer, lenp, ppos);
d12af679
EB
1713
1714 else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
ad02ac14 1715 (strcmp(ctl->procname, "base_reachable_time_ms") == 0))
1da177e4
LT
1716 ret = proc_dointvec_ms_jiffies(ctl, write,
1717 filp, buffer, lenp, ppos);
d12af679 1718 else
1da177e4 1719 ret = -1;
1da177e4
LT
1720
1721 if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
d12af679 1722 if (ctl->data == &idev->nd_parms->base_reachable_time)
1da177e4
LT
1723 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1724 idev->tstamp = jiffies;
1725 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1726 in6_dev_put(idev);
1727 }
1728 return ret;
1729}
1730
1731static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1732 int nlen, void __user *oldval,
1733 size_t __user *oldlenp,
1f29bcd7 1734 void __user *newval, size_t newlen)
1da177e4
LT
1735{
1736 struct net_device *dev = ctl->extra1;
1737 struct inet6_dev *idev;
1738 int ret;
1739
1740 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1741 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1742 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1743
1744 switch (ctl->ctl_name) {
1745 case NET_NEIGH_REACHABLE_TIME:
1746 ret = sysctl_jiffies(ctl, name, nlen,
1f29bcd7 1747 oldval, oldlenp, newval, newlen);
1da177e4
LT
1748 break;
1749 case NET_NEIGH_RETRANS_TIME_MS:
1750 case NET_NEIGH_REACHABLE_TIME_MS:
1751 ret = sysctl_ms_jiffies(ctl, name, nlen,
1f29bcd7 1752 oldval, oldlenp, newval, newlen);
1da177e4
LT
1753 break;
1754 default:
1755 ret = 0;
1756 }
1757
1758 if (newval && newlen && ret > 0 &&
1759 dev && (idev = in6_dev_get(dev)) != NULL) {
1760 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1761 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1762 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1763 idev->tstamp = jiffies;
1764 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1765 in6_dev_put(idev);
1766 }
1767
1768 return ret;
1769}
1770
1771#endif
1772
1762f7e8 1773static int ndisc_net_init(struct net *net)
1da177e4
LT
1774{
1775 struct ipv6_pinfo *np;
1776 struct sock *sk;
1ab1457c 1777 int err;
1da177e4 1778
1ed8516f
DL
1779 err = inet_ctl_sock_create(&sk, PF_INET6,
1780 SOCK_RAW, IPPROTO_ICMPV6, net);
1da177e4
LT
1781 if (err < 0) {
1782 ND_PRINTK0(KERN_ERR
1ab1457c 1783 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1da177e4 1784 err);
1da177e4
LT
1785 return err;
1786 }
1787
1ed8516f 1788 net->ipv6.ndisc_sk = sk;
1762f7e8 1789
1da177e4 1790 np = inet6_sk(sk);
1da177e4
LT
1791 np->hop_limit = 255;
1792 /* Do not loopback ndisc messages */
1793 np->mc_loop = 0;
1da177e4 1794
1762f7e8
DL
1795 return 0;
1796}
1797
1798static void ndisc_net_exit(struct net *net)
1799{
1ed8516f 1800 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1762f7e8
DL
1801}
1802
1803static struct pernet_operations ndisc_net_ops = {
1804 .init = ndisc_net_init,
1805 .exit = ndisc_net_exit,
1806};
1807
1808int __init ndisc_init(void)
1809{
1810 int err;
1811
1812 err = register_pernet_subsys(&ndisc_net_ops);
1813 if (err)
1814 return err;
1ab1457c
YH
1815 /*
1816 * Initialize the neighbour table
1817 */
1da177e4
LT
1818 neigh_table_init(&nd_tbl);
1819
1820#ifdef CONFIG_SYSCTL
1762f7e8
DL
1821 err = neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6,
1822 NET_IPV6_NEIGH, "ipv6",
1823 &ndisc_ifinfo_sysctl_change,
1824 &ndisc_ifinfo_sysctl_strategy);
1825 if (err)
1826 goto out_unregister_pernet;
1da177e4 1827#endif
1762f7e8
DL
1828 err = register_netdevice_notifier(&ndisc_netdev_notifier);
1829 if (err)
1830 goto out_unregister_sysctl;
1831out:
1832 return err;
1da177e4 1833
1762f7e8
DL
1834out_unregister_sysctl:
1835#ifdef CONFIG_SYSCTL
1836 neigh_sysctl_unregister(&nd_tbl.parms);
1837out_unregister_pernet:
1838#endif
1839 unregister_pernet_subsys(&ndisc_net_ops);
1840 goto out;
1da177e4
LT
1841}
1842
1843void ndisc_cleanup(void)
1844{
36f73d0c 1845 unregister_netdevice_notifier(&ndisc_netdev_notifier);
1da177e4
LT
1846#ifdef CONFIG_SYSCTL
1847 neigh_sysctl_unregister(&nd_tbl.parms);
1848#endif
1849 neigh_table_clear(&nd_tbl);
1762f7e8 1850 unregister_pernet_subsys(&ndisc_net_ops);
1da177e4 1851}