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