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(x...) printk(KERN_DEBUG x)
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
38 #define ND_PRINTK1 ND_PRINTK
42 #define ND_PRINTK2 ND_PRINTK
45 #define __NO_VERSION__
46 #include <linux/module.h>
47 #include <linux/config.h>
48 #include <linux/errno.h>
49 #include <linux/types.h>
50 #include <linux/socket.h>
51 #include <linux/sockios.h>
52 #include <linux/sched.h>
53 #include <linux/net.h>
54 #include <linux/in6.h>
55 #include <linux/route.h>
56 #include <linux/init.h>
58 #include <linux/sysctl.h>
61 #include <linux/if_arp.h>
62 #include <linux/ipv6.h>
63 #include <linux/icmpv6.h>
69 #include <net/protocol.h>
70 #include <net/ndisc.h>
71 #include <net/ip6_route.h>
72 #include <net/addrconf.h>
75 #include <net/checksum.h>
76 #include <linux/proc_fs.h>
78 static struct socket *ndisc_socket;
80 static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
81 static int ndisc_constructor(struct neighbour *neigh);
82 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
83 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
84 static int pndisc_constructor(struct pneigh_entry *n);
85 static void pndisc_destructor(struct pneigh_entry *n);
86 static void pndisc_redo(struct sk_buff *skb);
88 static struct neigh_ops ndisc_generic_ops =
95 neigh_connected_output,
100 static struct neigh_ops ndisc_hh_ops =
106 neigh_resolve_output,
107 neigh_resolve_output,
113 static struct neigh_ops ndisc_direct_ops =
125 struct neigh_table nd_tbl =
129 sizeof(struct neighbour) + sizeof(struct in6_addr),
130 sizeof(struct in6_addr),
137 { NULL, NULL, &nd_tbl, 0, NULL, NULL,
138 30*HZ, 1*HZ, 60*HZ, 30*HZ, 5*HZ, 3, 3, 0, 3, 1*HZ, (8*HZ)/10, 64, 0 },
139 30*HZ, 128, 512, 1024,
142 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
144 static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
146 int space = NDISC_OPT_SPACE(data_len);
150 memcpy(opt+2, data, data_len);
153 if ((space -= data_len) > 0)
154 memset(opt, 0, space);
158 struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
159 struct nd_opt_hdr *end)
162 if (!cur || !end || cur >= end)
164 type = cur->nd_opt_type;
166 cur = ((void *)cur) + (cur->nd_opt_len << 3);
167 } while(cur < end && cur->nd_opt_type != type);
168 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
171 struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
172 struct ndisc_options *ndopts)
174 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
176 if (!nd_opt || opt_len < 0 || !ndopts)
178 memset(ndopts, 0, sizeof(*ndopts));
181 if (opt_len < sizeof(struct nd_opt_hdr))
183 l = nd_opt->nd_opt_len << 3;
184 if (opt_len < l || l == 0)
186 switch (nd_opt->nd_opt_type) {
187 case ND_OPT_SOURCE_LL_ADDR:
188 case ND_OPT_TARGET_LL_ADDR:
190 case ND_OPT_REDIRECT_HDR:
191 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
192 ND_PRINTK2((KERN_WARNING
193 "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
194 nd_opt->nd_opt_type));
196 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
199 case ND_OPT_PREFIX_INFO:
200 ndopts->nd_opts_pi_end = nd_opt;
201 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
202 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
206 * Unknown options must be silently ignored,
207 * to accomodate future extension to the protocol.
209 ND_PRINTK2(KERN_WARNING
210 "ndisc_parse_options(): ignored unsupported option; type=%d, len=%d\n",
211 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
214 nd_opt = ((void *)nd_opt) + l;
219 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
223 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
225 ipv6_eth_mc_map(addr, buf);
227 case ARPHRD_IEEE802_TR:
228 ipv6_tr_mc_map(addr,buf);
232 memcpy(buf, dev->broadcast, dev->addr_len);
239 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
243 hash_val = *(u32*)(pkey + sizeof(struct in6_addr) - 4);
244 hash_val ^= (hash_val>>16);
245 hash_val ^= hash_val>>8;
246 hash_val ^= hash_val>>3;
247 hash_val = (hash_val^dev->ifindex)&NEIGH_HASHMASK;
252 static int ndisc_constructor(struct neighbour *neigh)
254 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
255 struct net_device *dev = neigh->dev;
256 struct inet6_dev *in6_dev = in6_dev_get(dev);
262 addr_type = ipv6_addr_type(addr);
263 if (in6_dev->nd_parms)
264 neigh->parms = in6_dev->nd_parms;
266 if (addr_type&IPV6_ADDR_MULTICAST)
267 neigh->type = RTN_MULTICAST;
269 neigh->type = RTN_UNICAST;
270 if (dev->hard_header == NULL) {
271 neigh->nud_state = NUD_NOARP;
272 neigh->ops = &ndisc_direct_ops;
273 neigh->output = neigh->ops->queue_xmit;
275 if (addr_type&IPV6_ADDR_MULTICAST) {
276 neigh->nud_state = NUD_NOARP;
277 ndisc_mc_map(addr, neigh->ha, dev, 1);
278 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
279 neigh->nud_state = NUD_NOARP;
280 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
281 if (dev->flags&IFF_LOOPBACK)
282 neigh->type = RTN_LOCAL;
283 } else if (dev->flags&IFF_POINTOPOINT) {
284 neigh->nud_state = NUD_NOARP;
285 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
287 if (dev->hard_header_cache)
288 neigh->ops = &ndisc_hh_ops;
290 neigh->ops = &ndisc_generic_ops;
291 if (neigh->nud_state&NUD_VALID)
292 neigh->output = neigh->ops->connected_output;
294 neigh->output = neigh->ops->output;
296 in6_dev_put(in6_dev);
300 static int pndisc_constructor(struct pneigh_entry *n)
302 struct in6_addr *addr = (struct in6_addr*)&n->key;
303 struct in6_addr maddr;
304 struct net_device *dev = n->dev;
306 if (dev == NULL || __in6_dev_get(dev) == NULL)
308 addrconf_addr_solict_mult(addr, &maddr);
309 ipv6_dev_mc_inc(dev, &maddr);
313 static void pndisc_destructor(struct pneigh_entry *n)
315 struct in6_addr *addr = (struct in6_addr*)&n->key;
316 struct in6_addr maddr;
317 struct net_device *dev = n->dev;
319 if (dev == NULL || __in6_dev_get(dev) == NULL)
321 addrconf_addr_solict_mult(addr, &maddr);
322 ipv6_dev_mc_dec(dev, &maddr);
328 ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
329 struct in6_addr *daddr, struct neighbour *neigh, int len)
331 unsigned char ha[MAX_ADDR_LEN];
332 unsigned char *h_dest = NULL;
334 skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
336 if (dev->hard_header) {
337 if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
338 ndisc_mc_map(daddr, ha, dev, 1);
341 read_lock_bh(&neigh->lock);
342 if (neigh->nud_state&NUD_VALID) {
343 memcpy(ha, neigh->ha, dev->addr_len);
346 read_unlock_bh(&neigh->lock);
348 neigh = neigh_lookup(&nd_tbl, daddr, dev);
350 read_lock_bh(&neigh->lock);
351 if (neigh->nud_state&NUD_VALID) {
352 memcpy(ha, neigh->ha, dev->addr_len);
355 read_unlock_bh(&neigh->lock);
356 neigh_release(neigh);
360 if (dev->hard_header(skb, dev, ETH_P_IPV6, h_dest, NULL, len) < 0)
369 * Send a Neighbour Advertisement
372 void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
373 struct in6_addr *daddr, struct in6_addr *solicited_addr,
374 int router, int solicited, int override, int inc_opt)
376 struct sock *sk = ndisc_socket->sk;
382 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
386 len += NDISC_OPT_SPACE(dev->addr_len);
391 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
395 ND_PRINTK1("send_na: alloc skb failed\n");
399 if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
404 ip6_nd_hdr(sk, skb, dev, solicited_addr, daddr, IPPROTO_ICMPV6, len);
406 msg = (struct nd_msg *) skb_put(skb, len);
408 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
409 msg->icmph.icmp6_code = 0;
410 msg->icmph.icmp6_cksum = 0;
412 msg->icmph.icmp6_unused = 0;
413 msg->icmph.icmp6_router = router;
414 msg->icmph.icmp6_solicited = solicited;
415 msg->icmph.icmp6_override = !!override;
417 /* Set the target address. */
418 ipv6_addr_copy(&msg->target, solicited_addr);
421 ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
424 msg->icmph.icmp6_cksum = csum_ipv6_magic(solicited_addr, daddr, len,
426 csum_partial((__u8 *) msg,
431 ICMP6_INC_STATS(Icmp6OutNeighborAdvertisements);
432 ICMP6_INC_STATS(Icmp6OutMsgs);
435 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
436 struct in6_addr *solicit,
437 struct in6_addr *daddr, struct in6_addr *saddr)
439 struct sock *sk = ndisc_socket->sk;
442 struct in6_addr addr_buf;
448 if (ipv6_get_lladdr(dev, &addr_buf))
453 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
454 send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY;
456 len += NDISC_OPT_SPACE(dev->addr_len);
458 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
461 ND_PRINTK1("send_ns: alloc skb failed\n");
465 if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
470 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
472 msg = (struct nd_msg *)skb_put(skb, len);
473 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
474 msg->icmph.icmp6_code = 0;
475 msg->icmph.icmp6_cksum = 0;
476 msg->icmph.icmp6_unused = 0;
478 /* Set the target address. */
479 ipv6_addr_copy(&msg->target, solicit);
482 ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
485 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
488 csum_partial((__u8 *) msg,
493 ICMP6_INC_STATS(Icmp6OutNeighborSolicits);
494 ICMP6_INC_STATS(Icmp6OutMsgs);
497 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
498 struct in6_addr *daddr)
500 struct sock *sk = ndisc_socket->sk;
502 struct icmp6hdr *hdr;
507 len = sizeof(struct icmp6hdr);
509 len += NDISC_OPT_SPACE(dev->addr_len);
511 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
514 ND_PRINTK1("send_ns: alloc skb failed\n");
518 if (ndisc_build_ll_hdr(skb, dev, daddr, NULL, len) == 0) {
523 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
525 hdr = (struct icmp6hdr *) skb_put(skb, len);
526 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
528 hdr->icmp6_cksum = 0;
529 hdr->icmp6_unused = 0;
531 opt = (u8*) (hdr + 1);
534 ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
537 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
539 csum_partial((__u8 *) hdr, len, 0));
544 ICMP6_INC_STATS(Icmp6OutRouterSolicits);
545 ICMP6_INC_STATS(Icmp6OutMsgs);
549 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
552 * "The sender MUST return an ICMP
553 * destination unreachable"
555 dst_link_failure(skb);
559 /* Called with locked neigh: either read or both */
561 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
563 struct in6_addr *saddr = NULL;
564 struct in6_addr mcaddr;
565 struct net_device *dev = neigh->dev;
566 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
567 int probes = atomic_read(&neigh->probes);
569 if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev))
570 saddr = &skb->nh.ipv6h->saddr;
572 if ((probes -= neigh->parms->ucast_probes) < 0) {
573 if (!(neigh->nud_state&NUD_VALID))
574 ND_PRINTK1("trying to ucast probe in NUD_INVALID\n");
575 ndisc_send_ns(dev, neigh, target, target, saddr);
576 } else if ((probes -= neigh->parms->app_probes) < 0) {
581 addrconf_addr_solict_mult(target, &mcaddr);
582 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
586 void ndisc_recv_ns(struct sk_buff *skb)
588 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
589 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
590 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
593 u32 ndoptlen = skb->tail - msg->opt;
594 struct ndisc_options ndopts;
595 struct net_device *dev = skb->dev;
596 struct inet6_ifaddr *ifp;
597 struct neighbour *neigh;
599 if (skb->len < sizeof(struct nd_msg)) {
601 printk(KERN_WARNING "ICMP NS: packet too short\n");
605 if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
607 printk(KERN_WARNING "ICMP NS: target address is multicast\n");
611 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
613 printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
617 if (ndopts.nd_opts_src_lladdr) {
618 lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
619 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
620 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
622 printk(KERN_WARNING "ICMP NS: bad lladdr length.\n");
627 /* XXX: RFC2461 7.1.1:
628 * If the IP source address is the unspecified address, there
629 * MUST NOT be source link-layer address option in the message.
631 * NOTE! Linux kernel < 2.4.4 broke this rule.
634 /* XXX: RFC2461 7.1.1:
635 * If the IP source address is the unspecified address, the IP
636 * destination address MUST be a solicited-node multicast address.
639 if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) {
640 int addr_type = ipv6_addr_type(saddr);
642 if (ifp->flags & IFA_F_TENTATIVE) {
643 /* Address is tentative. If the source
644 is unspecified address, it is someone
645 does DAD, otherwise we ignore solicitations
646 until DAD timer expires.
648 if (addr_type == IPV6_ADDR_ANY) {
649 if (dev->type == ARPHRD_IEEE802_TR) {
650 unsigned char *sadr = skb->mac.raw ;
651 if (((sadr[8] &0x7f) != (dev->dev_addr[0] & 0x7f)) ||
652 (sadr[9] != dev->dev_addr[1]) ||
653 (sadr[10] != dev->dev_addr[2]) ||
654 (sadr[11] != dev->dev_addr[3]) ||
655 (sadr[12] != dev->dev_addr[4]) ||
656 (sadr[13] != dev->dev_addr[5]))
658 addrconf_dad_failure(ifp) ;
661 addrconf_dad_failure(ifp);
668 if (addr_type == IPV6_ADDR_ANY) {
669 struct in6_addr maddr;
671 ipv6_addr_all_nodes(&maddr);
672 ndisc_send_na(dev, NULL, &maddr, &ifp->addr,
673 ifp->idev->cnf.forwarding, 0,
674 ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1,
680 if (addr_type & IPV6_ADDR_UNICAST) {
681 int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
684 nd_tbl.stats.rcv_probes_mcast++;
686 nd_tbl.stats.rcv_probes_ucast++;
689 * update / create cache entry
690 * for the source adddress
693 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
695 if (neigh || !dev->hard_header) {
696 ndisc_send_na(dev, neigh, saddr, &ifp->addr,
697 ifp->idev->cnf.forwarding, 1,
698 ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1,
701 neigh_release(neigh);
706 struct inet6_dev *in6_dev = in6_dev_get(dev);
707 int addr_type = ipv6_addr_type(saddr);
709 if (in6_dev && in6_dev->cnf.forwarding &&
710 (addr_type & IPV6_ADDR_UNICAST) &&
711 pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
712 int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
714 if (skb->stamp.tv_sec == 0 ||
715 skb->pkt_type == PACKET_HOST ||
717 in6_dev->nd_parms->proxy_delay == 0) {
719 nd_tbl.stats.rcv_probes_mcast++;
721 nd_tbl.stats.rcv_probes_ucast++;
723 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
726 ndisc_send_na(dev, neigh, saddr, &msg->target,
728 neigh_release(neigh);
731 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
733 pneigh_enqueue(&nd_tbl, in6_dev->nd_parms, n);
734 in6_dev_put(in6_dev);
739 in6_dev_put(in6_dev);
744 void ndisc_recv_na(struct sk_buff *skb)
746 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
747 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
748 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
751 u32 ndoptlen = skb->tail - msg->opt;
752 struct ndisc_options ndopts;
753 struct net_device *dev = skb->dev;
754 struct inet6_ifaddr *ifp;
755 struct neighbour *neigh;
757 if (skb->len < sizeof(struct nd_msg)) {
759 printk(KERN_WARNING "ICMP NA: packet too short\n");
763 if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
765 printk(KERN_WARNING "NDISC NA: target address is multicast\n");
769 if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) &&
770 msg->icmph.icmp6_solicited) {
771 ND_PRINTK0("NDISC: solicited NA is multicasted\n");
775 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
777 printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
780 if (ndopts.nd_opts_tgt_lladdr) {
781 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
782 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
783 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
785 printk(KERN_WARNING "NDISC NA: invalid lladdr length.\n");
789 if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) {
790 if (ifp->flags & IFA_F_TENTATIVE) {
791 addrconf_dad_failure(ifp);
794 /* What should we make now? The advertisement
795 is invalid, but ndisc specs say nothing
796 about it. It could be misconfiguration, or
797 an smart proxy agent tries to help us :-)
799 ND_PRINTK0("%s: someone advertises our address!\n",
800 ifp->idev->dev->name);
804 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
807 if (neigh->flags & NTF_ROUTER) {
808 if (msg->icmph.icmp6_router == 0) {
810 * Change: router to host
813 rt = rt6_get_dflt_router(saddr, dev);
815 /* It is safe only because
817 dst_release(&rt->u.dst);
822 if (msg->icmph.icmp6_router)
823 neigh->flags |= NTF_ROUTER;
826 neigh_update(neigh, lladdr,
827 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
828 msg->icmph.icmp6_override, 1);
829 neigh_release(neigh);
833 static void ndisc_router_discovery(struct sk_buff *skb)
835 struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
836 struct neighbour *neigh;
837 struct inet6_dev *in6_dev;
840 struct ndisc_options ndopts;
843 __u8 * opt = (__u8 *)(ra_msg + 1);
845 optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
847 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
849 printk(KERN_WARNING "ICMP RA: source address is not linklocal\n");
854 printk(KERN_WARNING "ICMP RA: packet too short\n");
859 * set the RA_RECV flag in the interface
862 in6_dev = in6_dev_get(skb->dev);
863 if (in6_dev == NULL) {
864 ND_PRINTK1("RA: can't find in6 device\n");
867 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
868 in6_dev_put(in6_dev);
872 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
873 in6_dev_put(in6_dev);
875 ND_PRINTK2(KERN_WARNING
876 "ICMP6 RA: invalid ND option, ignored.\n");
880 if (in6_dev->if_flags & IF_RS_SENT) {
882 * flag that an RA was received after an RS was sent
883 * out on this interface.
885 in6_dev->if_flags |= IF_RA_RCVD;
888 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
890 rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
892 if (rt && lifetime == 0) {
897 if (rt == NULL && lifetime) {
898 ND_PRINTK2("ndisc_rdisc: adding default router\n");
900 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
902 ND_PRINTK1("route_add failed\n");
903 in6_dev_put(in6_dev);
907 neigh = rt->rt6i_nexthop;
909 ND_PRINTK1("nd: add default router: null neighbour\n");
910 dst_release(&rt->u.dst);
911 in6_dev_put(in6_dev);
914 neigh->flags |= NTF_ROUTER;
917 * If we where using an "all destinations on link" route
921 rt6_purge_dflt_routers(RTF_ALLONLINK);
925 rt->rt6i_expires = jiffies + (HZ * lifetime);
927 if (ra_msg->icmph.icmp6_hop_limit)
928 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
931 * Update Reachable Time and Retrans Timer
934 if (in6_dev->nd_parms) {
935 __u32 rtime = ntohl(ra_msg->retrans_timer);
937 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
938 rtime = (rtime*HZ)/1000;
941 in6_dev->nd_parms->retrans_time = rtime;
944 rtime = ntohl(ra_msg->reachable_time);
945 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
946 rtime = (rtime*HZ)/1000;
951 if (rtime != in6_dev->nd_parms->base_reachable_time) {
952 in6_dev->nd_parms->base_reachable_time = rtime;
953 in6_dev->nd_parms->gc_staletime = 3 * rtime;
954 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
963 if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
966 if (ndopts.nd_opts_src_lladdr) {
967 lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
968 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
969 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
971 ND_PRINTK2(KERN_WARNING
972 "ICMP6 RA: Invalid lladdr length.\n");
976 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
979 if (ndopts.nd_opts_pi) {
980 struct nd_opt_hdr *p;
981 for (p = ndopts.nd_opts_pi;
983 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
984 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
988 if (ndopts.nd_opts_mtu) {
991 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
994 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
995 if (net_ratelimit()) {
996 ND_PRINTK0("NDISC: router announcement with mtu = %d\n",
1001 if (in6_dev->cnf.mtu6 != mtu) {
1002 in6_dev->cnf.mtu6 = mtu;
1005 rt->u.dst.pmtu = mtu;
1007 rt6_mtu_change(skb->dev, mtu);
1011 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1012 if (net_ratelimit())
1013 ND_PRINTK0(KERN_WARNING
1014 "ICMP6 RA: got illegal option with RA");
1018 dst_release(&rt->u.dst);
1019 in6_dev_put(in6_dev);
1022 static void ndisc_redirect_rcv(struct sk_buff *skb)
1024 struct inet6_dev *in6_dev;
1025 struct icmp6hdr *icmph;
1026 struct in6_addr *dest;
1027 struct in6_addr *target; /* new first hop to destination */
1028 struct neighbour *neigh;
1030 struct ndisc_options ndopts;
1035 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1036 if (net_ratelimit())
1037 printk(KERN_WARNING "ICMP redirect: source address is not linklocal\n");
1041 optlen = skb->tail - skb->h.raw;
1042 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1045 if (net_ratelimit())
1046 printk(KERN_WARNING "ICMP redirect: packet too small\n");
1050 icmph = (struct icmp6hdr *) skb->h.raw;
1051 target = (struct in6_addr *) (icmph + 1);
1054 if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) {
1055 if (net_ratelimit())
1056 printk(KERN_WARNING "ICMP redirect for multicast addr\n");
1060 if (ipv6_addr_cmp(dest, target) == 0) {
1062 } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1063 if (net_ratelimit())
1064 printk(KERN_WARNING "ICMP redirect: target address is not linklocal\n");
1068 in6_dev = in6_dev_get(skb->dev);
1071 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1072 in6_dev_put(in6_dev);
1076 /* XXX: RFC2461 8.1:
1077 * The IP source address of the Redirect MUST be the same as the current
1078 * first-hop router for the specified ICMP Destination Address.
1081 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1082 if (net_ratelimit())
1083 ND_PRINTK2(KERN_WARNING
1084 "ICMP6 Redirect: invalid ND options, rejected.\n");
1085 in6_dev_put(in6_dev);
1088 if (ndopts.nd_opts_tgt_lladdr) {
1089 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
1090 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1091 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1092 if (net_ratelimit())
1093 ND_PRINTK2(KERN_WARNING
1094 "ICMP6 Redirect: invalid lladdr length.\n");
1095 in6_dev_put(in6_dev);
1099 /* passed validation tests */
1102 We install redirect only if nexthop state is valid.
1105 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1107 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
1108 if (neigh->nud_state&NUD_VALID)
1109 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
1111 __neigh_event_send(neigh, NULL);
1112 neigh_release(neigh);
1114 in6_dev_put(in6_dev);
1117 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1118 struct in6_addr *target)
1120 struct sock *sk = ndisc_socket->sk;
1121 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1122 struct sk_buff *buff;
1123 struct icmp6hdr *icmph;
1124 struct in6_addr saddr_buf;
1125 struct in6_addr *addrp;
1126 struct net_device *dev;
1127 struct rt6_info *rt;
1134 rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
1139 if (rt->rt6i_flags & RTF_GATEWAY) {
1140 ND_PRINTK1("ndisc_send_redirect: not a neighbour\n");
1141 dst_release(&rt->u.dst);
1144 if (!xrlim_allow(&rt->u.dst, 1*HZ)) {
1145 dst_release(&rt->u.dst);
1148 dst_release(&rt->u.dst);
1150 if (dev->addr_len) {
1151 if (neigh->nud_state&NUD_VALID) {
1152 len += NDISC_OPT_SPACE(dev->addr_len);
1154 /* If nexthop is not valid, do not redirect!
1155 We will make it later, when will be sure,
1162 rd_len = min_t(unsigned int,
1163 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1167 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1168 ND_PRINTK1("redirect: no link_local addr for dev\n");
1172 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
1175 ND_PRINTK1("ndisc_send_redirect: alloc_skb failed\n");
1181 if (ndisc_build_ll_hdr(buff, dev, &skb->nh.ipv6h->saddr, NULL, len) == 0) {
1186 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1187 IPPROTO_ICMPV6, len);
1189 icmph = (struct icmp6hdr *) skb_put(buff, len);
1191 memset(icmph, 0, sizeof(struct icmp6hdr));
1192 icmph->icmp6_type = NDISC_REDIRECT;
1195 * copy target and destination addresses
1198 addrp = (struct in6_addr *)(icmph + 1);
1199 ipv6_addr_copy(addrp, target);
1201 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1203 opt = (u8*) (addrp + 1);
1206 * include target_address option
1210 opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
1213 * build redirect option and copy skb over to the new packet.
1217 *(opt++) = ND_OPT_REDIRECT_HDR;
1218 *(opt++) = (rd_len >> 3);
1221 memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1223 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1224 len, IPPROTO_ICMPV6,
1225 csum_partial((u8 *) icmph, len, 0));
1227 dev_queue_xmit(buff);
1229 ICMP6_INC_STATS(Icmp6OutRedirects);
1230 ICMP6_INC_STATS(Icmp6OutMsgs);
1233 static void pndisc_redo(struct sk_buff *skb)
1239 int ndisc_rcv(struct sk_buff *skb)
1241 struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
1243 __skb_push(skb, skb->data-skb->h.raw);
1245 if (skb->nh.ipv6h->hop_limit != 255) {
1246 if (net_ratelimit())
1248 "ICMP NDISC: fake message with non-255 Hop Limit received: %d\n",
1249 skb->nh.ipv6h->hop_limit);
1253 if (msg->icmph.icmp6_code != 0) {
1254 if (net_ratelimit())
1255 printk(KERN_WARNING "ICMP NDISC: code is not zero\n");
1259 switch (msg->icmph.icmp6_type) {
1260 case NDISC_NEIGHBOUR_SOLICITATION:
1264 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1268 case NDISC_ROUTER_ADVERTISEMENT:
1269 ndisc_router_discovery(skb);
1272 case NDISC_REDIRECT:
1273 ndisc_redirect_rcv(skb);
1280 int __init ndisc_init(struct net_proto_family *ops)
1285 ndisc_socket = sock_alloc();
1286 if (ndisc_socket == NULL) {
1288 "Failed to create the NDISC control socket.\n");
1291 ndisc_socket->inode->i_uid = 0;
1292 ndisc_socket->inode->i_gid = 0;
1293 ndisc_socket->type = SOCK_RAW;
1295 if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) {
1297 "Failed to initialize the NDISC control socket (err %d).\n",
1299 sock_release(ndisc_socket);
1300 ndisc_socket = NULL; /* For safety. */
1304 sk = ndisc_socket->sk;
1305 sk->allocation = GFP_ATOMIC;
1306 sk->net_pinfo.af_inet6.hop_limit = 255;
1307 /* Do not loopback ndisc messages */
1308 sk->net_pinfo.af_inet6.mc_loop = 0;
1309 sk->prot->unhash(sk);
1312 * Initialize the neighbour table
1315 neigh_table_init(&nd_tbl);
1317 #ifdef CONFIG_SYSCTL
1318 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
1324 void ndisc_cleanup(void)
1326 neigh_table_clear(&nd_tbl);
1327 sock_release(ndisc_socket);
1328 ndisc_socket = NULL; /* For safety. */