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