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