[PATCH] aic7xxx_osm build fix
[cris-mirror.git] / net / ipv6 / ndisc.c
blob7c291f4e9edce067774e38458e727a27bf640f68
1 /*
2 * Neighbour Discovery for IPv6
3 * Linux INET6 implementation
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Mike Shaver <shaver@ingenia.com>
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.
16 * Changes:
18 * Lars Fenneberg : fixed MTU setting on receipt
19 * of an RA.
21 * Janos Farkas : kmalloc failure checks
22 * Alexey Kuznetsov : state machine reworked
23 * and moved to net/core.
24 * Pekka Savola : RFC2461 validation
25 * YOSHIFUJI Hideaki @USAGI : Verify ND options properly
28 /* Set to 3 to get tracing... */
29 #define ND_DEBUG 1
31 #define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0)
32 #define ND_NOPRINTK(x...) do { ; } while(0)
33 #define ND_PRINTK0 ND_PRINTK
34 #define ND_PRINTK1 ND_NOPRINTK
35 #define ND_PRINTK2 ND_NOPRINTK
36 #define ND_PRINTK3 ND_NOPRINTK
37 #if ND_DEBUG >= 1
38 #undef ND_PRINTK1
39 #define ND_PRINTK1 ND_PRINTK
40 #endif
41 #if ND_DEBUG >= 2
42 #undef ND_PRINTK2
43 #define ND_PRINTK2 ND_PRINTK
44 #endif
45 #if ND_DEBUG >= 3
46 #undef ND_PRINTK3
47 #define ND_PRINTK3 ND_PRINTK
48 #endif
50 #include <linux/module.h>
51 #include <linux/config.h>
52 #include <linux/errno.h>
53 #include <linux/types.h>
54 #include <linux/socket.h>
55 #include <linux/sockios.h>
56 #include <linux/sched.h>
57 #include <linux/net.h>
58 #include <linux/in6.h>
59 #include <linux/route.h>
60 #include <linux/init.h>
61 #include <linux/rcupdate.h>
62 #ifdef CONFIG_SYSCTL
63 #include <linux/sysctl.h>
64 #endif
66 #include <linux/if_arp.h>
67 #include <linux/ipv6.h>
68 #include <linux/icmpv6.h>
69 #include <linux/jhash.h>
71 #include <net/sock.h>
72 #include <net/snmp.h>
74 #include <net/ipv6.h>
75 #include <net/protocol.h>
76 #include <net/ndisc.h>
77 #include <net/ip6_route.h>
78 #include <net/addrconf.h>
79 #include <net/icmp.h>
81 #include <net/flow.h>
82 #include <net/ip6_checksum.h>
83 #include <linux/proc_fs.h>
85 #include <linux/netfilter.h>
86 #include <linux/netfilter_ipv6.h>
88 static struct socket *ndisc_socket;
90 static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
91 static int ndisc_constructor(struct neighbour *neigh);
92 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
93 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
94 static int pndisc_constructor(struct pneigh_entry *n);
95 static void pndisc_destructor(struct pneigh_entry *n);
96 static void pndisc_redo(struct sk_buff *skb);
98 static struct neigh_ops ndisc_generic_ops = {
99 .family = AF_INET6,
100 .solicit = ndisc_solicit,
101 .error_report = ndisc_error_report,
102 .output = neigh_resolve_output,
103 .connected_output = neigh_connected_output,
104 .hh_output = dev_queue_xmit,
105 .queue_xmit = dev_queue_xmit,
108 static struct neigh_ops ndisc_hh_ops = {
109 .family = AF_INET6,
110 .solicit = ndisc_solicit,
111 .error_report = ndisc_error_report,
112 .output = neigh_resolve_output,
113 .connected_output = neigh_resolve_output,
114 .hh_output = dev_queue_xmit,
115 .queue_xmit = dev_queue_xmit,
119 static struct neigh_ops ndisc_direct_ops = {
120 .family = AF_INET6,
121 .output = dev_queue_xmit,
122 .connected_output = dev_queue_xmit,
123 .hh_output = dev_queue_xmit,
124 .queue_xmit = dev_queue_xmit,
127 struct neigh_table nd_tbl = {
128 .family = AF_INET6,
129 .entry_size = sizeof(struct neighbour) + sizeof(struct in6_addr),
130 .key_len = sizeof(struct in6_addr),
131 .hash = ndisc_hash,
132 .constructor = ndisc_constructor,
133 .pconstructor = pndisc_constructor,
134 .pdestructor = pndisc_destructor,
135 .proxy_redo = pndisc_redo,
136 .id = "ndisc_cache",
137 .parms = {
138 .tbl = &nd_tbl,
139 .base_reachable_time = 30 * HZ,
140 .retrans_time = 1 * HZ,
141 .gc_staletime = 60 * HZ,
142 .reachable_time = 30 * HZ,
143 .delay_probe_time = 5 * HZ,
144 .queue_len = 3,
145 .ucast_probes = 3,
146 .mcast_probes = 3,
147 .anycast_delay = 1 * HZ,
148 .proxy_delay = (8 * HZ) / 10,
149 .proxy_qlen = 64,
151 .gc_interval = 30 * HZ,
152 .gc_thresh1 = 128,
153 .gc_thresh2 = 512,
154 .gc_thresh3 = 1024,
157 /* ND options */
158 struct ndisc_options {
159 struct nd_opt_hdr *nd_opt_array[__ND_OPT_MAX];
162 #define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
163 #define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
164 #define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
165 #define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
166 #define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
167 #define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
169 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
172 * Return the padding between the option length and the start of the
173 * link addr. Currently only IP-over-InfiniBand needs this, although
174 * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
175 * also need a pad of 2.
177 static int ndisc_addr_option_pad(unsigned short type)
179 switch (type) {
180 case ARPHRD_INFINIBAND: return 2;
181 default: return 0;
185 static inline int ndisc_opt_addr_space(struct net_device *dev)
187 return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
190 static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
191 unsigned short addr_type)
193 int space = NDISC_OPT_SPACE(data_len);
194 int pad = ndisc_addr_option_pad(addr_type);
196 opt[0] = type;
197 opt[1] = space>>3;
199 memset(opt + 2, 0, pad);
200 opt += pad;
201 space -= pad;
203 memcpy(opt+2, data, data_len);
204 data_len += 2;
205 opt += data_len;
206 if ((space -= data_len) > 0)
207 memset(opt, 0, space);
208 return opt + space;
211 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
212 struct nd_opt_hdr *end)
214 int type;
215 if (!cur || !end || cur >= end)
216 return NULL;
217 type = cur->nd_opt_type;
218 do {
219 cur = ((void *)cur) + (cur->nd_opt_len << 3);
220 } while(cur < end && cur->nd_opt_type != type);
221 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
224 static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
225 struct ndisc_options *ndopts)
227 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
229 if (!nd_opt || opt_len < 0 || !ndopts)
230 return NULL;
231 memset(ndopts, 0, sizeof(*ndopts));
232 while (opt_len) {
233 int l;
234 if (opt_len < sizeof(struct nd_opt_hdr))
235 return NULL;
236 l = nd_opt->nd_opt_len << 3;
237 if (opt_len < l || l == 0)
238 return NULL;
239 switch (nd_opt->nd_opt_type) {
240 case ND_OPT_SOURCE_LL_ADDR:
241 case ND_OPT_TARGET_LL_ADDR:
242 case ND_OPT_MTU:
243 case ND_OPT_REDIRECT_HDR:
244 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
245 ND_PRINTK2(KERN_WARNING
246 "%s(): duplicated ND6 option found: type=%d\n",
247 __FUNCTION__,
248 nd_opt->nd_opt_type);
249 } else {
250 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
252 break;
253 case ND_OPT_PREFIX_INFO:
254 ndopts->nd_opts_pi_end = nd_opt;
255 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
256 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
257 break;
258 default:
260 * Unknown options must be silently ignored,
261 * to accommodate future extension to the protocol.
263 ND_PRINTK2(KERN_NOTICE
264 "%s(): ignored unsupported option; type=%d, len=%d\n",
265 __FUNCTION__,
266 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
268 opt_len -= l;
269 nd_opt = ((void *)nd_opt) + l;
271 return ndopts;
274 static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
275 struct net_device *dev)
277 u8 *lladdr = (u8 *)(p + 1);
278 int lladdrlen = p->nd_opt_len << 3;
279 int prepad = ndisc_addr_option_pad(dev->type);
280 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
281 return NULL;
282 return (lladdr + prepad);
285 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
287 switch (dev->type) {
288 case ARPHRD_ETHER:
289 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
290 case ARPHRD_FDDI:
291 ipv6_eth_mc_map(addr, buf);
292 return 0;
293 case ARPHRD_IEEE802_TR:
294 ipv6_tr_mc_map(addr,buf);
295 return 0;
296 case ARPHRD_ARCNET:
297 ipv6_arcnet_mc_map(addr, buf);
298 return 0;
299 case ARPHRD_INFINIBAND:
300 ipv6_ib_mc_map(addr, buf);
301 return 0;
302 default:
303 if (dir) {
304 memcpy(buf, dev->broadcast, dev->addr_len);
305 return 0;
308 return -EINVAL;
311 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
313 const u32 *p32 = pkey;
314 u32 addr_hash, i;
316 addr_hash = 0;
317 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
318 addr_hash ^= *p32++;
320 return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
323 static int ndisc_constructor(struct neighbour *neigh)
325 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
326 struct net_device *dev = neigh->dev;
327 struct inet6_dev *in6_dev;
328 struct neigh_parms *parms;
329 int is_multicast = ipv6_addr_is_multicast(addr);
331 rcu_read_lock();
332 in6_dev = in6_dev_get(dev);
333 if (in6_dev == NULL) {
334 rcu_read_unlock();
335 return -EINVAL;
338 parms = in6_dev->nd_parms;
339 __neigh_parms_put(neigh->parms);
340 neigh->parms = neigh_parms_clone(parms);
341 rcu_read_unlock();
343 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
344 if (dev->hard_header == NULL) {
345 neigh->nud_state = NUD_NOARP;
346 neigh->ops = &ndisc_direct_ops;
347 neigh->output = neigh->ops->queue_xmit;
348 } else {
349 if (is_multicast) {
350 neigh->nud_state = NUD_NOARP;
351 ndisc_mc_map(addr, neigh->ha, dev, 1);
352 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
353 neigh->nud_state = NUD_NOARP;
354 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
355 if (dev->flags&IFF_LOOPBACK)
356 neigh->type = RTN_LOCAL;
357 } else if (dev->flags&IFF_POINTOPOINT) {
358 neigh->nud_state = NUD_NOARP;
359 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
361 if (dev->hard_header_cache)
362 neigh->ops = &ndisc_hh_ops;
363 else
364 neigh->ops = &ndisc_generic_ops;
365 if (neigh->nud_state&NUD_VALID)
366 neigh->output = neigh->ops->connected_output;
367 else
368 neigh->output = neigh->ops->output;
370 in6_dev_put(in6_dev);
371 return 0;
374 static int pndisc_constructor(struct pneigh_entry *n)
376 struct in6_addr *addr = (struct in6_addr*)&n->key;
377 struct in6_addr maddr;
378 struct net_device *dev = n->dev;
380 if (dev == NULL || __in6_dev_get(dev) == NULL)
381 return -EINVAL;
382 addrconf_addr_solict_mult(addr, &maddr);
383 ipv6_dev_mc_inc(dev, &maddr);
384 return 0;
387 static void pndisc_destructor(struct pneigh_entry *n)
389 struct in6_addr *addr = (struct in6_addr*)&n->key;
390 struct in6_addr maddr;
391 struct net_device *dev = n->dev;
393 if (dev == NULL || __in6_dev_get(dev) == NULL)
394 return;
395 addrconf_addr_solict_mult(addr, &maddr);
396 ipv6_dev_mc_dec(dev, &maddr);
400 * Send a Neighbour Advertisement
403 static inline void ndisc_flow_init(struct flowi *fl, u8 type,
404 struct in6_addr *saddr, struct in6_addr *daddr)
406 memset(fl, 0, sizeof(*fl));
407 ipv6_addr_copy(&fl->fl6_src, saddr);
408 ipv6_addr_copy(&fl->fl6_dst, daddr);
409 fl->proto = IPPROTO_ICMPV6;
410 fl->fl_icmp_type = type;
411 fl->fl_icmp_code = 0;
414 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
415 struct in6_addr *daddr, struct in6_addr *solicited_addr,
416 int router, int solicited, int override, int inc_opt)
418 struct in6_addr tmpaddr;
419 struct inet6_ifaddr *ifp;
420 struct inet6_dev *idev;
421 struct flowi fl;
422 struct dst_entry* dst;
423 struct sock *sk = ndisc_socket->sk;
424 struct in6_addr *src_addr;
425 struct nd_msg *msg;
426 int len;
427 struct sk_buff *skb;
428 int err;
430 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
432 /* for anycast or proxy, solicited_addr != src_addr */
433 ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
434 if (ifp) {
435 src_addr = solicited_addr;
436 in6_ifa_put(ifp);
437 } else {
438 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
439 return;
440 src_addr = &tmpaddr;
443 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
445 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
446 if (!dst)
447 return;
449 err = xfrm_lookup(&dst, &fl, NULL, 0);
450 if (err < 0) {
451 dst_release(dst);
452 return;
455 if (inc_opt) {
456 if (dev->addr_len)
457 len += ndisc_opt_addr_space(dev);
458 else
459 inc_opt = 0;
462 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
463 1, &err);
465 if (skb == NULL) {
466 ND_PRINTK0(KERN_ERR
467 "ICMPv6 NA: %s() failed to allocate an skb.\n",
468 __FUNCTION__);
469 dst_release(dst);
470 return;
473 skb_reserve(skb, LL_RESERVED_SPACE(dev));
474 ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
476 msg = (struct nd_msg *)skb_put(skb, len);
477 skb->h.raw = (unsigned char*)msg;
479 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
480 msg->icmph.icmp6_code = 0;
481 msg->icmph.icmp6_cksum = 0;
483 msg->icmph.icmp6_unused = 0;
484 msg->icmph.icmp6_router = router;
485 msg->icmph.icmp6_solicited = solicited;
486 msg->icmph.icmp6_override = !!override;
488 /* Set the target address. */
489 ipv6_addr_copy(&msg->target, solicited_addr);
491 if (inc_opt)
492 ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
493 dev->addr_len, dev->type);
495 /* checksum */
496 msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len,
497 IPPROTO_ICMPV6,
498 csum_partial((__u8 *) msg,
499 len, 0));
501 skb->dst = dst;
502 idev = in6_dev_get(dst->dev);
503 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
504 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
505 if (!err) {
506 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
507 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
510 if (likely(idev != NULL))
511 in6_dev_put(idev);
514 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
515 struct in6_addr *solicit,
516 struct in6_addr *daddr, struct in6_addr *saddr)
518 struct flowi fl;
519 struct dst_entry* dst;
520 struct inet6_dev *idev;
521 struct sock *sk = ndisc_socket->sk;
522 struct sk_buff *skb;
523 struct nd_msg *msg;
524 struct in6_addr addr_buf;
525 int len;
526 int err;
527 int send_llinfo;
529 if (saddr == NULL) {
530 if (ipv6_get_lladdr(dev, &addr_buf))
531 return;
532 saddr = &addr_buf;
535 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
537 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
538 if (!dst)
539 return;
541 err = xfrm_lookup(&dst, &fl, NULL, 0);
542 if (err < 0) {
543 dst_release(dst);
544 return;
547 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
548 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
549 if (send_llinfo)
550 len += ndisc_opt_addr_space(dev);
552 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
553 1, &err);
554 if (skb == NULL) {
555 ND_PRINTK0(KERN_ERR
556 "ICMPv6 NA: %s() failed to allocate an skb.\n",
557 __FUNCTION__);
558 dst_release(dst);
559 return;
562 skb_reserve(skb, LL_RESERVED_SPACE(dev));
563 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
565 msg = (struct nd_msg *)skb_put(skb, len);
566 skb->h.raw = (unsigned char*)msg;
567 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
568 msg->icmph.icmp6_code = 0;
569 msg->icmph.icmp6_cksum = 0;
570 msg->icmph.icmp6_unused = 0;
572 /* Set the target address. */
573 ipv6_addr_copy(&msg->target, solicit);
575 if (send_llinfo)
576 ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
577 dev->addr_len, dev->type);
579 /* checksum */
580 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
581 daddr, len,
582 IPPROTO_ICMPV6,
583 csum_partial((__u8 *) msg,
584 len, 0));
585 /* send it! */
586 skb->dst = dst;
587 idev = in6_dev_get(dst->dev);
588 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
589 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
590 if (!err) {
591 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
592 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
595 if (likely(idev != NULL))
596 in6_dev_put(idev);
599 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
600 struct in6_addr *daddr)
602 struct flowi fl;
603 struct dst_entry* dst;
604 struct inet6_dev *idev;
605 struct sock *sk = ndisc_socket->sk;
606 struct sk_buff *skb;
607 struct icmp6hdr *hdr;
608 __u8 * opt;
609 int len;
610 int err;
612 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
614 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
615 if (!dst)
616 return;
618 err = xfrm_lookup(&dst, &fl, NULL, 0);
619 if (err < 0) {
620 dst_release(dst);
621 return;
624 len = sizeof(struct icmp6hdr);
625 if (dev->addr_len)
626 len += ndisc_opt_addr_space(dev);
628 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
629 1, &err);
630 if (skb == NULL) {
631 ND_PRINTK0(KERN_ERR
632 "ICMPv6 RS: %s() failed to allocate an skb.\n",
633 __FUNCTION__);
634 dst_release(dst);
635 return;
638 skb_reserve(skb, LL_RESERVED_SPACE(dev));
639 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
641 hdr = (struct icmp6hdr *)skb_put(skb, len);
642 skb->h.raw = (unsigned char*)hdr;
643 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
644 hdr->icmp6_code = 0;
645 hdr->icmp6_cksum = 0;
646 hdr->icmp6_unused = 0;
648 opt = (u8*) (hdr + 1);
650 if (dev->addr_len)
651 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
652 dev->addr_len, dev->type);
654 /* checksum */
655 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
656 IPPROTO_ICMPV6,
657 csum_partial((__u8 *) hdr, len, 0));
659 /* send it! */
660 skb->dst = dst;
661 idev = in6_dev_get(dst->dev);
662 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
663 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
664 if (!err) {
665 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
666 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
669 if (likely(idev != NULL))
670 in6_dev_put(idev);
674 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
677 * "The sender MUST return an ICMP
678 * destination unreachable"
680 dst_link_failure(skb);
681 kfree_skb(skb);
684 /* Called with locked neigh: either read or both */
686 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
688 struct in6_addr *saddr = NULL;
689 struct in6_addr mcaddr;
690 struct net_device *dev = neigh->dev;
691 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
692 int probes = atomic_read(&neigh->probes);
694 if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
695 saddr = &skb->nh.ipv6h->saddr;
697 if ((probes -= neigh->parms->ucast_probes) < 0) {
698 if (!(neigh->nud_state & NUD_VALID)) {
699 ND_PRINTK1(KERN_DEBUG
700 "%s(): trying to ucast probe in NUD_INVALID: "
701 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
702 __FUNCTION__,
703 NIP6(*target));
705 ndisc_send_ns(dev, neigh, target, target, saddr);
706 } else if ((probes -= neigh->parms->app_probes) < 0) {
707 #ifdef CONFIG_ARPD
708 neigh_app_ns(neigh);
709 #endif
710 } else {
711 addrconf_addr_solict_mult(target, &mcaddr);
712 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
716 static void ndisc_recv_ns(struct sk_buff *skb)
718 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
719 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
720 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
721 u8 *lladdr = NULL;
722 u32 ndoptlen = skb->tail - msg->opt;
723 struct ndisc_options ndopts;
724 struct net_device *dev = skb->dev;
725 struct inet6_ifaddr *ifp;
726 struct inet6_dev *idev = NULL;
727 struct neighbour *neigh;
728 int dad = ipv6_addr_any(saddr);
729 int inc;
731 if (ipv6_addr_is_multicast(&msg->target)) {
732 ND_PRINTK2(KERN_WARNING
733 "ICMPv6 NS: multicast target address");
734 return;
738 * RFC2461 7.1.1:
739 * DAD has to be destined for solicited node multicast address.
741 if (dad &&
742 !(daddr->s6_addr32[0] == htonl(0xff020000) &&
743 daddr->s6_addr32[1] == htonl(0x00000000) &&
744 daddr->s6_addr32[2] == htonl(0x00000001) &&
745 daddr->s6_addr [12] == 0xff )) {
746 ND_PRINTK2(KERN_WARNING
747 "ICMPv6 NS: bad DAD packet (wrong destination)\n");
748 return;
751 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
752 ND_PRINTK2(KERN_WARNING
753 "ICMPv6 NS: invalid ND options\n");
754 return;
757 if (ndopts.nd_opts_src_lladdr) {
758 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
759 if (!lladdr) {
760 ND_PRINTK2(KERN_WARNING
761 "ICMPv6 NS: invalid link-layer address length\n");
762 return;
765 /* RFC2461 7.1.1:
766 * If the IP source address is the unspecified address,
767 * there MUST NOT be source link-layer address option
768 * in the message.
770 if (dad) {
771 ND_PRINTK2(KERN_WARNING
772 "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
773 return;
777 inc = ipv6_addr_is_multicast(daddr);
779 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
780 if (ifp->flags & IFA_F_TENTATIVE) {
781 /* Address is tentative. If the source
782 is unspecified address, it is someone
783 does DAD, otherwise we ignore solicitations
784 until DAD timer expires.
786 if (!dad)
787 goto out;
788 if (dev->type == ARPHRD_IEEE802_TR) {
789 unsigned char *sadr = skb->mac.raw;
790 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
791 sadr[9] == dev->dev_addr[1] &&
792 sadr[10] == dev->dev_addr[2] &&
793 sadr[11] == dev->dev_addr[3] &&
794 sadr[12] == dev->dev_addr[4] &&
795 sadr[13] == dev->dev_addr[5]) {
796 /* looped-back to us */
797 goto out;
800 addrconf_dad_failure(ifp);
801 return;
804 idev = ifp->idev;
805 } else {
806 idev = in6_dev_get(dev);
807 if (!idev) {
808 /* XXX: count this drop? */
809 return;
812 if (ipv6_chk_acast_addr(dev, &msg->target) ||
813 (idev->cnf.forwarding &&
814 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
815 if (skb->stamp.tv_sec != LOCALLY_ENQUEUED &&
816 skb->pkt_type != PACKET_HOST &&
817 inc != 0 &&
818 idev->nd_parms->proxy_delay != 0) {
820 * for anycast or proxy,
821 * sender should delay its response
822 * by a random time between 0 and
823 * MAX_ANYCAST_DELAY_TIME seconds.
824 * (RFC2461) -- yoshfuji
826 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
827 if (n)
828 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
829 goto out;
831 } else
832 goto out;
835 if (dad) {
836 struct in6_addr maddr;
838 ipv6_addr_all_nodes(&maddr);
839 ndisc_send_na(dev, NULL, &maddr, &msg->target,
840 idev->cnf.forwarding, 0, (ifp != NULL), 1);
841 goto out;
844 if (inc)
845 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
846 else
847 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
850 * update / create cache entry
851 * for the source address
853 neigh = __neigh_lookup(&nd_tbl, saddr, dev,
854 !inc || lladdr || !dev->addr_len);
855 if (neigh)
856 neigh_update(neigh, lladdr, NUD_STALE,
857 NEIGH_UPDATE_F_WEAK_OVERRIDE|
858 NEIGH_UPDATE_F_OVERRIDE);
859 if (neigh || !dev->hard_header) {
860 ndisc_send_na(dev, neigh, saddr, &msg->target,
861 idev->cnf.forwarding,
862 1, (ifp != NULL && inc), inc);
863 if (neigh)
864 neigh_release(neigh);
867 out:
868 if (ifp)
869 in6_ifa_put(ifp);
870 else
871 in6_dev_put(idev);
873 return;
876 static void ndisc_recv_na(struct sk_buff *skb)
878 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
879 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
880 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
881 u8 *lladdr = NULL;
882 u32 ndoptlen = skb->tail - msg->opt;
883 struct ndisc_options ndopts;
884 struct net_device *dev = skb->dev;
885 struct inet6_ifaddr *ifp;
886 struct neighbour *neigh;
888 if (skb->len < sizeof(struct nd_msg)) {
889 ND_PRINTK2(KERN_WARNING
890 "ICMPv6 NA: packet too short\n");
891 return;
894 if (ipv6_addr_is_multicast(&msg->target)) {
895 ND_PRINTK2(KERN_WARNING
896 "ICMPv6 NA: target address is multicast.\n");
897 return;
900 if (ipv6_addr_is_multicast(daddr) &&
901 msg->icmph.icmp6_solicited) {
902 ND_PRINTK2(KERN_WARNING
903 "ICMPv6 NA: solicited NA is multicasted.\n");
904 return;
907 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
908 ND_PRINTK2(KERN_WARNING
909 "ICMPv6 NS: invalid ND option\n");
910 return;
912 if (ndopts.nd_opts_tgt_lladdr) {
913 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
914 if (!lladdr) {
915 ND_PRINTK2(KERN_WARNING
916 "ICMPv6 NA: invalid link-layer address length\n");
917 return;
920 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
921 if (ifp->flags & IFA_F_TENTATIVE) {
922 addrconf_dad_failure(ifp);
923 return;
925 /* What should we make now? The advertisement
926 is invalid, but ndisc specs say nothing
927 about it. It could be misconfiguration, or
928 an smart proxy agent tries to help us :-)
930 ND_PRINTK1(KERN_WARNING
931 "ICMPv6 NA: someone advertises our address on %s!\n",
932 ifp->idev->dev->name);
933 in6_ifa_put(ifp);
934 return;
936 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
938 if (neigh) {
939 u8 old_flags = neigh->flags;
941 if (neigh->nud_state & NUD_FAILED)
942 goto out;
944 neigh_update(neigh, lladdr,
945 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
946 NEIGH_UPDATE_F_WEAK_OVERRIDE|
947 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
948 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
949 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
951 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
953 * Change: router to host
955 struct rt6_info *rt;
956 rt = rt6_get_dflt_router(saddr, dev);
957 if (rt)
958 ip6_del_rt(rt, NULL, NULL);
961 out:
962 neigh_release(neigh);
966 static void ndisc_recv_rs(struct sk_buff *skb)
968 struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
969 unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
970 struct neighbour *neigh;
971 struct inet6_dev *idev;
972 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
973 struct ndisc_options ndopts;
974 u8 *lladdr = NULL;
976 if (skb->len < sizeof(*rs_msg))
977 return;
979 idev = in6_dev_get(skb->dev);
980 if (!idev) {
981 if (net_ratelimit())
982 ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
983 return;
986 /* Don't accept RS if we're not in router mode */
987 if (!idev->cnf.forwarding)
988 goto out;
991 * Don't update NCE if src = ::;
992 * this implies that the source node has no ip address assigned yet.
994 if (ipv6_addr_any(saddr))
995 goto out;
997 /* Parse ND options */
998 if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
999 if (net_ratelimit())
1000 ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
1001 goto out;
1004 if (ndopts.nd_opts_src_lladdr) {
1005 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1006 skb->dev);
1007 if (!lladdr)
1008 goto out;
1011 neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1012 if (neigh) {
1013 neigh_update(neigh, lladdr, NUD_STALE,
1014 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1015 NEIGH_UPDATE_F_OVERRIDE|
1016 NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1017 neigh_release(neigh);
1019 out:
1020 in6_dev_put(idev);
1023 static void ndisc_router_discovery(struct sk_buff *skb)
1025 struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
1026 struct neighbour *neigh = NULL;
1027 struct inet6_dev *in6_dev;
1028 struct rt6_info *rt;
1029 int lifetime;
1030 struct ndisc_options ndopts;
1031 int optlen;
1033 __u8 * opt = (__u8 *)(ra_msg + 1);
1035 optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
1037 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1038 ND_PRINTK2(KERN_WARNING
1039 "ICMPv6 RA: source address is not link-local.\n");
1040 return;
1042 if (optlen < 0) {
1043 ND_PRINTK2(KERN_WARNING
1044 "ICMPv6 RA: packet too short\n");
1045 return;
1049 * set the RA_RECV flag in the interface
1052 in6_dev = in6_dev_get(skb->dev);
1053 if (in6_dev == NULL) {
1054 ND_PRINTK0(KERN_ERR
1055 "ICMPv6 RA: can't find inet6 device for %s.\n",
1056 skb->dev->name);
1057 return;
1059 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1060 in6_dev_put(in6_dev);
1061 return;
1064 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1065 in6_dev_put(in6_dev);
1066 ND_PRINTK2(KERN_WARNING
1067 "ICMP6 RA: invalid ND options\n");
1068 return;
1071 if (in6_dev->if_flags & IF_RS_SENT) {
1073 * flag that an RA was received after an RS was sent
1074 * out on this interface.
1076 in6_dev->if_flags |= IF_RA_RCVD;
1080 * Remember the managed/otherconf flags from most recently
1081 * received RA message (RFC 2462) -- yoshfuji
1083 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1084 IF_RA_OTHERCONF)) |
1085 (ra_msg->icmph.icmp6_addrconf_managed ?
1086 IF_RA_MANAGED : 0) |
1087 (ra_msg->icmph.icmp6_addrconf_other ?
1088 IF_RA_OTHERCONF : 0);
1090 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1092 rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1094 if (rt)
1095 neigh = rt->rt6i_nexthop;
1097 if (rt && lifetime == 0) {
1098 neigh_clone(neigh);
1099 ip6_del_rt(rt, NULL, NULL);
1100 rt = NULL;
1103 if (rt == NULL && lifetime) {
1104 ND_PRINTK3(KERN_DEBUG
1105 "ICMPv6 RA: adding default router.\n");
1107 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1108 if (rt == NULL) {
1109 ND_PRINTK0(KERN_ERR
1110 "ICMPv6 RA: %s() failed to add default route.\n",
1111 __FUNCTION__);
1112 in6_dev_put(in6_dev);
1113 return;
1116 neigh = rt->rt6i_nexthop;
1117 if (neigh == NULL) {
1118 ND_PRINTK0(KERN_ERR
1119 "ICMPv6 RA: %s() got default router without neighbour.\n",
1120 __FUNCTION__);
1121 dst_release(&rt->u.dst);
1122 in6_dev_put(in6_dev);
1123 return;
1125 neigh->flags |= NTF_ROUTER;
1128 if (rt)
1129 rt->rt6i_expires = jiffies + (HZ * lifetime);
1131 if (ra_msg->icmph.icmp6_hop_limit) {
1132 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1133 if (rt)
1134 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1138 * Update Reachable Time and Retrans Timer
1141 if (in6_dev->nd_parms) {
1142 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1144 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1145 rtime = (rtime*HZ)/1000;
1146 if (rtime < HZ/10)
1147 rtime = HZ/10;
1148 in6_dev->nd_parms->retrans_time = rtime;
1149 in6_dev->tstamp = jiffies;
1150 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1153 rtime = ntohl(ra_msg->reachable_time);
1154 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1155 rtime = (rtime*HZ)/1000;
1157 if (rtime < HZ/10)
1158 rtime = HZ/10;
1160 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1161 in6_dev->nd_parms->base_reachable_time = rtime;
1162 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1163 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1164 in6_dev->tstamp = jiffies;
1165 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1171 * Process options.
1174 if (!neigh)
1175 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1176 skb->dev, 1);
1177 if (neigh) {
1178 u8 *lladdr = NULL;
1179 if (ndopts.nd_opts_src_lladdr) {
1180 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1181 skb->dev);
1182 if (!lladdr) {
1183 ND_PRINTK2(KERN_WARNING
1184 "ICMPv6 RA: invalid link-layer address length\n");
1185 goto out;
1188 neigh_update(neigh, lladdr, NUD_STALE,
1189 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1190 NEIGH_UPDATE_F_OVERRIDE|
1191 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1192 NEIGH_UPDATE_F_ISROUTER);
1195 if (ndopts.nd_opts_pi) {
1196 struct nd_opt_hdr *p;
1197 for (p = ndopts.nd_opts_pi;
1199 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1200 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1204 if (ndopts.nd_opts_mtu) {
1205 u32 mtu;
1207 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1208 mtu = ntohl(mtu);
1210 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1211 ND_PRINTK2(KERN_WARNING
1212 "ICMPv6 RA: invalid mtu: %d\n",
1213 mtu);
1214 } else if (in6_dev->cnf.mtu6 != mtu) {
1215 in6_dev->cnf.mtu6 = mtu;
1217 if (rt)
1218 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1220 rt6_mtu_change(skb->dev, mtu);
1224 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1225 ND_PRINTK2(KERN_WARNING
1226 "ICMPv6 RA: invalid RA options");
1228 out:
1229 if (rt)
1230 dst_release(&rt->u.dst);
1231 else if (neigh)
1232 neigh_release(neigh);
1233 in6_dev_put(in6_dev);
1236 static void ndisc_redirect_rcv(struct sk_buff *skb)
1238 struct inet6_dev *in6_dev;
1239 struct icmp6hdr *icmph;
1240 struct in6_addr *dest;
1241 struct in6_addr *target; /* new first hop to destination */
1242 struct neighbour *neigh;
1243 int on_link = 0;
1244 struct ndisc_options ndopts;
1245 int optlen;
1246 u8 *lladdr = NULL;
1248 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1249 ND_PRINTK2(KERN_WARNING
1250 "ICMPv6 Redirect: source address is not link-local.\n");
1251 return;
1254 optlen = skb->tail - skb->h.raw;
1255 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1257 if (optlen < 0) {
1258 ND_PRINTK2(KERN_WARNING
1259 "ICMPv6 Redirect: packet too short\n");
1260 return;
1263 icmph = (struct icmp6hdr *) skb->h.raw;
1264 target = (struct in6_addr *) (icmph + 1);
1265 dest = target + 1;
1267 if (ipv6_addr_is_multicast(dest)) {
1268 ND_PRINTK2(KERN_WARNING
1269 "ICMPv6 Redirect: destination address is multicast.\n");
1270 return;
1273 if (ipv6_addr_equal(dest, target)) {
1274 on_link = 1;
1275 } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1276 ND_PRINTK2(KERN_WARNING
1277 "ICMPv6 Redirect: target address is not link-local.\n");
1278 return;
1281 in6_dev = in6_dev_get(skb->dev);
1282 if (!in6_dev)
1283 return;
1284 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1285 in6_dev_put(in6_dev);
1286 return;
1289 /* RFC2461 8.1:
1290 * The IP source address of the Redirect MUST be the same as the current
1291 * first-hop router for the specified ICMP Destination Address.
1294 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1295 ND_PRINTK2(KERN_WARNING
1296 "ICMPv6 Redirect: invalid ND options\n");
1297 in6_dev_put(in6_dev);
1298 return;
1300 if (ndopts.nd_opts_tgt_lladdr) {
1301 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1302 skb->dev);
1303 if (!lladdr) {
1304 ND_PRINTK2(KERN_WARNING
1305 "ICMPv6 Redirect: invalid link-layer address length\n");
1306 in6_dev_put(in6_dev);
1307 return;
1311 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1312 if (neigh) {
1313 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr,
1314 on_link);
1315 neigh_release(neigh);
1317 in6_dev_put(in6_dev);
1320 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1321 struct in6_addr *target)
1323 struct sock *sk = ndisc_socket->sk;
1324 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1325 struct sk_buff *buff;
1326 struct icmp6hdr *icmph;
1327 struct in6_addr saddr_buf;
1328 struct in6_addr *addrp;
1329 struct net_device *dev;
1330 struct rt6_info *rt;
1331 struct dst_entry *dst;
1332 struct inet6_dev *idev;
1333 struct flowi fl;
1334 u8 *opt;
1335 int rd_len;
1336 int err;
1337 int hlen;
1338 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1340 dev = skb->dev;
1342 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1343 ND_PRINTK2(KERN_WARNING
1344 "ICMPv6 Redirect: no link-local address on %s\n",
1345 dev->name);
1346 return;
1349 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1351 dst = ip6_route_output(NULL, &fl);
1352 if (dst == NULL)
1353 return;
1355 err = xfrm_lookup(&dst, &fl, NULL, 0);
1356 if (err) {
1357 dst_release(dst);
1358 return;
1361 rt = (struct rt6_info *) dst;
1363 if (rt->rt6i_flags & RTF_GATEWAY) {
1364 ND_PRINTK2(KERN_WARNING
1365 "ICMPv6 Redirect: destination is not a neighbour.\n");
1366 dst_release(dst);
1367 return;
1369 if (!xrlim_allow(dst, 1*HZ)) {
1370 dst_release(dst);
1371 return;
1374 if (dev->addr_len) {
1375 read_lock_bh(&neigh->lock);
1376 if (neigh->nud_state & NUD_VALID) {
1377 memcpy(ha_buf, neigh->ha, dev->addr_len);
1378 read_unlock_bh(&neigh->lock);
1379 ha = ha_buf;
1380 len += ndisc_opt_addr_space(dev);
1381 } else
1382 read_unlock_bh(&neigh->lock);
1385 rd_len = min_t(unsigned int,
1386 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1387 rd_len &= ~0x7;
1388 len += rd_len;
1390 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1391 1, &err);
1392 if (buff == NULL) {
1393 ND_PRINTK0(KERN_ERR
1394 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1395 __FUNCTION__);
1396 dst_release(dst);
1397 return;
1400 hlen = 0;
1402 skb_reserve(buff, LL_RESERVED_SPACE(dev));
1403 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1404 IPPROTO_ICMPV6, len);
1406 icmph = (struct icmp6hdr *)skb_put(buff, len);
1407 buff->h.raw = (unsigned char*)icmph;
1409 memset(icmph, 0, sizeof(struct icmp6hdr));
1410 icmph->icmp6_type = NDISC_REDIRECT;
1413 * copy target and destination addresses
1416 addrp = (struct in6_addr *)(icmph + 1);
1417 ipv6_addr_copy(addrp, target);
1418 addrp++;
1419 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1421 opt = (u8*) (addrp + 1);
1424 * include target_address option
1427 if (ha)
1428 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1429 dev->addr_len, dev->type);
1432 * build redirect option and copy skb over to the new packet.
1435 memset(opt, 0, 8);
1436 *(opt++) = ND_OPT_REDIRECT_HDR;
1437 *(opt++) = (rd_len >> 3);
1438 opt += 6;
1440 memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1442 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1443 len, IPPROTO_ICMPV6,
1444 csum_partial((u8 *) icmph, len, 0));
1446 buff->dst = dst;
1447 idev = in6_dev_get(dst->dev);
1448 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1449 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1450 if (!err) {
1451 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1452 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1455 if (likely(idev != NULL))
1456 in6_dev_put(idev);
1459 static void pndisc_redo(struct sk_buff *skb)
1461 ndisc_rcv(skb);
1462 kfree_skb(skb);
1465 int ndisc_rcv(struct sk_buff *skb)
1467 struct nd_msg *msg;
1469 if (!pskb_may_pull(skb, skb->len))
1470 return 0;
1472 msg = (struct nd_msg *) skb->h.raw;
1474 __skb_push(skb, skb->data-skb->h.raw);
1476 if (skb->nh.ipv6h->hop_limit != 255) {
1477 ND_PRINTK2(KERN_WARNING
1478 "ICMPv6 NDISC: invalid hop-limit: %d\n",
1479 skb->nh.ipv6h->hop_limit);
1480 return 0;
1483 if (msg->icmph.icmp6_code != 0) {
1484 ND_PRINTK2(KERN_WARNING
1485 "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1486 msg->icmph.icmp6_code);
1487 return 0;
1490 switch (msg->icmph.icmp6_type) {
1491 case NDISC_NEIGHBOUR_SOLICITATION:
1492 ndisc_recv_ns(skb);
1493 break;
1495 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1496 ndisc_recv_na(skb);
1497 break;
1499 case NDISC_ROUTER_SOLICITATION:
1500 ndisc_recv_rs(skb);
1501 break;
1503 case NDISC_ROUTER_ADVERTISEMENT:
1504 ndisc_router_discovery(skb);
1505 break;
1507 case NDISC_REDIRECT:
1508 ndisc_redirect_rcv(skb);
1509 break;
1512 return 0;
1515 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1517 struct net_device *dev = ptr;
1519 switch (event) {
1520 case NETDEV_CHANGEADDR:
1521 neigh_changeaddr(&nd_tbl, dev);
1522 fib6_run_gc(~0UL);
1523 break;
1524 case NETDEV_DOWN:
1525 neigh_ifdown(&nd_tbl, dev);
1526 fib6_run_gc(~0UL);
1527 break;
1528 default:
1529 break;
1532 return NOTIFY_DONE;
1535 static struct notifier_block ndisc_netdev_notifier = {
1536 .notifier_call = ndisc_netdev_event,
1539 #ifdef CONFIG_SYSCTL
1540 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1541 const char *func, const char *dev_name)
1543 static char warncomm[TASK_COMM_LEN];
1544 static int warned;
1545 if (strcmp(warncomm, current->comm) && warned < 5) {
1546 strcpy(warncomm, current->comm);
1547 printk(KERN_WARNING
1548 "process `%s' is using deprecated sysctl (%s) "
1549 "net.ipv6.neigh.%s.%s; "
1550 "Use net.ipv6.neigh.%s.%s_ms "
1551 "instead.\n",
1552 warncomm, func,
1553 dev_name, ctl->procname,
1554 dev_name, ctl->procname);
1555 warned++;
1559 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1561 struct net_device *dev = ctl->extra1;
1562 struct inet6_dev *idev;
1563 int ret;
1565 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1566 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1567 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1569 switch (ctl->ctl_name) {
1570 case NET_NEIGH_RETRANS_TIME:
1571 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1572 break;
1573 case NET_NEIGH_REACHABLE_TIME:
1574 ret = proc_dointvec_jiffies(ctl, write,
1575 filp, buffer, lenp, ppos);
1576 break;
1577 case NET_NEIGH_RETRANS_TIME_MS:
1578 case NET_NEIGH_REACHABLE_TIME_MS:
1579 ret = proc_dointvec_ms_jiffies(ctl, write,
1580 filp, buffer, lenp, ppos);
1581 break;
1582 default:
1583 ret = -1;
1586 if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1587 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1588 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1589 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1590 idev->tstamp = jiffies;
1591 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1592 in6_dev_put(idev);
1594 return ret;
1597 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1598 int nlen, void __user *oldval,
1599 size_t __user *oldlenp,
1600 void __user *newval, size_t newlen,
1601 void **context)
1603 struct net_device *dev = ctl->extra1;
1604 struct inet6_dev *idev;
1605 int ret;
1607 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1608 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1609 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1611 switch (ctl->ctl_name) {
1612 case NET_NEIGH_REACHABLE_TIME:
1613 ret = sysctl_jiffies(ctl, name, nlen,
1614 oldval, oldlenp, newval, newlen,
1615 context);
1616 break;
1617 case NET_NEIGH_RETRANS_TIME_MS:
1618 case NET_NEIGH_REACHABLE_TIME_MS:
1619 ret = sysctl_ms_jiffies(ctl, name, nlen,
1620 oldval, oldlenp, newval, newlen,
1621 context);
1622 break;
1623 default:
1624 ret = 0;
1627 if (newval && newlen && ret > 0 &&
1628 dev && (idev = in6_dev_get(dev)) != NULL) {
1629 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1630 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1631 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1632 idev->tstamp = jiffies;
1633 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1634 in6_dev_put(idev);
1637 return ret;
1640 #endif
1642 int __init ndisc_init(struct net_proto_family *ops)
1644 struct ipv6_pinfo *np;
1645 struct sock *sk;
1646 int err;
1648 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1649 if (err < 0) {
1650 ND_PRINTK0(KERN_ERR
1651 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1652 err);
1653 ndisc_socket = NULL; /* For safety. */
1654 return err;
1657 sk = ndisc_socket->sk;
1658 np = inet6_sk(sk);
1659 sk->sk_allocation = GFP_ATOMIC;
1660 np->hop_limit = 255;
1661 /* Do not loopback ndisc messages */
1662 np->mc_loop = 0;
1663 sk->sk_prot->unhash(sk);
1666 * Initialize the neighbour table
1669 neigh_table_init(&nd_tbl);
1671 #ifdef CONFIG_SYSCTL
1672 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH,
1673 "ipv6",
1674 &ndisc_ifinfo_sysctl_change,
1675 &ndisc_ifinfo_sysctl_strategy);
1676 #endif
1678 register_netdevice_notifier(&ndisc_netdev_notifier);
1679 return 0;
1682 void ndisc_cleanup(void)
1684 #ifdef CONFIG_SYSCTL
1685 neigh_sysctl_unregister(&nd_tbl.parms);
1686 #endif
1687 neigh_table_clear(&nd_tbl);
1688 sock_release(ndisc_socket);
1689 ndisc_socket = NULL; /* For safety. */