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