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