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