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