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/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>
63 #include <linux/sysctl.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_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)
180 case ARPHRD_INFINIBAND: return 2;
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);
199 memset(opt + 2, 0, pad);
203 memcpy(opt+2, data, data_len);
206 if ((space -= data_len) > 0)
207 memset(opt, 0, space);
211 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
212 struct nd_opt_hdr *end)
215 if (!cur || !end || cur >= end)
217 type = cur->nd_opt_type;
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)
231 memset(ndopts, 0, sizeof(*ndopts));
234 if (opt_len < sizeof(struct nd_opt_hdr))
236 l = nd_opt->nd_opt_len << 3;
237 if (opt_len < l || l == 0)
239 switch (nd_opt->nd_opt_type) {
240 case ND_OPT_SOURCE_LL_ADDR:
241 case ND_OPT_TARGET_LL_ADDR:
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",
248 nd_opt->nd_opt_type);
250 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
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;
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",
266 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
269 nd_opt = ((void *)nd_opt) + l;
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))
282 return (lladdr + prepad);
285 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
289 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
291 ipv6_eth_mc_map(addr, buf);
293 case ARPHRD_IEEE802_TR:
294 ipv6_tr_mc_map(addr,buf);
297 ipv6_arcnet_mc_map(addr, buf);
299 case ARPHRD_INFINIBAND:
300 ipv6_ib_mc_map(addr, buf);
304 memcpy(buf, dev->broadcast, dev->addr_len);
311 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
313 const u32 *p32 = pkey;
317 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
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);
332 in6_dev = in6_dev_get(dev);
333 if (in6_dev == NULL) {
338 parms = in6_dev->nd_parms;
339 __neigh_parms_put(neigh->parms);
340 neigh->parms = neigh_parms_clone(parms);
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;
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;
364 neigh->ops = &ndisc_generic_ops;
365 if (neigh->nud_state&NUD_VALID)
366 neigh->output = neigh->ops->connected_output;
368 neigh->output = neigh->ops->output;
370 in6_dev_put(in6_dev);
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)
382 addrconf_addr_solict_mult(addr, &maddr);
383 ipv6_dev_mc_inc(dev, &maddr);
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)
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;
422 struct dst_entry* dst;
423 struct sock *sk = ndisc_socket->sk;
424 struct in6_addr *src_addr;
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);
435 src_addr = solicited_addr;
438 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
443 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
445 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
449 err = xfrm_lookup(&dst, &fl, NULL, 0);
457 len += ndisc_opt_addr_space(dev);
462 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
467 "ICMPv6 NA: %s() failed to allocate an skb.\n",
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);
492 ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
493 dev->addr_len, dev->type);
496 msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len,
498 csum_partial((__u8 *) msg,
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);
506 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
507 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
510 if (likely(idev != NULL))
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)
519 struct dst_entry* dst;
520 struct inet6_dev *idev;
521 struct sock *sk = ndisc_socket->sk;
524 struct in6_addr addr_buf;
530 if (ipv6_get_lladdr(dev, &addr_buf))
535 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
537 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
541 err = xfrm_lookup(&dst, &fl, NULL, 0);
547 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
548 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
550 len += ndisc_opt_addr_space(dev);
552 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
556 "ICMPv6 NA: %s() failed to allocate an skb.\n",
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);
576 ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
577 dev->addr_len, dev->type);
580 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
583 csum_partial((__u8 *) msg,
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);
591 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
592 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
595 if (likely(idev != NULL))
599 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
600 struct in6_addr *daddr)
603 struct dst_entry* dst;
604 struct inet6_dev *idev;
605 struct sock *sk = ndisc_socket->sk;
607 struct icmp6hdr *hdr;
612 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
614 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
618 err = xfrm_lookup(&dst, &fl, NULL, 0);
624 len = sizeof(struct icmp6hdr);
626 len += ndisc_opt_addr_space(dev);
628 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
632 "ICMPv6 RS: %s() failed to allocate an skb.\n",
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;
645 hdr->icmp6_cksum = 0;
646 hdr->icmp6_unused = 0;
648 opt = (u8*) (hdr + 1);
651 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
652 dev->addr_len, dev->type);
655 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
657 csum_partial((__u8 *) hdr, len, 0));
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);
665 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
666 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
669 if (likely(idev != NULL))
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);
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",
705 ndisc_send_ns(dev, neigh, target, target, saddr);
706 } else if ((probes -= neigh->parms->app_probes) < 0) {
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;
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);
731 if (ipv6_addr_is_multicast(&msg->target)) {
732 ND_PRINTK2(KERN_WARNING
733 "ICMPv6 NS: multicast target address");
739 * DAD has to be destined for solicited node multicast address.
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");
751 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
752 ND_PRINTK2(KERN_WARNING
753 "ICMPv6 NS: invalid ND options\n");
757 if (ndopts.nd_opts_src_lladdr) {
758 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
760 ND_PRINTK2(KERN_WARNING
761 "ICMPv6 NS: invalid link-layer address length\n");
766 * If the IP source address is the unspecified address,
767 * there MUST NOT be source link-layer address option
771 ND_PRINTK2(KERN_WARNING
772 "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
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.
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 */
800 addrconf_dad_failure(ifp);
806 idev = in6_dev_get(dev);
808 /* XXX: count this drop? */
812 if (ipv6_chk_acast_addr(dev, &msg->target) ||
813 (idev->cnf.forwarding &&
814 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
815 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
816 skb->pkt_type != PACKET_HOST &&
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);
828 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
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);
845 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
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);
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);
864 neigh_release(neigh);
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;
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");
894 if (ipv6_addr_is_multicast(&msg->target)) {
895 ND_PRINTK2(KERN_WARNING
896 "ICMPv6 NA: target address is multicast.\n");
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");
907 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
908 ND_PRINTK2(KERN_WARNING
909 "ICMPv6 NS: invalid ND option\n");
912 if (ndopts.nd_opts_tgt_lladdr) {
913 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
915 ND_PRINTK2(KERN_WARNING
916 "ICMPv6 NA: invalid link-layer address length\n");
920 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
921 if (ifp->flags & IFA_F_TENTATIVE) {
922 addrconf_dad_failure(ifp);
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);
936 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
939 u8 old_flags = neigh->flags;
941 if (neigh->nud_state & NUD_FAILED)
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
956 rt = rt6_get_dflt_router(saddr, dev);
958 ip6_del_rt(rt, NULL, NULL, NULL);
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;
976 if (skb->len < sizeof(*rs_msg))
979 idev = in6_dev_get(skb->dev);
982 ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
986 /* Don't accept RS if we're not in router mode */
987 if (!idev->cnf.forwarding)
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))
997 /* Parse ND options */
998 if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
1000 ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
1004 if (ndopts.nd_opts_src_lladdr) {
1005 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1011 neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
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);
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;
1030 struct ndisc_options ndopts;
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");
1043 ND_PRINTK2(KERN_WARNING
1044 "ICMPv6 RA: packet too short\n");
1049 * set the RA_RECV flag in the interface
1052 in6_dev = in6_dev_get(skb->dev);
1053 if (in6_dev == NULL) {
1055 "ICMPv6 RA: can't find inet6 device for %s.\n",
1059 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1060 in6_dev_put(in6_dev);
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");
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 |
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);
1095 neigh = rt->rt6i_nexthop;
1097 if (rt && lifetime == 0) {
1099 ip6_del_rt(rt, NULL, NULL, 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);
1110 "ICMPv6 RA: %s() failed to add default route.\n",
1112 in6_dev_put(in6_dev);
1116 neigh = rt->rt6i_nexthop;
1117 if (neigh == NULL) {
1119 "ICMPv6 RA: %s() got default router without neighbour.\n",
1121 dst_release(&rt->u.dst);
1122 in6_dev_put(in6_dev);
1125 neigh->flags |= NTF_ROUTER;
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;
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;
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;
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);
1175 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1179 if (ndopts.nd_opts_src_lladdr) {
1180 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1183 ND_PRINTK2(KERN_WARNING
1184 "ICMPv6 RA: invalid link-layer address length\n");
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) {
1207 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1210 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1211 ND_PRINTK2(KERN_WARNING
1212 "ICMPv6 RA: invalid mtu: %d\n",
1214 } else if (in6_dev->cnf.mtu6 != mtu) {
1215 in6_dev->cnf.mtu6 = mtu;
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");
1230 dst_release(&rt->u.dst);
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;
1244 struct ndisc_options ndopts;
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");
1254 optlen = skb->tail - skb->h.raw;
1255 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1258 ND_PRINTK2(KERN_WARNING
1259 "ICMPv6 Redirect: packet too short\n");
1263 icmph = (struct icmp6hdr *) skb->h.raw;
1264 target = (struct in6_addr *) (icmph + 1);
1267 if (ipv6_addr_is_multicast(dest)) {
1268 ND_PRINTK2(KERN_WARNING
1269 "ICMPv6 Redirect: destination address is multicast.\n");
1273 if (ipv6_addr_equal(dest, target)) {
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");
1281 in6_dev = in6_dev_get(skb->dev);
1284 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1285 in6_dev_put(in6_dev);
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);
1300 if (ndopts.nd_opts_tgt_lladdr) {
1301 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1304 ND_PRINTK2(KERN_WARNING
1305 "ICMPv6 Redirect: invalid link-layer address length\n");
1306 in6_dev_put(in6_dev);
1311 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1313 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr,
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;
1338 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1342 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1343 ND_PRINTK2(KERN_WARNING
1344 "ICMPv6 Redirect: no link-local address on %s\n",
1349 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1351 dst = ip6_route_output(NULL, &fl);
1355 err = xfrm_lookup(&dst, &fl, NULL, 0);
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");
1369 if (!xrlim_allow(dst, 1*HZ)) {
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);
1380 len += ndisc_opt_addr_space(dev);
1382 read_unlock_bh(&neigh->lock);
1385 rd_len = min_t(unsigned int,
1386 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1390 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1394 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
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);
1419 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1421 opt = (u8*) (addrp + 1);
1424 * include target_address option
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.
1436 *(opt++) = ND_OPT_REDIRECT_HDR;
1437 *(opt++) = (rd_len >> 3);
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));
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);
1451 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1452 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1455 if (likely(idev != NULL))
1459 static void pndisc_redo(struct sk_buff *skb)
1465 int ndisc_rcv(struct sk_buff *skb)
1469 if (!pskb_may_pull(skb, skb->len))
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);
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);
1490 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1492 switch (msg->icmph.icmp6_type) {
1493 case NDISC_NEIGHBOUR_SOLICITATION:
1497 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1501 case NDISC_ROUTER_SOLICITATION:
1505 case NDISC_ROUTER_ADVERTISEMENT:
1506 ndisc_router_discovery(skb);
1509 case NDISC_REDIRECT:
1510 ndisc_redirect_rcv(skb);
1517 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1519 struct net_device *dev = ptr;
1522 case NETDEV_CHANGEADDR:
1523 neigh_changeaddr(&nd_tbl, dev);
1527 neigh_ifdown(&nd_tbl, dev);
1537 static struct notifier_block ndisc_netdev_notifier = {
1538 .notifier_call = ndisc_netdev_event,
1541 #ifdef CONFIG_SYSCTL
1542 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1543 const char *func, const char *dev_name)
1545 static char warncomm[TASK_COMM_LEN];
1547 if (strcmp(warncomm, current->comm) && warned < 5) {
1548 strcpy(warncomm, current->comm);
1550 "process `%s' is using deprecated sysctl (%s) "
1551 "net.ipv6.neigh.%s.%s; "
1552 "Use net.ipv6.neigh.%s.%s_ms "
1555 dev_name, ctl->procname,
1556 dev_name, ctl->procname);
1561 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1563 struct net_device *dev = ctl->extra1;
1564 struct inet6_dev *idev;
1567 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1568 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1569 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1571 switch (ctl->ctl_name) {
1572 case NET_NEIGH_RETRANS_TIME:
1573 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1575 case NET_NEIGH_REACHABLE_TIME:
1576 ret = proc_dointvec_jiffies(ctl, write,
1577 filp, buffer, lenp, ppos);
1579 case NET_NEIGH_RETRANS_TIME_MS:
1580 case NET_NEIGH_REACHABLE_TIME_MS:
1581 ret = proc_dointvec_ms_jiffies(ctl, write,
1582 filp, buffer, lenp, ppos);
1588 if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1589 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1590 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1591 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1592 idev->tstamp = jiffies;
1593 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1599 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1600 int nlen, void __user *oldval,
1601 size_t __user *oldlenp,
1602 void __user *newval, size_t newlen,
1605 struct net_device *dev = ctl->extra1;
1606 struct inet6_dev *idev;
1609 if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1610 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1611 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1613 switch (ctl->ctl_name) {
1614 case NET_NEIGH_REACHABLE_TIME:
1615 ret = sysctl_jiffies(ctl, name, nlen,
1616 oldval, oldlenp, newval, newlen,
1619 case NET_NEIGH_RETRANS_TIME_MS:
1620 case NET_NEIGH_REACHABLE_TIME_MS:
1621 ret = sysctl_ms_jiffies(ctl, name, nlen,
1622 oldval, oldlenp, newval, newlen,
1629 if (newval && newlen && ret > 0 &&
1630 dev && (idev = in6_dev_get(dev)) != NULL) {
1631 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1632 ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1633 idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1634 idev->tstamp = jiffies;
1635 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1644 int __init ndisc_init(struct net_proto_family *ops)
1646 struct ipv6_pinfo *np;
1650 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1653 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1655 ndisc_socket = NULL; /* For safety. */
1659 sk = ndisc_socket->sk;
1661 sk->sk_allocation = GFP_ATOMIC;
1662 np->hop_limit = 255;
1663 /* Do not loopback ndisc messages */
1665 sk->sk_prot->unhash(sk);
1668 * Initialize the neighbour table
1671 neigh_table_init(&nd_tbl);
1673 #ifdef CONFIG_SYSCTL
1674 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH,
1676 &ndisc_ifinfo_sysctl_change,
1677 &ndisc_ifinfo_sysctl_strategy);
1680 register_netdevice_notifier(&ndisc_netdev_notifier);
1684 void ndisc_cleanup(void)
1686 #ifdef CONFIG_SYSCTL
1687 neigh_sysctl_unregister(&nd_tbl.parms);
1689 neigh_table_clear(&nd_tbl);
1690 sock_release(ndisc_socket);
1691 ndisc_socket = NULL; /* For safety. */