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>
62 #include <linux/sysctl.h>
65 #include <linux/if_arp.h>
66 #include <linux/ipv6.h>
67 #include <linux/icmpv6.h>
73 #include <net/protocol.h>
74 #include <net/ndisc.h>
75 #include <net/ip6_route.h>
76 #include <net/addrconf.h>
80 #include <net/checksum.h>
81 #include <linux/proc_fs.h>
83 #include <linux/netfilter.h>
84 #include <linux/netfilter_ipv6.h>
86 static struct socket *ndisc_socket;
88 static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
89 static int ndisc_constructor(struct neighbour *neigh);
90 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
91 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
92 static int pndisc_constructor(struct pneigh_entry *n);
93 static void pndisc_destructor(struct pneigh_entry *n);
94 static void pndisc_redo(struct sk_buff *skb);
96 static struct neigh_ops ndisc_generic_ops = {
98 .solicit = ndisc_solicit,
99 .error_report = ndisc_error_report,
100 .output = neigh_resolve_output,
101 .connected_output = neigh_connected_output,
102 .hh_output = dev_queue_xmit,
103 .queue_xmit = dev_queue_xmit,
106 static struct neigh_ops ndisc_hh_ops = {
108 .solicit = ndisc_solicit,
109 .error_report = ndisc_error_report,
110 .output = neigh_resolve_output,
111 .connected_output = neigh_resolve_output,
112 .hh_output = dev_queue_xmit,
113 .queue_xmit = dev_queue_xmit,
117 static struct neigh_ops ndisc_direct_ops = {
119 .output = dev_queue_xmit,
120 .connected_output = dev_queue_xmit,
121 .hh_output = dev_queue_xmit,
122 .queue_xmit = dev_queue_xmit,
125 struct neigh_table nd_tbl = {
127 .entry_size = sizeof(struct neighbour) + sizeof(struct in6_addr),
128 .key_len = sizeof(struct in6_addr),
130 .constructor = ndisc_constructor,
131 .pconstructor = pndisc_constructor,
132 .pdestructor = pndisc_destructor,
133 .proxy_redo = pndisc_redo,
137 .base_reachable_time = 30 * HZ,
138 .retrans_time = 1 * HZ,
139 .gc_staletime = 60 * HZ,
140 .reachable_time = 30 * HZ,
141 .delay_probe_time = 5 * HZ,
145 .anycast_delay = 1 * HZ,
146 .proxy_delay = (8 * HZ) / 10,
149 .gc_interval = 30 * HZ,
156 struct ndisc_options {
157 struct nd_opt_hdr *nd_opt_array[7];
158 struct nd_opt_hdr *nd_opt_piend;
161 #define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
162 #define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
163 #define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
164 #define nd_opts_pi_end nd_opt_piend
165 #define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
166 #define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
168 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
170 static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
172 int space = NDISC_OPT_SPACE(data_len);
176 memcpy(opt+2, data, data_len);
179 if ((space -= data_len) > 0)
180 memset(opt, 0, space);
184 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
185 struct nd_opt_hdr *end)
188 if (!cur || !end || cur >= end)
190 type = cur->nd_opt_type;
192 cur = ((void *)cur) + (cur->nd_opt_len << 3);
193 } while(cur < end && cur->nd_opt_type != type);
194 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
197 static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
198 struct ndisc_options *ndopts)
200 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
202 if (!nd_opt || opt_len < 0 || !ndopts)
204 memset(ndopts, 0, sizeof(*ndopts));
207 if (opt_len < sizeof(struct nd_opt_hdr))
209 l = nd_opt->nd_opt_len << 3;
210 if (opt_len < l || l == 0)
212 switch (nd_opt->nd_opt_type) {
213 case ND_OPT_SOURCE_LL_ADDR:
214 case ND_OPT_TARGET_LL_ADDR:
216 case ND_OPT_REDIRECT_HDR:
217 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
218 ND_PRINTK2(KERN_WARNING
219 "%s(): duplicated ND6 option found: type=%d\n",
221 nd_opt->nd_opt_type);
223 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
226 case ND_OPT_PREFIX_INFO:
227 ndopts->nd_opts_pi_end = nd_opt;
228 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
229 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
233 * Unknown options must be silently ignored,
234 * to accommodate future extension to the protocol.
236 ND_PRINTK2(KERN_NOTICE
237 "%s(): ignored unsupported option; type=%d, len=%d\n",
239 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
242 nd_opt = ((void *)nd_opt) + l;
247 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
251 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
253 ipv6_eth_mc_map(addr, buf);
255 case ARPHRD_IEEE802_TR:
256 ipv6_tr_mc_map(addr,buf);
259 ipv6_arcnet_mc_map(addr, buf);
263 memcpy(buf, dev->broadcast, dev->addr_len);
270 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
274 hash_val = *(u32*)(pkey + sizeof(struct in6_addr) - 4);
275 hash_val ^= (hash_val>>16);
276 hash_val ^= hash_val>>8;
277 hash_val ^= hash_val>>3;
278 hash_val = (hash_val^dev->ifindex)&NEIGH_HASHMASK;
283 static int ndisc_constructor(struct neighbour *neigh)
285 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
286 struct net_device *dev = neigh->dev;
287 struct inet6_dev *in6_dev = in6_dev_get(dev);
288 int is_multicast = ipv6_addr_is_multicast(addr);
293 if (in6_dev->nd_parms)
294 neigh->parms = in6_dev->nd_parms;
296 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
297 if (dev->hard_header == NULL) {
298 neigh->nud_state = NUD_NOARP;
299 neigh->ops = &ndisc_direct_ops;
300 neigh->output = neigh->ops->queue_xmit;
303 neigh->nud_state = NUD_NOARP;
304 ndisc_mc_map(addr, neigh->ha, dev, 1);
305 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
306 neigh->nud_state = NUD_NOARP;
307 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
308 if (dev->flags&IFF_LOOPBACK)
309 neigh->type = RTN_LOCAL;
310 } else if (dev->flags&IFF_POINTOPOINT) {
311 neigh->nud_state = NUD_NOARP;
312 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
314 if (dev->hard_header_cache)
315 neigh->ops = &ndisc_hh_ops;
317 neigh->ops = &ndisc_generic_ops;
318 if (neigh->nud_state&NUD_VALID)
319 neigh->output = neigh->ops->connected_output;
321 neigh->output = neigh->ops->output;
323 in6_dev_put(in6_dev);
327 static int pndisc_constructor(struct pneigh_entry *n)
329 struct in6_addr *addr = (struct in6_addr*)&n->key;
330 struct in6_addr maddr;
331 struct net_device *dev = n->dev;
333 if (dev == NULL || __in6_dev_get(dev) == NULL)
335 addrconf_addr_solict_mult(addr, &maddr);
336 ipv6_dev_mc_inc(dev, &maddr);
340 static void pndisc_destructor(struct pneigh_entry *n)
342 struct in6_addr *addr = (struct in6_addr*)&n->key;
343 struct in6_addr maddr;
344 struct net_device *dev = n->dev;
346 if (dev == NULL || __in6_dev_get(dev) == NULL)
348 addrconf_addr_solict_mult(addr, &maddr);
349 ipv6_dev_mc_dec(dev, &maddr);
353 * Send a Neighbour Advertisement
356 static inline void ndisc_flow_init(struct flowi *fl, u8 type,
357 struct in6_addr *saddr, struct in6_addr *daddr)
359 memset(fl, 0, sizeof(*fl));
360 ipv6_addr_copy(&fl->fl6_src, saddr);
361 ipv6_addr_copy(&fl->fl6_dst, daddr);
362 fl->proto = IPPROTO_ICMPV6;
363 fl->fl_icmp_type = type;
364 fl->fl_icmp_code = 0;
367 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
368 struct in6_addr *daddr, struct in6_addr *solicited_addr,
369 int router, int solicited, int override, int inc_opt)
371 struct in6_addr tmpaddr;
372 struct inet6_ifaddr *ifp;
373 struct inet6_dev *idev;
375 struct dst_entry* dst;
376 struct sock *sk = ndisc_socket->sk;
377 struct in6_addr *src_addr;
383 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
385 /* for anycast or proxy, solicited_addr != src_addr */
386 ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
388 src_addr = solicited_addr;
391 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
396 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
398 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
402 err = xfrm_lookup(&dst, &fl, NULL, 0);
410 len += NDISC_OPT_SPACE(dev->addr_len);
415 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
420 "ICMPv6 NA: %s() failed to allocate an skb.\n",
426 skb_reserve(skb, LL_RESERVED_SPACE(dev));
427 ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
429 msg = (struct nd_msg *)skb_put(skb, len);
430 skb->h.raw = (unsigned char*)msg;
432 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
433 msg->icmph.icmp6_code = 0;
434 msg->icmph.icmp6_cksum = 0;
436 msg->icmph.icmp6_unused = 0;
437 msg->icmph.icmp6_router = router;
438 msg->icmph.icmp6_solicited = solicited;
439 msg->icmph.icmp6_override = !!override;
441 /* Set the target address. */
442 ipv6_addr_copy(&msg->target, solicited_addr);
445 ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
448 msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len,
450 csum_partial((__u8 *) msg,
454 idev = in6_dev_get(dst->dev);
455 IP6_INC_STATS(Ip6OutRequests);
456 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
458 ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements);
459 ICMP6_INC_STATS(idev, Icmp6OutMsgs);
462 if (likely(idev != NULL))
466 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
467 struct in6_addr *solicit,
468 struct in6_addr *daddr, struct in6_addr *saddr)
471 struct dst_entry* dst;
472 struct inet6_dev *idev;
473 struct sock *sk = ndisc_socket->sk;
476 struct in6_addr addr_buf;
482 if (ipv6_get_lladdr(dev, &addr_buf))
487 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
489 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
493 err = xfrm_lookup(&dst, &fl, NULL, 0);
499 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
500 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
502 len += NDISC_OPT_SPACE(dev->addr_len);
504 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
508 "ICMPv6 NA: %s() failed to allocate an skb.\n",
514 skb_reserve(skb, LL_RESERVED_SPACE(dev));
515 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
517 msg = (struct nd_msg *)skb_put(skb, len);
518 skb->h.raw = (unsigned char*)msg;
519 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
520 msg->icmph.icmp6_code = 0;
521 msg->icmph.icmp6_cksum = 0;
522 msg->icmph.icmp6_unused = 0;
524 /* Set the target address. */
525 ipv6_addr_copy(&msg->target, solicit);
528 ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
531 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
534 csum_partial((__u8 *) msg,
538 idev = in6_dev_get(dst->dev);
539 IP6_INC_STATS(Ip6OutRequests);
540 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
542 ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits);
543 ICMP6_INC_STATS(idev, Icmp6OutMsgs);
546 if (likely(idev != NULL))
550 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
551 struct in6_addr *daddr)
554 struct dst_entry* dst;
555 struct inet6_dev *idev;
556 struct sock *sk = ndisc_socket->sk;
558 struct icmp6hdr *hdr;
563 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
565 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
569 err = xfrm_lookup(&dst, &fl, NULL, 0);
575 len = sizeof(struct icmp6hdr);
577 len += NDISC_OPT_SPACE(dev->addr_len);
579 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
583 "ICMPv6 RS: %s() failed to allocate an skb.\n",
589 skb_reserve(skb, LL_RESERVED_SPACE(dev));
590 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
592 hdr = (struct icmp6hdr *)skb_put(skb, len);
593 skb->h.raw = (unsigned char*)hdr;
594 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
596 hdr->icmp6_cksum = 0;
597 hdr->icmp6_unused = 0;
599 opt = (u8*) (hdr + 1);
602 ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
605 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
607 csum_partial((__u8 *) hdr, len, 0));
611 idev = in6_dev_get(dst->dev);
612 IP6_INC_STATS(Ip6OutRequests);
613 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
615 ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits);
616 ICMP6_INC_STATS(idev, Icmp6OutMsgs);
619 if (likely(idev != NULL))
624 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
627 * "The sender MUST return an ICMP
628 * destination unreachable"
630 dst_link_failure(skb);
634 /* Called with locked neigh: either read or both */
636 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
638 struct in6_addr *saddr = NULL;
639 struct in6_addr mcaddr;
640 struct net_device *dev = neigh->dev;
641 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
642 int probes = atomic_read(&neigh->probes);
644 if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
645 saddr = &skb->nh.ipv6h->saddr;
647 if ((probes -= neigh->parms->ucast_probes) < 0) {
648 if (!(neigh->nud_state & NUD_VALID)) {
649 ND_PRINTK1(KERN_DEBUG
650 "%s(): trying to ucast probe in NUD_INVALID: "
651 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
655 ndisc_send_ns(dev, neigh, target, target, saddr);
656 } else if ((probes -= neigh->parms->app_probes) < 0) {
661 addrconf_addr_solict_mult(target, &mcaddr);
662 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
666 static void ndisc_recv_ns(struct sk_buff *skb)
668 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
669 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
670 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
673 u32 ndoptlen = skb->tail - msg->opt;
674 struct ndisc_options ndopts;
675 struct net_device *dev = skb->dev;
676 struct inet6_ifaddr *ifp;
677 struct inet6_dev *idev = NULL;
678 struct neighbour *neigh;
679 int dad = ipv6_addr_any(saddr);
682 if (ipv6_addr_is_multicast(&msg->target)) {
683 ND_PRINTK2(KERN_WARNING
684 "ICMPv6 NS: multicast target address");
690 * DAD has to be destined for solicited node multicast address.
693 !(daddr->s6_addr32[0] == htonl(0xff020000) &&
694 daddr->s6_addr32[1] == htonl(0x00000000) &&
695 daddr->s6_addr32[2] == htonl(0x00000001) &&
696 daddr->s6_addr [12] == 0xff )) {
697 ND_PRINTK2(KERN_WARNING
698 "ICMPv6 NS: bad DAD packet (wrong destination)\n");
702 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
703 ND_PRINTK2(KERN_WARNING
704 "ICMPv6 NS: invalid ND options\n");
708 if (ndopts.nd_opts_src_lladdr) {
709 lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
710 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
711 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
712 ND_PRINTK2(KERN_WARNING
713 "ICMPv6 NS: invalid link-layer address length\n");
718 * If the IP source address is the unspecified address,
719 * there MUST NOT be source link-layer address option
723 ND_PRINTK2(KERN_WARNING
724 "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
729 inc = ipv6_addr_is_multicast(daddr);
731 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
732 if (ifp->flags & IFA_F_TENTATIVE) {
733 /* Address is tentative. If the source
734 is unspecified address, it is someone
735 does DAD, otherwise we ignore solicitations
736 until DAD timer expires.
740 if (dev->type == ARPHRD_IEEE802_TR) {
741 unsigned char *sadr = skb->mac.raw;
742 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
743 sadr[9] == dev->dev_addr[1] &&
744 sadr[10] == dev->dev_addr[2] &&
745 sadr[11] == dev->dev_addr[3] &&
746 sadr[12] == dev->dev_addr[4] &&
747 sadr[13] == dev->dev_addr[5]) {
748 /* looped-back to us */
752 addrconf_dad_failure(ifp);
758 idev = in6_dev_get(dev);
760 /* XXX: count this drop? */
764 if (ipv6_chk_acast_addr(dev, &msg->target) ||
765 (idev->cnf.forwarding &&
766 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
767 if (skb->stamp.tv_sec != LOCALLY_ENQUEUED &&
768 skb->pkt_type != PACKET_HOST &&
770 idev->nd_parms->proxy_delay != 0) {
772 * for anycast or proxy,
773 * sender should delay its response
774 * by a random time between 0 and
775 * MAX_ANYCAST_DELAY_TIME seconds.
776 * (RFC2461) -- yoshfuji
778 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
780 pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
788 struct in6_addr maddr;
790 ipv6_addr_all_nodes(&maddr);
791 ndisc_send_na(dev, NULL, &maddr, &msg->target,
792 idev->cnf.forwarding, 0, (ifp != NULL), 1);
797 nd_tbl.stats.rcv_probes_mcast++;
799 nd_tbl.stats.rcv_probes_ucast++;
802 * update / create cache entry
803 * for the source address
805 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
807 if (neigh || !dev->hard_header) {
808 ndisc_send_na(dev, neigh, saddr, &msg->target,
809 idev->cnf.forwarding,
810 1, (ifp != NULL && inc), inc);
812 neigh_release(neigh);
824 static void ndisc_recv_na(struct sk_buff *skb)
826 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
827 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
828 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
831 u32 ndoptlen = skb->tail - msg->opt;
832 struct ndisc_options ndopts;
833 struct net_device *dev = skb->dev;
834 struct inet6_ifaddr *ifp;
835 struct neighbour *neigh;
837 if (skb->len < sizeof(struct nd_msg)) {
838 ND_PRINTK2(KERN_WARNING
839 "ICMPv6 NA: packet too short\n");
843 if (ipv6_addr_is_multicast(&msg->target)) {
844 ND_PRINTK2(KERN_WARNING
845 "ICMPv6 NA: target address is multicast.\n");
849 if (ipv6_addr_is_multicast(daddr) &&
850 msg->icmph.icmp6_solicited) {
851 ND_PRINTK2(KERN_WARNING
852 "ICMPv6 NA: solicited NA is multicasted.\n");
856 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
857 ND_PRINTK2(KERN_WARNING
858 "ICMPv6 NS: invalid ND option\n");
861 if (ndopts.nd_opts_tgt_lladdr) {
862 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
863 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
864 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
865 ND_PRINTK2(KERN_WARNING
866 "ICMPv6 NA: invalid link-layer address length\n");
870 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
871 if (ifp->flags & IFA_F_TENTATIVE) {
872 addrconf_dad_failure(ifp);
875 /* What should we make now? The advertisement
876 is invalid, but ndisc specs say nothing
877 about it. It could be misconfiguration, or
878 an smart proxy agent tries to help us :-)
880 ND_PRINTK1(KERN_WARNING
881 "ICMPv6 NA: someone advertises our address on %s!\n",
882 ifp->idev->dev->name);
886 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
889 if (neigh->flags & NTF_ROUTER) {
890 if (msg->icmph.icmp6_router == 0) {
892 * Change: router to host
895 rt = rt6_get_dflt_router(saddr, dev);
897 ip6_del_rt(rt, NULL, NULL);
900 if (msg->icmph.icmp6_router)
901 neigh->flags |= NTF_ROUTER;
904 neigh_update(neigh, lladdr,
905 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
906 msg->icmph.icmp6_override, 1);
907 neigh_release(neigh);
911 static void ndisc_router_discovery(struct sk_buff *skb)
913 struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
914 struct neighbour *neigh;
915 struct inet6_dev *in6_dev;
918 struct ndisc_options ndopts;
921 __u8 * opt = (__u8 *)(ra_msg + 1);
923 optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
925 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
926 ND_PRINTK2(KERN_WARNING
927 "ICMPv6 RA: source address is not link-local.\n");
931 ND_PRINTK2(KERN_WARNING
932 "ICMPv6 RA: packet too short\n");
937 * set the RA_RECV flag in the interface
940 in6_dev = in6_dev_get(skb->dev);
941 if (in6_dev == NULL) {
943 "ICMPv6 RA: can't find inet6 device for %s.\n",
947 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
948 in6_dev_put(in6_dev);
952 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
953 in6_dev_put(in6_dev);
954 ND_PRINTK2(KERN_WARNING
955 "ICMP6 RA: invalid ND options\n");
959 if (in6_dev->if_flags & IF_RS_SENT) {
961 * flag that an RA was received after an RS was sent
962 * out on this interface.
964 in6_dev->if_flags |= IF_RA_RCVD;
968 * Remember the managed/otherconf flags from most recently
969 * received RA message (RFC 2462) -- yoshfuji
971 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
973 (ra_msg->icmph.icmp6_addrconf_managed ?
975 (ra_msg->icmph.icmp6_addrconf_other ?
976 IF_RA_OTHERCONF : 0);
978 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
980 rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
982 if (rt && lifetime == 0) {
983 ip6_del_rt(rt, NULL, NULL);
987 if (rt == NULL && lifetime) {
988 ND_PRINTK3(KERN_DEBUG
989 "ICMPv6 RA: adding default router.\n");
991 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
994 "ICMPv6 RA: %s() failed to add default route.\n",
996 in6_dev_put(in6_dev);
1000 neigh = rt->rt6i_nexthop;
1001 if (neigh == NULL) {
1003 "ICMPv6 RA: %s() got default router without neighbour.\n",
1005 dst_release(&rt->u.dst);
1006 in6_dev_put(in6_dev);
1009 neigh->flags |= NTF_ROUTER;
1012 * If we where using an "all destinations on link" route
1016 rt6_purge_dflt_routers(RTF_ALLONLINK);
1020 rt->rt6i_expires = jiffies + (HZ * lifetime);
1022 if (ra_msg->icmph.icmp6_hop_limit)
1023 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1026 * Update Reachable Time and Retrans Timer
1029 if (in6_dev->nd_parms) {
1030 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1032 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1033 rtime = (rtime*HZ)/1000;
1036 in6_dev->nd_parms->retrans_time = rtime;
1037 in6_dev->tstamp = jiffies;
1038 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1041 rtime = ntohl(ra_msg->reachable_time);
1042 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1043 rtime = (rtime*HZ)/1000;
1048 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1049 in6_dev->nd_parms->base_reachable_time = rtime;
1050 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1051 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1052 in6_dev->tstamp = jiffies;
1053 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1062 if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
1065 if (ndopts.nd_opts_src_lladdr) {
1066 lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
1067 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
1068 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1069 ND_PRINTK2(KERN_WARNING
1070 "ICMPv6 RA: invalid link-layer address length\n");
1074 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
1077 if (ndopts.nd_opts_pi) {
1078 struct nd_opt_hdr *p;
1079 for (p = ndopts.nd_opts_pi;
1081 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1082 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1086 if (ndopts.nd_opts_mtu) {
1089 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1092 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1093 ND_PRINTK2(KERN_WARNING
1094 "ICMPv6 RA: invalid mtu: %d\n",
1096 } else if (in6_dev->cnf.mtu6 != mtu) {
1097 in6_dev->cnf.mtu6 = mtu;
1100 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1102 rt6_mtu_change(skb->dev, mtu);
1106 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1107 ND_PRINTK2(KERN_WARNING
1108 "ICMPv6 RA: invalid RA options");
1112 dst_release(&rt->u.dst);
1113 in6_dev_put(in6_dev);
1116 static void ndisc_redirect_rcv(struct sk_buff *skb)
1118 struct inet6_dev *in6_dev;
1119 struct icmp6hdr *icmph;
1120 struct in6_addr *dest;
1121 struct in6_addr *target; /* new first hop to destination */
1122 struct neighbour *neigh;
1124 struct ndisc_options ndopts;
1129 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1130 ND_PRINTK2(KERN_WARNING
1131 "ICMPv6 Redirect: source address is not link-local.\n");
1135 optlen = skb->tail - skb->h.raw;
1136 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1139 ND_PRINTK2(KERN_WARNING
1140 "ICMPv6 Redirect: packet too short\n");
1144 icmph = (struct icmp6hdr *) skb->h.raw;
1145 target = (struct in6_addr *) (icmph + 1);
1148 if (ipv6_addr_is_multicast(dest)) {
1149 ND_PRINTK2(KERN_WARNING
1150 "ICMPv6 Redirect: destination address is multicast.\n");
1154 if (ipv6_addr_cmp(dest, target) == 0) {
1156 } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1157 ND_PRINTK2(KERN_WARNING
1158 "ICMPv6 Redirect: target address is not link-local.\n");
1162 in6_dev = in6_dev_get(skb->dev);
1165 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1166 in6_dev_put(in6_dev);
1171 * The IP source address of the Redirect MUST be the same as the current
1172 * first-hop router for the specified ICMP Destination Address.
1175 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1176 ND_PRINTK2(KERN_WARNING
1177 "ICMPv6 Redirect: invalid ND options\n");
1178 in6_dev_put(in6_dev);
1181 if (ndopts.nd_opts_tgt_lladdr) {
1182 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
1183 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1184 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1185 ND_PRINTK2(KERN_WARNING
1186 "ICMPv6 Redirect: invalid link-layer address length\n");
1187 in6_dev_put(in6_dev);
1191 /* passed validation tests */
1194 We install redirect only if nexthop state is valid.
1197 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1199 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
1200 if (neigh->nud_state&NUD_VALID)
1201 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
1203 __neigh_event_send(neigh, NULL);
1204 neigh_release(neigh);
1206 in6_dev_put(in6_dev);
1209 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1210 struct in6_addr *target)
1212 struct sock *sk = ndisc_socket->sk;
1213 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1214 struct sk_buff *buff;
1215 struct icmp6hdr *icmph;
1216 struct in6_addr saddr_buf;
1217 struct in6_addr *addrp;
1218 struct net_device *dev;
1219 struct rt6_info *rt;
1220 struct dst_entry *dst;
1221 struct inet6_dev *idev;
1230 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1231 ND_PRINTK2(KERN_WARNING
1232 "ICMPv6 Redirect: no link-local address on %s\n",
1237 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1239 rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
1244 err = xfrm_lookup(&dst, &fl, NULL, 0);
1250 rt = (struct rt6_info *) dst;
1252 if (rt->rt6i_flags & RTF_GATEWAY) {
1253 ND_PRINTK2(KERN_WARNING
1254 "ICMPv6 Redirect: destination is not a neighbour.\n");
1258 if (!xrlim_allow(dst, 1*HZ)) {
1263 if (dev->addr_len) {
1264 if (neigh->nud_state&NUD_VALID) {
1265 len += NDISC_OPT_SPACE(dev->addr_len);
1267 /* If nexthop is not valid, do not redirect!
1268 We will make it later, when will be sure,
1276 rd_len = min_t(unsigned int,
1277 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1281 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1285 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1293 skb_reserve(buff, LL_RESERVED_SPACE(dev));
1294 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1295 IPPROTO_ICMPV6, len);
1297 icmph = (struct icmp6hdr *)skb_put(buff, len);
1298 buff->h.raw = (unsigned char*)icmph;
1300 memset(icmph, 0, sizeof(struct icmp6hdr));
1301 icmph->icmp6_type = NDISC_REDIRECT;
1304 * copy target and destination addresses
1307 addrp = (struct in6_addr *)(icmph + 1);
1308 ipv6_addr_copy(addrp, target);
1310 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1312 opt = (u8*) (addrp + 1);
1315 * include target_address option
1319 opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
1322 * build redirect option and copy skb over to the new packet.
1326 *(opt++) = ND_OPT_REDIRECT_HDR;
1327 *(opt++) = (rd_len >> 3);
1330 memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1332 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1333 len, IPPROTO_ICMPV6,
1334 csum_partial((u8 *) icmph, len, 0));
1337 idev = in6_dev_get(dst->dev);
1338 IP6_INC_STATS(Ip6OutRequests);
1339 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1341 ICMP6_INC_STATS(idev, Icmp6OutRedirects);
1342 ICMP6_INC_STATS(idev, Icmp6OutMsgs);
1345 if (likely(idev != NULL))
1349 static void pndisc_redo(struct sk_buff *skb)
1355 int ndisc_rcv(struct sk_buff *skb)
1359 if (!pskb_may_pull(skb, skb->len))
1362 msg = (struct nd_msg *) skb->h.raw;
1364 __skb_push(skb, skb->data-skb->h.raw);
1366 if (skb->nh.ipv6h->hop_limit != 255) {
1367 ND_PRINTK2(KERN_WARNING
1368 "ICMPv6 NDISC: invalid hop-limit: %d\n",
1369 skb->nh.ipv6h->hop_limit);
1373 if (msg->icmph.icmp6_code != 0) {
1374 ND_PRINTK2(KERN_WARNING
1375 "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1376 msg->icmph.icmp6_code);
1380 switch (msg->icmph.icmp6_type) {
1381 case NDISC_NEIGHBOUR_SOLICITATION:
1385 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1389 case NDISC_ROUTER_ADVERTISEMENT:
1390 ndisc_router_discovery(skb);
1393 case NDISC_REDIRECT:
1394 ndisc_redirect_rcv(skb);
1401 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1403 struct net_device *dev = ptr;
1406 case NETDEV_CHANGEADDR:
1407 neigh_changeaddr(&nd_tbl, dev);
1411 neigh_ifdown(&nd_tbl, dev);
1421 static struct notifier_block ndisc_netdev_notifier = {
1422 .notifier_call = ndisc_netdev_event,
1425 #ifdef CONFIG_SYSCTL
1426 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp)
1428 struct net_device *dev = ctl->extra1;
1429 struct inet6_dev *idev;
1431 if (write && dev && (idev = in6_dev_get(dev)) != NULL) {
1432 idev->tstamp = jiffies;
1433 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1436 return proc_dointvec(ctl, write, filp, buffer, lenp);
1440 int __init ndisc_init(struct net_proto_family *ops)
1442 struct ipv6_pinfo *np;
1446 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1449 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1451 ndisc_socket = NULL; /* For safety. */
1455 sk = ndisc_socket->sk;
1457 sk->sk_allocation = GFP_ATOMIC;
1458 np->hop_limit = 255;
1459 /* Do not loopback ndisc messages */
1461 sk->sk_prot->unhash(sk);
1464 * Initialize the neighbour table
1467 neigh_table_init(&nd_tbl);
1469 #ifdef CONFIG_SYSCTL
1470 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH,
1471 "ipv6", &ndisc_ifinfo_sysctl_change);
1474 register_netdevice_notifier(&ndisc_netdev_notifier);
1478 void ndisc_cleanup(void)
1480 #ifdef CONFIG_SYSCTL
1481 neigh_sysctl_unregister(&nd_tbl.parms);
1483 neigh_table_clear(&nd_tbl);
1484 sock_release(ndisc_socket);
1485 ndisc_socket = NULL; /* For safety. */