2 * Neighbour Discovery for IPv6
3 * Linux INET6 implementation
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.
18 * Lars Fenneberg : fixed MTU setting on receipt
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... */
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
39 #define ND_PRINTK1 ND_PRINTK
43 #define ND_PRINTK2 ND_PRINTK
47 #define ND_PRINTK3 ND_PRINTK
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/types.h>
53 #include <linux/socket.h>
54 #include <linux/sockios.h>
55 #include <linux/sched.h>
56 #include <linux/net.h>
57 #include <linux/in6.h>
58 #include <linux/route.h>
59 #include <linux/init.h>
60 #include <linux/rcupdate.h>
62 #include <linux/sysctl.h>
65 #include <linux/if_addr.h>
66 #include <linux/if_arp.h>
67 #include <linux/ipv6.h>
68 #include <linux/icmpv6.h>
69 #include <linux/jhash.h>
75 #include <net/protocol.h>
76 #include <net/ndisc.h>
77 #include <net/ip6_route.h>
78 #include <net/addrconf.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 = {
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 = {
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 = {
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 = {
129 .entry_size = sizeof(struct neighbour) + sizeof(struct in6_addr),
130 .key_len = sizeof(struct in6_addr),
132 .constructor = ndisc_constructor,
133 .pconstructor = pndisc_constructor,
134 .pdestructor = pndisc_destructor,
135 .proxy_redo = pndisc_redo,
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,
147 .anycast_delay = 1 * HZ,
148 .proxy_delay = (8 * HZ) / 10,
151 .gc_interval = 30 * HZ,
158 struct ndisc_options {
159 struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
160 #ifdef CONFIG_IPV6_ROUTE_INFO
161 struct nd_opt_hdr *nd_opts_ri;
162 struct nd_opt_hdr *nd_opts_ri_end;
166 #define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
167 #define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
168 #define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
169 #define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
170 #define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
171 #define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
173 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
176 * Return the padding between the option length and the start of the
177 * link addr. Currently only IP-over-InfiniBand needs this, although
178 * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
179 * also need a pad of 2.
181 static int ndisc_addr_option_pad(unsigned short type)
184 case ARPHRD_INFINIBAND: return 2;
189 static inline int ndisc_opt_addr_space(struct net_device *dev)
191 return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
194 static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
195 unsigned short addr_type)
197 int space = NDISC_OPT_SPACE(data_len);
198 int pad = ndisc_addr_option_pad(addr_type);
203 memset(opt + 2, 0, pad);
207 memcpy(opt+2, data, data_len);
210 if ((space -= data_len) > 0)
211 memset(opt, 0, space);
215 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
216 struct nd_opt_hdr *end)
219 if (!cur || !end || cur >= end)
221 type = cur->nd_opt_type;
223 cur = ((void *)cur) + (cur->nd_opt_len << 3);
224 } while(cur < end && cur->nd_opt_type != type);
225 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
228 static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
229 struct ndisc_options *ndopts)
231 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
233 if (!nd_opt || opt_len < 0 || !ndopts)
235 memset(ndopts, 0, sizeof(*ndopts));
238 if (opt_len < sizeof(struct nd_opt_hdr))
240 l = nd_opt->nd_opt_len << 3;
241 if (opt_len < l || l == 0)
243 switch (nd_opt->nd_opt_type) {
244 case ND_OPT_SOURCE_LL_ADDR:
245 case ND_OPT_TARGET_LL_ADDR:
247 case ND_OPT_REDIRECT_HDR:
248 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
249 ND_PRINTK2(KERN_WARNING
250 "%s(): duplicated ND6 option found: type=%d\n",
252 nd_opt->nd_opt_type);
254 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
257 case ND_OPT_PREFIX_INFO:
258 ndopts->nd_opts_pi_end = nd_opt;
259 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
260 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
262 #ifdef CONFIG_IPV6_ROUTE_INFO
263 case ND_OPT_ROUTE_INFO:
264 ndopts->nd_opts_ri_end = nd_opt;
265 if (!ndopts->nd_opts_ri)
266 ndopts->nd_opts_ri = nd_opt;
271 * Unknown options must be silently ignored,
272 * to accommodate future extension to the protocol.
274 ND_PRINTK2(KERN_NOTICE
275 "%s(): ignored unsupported option; type=%d, len=%d\n",
277 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
280 nd_opt = ((void *)nd_opt) + l;
285 static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
286 struct net_device *dev)
288 u8 *lladdr = (u8 *)(p + 1);
289 int lladdrlen = p->nd_opt_len << 3;
290 int prepad = ndisc_addr_option_pad(dev->type);
291 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
293 return (lladdr + prepad);
296 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
300 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
302 ipv6_eth_mc_map(addr, buf);
304 case ARPHRD_IEEE802_TR:
305 ipv6_tr_mc_map(addr,buf);
308 ipv6_arcnet_mc_map(addr, buf);
310 case ARPHRD_INFINIBAND:
311 ipv6_ib_mc_map(addr, buf);
315 memcpy(buf, dev->broadcast, dev->addr_len);
322 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
324 const u32 *p32 = pkey;
328 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
331 return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
334 static int ndisc_constructor(struct neighbour *neigh)
336 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
337 struct net_device *dev = neigh->dev;
338 struct inet6_dev *in6_dev;
339 struct neigh_parms *parms;
340 int is_multicast = ipv6_addr_is_multicast(addr);
343 in6_dev = in6_dev_get(dev);
344 if (in6_dev == NULL) {
349 parms = in6_dev->nd_parms;
350 __neigh_parms_put(neigh->parms);
351 neigh->parms = neigh_parms_clone(parms);
354 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
355 if (dev->hard_header == NULL) {
356 neigh->nud_state = NUD_NOARP;
357 neigh->ops = &ndisc_direct_ops;
358 neigh->output = neigh->ops->queue_xmit;
361 neigh->nud_state = NUD_NOARP;
362 ndisc_mc_map(addr, neigh->ha, dev, 1);
363 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
364 neigh->nud_state = NUD_NOARP;
365 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
366 if (dev->flags&IFF_LOOPBACK)
367 neigh->type = RTN_LOCAL;
368 } else if (dev->flags&IFF_POINTOPOINT) {
369 neigh->nud_state = NUD_NOARP;
370 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
372 if (dev->hard_header_cache)
373 neigh->ops = &ndisc_hh_ops;
375 neigh->ops = &ndisc_generic_ops;
376 if (neigh->nud_state&NUD_VALID)
377 neigh->output = neigh->ops->connected_output;
379 neigh->output = neigh->ops->output;
381 in6_dev_put(in6_dev);
385 static int pndisc_constructor(struct pneigh_entry *n)
387 struct in6_addr *addr = (struct in6_addr*)&n->key;
388 struct in6_addr maddr;
389 struct net_device *dev = n->dev;
391 if (dev == NULL || __in6_dev_get(dev) == NULL)
393 addrconf_addr_solict_mult(addr, &maddr);
394 ipv6_dev_mc_inc(dev, &maddr);
398 static void pndisc_destructor(struct pneigh_entry *n)
400 struct in6_addr *addr = (struct in6_addr*)&n->key;
401 struct in6_addr maddr;
402 struct net_device *dev = n->dev;
404 if (dev == NULL || __in6_dev_get(dev) == NULL)
406 addrconf_addr_solict_mult(addr, &maddr);
407 ipv6_dev_mc_dec(dev, &maddr);
411 * Send a Neighbour Advertisement
414 static inline void ndisc_flow_init(struct flowi *fl, u8 type,
415 struct in6_addr *saddr, struct in6_addr *daddr)
417 memset(fl, 0, sizeof(*fl));
418 ipv6_addr_copy(&fl->fl6_src, saddr);
419 ipv6_addr_copy(&fl->fl6_dst, daddr);
420 fl->proto = IPPROTO_ICMPV6;
421 fl->fl_icmp_type = type;
422 fl->fl_icmp_code = 0;
423 security_sk_classify_flow(ndisc_socket->sk, fl);
426 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
427 struct in6_addr *daddr, struct in6_addr *solicited_addr,
428 int router, int solicited, int override, int inc_opt)
430 struct in6_addr tmpaddr;
431 struct inet6_ifaddr *ifp;
432 struct inet6_dev *idev;
434 struct dst_entry* dst;
435 struct sock *sk = ndisc_socket->sk;
436 struct in6_addr *src_addr;
442 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
444 /* for anycast or proxy, solicited_addr != src_addr */
445 ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
447 src_addr = solicited_addr;
450 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
455 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
457 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
461 err = xfrm_lookup(&dst, &fl, NULL, 0);
467 len += ndisc_opt_addr_space(dev);
472 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
477 "ICMPv6 NA: %s() failed to allocate an skb.\n",
483 skb_reserve(skb, LL_RESERVED_SPACE(dev));
484 ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
486 msg = (struct nd_msg *)skb_put(skb, len);
487 skb->h.raw = (unsigned char*)msg;
489 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
490 msg->icmph.icmp6_code = 0;
491 msg->icmph.icmp6_cksum = 0;
493 msg->icmph.icmp6_unused = 0;
494 msg->icmph.icmp6_router = router;
495 msg->icmph.icmp6_solicited = solicited;
496 msg->icmph.icmp6_override = !!override;
498 /* Set the target address. */
499 ipv6_addr_copy(&msg->target, solicited_addr);
502 ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
503 dev->addr_len, dev->type);
506 msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len,
508 csum_partial((__u8 *) msg,
512 idev = in6_dev_get(dst->dev);
513 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
514 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
516 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
517 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
520 if (likely(idev != NULL))
524 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
525 struct in6_addr *solicit,
526 struct in6_addr *daddr, struct in6_addr *saddr)
529 struct dst_entry* dst;
530 struct inet6_dev *idev;
531 struct sock *sk = ndisc_socket->sk;
534 struct in6_addr addr_buf;
540 if (ipv6_get_lladdr(dev, &addr_buf))
545 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
547 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
551 err = xfrm_lookup(&dst, &fl, NULL, 0);
555 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
556 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
558 len += ndisc_opt_addr_space(dev);
560 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
564 "ICMPv6 NA: %s() failed to allocate an skb.\n",
570 skb_reserve(skb, LL_RESERVED_SPACE(dev));
571 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
573 msg = (struct nd_msg *)skb_put(skb, len);
574 skb->h.raw = (unsigned char*)msg;
575 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
576 msg->icmph.icmp6_code = 0;
577 msg->icmph.icmp6_cksum = 0;
578 msg->icmph.icmp6_unused = 0;
580 /* Set the target address. */
581 ipv6_addr_copy(&msg->target, solicit);
584 ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
585 dev->addr_len, dev->type);
588 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
591 csum_partial((__u8 *) msg,
595 idev = in6_dev_get(dst->dev);
596 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
597 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
599 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
600 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
603 if (likely(idev != NULL))
607 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
608 struct in6_addr *daddr)
611 struct dst_entry* dst;
612 struct inet6_dev *idev;
613 struct sock *sk = ndisc_socket->sk;
615 struct icmp6hdr *hdr;
620 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
622 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
626 err = xfrm_lookup(&dst, &fl, NULL, 0);
630 len = sizeof(struct icmp6hdr);
632 len += ndisc_opt_addr_space(dev);
634 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
638 "ICMPv6 RS: %s() failed to allocate an skb.\n",
644 skb_reserve(skb, LL_RESERVED_SPACE(dev));
645 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
647 hdr = (struct icmp6hdr *)skb_put(skb, len);
648 skb->h.raw = (unsigned char*)hdr;
649 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
651 hdr->icmp6_cksum = 0;
652 hdr->icmp6_unused = 0;
654 opt = (u8*) (hdr + 1);
657 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
658 dev->addr_len, dev->type);
661 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
663 csum_partial((__u8 *) hdr, len, 0));
667 idev = in6_dev_get(dst->dev);
668 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
669 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
671 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
672 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
675 if (likely(idev != NULL))
680 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
683 * "The sender MUST return an ICMP
684 * destination unreachable"
686 dst_link_failure(skb);
690 /* Called with locked neigh: either read or both */
692 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
694 struct in6_addr *saddr = NULL;
695 struct in6_addr mcaddr;
696 struct net_device *dev = neigh->dev;
697 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
698 int probes = atomic_read(&neigh->probes);
700 if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
701 saddr = &skb->nh.ipv6h->saddr;
703 if ((probes -= neigh->parms->ucast_probes) < 0) {
704 if (!(neigh->nud_state & NUD_VALID)) {
705 ND_PRINTK1(KERN_DEBUG
706 "%s(): trying to ucast probe in NUD_INVALID: "
711 ndisc_send_ns(dev, neigh, target, target, saddr);
712 } else if ((probes -= neigh->parms->app_probes) < 0) {
717 addrconf_addr_solict_mult(target, &mcaddr);
718 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
722 static void ndisc_recv_ns(struct sk_buff *skb)
724 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
725 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
726 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
728 u32 ndoptlen = skb->tail - msg->opt;
729 struct ndisc_options ndopts;
730 struct net_device *dev = skb->dev;
731 struct inet6_ifaddr *ifp;
732 struct inet6_dev *idev = NULL;
733 struct neighbour *neigh;
734 int dad = ipv6_addr_any(saddr);
737 if (ipv6_addr_is_multicast(&msg->target)) {
738 ND_PRINTK2(KERN_WARNING
739 "ICMPv6 NS: multicast target address");
745 * DAD has to be destined for solicited node multicast address.
748 !(daddr->s6_addr32[0] == htonl(0xff020000) &&
749 daddr->s6_addr32[1] == htonl(0x00000000) &&
750 daddr->s6_addr32[2] == htonl(0x00000001) &&
751 daddr->s6_addr [12] == 0xff )) {
752 ND_PRINTK2(KERN_WARNING
753 "ICMPv6 NS: bad DAD packet (wrong destination)\n");
757 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
758 ND_PRINTK2(KERN_WARNING
759 "ICMPv6 NS: invalid ND options\n");
763 if (ndopts.nd_opts_src_lladdr) {
764 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
766 ND_PRINTK2(KERN_WARNING
767 "ICMPv6 NS: invalid link-layer address length\n");
772 * If the IP source address is the unspecified address,
773 * there MUST NOT be source link-layer address option
777 ND_PRINTK2(KERN_WARNING
778 "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
783 inc = ipv6_addr_is_multicast(daddr);
785 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
786 if (ifp->flags & IFA_F_TENTATIVE) {
787 /* Address is tentative. If the source
788 is unspecified address, it is someone
789 does DAD, otherwise we ignore solicitations
790 until DAD timer expires.
794 if (dev->type == ARPHRD_IEEE802_TR) {
795 unsigned char *sadr = skb->mac.raw;
796 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
797 sadr[9] == dev->dev_addr[1] &&
798 sadr[10] == dev->dev_addr[2] &&
799 sadr[11] == dev->dev_addr[3] &&
800 sadr[12] == dev->dev_addr[4] &&
801 sadr[13] == dev->dev_addr[5]) {
802 /* looped-back to us */
806 addrconf_dad_failure(ifp);
812 idev = in6_dev_get(dev);
814 /* XXX: count this drop? */
818 if (ipv6_chk_acast_addr(dev, &msg->target) ||
819 (idev->cnf.forwarding &&
820 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
821 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
822 skb->pkt_type != PACKET_HOST &&
824 idev->nd_parms->proxy_delay != 0) {
826 * for anycast or proxy,
827 * sender should delay its response
828 * by a random time between 0 and
829 * MAX_ANYCAST_DELAY_TIME seconds.
830 * (RFC2461) -- yoshfuji
832 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
834 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
842 struct in6_addr maddr;
844 ipv6_addr_all_nodes(&maddr);
845 ndisc_send_na(dev, NULL, &maddr, &msg->target,
846 idev->cnf.forwarding, 0, (ifp != NULL), 1);
851 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
853 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
856 * update / create cache entry
857 * for the source address
859 neigh = __neigh_lookup(&nd_tbl, saddr, dev,
860 !inc || lladdr || !dev->addr_len);
862 neigh_update(neigh, lladdr, NUD_STALE,
863 NEIGH_UPDATE_F_WEAK_OVERRIDE|
864 NEIGH_UPDATE_F_OVERRIDE);
865 if (neigh || !dev->hard_header) {
866 ndisc_send_na(dev, neigh, saddr, &msg->target,
867 idev->cnf.forwarding,
868 1, (ifp != NULL && inc), inc);
870 neigh_release(neigh);
882 static void ndisc_recv_na(struct sk_buff *skb)
884 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
885 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
886 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
888 u32 ndoptlen = skb->tail - msg->opt;
889 struct ndisc_options ndopts;
890 struct net_device *dev = skb->dev;
891 struct inet6_ifaddr *ifp;
892 struct neighbour *neigh;
894 if (skb->len < sizeof(struct nd_msg)) {
895 ND_PRINTK2(KERN_WARNING
896 "ICMPv6 NA: packet too short\n");
900 if (ipv6_addr_is_multicast(&msg->target)) {
901 ND_PRINTK2(KERN_WARNING
902 "ICMPv6 NA: target address is multicast.\n");
906 if (ipv6_addr_is_multicast(daddr) &&
907 msg->icmph.icmp6_solicited) {
908 ND_PRINTK2(KERN_WARNING
909 "ICMPv6 NA: solicited NA is multicasted.\n");
913 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
914 ND_PRINTK2(KERN_WARNING
915 "ICMPv6 NS: invalid ND option\n");
918 if (ndopts.nd_opts_tgt_lladdr) {
919 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
921 ND_PRINTK2(KERN_WARNING
922 "ICMPv6 NA: invalid link-layer address length\n");
926 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
927 if (ifp->flags & IFA_F_TENTATIVE) {
928 addrconf_dad_failure(ifp);
931 /* What should we make now? The advertisement
932 is invalid, but ndisc specs say nothing
933 about it. It could be misconfiguration, or
934 an smart proxy agent tries to help us :-)
936 ND_PRINTK1(KERN_WARNING
937 "ICMPv6 NA: someone advertises our address on %s!\n",
938 ifp->idev->dev->name);
942 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
945 u8 old_flags = neigh->flags;
947 if (neigh->nud_state & NUD_FAILED)
950 neigh_update(neigh, lladdr,
951 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
952 NEIGH_UPDATE_F_WEAK_OVERRIDE|
953 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
954 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
955 (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
957 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
959 * Change: router to host
962 rt = rt6_get_dflt_router(saddr, dev);
968 neigh_release(neigh);
972 static void ndisc_recv_rs(struct sk_buff *skb)
974 struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
975 unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
976 struct neighbour *neigh;
977 struct inet6_dev *idev;
978 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
979 struct ndisc_options ndopts;
982 if (skb->len < sizeof(*rs_msg))
985 idev = in6_dev_get(skb->dev);
988 ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
992 /* Don't accept RS if we're not in router mode */
993 if (!idev->cnf.forwarding)
997 * Don't update NCE if src = ::;
998 * this implies that the source node has no ip address assigned yet.
1000 if (ipv6_addr_any(saddr))
1003 /* Parse ND options */
1004 if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
1005 if (net_ratelimit())
1006 ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
1010 if (ndopts.nd_opts_src_lladdr) {
1011 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1017 neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1019 neigh_update(neigh, lladdr, NUD_STALE,
1020 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1021 NEIGH_UPDATE_F_OVERRIDE|
1022 NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1023 neigh_release(neigh);
1029 static void ndisc_router_discovery(struct sk_buff *skb)
1031 struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
1032 struct neighbour *neigh = NULL;
1033 struct inet6_dev *in6_dev;
1034 struct rt6_info *rt = NULL;
1036 struct ndisc_options ndopts;
1038 unsigned int pref = 0;
1040 __u8 * opt = (__u8 *)(ra_msg + 1);
1042 optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
1044 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1045 ND_PRINTK2(KERN_WARNING
1046 "ICMPv6 RA: source address is not link-local.\n");
1050 ND_PRINTK2(KERN_WARNING
1051 "ICMPv6 RA: packet too short\n");
1056 * set the RA_RECV flag in the interface
1059 in6_dev = in6_dev_get(skb->dev);
1060 if (in6_dev == NULL) {
1062 "ICMPv6 RA: can't find inet6 device for %s.\n",
1066 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1067 in6_dev_put(in6_dev);
1071 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1072 in6_dev_put(in6_dev);
1073 ND_PRINTK2(KERN_WARNING
1074 "ICMP6 RA: invalid ND options\n");
1078 if (in6_dev->if_flags & IF_RS_SENT) {
1080 * flag that an RA was received after an RS was sent
1081 * out on this interface.
1083 in6_dev->if_flags |= IF_RA_RCVD;
1087 * Remember the managed/otherconf flags from most recently
1088 * received RA message (RFC 2462) -- yoshfuji
1090 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1092 (ra_msg->icmph.icmp6_addrconf_managed ?
1093 IF_RA_MANAGED : 0) |
1094 (ra_msg->icmph.icmp6_addrconf_other ?
1095 IF_RA_OTHERCONF : 0);
1097 if (!in6_dev->cnf.accept_ra_defrtr)
1100 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1102 #ifdef CONFIG_IPV6_ROUTER_PREF
1103 pref = ra_msg->icmph.icmp6_router_pref;
1104 /* 10b is handled as if it were 00b (medium) */
1105 if (pref == ICMPV6_ROUTER_PREF_INVALID ||
1106 in6_dev->cnf.accept_ra_rtr_pref)
1107 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1110 rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1113 neigh = rt->rt6i_nexthop;
1115 if (rt && lifetime == 0) {
1121 if (rt == NULL && lifetime) {
1122 ND_PRINTK3(KERN_DEBUG
1123 "ICMPv6 RA: adding default router.\n");
1125 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
1128 "ICMPv6 RA: %s() failed to add default route.\n",
1130 in6_dev_put(in6_dev);
1134 neigh = rt->rt6i_nexthop;
1135 if (neigh == NULL) {
1137 "ICMPv6 RA: %s() got default router without neighbour.\n",
1139 dst_release(&rt->u.dst);
1140 in6_dev_put(in6_dev);
1143 neigh->flags |= NTF_ROUTER;
1145 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1149 rt->rt6i_expires = jiffies + (HZ * lifetime);
1151 if (ra_msg->icmph.icmp6_hop_limit) {
1152 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1154 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1160 * Update Reachable Time and Retrans Timer
1163 if (in6_dev->nd_parms) {
1164 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1166 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1167 rtime = (rtime*HZ)/1000;
1170 in6_dev->nd_parms->retrans_time = rtime;
1171 in6_dev->tstamp = jiffies;
1172 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1175 rtime = ntohl(ra_msg->reachable_time);
1176 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1177 rtime = (rtime*HZ)/1000;
1182 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1183 in6_dev->nd_parms->base_reachable_time = rtime;
1184 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1185 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1186 in6_dev->tstamp = jiffies;
1187 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1197 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1201 if (ndopts.nd_opts_src_lladdr) {
1202 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1205 ND_PRINTK2(KERN_WARNING
1206 "ICMPv6 RA: invalid link-layer address length\n");
1210 neigh_update(neigh, lladdr, NUD_STALE,
1211 NEIGH_UPDATE_F_WEAK_OVERRIDE|
1212 NEIGH_UPDATE_F_OVERRIDE|
1213 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1214 NEIGH_UPDATE_F_ISROUTER);
1217 #ifdef CONFIG_IPV6_ROUTE_INFO
1218 if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1219 struct nd_opt_hdr *p;
1220 for (p = ndopts.nd_opts_ri;
1222 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1223 if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1225 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
1226 &skb->nh.ipv6h->saddr);
1231 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1232 struct nd_opt_hdr *p;
1233 for (p = ndopts.nd_opts_pi;
1235 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1236 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1240 if (ndopts.nd_opts_mtu) {
1243 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1246 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1247 ND_PRINTK2(KERN_WARNING
1248 "ICMPv6 RA: invalid mtu: %d\n",
1250 } else if (in6_dev->cnf.mtu6 != mtu) {
1251 in6_dev->cnf.mtu6 = mtu;
1254 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1256 rt6_mtu_change(skb->dev, mtu);
1260 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1261 ND_PRINTK2(KERN_WARNING
1262 "ICMPv6 RA: invalid RA options");
1266 dst_release(&rt->u.dst);
1268 neigh_release(neigh);
1269 in6_dev_put(in6_dev);
1272 static void ndisc_redirect_rcv(struct sk_buff *skb)
1274 struct inet6_dev *in6_dev;
1275 struct icmp6hdr *icmph;
1276 struct in6_addr *dest;
1277 struct in6_addr *target; /* new first hop to destination */
1278 struct neighbour *neigh;
1280 struct ndisc_options ndopts;
1284 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1285 ND_PRINTK2(KERN_WARNING
1286 "ICMPv6 Redirect: source address is not link-local.\n");
1290 optlen = skb->tail - skb->h.raw;
1291 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1294 ND_PRINTK2(KERN_WARNING
1295 "ICMPv6 Redirect: packet too short\n");
1299 icmph = (struct icmp6hdr *) skb->h.raw;
1300 target = (struct in6_addr *) (icmph + 1);
1303 if (ipv6_addr_is_multicast(dest)) {
1304 ND_PRINTK2(KERN_WARNING
1305 "ICMPv6 Redirect: destination address is multicast.\n");
1309 if (ipv6_addr_equal(dest, target)) {
1311 } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1312 ND_PRINTK2(KERN_WARNING
1313 "ICMPv6 Redirect: target address is not link-local.\n");
1317 in6_dev = in6_dev_get(skb->dev);
1320 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1321 in6_dev_put(in6_dev);
1326 * The IP source address of the Redirect MUST be the same as the current
1327 * first-hop router for the specified ICMP Destination Address.
1330 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1331 ND_PRINTK2(KERN_WARNING
1332 "ICMPv6 Redirect: invalid ND options\n");
1333 in6_dev_put(in6_dev);
1336 if (ndopts.nd_opts_tgt_lladdr) {
1337 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1340 ND_PRINTK2(KERN_WARNING
1341 "ICMPv6 Redirect: invalid link-layer address length\n");
1342 in6_dev_put(in6_dev);
1347 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1349 rt6_redirect(dest, &skb->nh.ipv6h->daddr,
1350 &skb->nh.ipv6h->saddr, neigh, lladdr,
1352 neigh_release(neigh);
1354 in6_dev_put(in6_dev);
1357 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1358 struct in6_addr *target)
1360 struct sock *sk = ndisc_socket->sk;
1361 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1362 struct sk_buff *buff;
1363 struct icmp6hdr *icmph;
1364 struct in6_addr saddr_buf;
1365 struct in6_addr *addrp;
1366 struct net_device *dev;
1367 struct rt6_info *rt;
1368 struct dst_entry *dst;
1369 struct inet6_dev *idev;
1375 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1379 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1380 ND_PRINTK2(KERN_WARNING
1381 "ICMPv6 Redirect: no link-local address on %s\n",
1386 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1388 dst = ip6_route_output(NULL, &fl);
1392 err = xfrm_lookup(&dst, &fl, NULL, 0);
1396 rt = (struct rt6_info *) dst;
1398 if (rt->rt6i_flags & RTF_GATEWAY) {
1399 ND_PRINTK2(KERN_WARNING
1400 "ICMPv6 Redirect: destination is not a neighbour.\n");
1404 if (!xrlim_allow(dst, 1*HZ)) {
1409 if (dev->addr_len) {
1410 read_lock_bh(&neigh->lock);
1411 if (neigh->nud_state & NUD_VALID) {
1412 memcpy(ha_buf, neigh->ha, dev->addr_len);
1413 read_unlock_bh(&neigh->lock);
1415 len += ndisc_opt_addr_space(dev);
1417 read_unlock_bh(&neigh->lock);
1420 rd_len = min_t(unsigned int,
1421 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1425 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1429 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1437 skb_reserve(buff, LL_RESERVED_SPACE(dev));
1438 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1439 IPPROTO_ICMPV6, len);
1441 icmph = (struct icmp6hdr *)skb_put(buff, len);
1442 buff->h.raw = (unsigned char*)icmph;
1444 memset(icmph, 0, sizeof(struct icmp6hdr));
1445 icmph->icmp6_type = NDISC_REDIRECT;
1448 * copy target and destination addresses
1451 addrp = (struct in6_addr *)(icmph + 1);
1452 ipv6_addr_copy(addrp, target);
1454 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1456 opt = (u8*) (addrp + 1);
1459 * include target_address option
1463 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1464 dev->addr_len, dev->type);
1467 * build redirect option and copy skb over to the new packet.
1471 *(opt++) = ND_OPT_REDIRECT_HDR;
1472 *(opt++) = (rd_len >> 3);
1475 memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1477 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1478 len, IPPROTO_ICMPV6,
1479 csum_partial((u8 *) icmph, len, 0));
1482 idev = in6_dev_get(dst->dev);
1483 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1484 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1486 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1487 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1490 if (likely(idev != NULL))
1494 static void pndisc_redo(struct sk_buff *skb)
1500 int ndisc_rcv(struct sk_buff *skb)
1504 if (!pskb_may_pull(skb, skb->len))
1507 msg = (struct nd_msg *) skb->h.raw;
1509 __skb_push(skb, skb->data-skb->h.raw);
1511 if (skb->nh.ipv6h->hop_limit != 255) {
1512 ND_PRINTK2(KERN_WARNING
1513 "ICMPv6 NDISC: invalid hop-limit: %d\n",
1514 skb->nh.ipv6h->hop_limit);
1518 if (msg->icmph.icmp6_code != 0) {
1519 ND_PRINTK2(KERN_WARNING
1520 "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1521 msg->icmph.icmp6_code);
1525 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1527 switch (msg->icmph.icmp6_type) {
1528 case NDISC_NEIGHBOUR_SOLICITATION:
1532 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1536 case NDISC_ROUTER_SOLICITATION:
1540 case NDISC_ROUTER_ADVERTISEMENT:
1541 ndisc_router_discovery(skb);
1544 case NDISC_REDIRECT:
1545 ndisc_redirect_rcv(skb);
1552 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1554 struct net_device *dev = ptr;
1557 case NETDEV_CHANGEADDR:
1558 neigh_changeaddr(&nd_tbl, dev);
1562 neigh_ifdown(&nd_tbl, dev);
1572 static struct notifier_block ndisc_netdev_notifier = {
1573 .notifier_call = ndisc_netdev_event,
1576 #ifdef CONFIG_SYSCTL
1577 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1578 const char *func, const char *dev_name)
1580 static char warncomm[TASK_COMM_LEN];
1582 if (strcmp(warncomm, current->comm) && warned < 5) {
1583 strcpy(warncomm, current->comm);
1585 "process `%s' is using deprecated sysctl (%s) "
1586 "net.ipv6.neigh.%s.%s; "
1587 "Use net.ipv6.neigh.%s.%s_ms "
1590 dev_name, ctl->procname,
1591 dev_name, ctl->procname);
1596 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1598 struct net_device *dev = ctl->extra1;
1599 struct inet6_dev *idev;
1602 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1603 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1604 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1606 switch (ctl->ctl_name) {
1607 case NET_NEIGH_RETRANS_TIME:
1608 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1610 case NET_NEIGH_REACHABLE_TIME:
1611 ret = proc_dointvec_jiffies(ctl, write,
1612 filp, buffer, lenp, ppos);
1614 case NET_NEIGH_RETRANS_TIME_MS:
1615 case NET_NEIGH_REACHABLE_TIME_MS:
1616 ret = proc_dointvec_ms_jiffies(ctl, write,
1617 filp, buffer, lenp, ppos);
1623 if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1624 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1625 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1626 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1627 idev->tstamp = jiffies;
1628 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1634 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1635 int nlen, void __user *oldval,
1636 size_t __user *oldlenp,
1637 void __user *newval, size_t newlen,
1640 struct net_device *dev = ctl->extra1;
1641 struct inet6_dev *idev;
1644 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1645 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1646 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1648 switch (ctl->ctl_name) {
1649 case NET_NEIGH_REACHABLE_TIME:
1650 ret = sysctl_jiffies(ctl, name, nlen,
1651 oldval, oldlenp, newval, newlen,
1654 case NET_NEIGH_RETRANS_TIME_MS:
1655 case NET_NEIGH_REACHABLE_TIME_MS:
1656 ret = sysctl_ms_jiffies(ctl, name, nlen,
1657 oldval, oldlenp, newval, newlen,
1664 if (newval && newlen && ret > 0 &&
1665 dev && (idev = in6_dev_get(dev)) != NULL) {
1666 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1667 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1668 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1669 idev->tstamp = jiffies;
1670 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1679 int __init ndisc_init(struct net_proto_family *ops)
1681 struct ipv6_pinfo *np;
1685 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1688 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1690 ndisc_socket = NULL; /* For safety. */
1694 sk = ndisc_socket->sk;
1696 sk->sk_allocation = GFP_ATOMIC;
1697 np->hop_limit = 255;
1698 /* Do not loopback ndisc messages */
1700 sk->sk_prot->unhash(sk);
1703 * Initialize the neighbour table
1706 neigh_table_init(&nd_tbl);
1708 #ifdef CONFIG_SYSCTL
1709 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH,
1711 &ndisc_ifinfo_sysctl_change,
1712 &ndisc_ifinfo_sysctl_strategy);
1715 register_netdevice_notifier(&ndisc_netdev_notifier);
1719 void ndisc_cleanup(void)
1721 #ifdef CONFIG_SYSCTL
1722 neigh_sysctl_unregister(&nd_tbl.parms);
1724 neigh_table_clear(&nd_tbl);
1725 sock_release(ndisc_socket);
1726 ndisc_socket = NULL; /* For safety. */