uapi: add missing netconf.h to export list
[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 *
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;
f47b9464
BH
538
539 idev = in6_dev_get(dev);
540 if (!idev)
541 return;
542
543 read_lock_bh(&idev->lock);
544 list_for_each_entry(ifa, &idev->addr_list, if_list) {
9fafd65a 545 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr,
f47b9464
BH
546 /*router=*/ !!idev->cnf.forwarding,
547 /*solicited=*/ false, /*override=*/ true,
548 /*inc_opt=*/ true);
549 }
550 read_unlock_bh(&idev->lock);
551
552 in6_dev_put(idev);
553}
554
1da177e4 555void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
9acd9f3a
YH
556 const struct in6_addr *solicit,
557 const struct in6_addr *daddr, const struct in6_addr *saddr)
1da177e4 558{
1da177e4 559 struct in6_addr addr_buf;
e1ec7842
YH
560 struct icmp6hdr icmp6h = {
561 .icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
562 };
1da177e4
LT
563
564 if (saddr == NULL) {
95c385b4
NH
565 if (ipv6_get_lladdr(dev, &addr_buf,
566 (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
1da177e4
LT
567 return;
568 saddr = &addr_buf;
569 }
570
e1ec7842
YH
571 __ndisc_send(dev, neigh, daddr, saddr,
572 &icmp6h, solicit,
14878f75 573 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
1da177e4
LT
574}
575
9acd9f3a
YH
576void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
577 const struct in6_addr *daddr)
1da177e4 578{
e1ec7842
YH
579 struct icmp6hdr icmp6h = {
580 .icmp6_type = NDISC_ROUTER_SOLICITATION,
581 };
95c385b4 582 int send_sllao = dev->addr_len;
95c385b4
NH
583
584#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
585 /*
586 * According to section 2.2 of RFC 4429, we must not
587 * send router solicitations with a sllao from
588 * optimistic addresses, but we may send the solicitation
589 * if we don't include the sllao. So here we check
590 * if our address is optimistic, and if so, we
bea85195 591 * suppress the inclusion of the sllao.
95c385b4
NH
592 */
593 if (send_sllao) {
c346dca1 594 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(dev_net(dev), saddr,
1cab3da6 595 dev, 1);
95c385b4
NH
596 if (ifp) {
597 if (ifp->flags & IFA_F_OPTIMISTIC) {
ca043569 598 send_sllao = 0;
95c385b4 599 }
ca043569 600 in6_ifa_put(ifp);
95c385b4
NH
601 } else {
602 send_sllao = 0;
603 }
604 }
605#endif
e1ec7842
YH
606 __ndisc_send(dev, NULL, daddr, saddr,
607 &icmp6h, NULL,
14878f75 608 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
1da177e4 609}
1ab1457c 610
1da177e4
LT
611
612static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
613{
614 /*
615 * "The sender MUST return an ICMP
616 * destination unreachable"
617 */
618 dst_link_failure(skb);
619 kfree_skb(skb);
620}
621
622/* Called with locked neigh: either read or both */
623
624static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
625{
626 struct in6_addr *saddr = NULL;
627 struct in6_addr mcaddr;
628 struct net_device *dev = neigh->dev;
629 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
630 int probes = atomic_read(&neigh->probes);
631
c346dca1 632 if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
0660e03f 633 saddr = &ipv6_hdr(skb)->saddr;
1da177e4
LT
634
635 if ((probes -= neigh->parms->ucast_probes) < 0) {
636 if (!(neigh->nud_state & NUD_VALID)) {
675418d5
JP
637 ND_PRINTK(1, dbg,
638 "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
639 __func__, target);
1da177e4
LT
640 }
641 ndisc_send_ns(dev, neigh, target, target, saddr);
642 } else if ((probes -= neigh->parms->app_probes) < 0) {
643#ifdef CONFIG_ARPD
644 neigh_app_ns(neigh);
645#endif
646 } else {
647 addrconf_addr_solict_mult(target, &mcaddr);
648 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
649 }
650}
651
0736ffc0
YH
652static int pndisc_is_router(const void *pkey,
653 struct net_device *dev)
fa86d322
PE
654{
655 struct pneigh_entry *n;
0736ffc0 656 int ret = -1;
fa86d322
PE
657
658 read_lock_bh(&nd_tbl.lock);
0736ffc0
YH
659 n = __pneigh_lookup(&nd_tbl, dev_net(dev), pkey, dev);
660 if (n)
661 ret = !!(n->flags & NTF_ROUTER);
fa86d322
PE
662 read_unlock_bh(&nd_tbl.lock);
663
0736ffc0 664 return ret;
fa86d322
PE
665}
666
1da177e4
LT
667static void ndisc_recv_ns(struct sk_buff *skb)
668{
9c70220b 669 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
b71d1d42
ED
670 const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
671 const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
1da177e4 672 u8 *lladdr = NULL;
27a884dc
ACM
673 u32 ndoptlen = skb->tail - (skb->transport_header +
674 offsetof(struct nd_msg, opt));
1da177e4
LT
675 struct ndisc_options ndopts;
676 struct net_device *dev = skb->dev;
677 struct inet6_ifaddr *ifp;
678 struct inet6_dev *idev = NULL;
679 struct neighbour *neigh;
680 int dad = ipv6_addr_any(saddr);
a50feda5 681 bool inc;
0736ffc0 682 int is_router = -1;
1da177e4
LT
683
684 if (ipv6_addr_is_multicast(&msg->target)) {
675418d5 685 ND_PRINTK(2, warn, "NS: multicast target address\n");
1da177e4
LT
686 return;
687 }
688
689 /*
690 * RFC2461 7.1.1:
691 * DAD has to be destined for solicited node multicast address.
692 */
693 if (dad &&
694 !(daddr->s6_addr32[0] == htonl(0xff020000) &&
695 daddr->s6_addr32[1] == htonl(0x00000000) &&
696 daddr->s6_addr32[2] == htonl(0x00000001) &&
697 daddr->s6_addr [12] == 0xff )) {
675418d5 698 ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n");
1da177e4
LT
699 return;
700 }
701
702 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
675418d5 703 ND_PRINTK(2, warn, "NS: invalid ND options\n");
1da177e4
LT
704 return;
705 }
706
707 if (ndopts.nd_opts_src_lladdr) {
708 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
709 if (!lladdr) {
675418d5
JP
710 ND_PRINTK(2, warn,
711 "NS: invalid link-layer address length\n");
1da177e4
LT
712 return;
713 }
714
715 /* RFC2461 7.1.1:
1ab1457c
YH
716 * If the IP source address is the unspecified address,
717 * there MUST NOT be source link-layer address option
1da177e4
LT
718 * in the message.
719 */
720 if (dad) {
675418d5
JP
721 ND_PRINTK(2, warn,
722 "NS: bad DAD packet (link-layer address option)\n");
1da177e4
LT
723 return;
724 }
725 }
726
727 inc = ipv6_addr_is_multicast(daddr);
728
c346dca1 729 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
a18bc695 730 if (ifp) {
95c385b4
NH
731
732 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
733 if (dad) {
95c385b4
NH
734 /*
735 * We are colliding with another node
736 * who is doing DAD
737 * so fail our DAD process
738 */
739 addrconf_dad_failure(ifp);
9e3be4b3 740 return;
95c385b4
NH
741 } else {
742 /*
743 * This is not a dad solicitation.
744 * If we are an optimistic node,
745 * we should respond.
746 * Otherwise, we should ignore it.
747 */
748 if (!(ifp->flags & IFA_F_OPTIMISTIC))
1da177e4 749 goto out;
1da177e4 750 }
1da177e4
LT
751 }
752
753 idev = ifp->idev;
754 } else {
53b7997f
YH
755 struct net *net = dev_net(dev);
756
1da177e4
LT
757 idev = in6_dev_get(dev);
758 if (!idev) {
759 /* XXX: count this drop? */
760 return;
761 }
762
53b7997f 763 if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
1ab1457c 764 (idev->cnf.forwarding &&
53b7997f 765 (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
0736ffc0 766 (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
a61bbcf2 767 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
1da177e4
LT
768 skb->pkt_type != PACKET_HOST &&
769 inc != 0 &&
770 idev->nd_parms->proxy_delay != 0) {
771 /*
772 * for anycast or proxy,
1ab1457c
YH
773 * sender should delay its response
774 * by a random time between 0 and
1da177e4
LT
775 * MAX_ANYCAST_DELAY_TIME seconds.
776 * (RFC2461) -- yoshfuji
777 */
778 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
779 if (n)
780 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
781 goto out;
782 }
783 } else
784 goto out;
785 }
786
0736ffc0
YH
787 if (is_router < 0)
788 is_router = !!idev->cnf.forwarding;
62dd9318 789
1da177e4 790 if (dad) {
f3ee4010 791 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
62dd9318 792 is_router, 0, (ifp != NULL), 1);
1da177e4
LT
793 goto out;
794 }
795
796 if (inc)
797 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
798 else
799 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
800
1ab1457c 801 /*
1da177e4
LT
802 * update / create cache entry
803 * for the source address
804 */
805 neigh = __neigh_lookup(&nd_tbl, saddr, dev,
806 !inc || lladdr || !dev->addr_len);
807 if (neigh)
1ab1457c 808 neigh_update(neigh, lladdr, NUD_STALE,
1da177e4
LT
809 NEIGH_UPDATE_F_WEAK_OVERRIDE|
810 NEIGH_UPDATE_F_OVERRIDE);
3b04ddde 811 if (neigh || !dev->header_ops) {
1da177e4 812 ndisc_send_na(dev, neigh, saddr, &msg->target,
62dd9318 813 is_router,
1da177e4
LT
814 1, (ifp != NULL && inc), inc);
815 if (neigh)
816 neigh_release(neigh);
817 }
818
819out:
820 if (ifp)
821 in6_ifa_put(ifp);
822 else
823 in6_dev_put(idev);
1da177e4
LT
824}
825
826static void ndisc_recv_na(struct sk_buff *skb)
827{
9c70220b 828 struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
b71d1d42
ED
829 const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
830 const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
1da177e4 831 u8 *lladdr = NULL;
27a884dc
ACM
832 u32 ndoptlen = skb->tail - (skb->transport_header +
833 offsetof(struct nd_msg, opt));
1da177e4
LT
834 struct ndisc_options ndopts;
835 struct net_device *dev = skb->dev;
836 struct inet6_ifaddr *ifp;
837 struct neighbour *neigh;
838
839 if (skb->len < sizeof(struct nd_msg)) {
675418d5 840 ND_PRINTK(2, warn, "NA: packet too short\n");
1da177e4
LT
841 return;
842 }
843
844 if (ipv6_addr_is_multicast(&msg->target)) {
675418d5 845 ND_PRINTK(2, warn, "NA: target address is multicast\n");
1da177e4
LT
846 return;
847 }
848
849 if (ipv6_addr_is_multicast(daddr) &&
850 msg->icmph.icmp6_solicited) {
675418d5 851 ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n");
1da177e4
LT
852 return;
853 }
1ab1457c 854
1da177e4 855 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
675418d5 856 ND_PRINTK(2, warn, "NS: invalid ND option\n");
1da177e4
LT
857 return;
858 }
859 if (ndopts.nd_opts_tgt_lladdr) {
860 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
861 if (!lladdr) {
675418d5
JP
862 ND_PRINTK(2, warn,
863 "NA: invalid link-layer address length\n");
1da177e4
LT
864 return;
865 }
866 }
c346dca1 867 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
a18bc695 868 if (ifp) {
bd015928
DW
869 if (skb->pkt_type != PACKET_LOOPBACK
870 && (ifp->flags & IFA_F_TENTATIVE)) {
871 addrconf_dad_failure(ifp);
872 return;
1da177e4
LT
873 }
874 /* What should we make now? The advertisement
875 is invalid, but ndisc specs say nothing
876 about it. It could be misconfiguration, or
877 an smart proxy agent tries to help us :-)
24fc7b86
JS
878
879 We should not print the error if NA has been
880 received from loopback - it is just our own
881 unsolicited advertisement.
1da177e4 882 */
24fc7b86 883 if (skb->pkt_type != PACKET_LOOPBACK)
675418d5
JP
884 ND_PRINTK(1, warn,
885 "NA: someone advertises our address %pI6 on %s!\n",
886 &ifp->addr, ifp->idev->dev->name);
1da177e4
LT
887 in6_ifa_put(ifp);
888 return;
889 }
890 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
891
892 if (neigh) {
893 u8 old_flags = neigh->flags;
53b7997f 894 struct net *net = dev_net(dev);
1da177e4
LT
895
896 if (neigh->nud_state & NUD_FAILED)
897 goto out;
898
5f3e6e9e
VN
899 /*
900 * Don't update the neighbor cache entry on a proxy NA from
901 * ourselves because either the proxied node is off link or it
902 * has already sent a NA to us.
903 */
904 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
53b7997f
YH
905 net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
906 pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
b20b6d97 907 /* XXX: idev->cnf.proxy_ndp */
5f3e6e9e 908 goto out;
fbea49e1 909 }
5f3e6e9e 910
1da177e4
LT
911 neigh_update(neigh, lladdr,
912 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
913 NEIGH_UPDATE_F_WEAK_OVERRIDE|
914 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
915 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
916 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
917
918 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
919 /*
920 * Change: router to host
921 */
922 struct rt6_info *rt;
923 rt = rt6_get_dflt_router(saddr, dev);
924 if (rt)
e0a1ad73 925 ip6_del_rt(rt);
1da177e4
LT
926 }
927
928out:
929 neigh_release(neigh);
930 }
931}
932
933static void ndisc_recv_rs(struct sk_buff *skb)
934{
9c70220b 935 struct rs_msg *rs_msg = (struct rs_msg *)skb_transport_header(skb);
1da177e4
LT
936 unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
937 struct neighbour *neigh;
938 struct inet6_dev *idev;
b71d1d42 939 const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
1da177e4
LT
940 struct ndisc_options ndopts;
941 u8 *lladdr = NULL;
942
943 if (skb->len < sizeof(*rs_msg))
944 return;
945
cfdf7647 946 idev = __in6_dev_get(skb->dev);
1da177e4 947 if (!idev) {
675418d5 948 ND_PRINTK(1, err, "RS: can't find in6 device\n");
1da177e4
LT
949 return;
950 }
951
952 /* Don't accept RS if we're not in router mode */
953 if (!idev->cnf.forwarding)
954 goto out;
955
956 /*
957 * Don't update NCE if src = ::;
958 * this implies that the source node has no ip address assigned yet.
959 */
960 if (ipv6_addr_any(saddr))
961 goto out;
962
963 /* Parse ND options */
964 if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
675418d5 965 ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n");
1da177e4
LT
966 goto out;
967 }
968
969 if (ndopts.nd_opts_src_lladdr) {
970 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
971 skb->dev);
972 if (!lladdr)
973 goto out;
974 }
975
976 neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
977 if (neigh) {
978 neigh_update(neigh, lladdr, NUD_STALE,
979 NEIGH_UPDATE_F_WEAK_OVERRIDE|
980 NEIGH_UPDATE_F_OVERRIDE|
981 NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
982 neigh_release(neigh);
983 }
984out:
cfdf7647 985 return;
1da177e4
LT
986}
987
31910575
PY
988static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
989{
990 struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
991 struct sk_buff *skb;
992 struct nlmsghdr *nlh;
993 struct nduseroptmsg *ndmsg;
c346dca1 994 struct net *net = dev_net(ra->dev);
31910575
PY
995 int err;
996 int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
997 + (opt->nd_opt_len << 3));
998 size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr));
999
1000 skb = nlmsg_new(msg_size, GFP_ATOMIC);
1001 if (skb == NULL) {
1002 err = -ENOBUFS;
1003 goto errout;
1004 }
1005
1006 nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0);
1007 if (nlh == NULL) {
1008 goto nla_put_failure;
1009 }
1010
1011 ndmsg = nlmsg_data(nlh);
1012 ndmsg->nduseropt_family = AF_INET6;
dbb2ed24 1013 ndmsg->nduseropt_ifindex = ra->dev->ifindex;
31910575
PY
1014 ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
1015 ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
1016 ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
1017
1018 memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
1019
c78679e8
DM
1020 if (nla_put(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
1021 &ipv6_hdr(ra)->saddr))
1022 goto nla_put_failure;
31910575
PY
1023 nlmsg_end(skb, nlh);
1024
1ce85fe4 1025 rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
31910575
PY
1026 return;
1027
1028nla_put_failure:
1029 nlmsg_free(skb);
1030 err = -EMSGSIZE;
1031errout:
a18bc695 1032 rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
31910575
PY
1033}
1034
1da177e4
LT
1035static void ndisc_router_discovery(struct sk_buff *skb)
1036{
9c70220b 1037 struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
1da177e4
LT
1038 struct neighbour *neigh = NULL;
1039 struct inet6_dev *in6_dev;
65f5c7c1 1040 struct rt6_info *rt = NULL;
1da177e4
LT
1041 int lifetime;
1042 struct ndisc_options ndopts;
1043 int optlen;
ebacaaa0 1044 unsigned int pref = 0;
1da177e4
LT
1045
1046 __u8 * opt = (__u8 *)(ra_msg + 1);
1047
27a884dc 1048 optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg);
1da177e4 1049
0660e03f 1050 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
675418d5 1051 ND_PRINTK(2, warn, "RA: source address is not link-local\n");
1da177e4
LT
1052 return;
1053 }
1054 if (optlen < 0) {
675418d5 1055 ND_PRINTK(2, warn, "RA: packet too short\n");
1da177e4
LT
1056 return;
1057 }
1058
de357cc0 1059#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0 1060 if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
675418d5 1061 ND_PRINTK(2, warn, "RA: from host or unauthorized router\n");
fadf6bf0
TF
1062 return;
1063 }
de357cc0 1064#endif
fadf6bf0 1065
1da177e4
LT
1066 /*
1067 * set the RA_RECV flag in the interface
1068 */
1069
cfdf7647 1070 in6_dev = __in6_dev_get(skb->dev);
1da177e4 1071 if (in6_dev == NULL) {
675418d5
JP
1072 ND_PRINTK(0, err, "RA: can't find inet6 device for %s\n",
1073 skb->dev->name);
1da177e4
LT
1074 return;
1075 }
1da177e4
LT
1076
1077 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
675418d5 1078 ND_PRINTK(2, warn, "RA: invalid ND options\n");
1da177e4
LT
1079 return;
1080 }
1081
aeaf6e9d 1082 if (!ipv6_accept_ra(in6_dev))
31ce8c71
DW
1083 goto skip_linkparms;
1084
de357cc0 1085#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1086 /* skip link-specific parameters from interior routers */
1087 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1088 goto skip_linkparms;
de357cc0 1089#endif
fadf6bf0 1090
1da177e4
LT
1091 if (in6_dev->if_flags & IF_RS_SENT) {
1092 /*
1093 * flag that an RA was received after an RS was sent
1094 * out on this interface.
1095 */
1096 in6_dev->if_flags |= IF_RA_RCVD;
1097 }
1098
1099 /*
1100 * Remember the managed/otherconf flags from most recently
1101 * received RA message (RFC 2462) -- yoshfuji
1102 */
1103 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1104 IF_RA_OTHERCONF)) |
1105 (ra_msg->icmph.icmp6_addrconf_managed ?
1106 IF_RA_MANAGED : 0) |
1107 (ra_msg->icmph.icmp6_addrconf_other ?
1108 IF_RA_OTHERCONF : 0);
1109
65f5c7c1
YH
1110 if (!in6_dev->cnf.accept_ra_defrtr)
1111 goto skip_defrtr;
1112
9f56220f
AH
1113 if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0))
1114 goto skip_defrtr;
1115
1da177e4
LT
1116 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1117
ebacaaa0
YH
1118#ifdef CONFIG_IPV6_ROUTER_PREF
1119 pref = ra_msg->icmph.icmp6_router_pref;
1120 /* 10b is handled as if it were 00b (medium) */
930d6ff2 1121 if (pref == ICMPV6_ROUTER_PREF_INVALID ||
6d5b78cd 1122 !in6_dev->cnf.accept_ra_rtr_pref)
ebacaaa0
YH
1123 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1124#endif
1125
0660e03f 1126 rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
1da177e4 1127
eb857186
DM
1128 if (rt) {
1129 neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
1130 if (!neigh) {
675418d5
JP
1131 ND_PRINTK(0, err,
1132 "RA: %s got default router without neighbour\n",
1133 __func__);
94e187c0 1134 ip6_rt_put(rt);
eb857186
DM
1135 return;
1136 }
1137 }
1da177e4 1138 if (rt && lifetime == 0) {
e0a1ad73 1139 ip6_del_rt(rt);
1da177e4
LT
1140 rt = NULL;
1141 }
1142
1143 if (rt == NULL && lifetime) {
675418d5 1144 ND_PRINTK(3, dbg, "RA: adding default router\n");
1da177e4 1145
0660e03f 1146 rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);
1da177e4 1147 if (rt == NULL) {
675418d5
JP
1148 ND_PRINTK(0, err,
1149 "RA: %s failed to add default route\n",
1150 __func__);
1da177e4
LT
1151 return;
1152 }
1153
eb857186 1154 neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
1da177e4 1155 if (neigh == NULL) {
675418d5
JP
1156 ND_PRINTK(0, err,
1157 "RA: %s got default router without neighbour\n",
1158 __func__);
94e187c0 1159 ip6_rt_put(rt);
1da177e4
LT
1160 return;
1161 }
1162 neigh->flags |= NTF_ROUTER;
ebacaaa0 1163 } else if (rt) {
22441cfa 1164 rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1da177e4
LT
1165 }
1166
1167 if (rt)
1716a961 1168 rt6_set_expires(rt, jiffies + (HZ * lifetime));
1da177e4
LT
1169 if (ra_msg->icmph.icmp6_hop_limit) {
1170 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1171 if (rt)
defb3519
DM
1172 dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
1173 ra_msg->icmph.icmp6_hop_limit);
1da177e4
LT
1174 }
1175
65f5c7c1
YH
1176skip_defrtr:
1177
1da177e4
LT
1178 /*
1179 * Update Reachable Time and Retrans Timer
1180 */
1181
1182 if (in6_dev->nd_parms) {
1183 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1184
1185 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1186 rtime = (rtime*HZ)/1000;
1187 if (rtime < HZ/10)
1188 rtime = HZ/10;
1189 in6_dev->nd_parms->retrans_time = rtime;
1190 in6_dev->tstamp = jiffies;
1191 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1192 }
1193
1194 rtime = ntohl(ra_msg->reachable_time);
1195 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1196 rtime = (rtime*HZ)/1000;
1197
1198 if (rtime < HZ/10)
1199 rtime = HZ/10;
1200
1201 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1202 in6_dev->nd_parms->base_reachable_time = rtime;
1203 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1204 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1205 in6_dev->tstamp = jiffies;
1206 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1207 }
1208 }
1209 }
1210
fadf6bf0
TF
1211skip_linkparms:
1212
1da177e4
LT
1213 /*
1214 * Process options.
1215 */
1216
1217 if (!neigh)
0660e03f 1218 neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr,
1da177e4
LT
1219 skb->dev, 1);
1220 if (neigh) {
1221 u8 *lladdr = NULL;
1222 if (ndopts.nd_opts_src_lladdr) {
1223 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1224 skb->dev);
1225 if (!lladdr) {
675418d5
JP
1226 ND_PRINTK(2, warn,
1227 "RA: invalid link-layer address length\n");
1da177e4
LT
1228 goto out;
1229 }
1230 }
1231 neigh_update(neigh, lladdr, NUD_STALE,
1232 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1233 NEIGH_UPDATE_F_OVERRIDE|
1234 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1235 NEIGH_UPDATE_F_ISROUTER);
1236 }
1237
aeaf6e9d 1238 if (!ipv6_accept_ra(in6_dev))
31ce8c71
DW
1239 goto out;
1240
70ceb4f5 1241#ifdef CONFIG_IPV6_ROUTE_INFO
9f56220f
AH
1242 if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0))
1243 goto skip_routeinfo;
1244
09c884d4 1245 if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
70ceb4f5
YH
1246 struct nd_opt_hdr *p;
1247 for (p = ndopts.nd_opts_ri;
1248 p;
1249 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
6294e000
YH
1250 struct route_info *ri = (struct route_info *)p;
1251#ifdef CONFIG_IPV6_NDISC_NODETYPE
1252 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
1253 ri->prefix_len == 0)
1254 continue;
1255#endif
1256 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
09c884d4 1257 continue;
70ceb4f5 1258 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
0660e03f 1259 &ipv6_hdr(skb)->saddr);
70ceb4f5
YH
1260 }
1261 }
9f56220f
AH
1262
1263skip_routeinfo:
70ceb4f5
YH
1264#endif
1265
de357cc0 1266#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1267 /* skip link-specific ndopts from interior routers */
1268 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1269 goto out;
de357cc0 1270#endif
fadf6bf0 1271
c4fd30eb 1272 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1da177e4
LT
1273 struct nd_opt_hdr *p;
1274 for (p = ndopts.nd_opts_pi;
1275 p;
1276 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
e6bff995
NH
1277 addrconf_prefix_rcv(skb->dev, (u8 *)p,
1278 (p->nd_opt_len) << 3,
1279 ndopts.nd_opts_src_lladdr != NULL);
1da177e4
LT
1280 }
1281 }
1282
1283 if (ndopts.nd_opts_mtu) {
e69a4adc 1284 __be32 n;
1da177e4
LT
1285 u32 mtu;
1286
e69a4adc
AV
1287 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1288 mtu = ntohl(n);
1da177e4
LT
1289
1290 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
675418d5 1291 ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
1da177e4
LT
1292 } else if (in6_dev->cnf.mtu6 != mtu) {
1293 in6_dev->cnf.mtu6 = mtu;
1294
1295 if (rt)
defb3519 1296 dst_metric_set(&rt->dst, RTAX_MTU, mtu);
1da177e4
LT
1297
1298 rt6_mtu_change(skb->dev, mtu);
1299 }
1300 }
1ab1457c 1301
31910575 1302 if (ndopts.nd_useropts) {
61cf46ad
YH
1303 struct nd_opt_hdr *p;
1304 for (p = ndopts.nd_useropts;
1305 p;
1306 p = ndisc_next_useropt(p, ndopts.nd_useropts_end)) {
1307 ndisc_ra_useropt(skb, p);
31910575
PY
1308 }
1309 }
1310
1da177e4 1311 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
675418d5 1312 ND_PRINTK(2, warn, "RA: invalid RA options\n");
1da177e4
LT
1313 }
1314out:
94e187c0 1315 ip6_rt_put(rt);
eb857186 1316 if (neigh)
1da177e4 1317 neigh_release(neigh);
1da177e4
LT
1318}
1319
1320static void ndisc_redirect_rcv(struct sk_buff *skb)
1321{
de357cc0 1322#ifdef CONFIG_IPV6_NDISC_NODETYPE
fadf6bf0
TF
1323 switch (skb->ndisc_nodetype) {
1324 case NDISC_NODETYPE_HOST:
1325 case NDISC_NODETYPE_NODEFAULT:
675418d5
JP
1326 ND_PRINTK(2, warn,
1327 "Redirect: from host or unauthorized router\n");
fadf6bf0
TF
1328 return;
1329 }
de357cc0 1330#endif
fadf6bf0 1331
0660e03f 1332 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
675418d5
JP
1333 ND_PRINTK(2, warn,
1334 "Redirect: source address is not link-local\n");
1da177e4
LT
1335 return;
1336 }
1337
b94f1c09 1338 icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
1da177e4
LT
1339}
1340
4991969a 1341void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
1da177e4 1342{
1762f7e8 1343 struct net_device *dev = skb->dev;
c346dca1 1344 struct net *net = dev_net(dev);
1762f7e8 1345 struct sock *sk = net->ipv6.ndisc_sk;
1da177e4 1346 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
fbfe95a4 1347 struct inet_peer *peer;
1da177e4
LT
1348 struct sk_buff *buff;
1349 struct icmp6hdr *icmph;
1350 struct in6_addr saddr_buf;
1351 struct in6_addr *addrp;
1da177e4
LT
1352 struct rt6_info *rt;
1353 struct dst_entry *dst;
1354 struct inet6_dev *idev;
4c9483b2 1355 struct flowi6 fl6;
1da177e4 1356 u8 *opt;
a7ae1992 1357 int hlen, tlen;
1da177e4
LT
1358 int rd_len;
1359 int err;
1da177e4 1360 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1d861aa4 1361 bool ret;
1da177e4 1362
95c385b4 1363 if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
675418d5
JP
1364 ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n",
1365 dev->name);
1ab1457c
YH
1366 return;
1367 }
1da177e4 1368
0660e03f 1369 if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
bf0b48df 1370 ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
675418d5
JP
1371 ND_PRINTK(2, warn,
1372 "Redirect: target address is not link-local unicast\n");
29556526
LY
1373 return;
1374 }
1375
4c9483b2 1376 icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
95e41e93 1377 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
1da177e4 1378
4c9483b2 1379 dst = ip6_route_output(net, NULL, &fl6);
5095d64d
RL
1380 if (dst->error) {
1381 dst_release(dst);
1da177e4 1382 return;
5095d64d 1383 }
4c9483b2 1384 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
452edd59 1385 if (IS_ERR(dst))
1da177e4 1386 return;
1da177e4
LT
1387
1388 rt = (struct rt6_info *) dst;
1389
1390 if (rt->rt6i_flags & RTF_GATEWAY) {
675418d5
JP
1391 ND_PRINTK(2, warn,
1392 "Redirect: destination is not a neighbour\n");
d73f0801 1393 goto release;
1da177e4 1394 }
1d861aa4
DM
1395 peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
1396 ret = inet_peer_xrlim_allow(peer, 1*HZ);
1397 if (peer)
1398 inet_putpeer(peer);
1399 if (!ret)
d73f0801 1400 goto release;
1da177e4
LT
1401
1402 if (dev->addr_len) {
4991969a
DM
1403 struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
1404 if (!neigh) {
675418d5
JP
1405 ND_PRINTK(2, warn,
1406 "Redirect: no neigh for target address\n");
4991969a
DM
1407 goto release;
1408 }
1409
1da177e4
LT
1410 read_lock_bh(&neigh->lock);
1411 if (neigh->nud_state & NUD_VALID) {
1412 memcpy(ha_buf, neigh->ha, dev->addr_len);
1413 read_unlock_bh(&neigh->lock);
1414 ha = ha_buf;
1415 len += ndisc_opt_addr_space(dev);
1416 } else
1417 read_unlock_bh(&neigh->lock);
4991969a
DM
1418
1419 neigh_release(neigh);
1da177e4
LT
1420 }
1421
1422 rd_len = min_t(unsigned int,
1423 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1424 rd_len &= ~0x7;
1425 len += rd_len;
1426
a7ae1992
HX
1427 hlen = LL_RESERVED_SPACE(dev);
1428 tlen = dev->needed_tailroom;
d54a81d3
DM
1429 buff = sock_alloc_send_skb(sk,
1430 (MAX_HEADER + sizeof(struct ipv6hdr) +
a7ae1992 1431 len + hlen + tlen),
1da177e4
LT
1432 1, &err);
1433 if (buff == NULL) {
675418d5
JP
1434 ND_PRINTK(0, err,
1435 "Redirect: %s failed to allocate an skb, err=%d\n",
1436 __func__, err);
d73f0801 1437 goto release;
1da177e4
LT
1438 }
1439
a7ae1992 1440 skb_reserve(buff, hlen);
0660e03f 1441 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
1da177e4
LT
1442 IPPROTO_ICMPV6, len);
1443
27a884dc 1444 skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
d10ba34b
ACM
1445 skb_put(buff, len);
1446 icmph = icmp6_hdr(buff);
1da177e4
LT
1447
1448 memset(icmph, 0, sizeof(struct icmp6hdr));
1449 icmph->icmp6_type = NDISC_REDIRECT;
1450
1451 /*
1452 * copy target and destination addresses
1453 */
1454
1455 addrp = (struct in6_addr *)(icmph + 1);
4e3fd7a0 1456 *addrp = *target;
1da177e4 1457 addrp++;
4e3fd7a0 1458 *addrp = ipv6_hdr(skb)->daddr;
1da177e4
LT
1459
1460 opt = (u8*) (addrp + 1);
1461
1462 /*
1463 * include target_address option
1464 */
1465
1466 if (ha)
1467 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1468 dev->addr_len, dev->type);
1469
1470 /*
1471 * build redirect option and copy skb over to the new packet.
1472 */
1473
1ab1457c 1474 memset(opt, 0, 8);
1da177e4
LT
1475 *(opt++) = ND_OPT_REDIRECT_HDR;
1476 *(opt++) = (rd_len >> 3);
1477 opt += 6;
1478
0660e03f 1479 memcpy(opt, ipv6_hdr(skb), rd_len - 8);
1da177e4 1480
0660e03f 1481 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
1da177e4 1482 len, IPPROTO_ICMPV6,
07f0757a 1483 csum_partial(icmph, len, 0));
1da177e4 1484
adf30907 1485 skb_dst_set(buff, dst);
cfdf7647
ED
1486 rcu_read_lock();
1487 idev = __in6_dev_get(dst->dev);
edf391ff 1488 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
b2e0b385 1489 err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
6e23ae2a 1490 dst_output);
1da177e4 1491 if (!err) {
5c5d244b 1492 ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);
a862f6a6 1493 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1da177e4
LT
1494 }
1495
cfdf7647 1496 rcu_read_unlock();
d73f0801
IJ
1497 return;
1498
1499release:
1500 dst_release(dst);
1da177e4
LT
1501}
1502
1503static void pndisc_redo(struct sk_buff *skb)
1504{
140e26fc 1505 ndisc_recv_ns(skb);
1da177e4
LT
1506 kfree_skb(skb);
1507}
1508
1509int ndisc_rcv(struct sk_buff *skb)
1510{
1511 struct nd_msg *msg;
1512
1513 if (!pskb_may_pull(skb, skb->len))
1514 return 0;
1515
9c70220b 1516 msg = (struct nd_msg *)skb_transport_header(skb);
1da177e4 1517
9c70220b 1518 __skb_push(skb, skb->data - skb_transport_header(skb));
1da177e4 1519
0660e03f 1520 if (ipv6_hdr(skb)->hop_limit != 255) {
675418d5
JP
1521 ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n",
1522 ipv6_hdr(skb)->hop_limit);
1da177e4
LT
1523 return 0;
1524 }
1525
1526 if (msg->icmph.icmp6_code != 0) {
675418d5
JP
1527 ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n",
1528 msg->icmph.icmp6_code);
1da177e4
LT
1529 return 0;
1530 }
1531
a61bbcf2
PM
1532 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1533
1da177e4
LT
1534 switch (msg->icmph.icmp6_type) {
1535 case NDISC_NEIGHBOUR_SOLICITATION:
1536 ndisc_recv_ns(skb);
1537 break;
1538
1539 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1540 ndisc_recv_na(skb);
1541 break;
1542
1543 case NDISC_ROUTER_SOLICITATION:
1544 ndisc_recv_rs(skb);
1545 break;
1546
1547 case NDISC_ROUTER_ADVERTISEMENT:
1548 ndisc_router_discovery(skb);
1549 break;
1550
1551 case NDISC_REDIRECT:
1552 ndisc_redirect_rcv(skb);
1553 break;
3ff50b79 1554 }
1da177e4
LT
1555
1556 return 0;
1557}
1558
1559static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1560{
1561 struct net_device *dev = ptr;
c346dca1 1562 struct net *net = dev_net(dev);
5cb04436 1563 struct inet6_dev *idev;
1da177e4
LT
1564
1565 switch (event) {
1566 case NETDEV_CHANGEADDR:
1567 neigh_changeaddr(&nd_tbl, dev);
5b7c931d 1568 fib6_run_gc(~0UL, net);
5cb04436
HFS
1569 idev = in6_dev_get(dev);
1570 if (!idev)
1571 break;
1572 if (idev->cnf.ndisc_notify)
1573 ndisc_send_unsol_na(dev);
1574 in6_dev_put(idev);
1da177e4
LT
1575 break;
1576 case NETDEV_DOWN:
1577 neigh_ifdown(&nd_tbl, dev);
5b7c931d 1578 fib6_run_gc(~0UL, net);
1da177e4 1579 break;
f47b9464
BH
1580 case NETDEV_NOTIFY_PEERS:
1581 ndisc_send_unsol_na(dev);
1582 break;
1da177e4
LT
1583 default:
1584 break;
1585 }
1586
1587 return NOTIFY_DONE;
1588}
1589
1590static struct notifier_block ndisc_netdev_notifier = {
1591 .notifier_call = ndisc_netdev_event,
1592};
1593
1594#ifdef CONFIG_SYSCTL
1595static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1596 const char *func, const char *dev_name)
1597{
1598 static char warncomm[TASK_COMM_LEN];
1599 static int warned;
1600 if (strcmp(warncomm, current->comm) && warned < 5) {
1601 strcpy(warncomm, current->comm);
f3213831 1602 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
1603 warncomm, func,
1604 dev_name, ctl->procname,
1605 dev_name, ctl->procname);
1606 warned++;
1607 }
1608}
1609
8d65af78 1610int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1da177e4
LT
1611{
1612 struct net_device *dev = ctl->extra1;
1613 struct inet6_dev *idev;
1614 int ret;
1615
d12af679
EB
1616 if ((strcmp(ctl->procname, "retrans_time") == 0) ||
1617 (strcmp(ctl->procname, "base_reachable_time") == 0))
1da177e4
LT
1618 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1619
d12af679 1620 if (strcmp(ctl->procname, "retrans_time") == 0)
8d65af78 1621 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
d12af679
EB
1622
1623 else if (strcmp(ctl->procname, "base_reachable_time") == 0)
1da177e4 1624 ret = proc_dointvec_jiffies(ctl, write,
8d65af78 1625 buffer, lenp, ppos);
d12af679
EB
1626
1627 else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
ad02ac14 1628 (strcmp(ctl->procname, "base_reachable_time_ms") == 0))
1da177e4 1629 ret = proc_dointvec_ms_jiffies(ctl, write,
8d65af78 1630 buffer, lenp, ppos);
d12af679 1631 else
1da177e4 1632 ret = -1;
1da177e4
LT
1633
1634 if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
d12af679 1635 if (ctl->data == &idev->nd_parms->base_reachable_time)
1da177e4
LT
1636 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1637 idev->tstamp = jiffies;
1638 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1639 in6_dev_put(idev);
1640 }
1641 return ret;
1642}
1643
1da177e4
LT
1644
1645#endif
1646
2c8c1e72 1647static int __net_init ndisc_net_init(struct net *net)
1da177e4
LT
1648{
1649 struct ipv6_pinfo *np;
1650 struct sock *sk;
1ab1457c 1651 int err;
1da177e4 1652
1ed8516f
DL
1653 err = inet_ctl_sock_create(&sk, PF_INET6,
1654 SOCK_RAW, IPPROTO_ICMPV6, net);
1da177e4 1655 if (err < 0) {
675418d5
JP
1656 ND_PRINTK(0, err,
1657 "NDISC: Failed to initialize the control socket (err %d)\n",
1658 err);
1da177e4
LT
1659 return err;
1660 }
1661
1ed8516f 1662 net->ipv6.ndisc_sk = sk;
1762f7e8 1663
1da177e4 1664 np = inet6_sk(sk);
1da177e4
LT
1665 np->hop_limit = 255;
1666 /* Do not loopback ndisc messages */
1667 np->mc_loop = 0;
1da177e4 1668
1762f7e8
DL
1669 return 0;
1670}
1671
2c8c1e72 1672static void __net_exit ndisc_net_exit(struct net *net)
1762f7e8 1673{
1ed8516f 1674 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1762f7e8
DL
1675}
1676
1677static struct pernet_operations ndisc_net_ops = {
1678 .init = ndisc_net_init,
1679 .exit = ndisc_net_exit,
1680};
1681
1682int __init ndisc_init(void)
1683{
1684 int err;
1685
1686 err = register_pernet_subsys(&ndisc_net_ops);
1687 if (err)
1688 return err;
1ab1457c
YH
1689 /*
1690 * Initialize the neighbour table
1691 */
1da177e4
LT
1692 neigh_table_init(&nd_tbl);
1693
1694#ifdef CONFIG_SYSCTL
54716e3b 1695 err = neigh_sysctl_register(NULL, &nd_tbl.parms, "ipv6",
f8572d8f 1696 &ndisc_ifinfo_sysctl_change);
1762f7e8
DL
1697 if (err)
1698 goto out_unregister_pernet;
1da177e4 1699#endif
1762f7e8
DL
1700 err = register_netdevice_notifier(&ndisc_netdev_notifier);
1701 if (err)
1702 goto out_unregister_sysctl;
1703out:
1704 return err;
1da177e4 1705
1762f7e8
DL
1706out_unregister_sysctl:
1707#ifdef CONFIG_SYSCTL
1708 neigh_sysctl_unregister(&nd_tbl.parms);
1709out_unregister_pernet:
1710#endif
1711 unregister_pernet_subsys(&ndisc_net_ops);
1712 goto out;
1da177e4
LT
1713}
1714
1715void ndisc_cleanup(void)
1716{
36f73d0c 1717 unregister_netdevice_notifier(&ndisc_netdev_notifier);
1da177e4
LT
1718#ifdef CONFIG_SYSCTL
1719 neigh_sysctl_unregister(&nd_tbl.parms);
1720#endif
1721 neigh_table_clear(&nd_tbl);
1762f7e8 1722 unregister_pernet_subsys(&ndisc_net_ops);
1da177e4 1723}
This page took 1.028381 seconds and 5 git commands to generate.