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