upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / net / ipv6 / ndisc.c
1 /*
2  *      Neighbour Discovery for IPv6
3  *      Linux INET6 implementation 
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>     
7  *      Mike Shaver             <shaver@ingenia.com>
8  *
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.
13  */
14
15 /*
16  *      Changes:
17  *
18  *      Lars Fenneberg                  :       fixed MTU setting on receipt
19  *                                              of an RA.
20  *
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
26  */
27
28 /* Set to 3 to get tracing... */
29 #define ND_DEBUG 1
30
31 #define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0)
32 #define ND_NOPRINTK(x...) do { ; } while(0)
33 #define ND_PRINTK0 ND_PRINTK
34 #define ND_PRINTK1 ND_NOPRINTK
35 #define ND_PRINTK2 ND_NOPRINTK
36 #define ND_PRINTK3 ND_NOPRINTK
37 #if ND_DEBUG >= 1
38 #undef ND_PRINTK1
39 #define ND_PRINTK1 ND_PRINTK
40 #endif
41 #if ND_DEBUG >= 2
42 #undef ND_PRINTK2
43 #define ND_PRINTK2 ND_PRINTK
44 #endif
45 #if ND_DEBUG >= 3
46 #undef ND_PRINTK3
47 #define ND_PRINTK3 ND_PRINTK
48 #endif
49
50 #include <linux/module.h>
51 #include <linux/config.h>
52 #include <linux/errno.h>
53 #include <linux/types.h>
54 #include <linux/socket.h>
55 #include <linux/sockios.h>
56 #include <linux/sched.h>
57 #include <linux/net.h>
58 #include <linux/in6.h>
59 #include <linux/route.h>
60 #include <linux/init.h>
61 #include <linux/rcupdate.h>
62 #ifdef CONFIG_SYSCTL
63 #include <linux/sysctl.h>
64 #endif
65
66 #include <linux/if_arp.h>
67 #include <linux/ipv6.h>
68 #include <linux/icmpv6.h>
69 #include <linux/jhash.h>
70
71 #include <net/sock.h>
72 #include <net/snmp.h>
73
74 #include <net/ipv6.h>
75 #include <net/protocol.h>
76 #include <net/ndisc.h>
77 #include <net/ip6_route.h>
78 #include <net/addrconf.h>
79 #include <net/icmp.h>
80
81 #include <net/flow.h>
82 #include <net/ip6_checksum.h>
83 #include <linux/proc_fs.h>
84
85 #include <linux/netfilter.h>
86 #include <linux/netfilter_ipv6.h>
87
88 static struct socket *ndisc_socket;
89
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);
97
98 static struct neigh_ops ndisc_generic_ops = {
99         .family =               AF_INET6,
100         .solicit =              ndisc_solicit,
101         .error_report =         ndisc_error_report,
102         .output =               neigh_resolve_output,
103         .connected_output =     neigh_connected_output,
104         .hh_output =            dev_queue_xmit,
105         .queue_xmit =           dev_queue_xmit,
106 };
107
108 static struct neigh_ops ndisc_hh_ops = {
109         .family =               AF_INET6,
110         .solicit =              ndisc_solicit,
111         .error_report =         ndisc_error_report,
112         .output =               neigh_resolve_output,
113         .connected_output =     neigh_resolve_output,
114         .hh_output =            dev_queue_xmit,
115         .queue_xmit =           dev_queue_xmit,
116 };
117
118
119 static struct neigh_ops ndisc_direct_ops = {
120         .family =               AF_INET6,
121         .output =               dev_queue_xmit,
122         .connected_output =     dev_queue_xmit,
123         .hh_output =            dev_queue_xmit,
124         .queue_xmit =           dev_queue_xmit,
125 };
126
127 struct neigh_table nd_tbl = {
128         .family =       AF_INET6,
129         .entry_size =   sizeof(struct neighbour) + sizeof(struct in6_addr),
130         .key_len =      sizeof(struct in6_addr),
131         .hash =         ndisc_hash,
132         .constructor =  ndisc_constructor,
133         .pconstructor = pndisc_constructor,
134         .pdestructor =  pndisc_destructor,
135         .proxy_redo =   pndisc_redo,
136         .id =           "ndisc_cache",
137         .parms = {
138                 .tbl =                  &nd_tbl,
139                 .base_reachable_time =  30 * HZ,
140                 .retrans_time =  1 * HZ,
141                 .gc_staletime = 60 * HZ,
142                 .reachable_time =               30 * HZ,
143                 .delay_probe_time =      5 * HZ,
144                 .queue_len =             3,
145                 .ucast_probes =  3,
146                 .mcast_probes =  3,
147                 .anycast_delay =         1 * HZ,
148                 .proxy_delay =          (8 * HZ) / 10,
149                 .proxy_qlen =           64,
150         },
151         .gc_interval =    30 * HZ,
152         .gc_thresh1 =    128,
153         .gc_thresh2 =    512,
154         .gc_thresh3 =   1024,
155 };
156
157 /* ND options */
158 struct ndisc_options {
159         struct nd_opt_hdr *nd_opt_array[7];
160         struct nd_opt_hdr *nd_opt_piend;
161 };
162
163 #define nd_opts_src_lladdr      nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
164 #define nd_opts_tgt_lladdr      nd_opt_array[ND_OPT_TARGET_LL_ADDR]
165 #define nd_opts_pi              nd_opt_array[ND_OPT_PREFIX_INFO]
166 #define nd_opts_pi_end          nd_opt_piend
167 #define nd_opts_rh              nd_opt_array[ND_OPT_REDIRECT_HDR]
168 #define nd_opts_mtu             nd_opt_array[ND_OPT_MTU]
169
170 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
171
172 static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
173 {
174         int space = NDISC_OPT_SPACE(data_len);
175
176         opt[0] = type;
177         opt[1] = space>>3;
178         memcpy(opt+2, data, data_len);
179         data_len += 2;
180         opt += data_len;
181         if ((space -= data_len) > 0)
182                 memset(opt, 0, space);
183         return opt + space;
184 }
185
186 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
187                                             struct nd_opt_hdr *end)
188 {
189         int type;
190         if (!cur || !end || cur >= end)
191                 return NULL;
192         type = cur->nd_opt_type;
193         do {
194                 cur = ((void *)cur) + (cur->nd_opt_len << 3);
195         } while(cur < end && cur->nd_opt_type != type);
196         return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
197 }
198
199 static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
200                                                  struct ndisc_options *ndopts)
201 {
202         struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
203
204         if (!nd_opt || opt_len < 0 || !ndopts)
205                 return NULL;
206         memset(ndopts, 0, sizeof(*ndopts));
207         while (opt_len) {
208                 int l;
209                 if (opt_len < sizeof(struct nd_opt_hdr))
210                         return NULL;
211                 l = nd_opt->nd_opt_len << 3;
212                 if (opt_len < l || l == 0)
213                         return NULL;
214                 switch (nd_opt->nd_opt_type) {
215                 case ND_OPT_SOURCE_LL_ADDR:
216                 case ND_OPT_TARGET_LL_ADDR:
217                 case ND_OPT_MTU:
218                 case ND_OPT_REDIRECT_HDR:
219                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
220                                 ND_PRINTK2(KERN_WARNING
221                                            "%s(): duplicated ND6 option found: type=%d\n",
222                                            __FUNCTION__,
223                                            nd_opt->nd_opt_type);
224                         } else {
225                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
226                         }
227                         break;
228                 case ND_OPT_PREFIX_INFO:
229                         ndopts->nd_opts_pi_end = nd_opt;
230                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
231                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
232                         break;
233                 default:
234                         /*
235                          * Unknown options must be silently ignored,
236                          * to accommodate future extension to the protocol.
237                          */
238                         ND_PRINTK2(KERN_NOTICE
239                                    "%s(): ignored unsupported option; type=%d, len=%d\n",
240                                    __FUNCTION__,
241                                    nd_opt->nd_opt_type, nd_opt->nd_opt_len);
242                 }
243                 opt_len -= l;
244                 nd_opt = ((void *)nd_opt) + l;
245         }
246         return ndopts;
247 }
248
249 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
250 {
251         switch (dev->type) {
252         case ARPHRD_ETHER:
253         case ARPHRD_IEEE802:    /* Not sure. Check it later. --ANK */
254         case ARPHRD_FDDI:
255                 ipv6_eth_mc_map(addr, buf);
256                 return 0;
257         case ARPHRD_IEEE802_TR:
258                 ipv6_tr_mc_map(addr,buf);
259                 return 0;
260         case ARPHRD_ARCNET:
261                 ipv6_arcnet_mc_map(addr, buf);
262                 return 0;
263         default:
264                 if (dir) {
265                         memcpy(buf, dev->broadcast, dev->addr_len);
266                         return 0;
267                 }
268         }
269         return -EINVAL;
270 }
271
272 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
273 {
274         const u32 *p32 = pkey;
275         u32 addr_hash, i;
276
277         addr_hash = 0;
278         for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
279                 addr_hash ^= *p32++;
280
281         return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
282 }
283
284 static int ndisc_constructor(struct neighbour *neigh)
285 {
286         struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
287         struct net_device *dev = neigh->dev;
288         struct inet6_dev *in6_dev;
289         struct neigh_parms *parms;
290         int is_multicast = ipv6_addr_is_multicast(addr);
291
292         rcu_read_lock();
293         in6_dev = in6_dev_get(dev);
294         if (in6_dev == NULL) {
295                 rcu_read_unlock();
296                 return -EINVAL;
297         }
298
299         parms = in6_dev->nd_parms;
300         __neigh_parms_put(neigh->parms);
301         neigh->parms = neigh_parms_clone(parms);
302         rcu_read_unlock();
303
304         neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
305         if (dev->hard_header == NULL) {
306                 neigh->nud_state = NUD_NOARP;
307                 neigh->ops = &ndisc_direct_ops;
308                 neigh->output = neigh->ops->queue_xmit;
309         } else {
310                 if (is_multicast) {
311                         neigh->nud_state = NUD_NOARP;
312                         ndisc_mc_map(addr, neigh->ha, dev, 1);
313                 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
314                         neigh->nud_state = NUD_NOARP;
315                         memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
316                         if (dev->flags&IFF_LOOPBACK)
317                                 neigh->type = RTN_LOCAL;
318                 } else if (dev->flags&IFF_POINTOPOINT) {
319                         neigh->nud_state = NUD_NOARP;
320                         memcpy(neigh->ha, dev->broadcast, dev->addr_len);
321                 }
322                 if (dev->hard_header_cache)
323                         neigh->ops = &ndisc_hh_ops;
324                 else
325                         neigh->ops = &ndisc_generic_ops;
326                 if (neigh->nud_state&NUD_VALID)
327                         neigh->output = neigh->ops->connected_output;
328                 else
329                         neigh->output = neigh->ops->output;
330         }
331         in6_dev_put(in6_dev);
332         return 0;
333 }
334
335 static int pndisc_constructor(struct pneigh_entry *n)
336 {
337         struct in6_addr *addr = (struct in6_addr*)&n->key;
338         struct in6_addr maddr;
339         struct net_device *dev = n->dev;
340
341         if (dev == NULL || __in6_dev_get(dev) == NULL)
342                 return -EINVAL;
343         addrconf_addr_solict_mult(addr, &maddr);
344         ipv6_dev_mc_inc(dev, &maddr);
345         return 0;
346 }
347
348 static void pndisc_destructor(struct pneigh_entry *n)
349 {
350         struct in6_addr *addr = (struct in6_addr*)&n->key;
351         struct in6_addr maddr;
352         struct net_device *dev = n->dev;
353
354         if (dev == NULL || __in6_dev_get(dev) == NULL)
355                 return;
356         addrconf_addr_solict_mult(addr, &maddr);
357         ipv6_dev_mc_dec(dev, &maddr);
358 }
359
360 /*
361  *      Send a Neighbour Advertisement
362  */
363
364 static inline void ndisc_flow_init(struct flowi *fl, u8 type,
365                             struct in6_addr *saddr, struct in6_addr *daddr)
366 {
367         memset(fl, 0, sizeof(*fl));
368         ipv6_addr_copy(&fl->fl6_src, saddr);
369         ipv6_addr_copy(&fl->fl6_dst, daddr);
370         fl->proto               = IPPROTO_ICMPV6;
371         fl->fl_icmp_type        = type;
372         fl->fl_icmp_code        = 0;
373 }
374
375 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
376                    struct in6_addr *daddr, struct in6_addr *solicited_addr,
377                    int router, int solicited, int override, int inc_opt) 
378 {
379         struct in6_addr tmpaddr;
380         struct inet6_ifaddr *ifp;
381         struct inet6_dev *idev;
382         struct flowi fl;
383         struct dst_entry* dst;
384         struct sock *sk = ndisc_socket->sk;
385         struct in6_addr *src_addr;
386         struct nd_msg *msg;
387         int len;
388         struct sk_buff *skb;
389         int err;
390
391         len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
392
393         /* for anycast or proxy, solicited_addr != src_addr */
394         ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
395         if (ifp) {
396                 src_addr = solicited_addr;
397                 in6_ifa_put(ifp);
398         } else {
399                 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
400                         return;
401                 src_addr = &tmpaddr;
402         }
403
404         ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
405
406         dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
407         if (!dst)
408                 return;
409
410         err = xfrm_lookup(&dst, &fl, NULL, 0);
411         if (err < 0) {
412                 dst_release(dst);
413                 return;
414         }
415
416         if (inc_opt) {
417                 if (dev->addr_len)
418                         len += NDISC_OPT_SPACE(dev->addr_len);
419                 else
420                         inc_opt = 0;
421         }
422
423         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
424                                   1, &err);
425
426         if (skb == NULL) {
427                 ND_PRINTK0(KERN_ERR
428                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
429                            __FUNCTION__);
430                 dst_release(dst);
431                 return;
432         }
433
434         skb_reserve(skb, LL_RESERVED_SPACE(dev));
435         ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
436
437         msg = (struct nd_msg *)skb_put(skb, len);
438         skb->h.raw = (unsigned char*)msg;
439
440         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
441         msg->icmph.icmp6_code = 0;
442         msg->icmph.icmp6_cksum = 0;
443
444         msg->icmph.icmp6_unused = 0;
445         msg->icmph.icmp6_router    = router;
446         msg->icmph.icmp6_solicited = solicited;
447         msg->icmph.icmp6_override  = !!override;
448
449         /* Set the target address. */
450         ipv6_addr_copy(&msg->target, solicited_addr);
451
452         if (inc_opt)
453                 ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
454
455         /* checksum */
456         msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len, 
457                                                  IPPROTO_ICMPV6,
458                                                  csum_partial((__u8 *) msg, 
459                                                               len, 0));
460
461         skb->dst = dst;
462         idev = in6_dev_get(dst->dev);
463         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
464         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
465         if (!err) {
466                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
467                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
468         }
469
470         if (likely(idev != NULL))
471                 in6_dev_put(idev);
472 }        
473
474 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
475                    struct in6_addr *solicit,
476                    struct in6_addr *daddr, struct in6_addr *saddr) 
477 {
478         struct flowi fl;
479         struct dst_entry* dst;
480         struct inet6_dev *idev;
481         struct sock *sk = ndisc_socket->sk;
482         struct sk_buff *skb;
483         struct nd_msg *msg;
484         struct in6_addr addr_buf;
485         int len;
486         int err;
487         int send_llinfo;
488
489         if (saddr == NULL) {
490                 if (ipv6_get_lladdr(dev, &addr_buf))
491                         return;
492                 saddr = &addr_buf;
493         }
494
495         ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
496
497         dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
498         if (!dst)
499                 return;
500
501         err = xfrm_lookup(&dst, &fl, NULL, 0);
502         if (err < 0) {
503                 dst_release(dst);
504                 return;
505         }
506
507         len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
508         send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
509         if (send_llinfo)
510                 len += NDISC_OPT_SPACE(dev->addr_len);
511
512         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
513                                   1, &err);
514         if (skb == NULL) {
515                 ND_PRINTK0(KERN_ERR
516                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
517                            __FUNCTION__);
518                 dst_release(dst);
519                 return;
520         }
521
522         skb_reserve(skb, LL_RESERVED_SPACE(dev));
523         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
524
525         msg = (struct nd_msg *)skb_put(skb, len);
526         skb->h.raw = (unsigned char*)msg;
527         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
528         msg->icmph.icmp6_code = 0;
529         msg->icmph.icmp6_cksum = 0;
530         msg->icmph.icmp6_unused = 0;
531
532         /* Set the target address. */
533         ipv6_addr_copy(&msg->target, solicit);
534
535         if (send_llinfo)
536                 ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
537
538         /* checksum */
539         msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
540                                                  daddr, len, 
541                                                  IPPROTO_ICMPV6,
542                                                  csum_partial((__u8 *) msg, 
543                                                               len, 0));
544         /* send it! */
545         skb->dst = dst;
546         idev = in6_dev_get(dst->dev);
547         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
548         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
549         if (!err) {
550                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
551                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
552         }
553
554         if (likely(idev != NULL))
555                 in6_dev_put(idev);
556 }
557
558 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
559                    struct in6_addr *daddr)
560 {
561         struct flowi fl;
562         struct dst_entry* dst;
563         struct inet6_dev *idev;
564         struct sock *sk = ndisc_socket->sk;
565         struct sk_buff *skb;
566         struct icmp6hdr *hdr;
567         __u8 * opt;
568         int len;
569         int err;
570
571         ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
572
573         dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
574         if (!dst)
575                 return;
576
577         err = xfrm_lookup(&dst, &fl, NULL, 0);
578         if (err < 0) {
579                 dst_release(dst);
580                 return;
581         }
582
583         len = sizeof(struct icmp6hdr);
584         if (dev->addr_len)
585                 len += NDISC_OPT_SPACE(dev->addr_len);
586
587         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
588                                   1, &err);
589         if (skb == NULL) {
590                 ND_PRINTK0(KERN_ERR
591                            "ICMPv6 RS: %s() failed to allocate an skb.\n", 
592                            __FUNCTION__);
593                 dst_release(dst);
594                 return;
595         }
596
597         skb_reserve(skb, LL_RESERVED_SPACE(dev));
598         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
599
600         hdr = (struct icmp6hdr *)skb_put(skb, len);
601         skb->h.raw = (unsigned char*)hdr;
602         hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
603         hdr->icmp6_code = 0;
604         hdr->icmp6_cksum = 0;
605         hdr->icmp6_unused = 0;
606
607         opt = (u8*) (hdr + 1);
608
609         if (dev->addr_len)
610                 ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
611
612         /* checksum */
613         hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
614                                            IPPROTO_ICMPV6,
615                                            csum_partial((__u8 *) hdr, len, 0));
616
617         /* send it! */
618         skb->dst = dst;
619         idev = in6_dev_get(dst->dev);
620         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 
621         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
622         if (!err) {
623                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
624                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
625         }
626
627         if (likely(idev != NULL))
628                 in6_dev_put(idev);
629 }
630                    
631
632 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
633 {
634         /*
635          *      "The sender MUST return an ICMP
636          *       destination unreachable"
637          */
638         dst_link_failure(skb);
639         kfree_skb(skb);
640 }
641
642 /* Called with locked neigh: either read or both */
643
644 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
645 {
646         struct in6_addr *saddr = NULL;
647         struct in6_addr mcaddr;
648         struct net_device *dev = neigh->dev;
649         struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
650         int probes = atomic_read(&neigh->probes);
651
652         if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
653                 saddr = &skb->nh.ipv6h->saddr;
654
655         if ((probes -= neigh->parms->ucast_probes) < 0) {
656                 if (!(neigh->nud_state & NUD_VALID)) {
657                         ND_PRINTK1(KERN_DEBUG
658                                    "%s(): trying to ucast probe in NUD_INVALID: "
659                                    "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
660                                    __FUNCTION__,
661                                    NIP6(*target));
662                 }
663                 ndisc_send_ns(dev, neigh, target, target, saddr);
664         } else if ((probes -= neigh->parms->app_probes) < 0) {
665 #ifdef CONFIG_ARPD
666                 neigh_app_ns(neigh);
667 #endif
668         } else {
669                 addrconf_addr_solict_mult(target, &mcaddr);
670                 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
671         }
672 }
673
674 static void ndisc_recv_ns(struct sk_buff *skb)
675 {
676         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
677         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
678         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
679         u8 *lladdr = NULL;
680         int lladdrlen = 0;
681         u32 ndoptlen = skb->tail - msg->opt;
682         struct ndisc_options ndopts;
683         struct net_device *dev = skb->dev;
684         struct inet6_ifaddr *ifp;
685         struct inet6_dev *idev = NULL;
686         struct neighbour *neigh;
687         int dad = ipv6_addr_any(saddr);
688         int inc;
689
690         if (ipv6_addr_is_multicast(&msg->target)) {
691                 ND_PRINTK2(KERN_WARNING 
692                            "ICMPv6 NS: multicast target address");
693                 return;
694         }
695
696         /*
697          * RFC2461 7.1.1:
698          * DAD has to be destined for solicited node multicast address.
699          */
700         if (dad &&
701             !(daddr->s6_addr32[0] == htonl(0xff020000) &&
702               daddr->s6_addr32[1] == htonl(0x00000000) &&
703               daddr->s6_addr32[2] == htonl(0x00000001) &&
704               daddr->s6_addr [12] == 0xff )) {
705                 ND_PRINTK2(KERN_WARNING
706                            "ICMPv6 NS: bad DAD packet (wrong destination)\n");
707                 return;
708         }
709
710         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
711                 ND_PRINTK2(KERN_WARNING 
712                            "ICMPv6 NS: invalid ND options\n");
713                 return;
714         }
715
716         if (ndopts.nd_opts_src_lladdr) {
717                 lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
718                 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
719                 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
720                         ND_PRINTK2(KERN_WARNING
721                                    "ICMPv6 NS: invalid link-layer address length\n");
722                         return;
723                 }
724
725                 /* RFC2461 7.1.1:
726                  *      If the IP source address is the unspecified address, 
727                  *      there MUST NOT be source link-layer address option 
728                  *      in the message.
729                  */
730                 if (dad) {
731                         ND_PRINTK2(KERN_WARNING 
732                                    "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
733                         return;
734                 }
735         }
736
737         inc = ipv6_addr_is_multicast(daddr);
738
739         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
740                 if (ifp->flags & IFA_F_TENTATIVE) {
741                         /* Address is tentative. If the source
742                            is unspecified address, it is someone
743                            does DAD, otherwise we ignore solicitations
744                            until DAD timer expires.
745                          */
746                         if (!dad)
747                                 goto out;
748                         if (dev->type == ARPHRD_IEEE802_TR) {
749                                 unsigned char *sadr = skb->mac.raw;
750                                 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
751                                     sadr[9] == dev->dev_addr[1] &&
752                                     sadr[10] == dev->dev_addr[2] &&
753                                     sadr[11] == dev->dev_addr[3] &&
754                                     sadr[12] == dev->dev_addr[4] &&
755                                     sadr[13] == dev->dev_addr[5]) {
756                                         /* looped-back to us */
757                                         goto out;
758                                 }
759                         }
760                         addrconf_dad_failure(ifp); 
761                         return;
762                 }
763
764                 idev = ifp->idev;
765         } else {
766                 idev = in6_dev_get(dev);
767                 if (!idev) {
768                         /* XXX: count this drop? */
769                         return;
770                 }
771
772                 if (ipv6_chk_acast_addr(dev, &msg->target) ||
773                     (idev->cnf.forwarding && 
774                      pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
775                         if (skb->stamp.tv_sec != LOCALLY_ENQUEUED &&
776                             skb->pkt_type != PACKET_HOST &&
777                             inc != 0 &&
778                             idev->nd_parms->proxy_delay != 0) {
779                                 /*
780                                  * for anycast or proxy,
781                                  * sender should delay its response 
782                                  * by a random time between 0 and 
783                                  * MAX_ANYCAST_DELAY_TIME seconds.
784                                  * (RFC2461) -- yoshfuji
785                                  */
786                                 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
787                                 if (n)
788                                         pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
789                                 goto out;
790                         }
791                 } else
792                         goto out;
793         }
794
795         if (dad) {
796                 struct in6_addr maddr;
797
798                 ipv6_addr_all_nodes(&maddr);
799                 ndisc_send_na(dev, NULL, &maddr, &msg->target,
800                               idev->cnf.forwarding, 0, (ifp != NULL), 1);
801                 goto out;
802         }
803
804         if (inc)
805                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
806         else
807                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
808
809         /* 
810          *      update / create cache entry
811          *      for the source address
812          */
813         neigh = __neigh_lookup(&nd_tbl, saddr, dev,
814                                !inc || lladdr || !dev->addr_len);
815         if (neigh)
816                 neigh_update(neigh, lladdr, NUD_STALE, 
817                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
818                              NEIGH_UPDATE_F_OVERRIDE);
819         if (neigh || !dev->hard_header) {
820                 ndisc_send_na(dev, neigh, saddr, &msg->target,
821                               idev->cnf.forwarding, 
822                               1, (ifp != NULL && inc), inc);
823                 if (neigh)
824                         neigh_release(neigh);
825         }
826
827 out:
828         if (ifp)
829                 in6_ifa_put(ifp);
830         else
831                 in6_dev_put(idev);
832
833         return;
834 }
835
836 static void ndisc_recv_na(struct sk_buff *skb)
837 {
838         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
839         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
840         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
841         u8 *lladdr = NULL;
842         int lladdrlen = 0;
843         u32 ndoptlen = skb->tail - msg->opt;
844         struct ndisc_options ndopts;
845         struct net_device *dev = skb->dev;
846         struct inet6_ifaddr *ifp;
847         struct neighbour *neigh;
848
849         if (skb->len < sizeof(struct nd_msg)) {
850                 ND_PRINTK2(KERN_WARNING
851                            "ICMPv6 NA: packet too short\n");
852                 return;
853         }
854
855         if (ipv6_addr_is_multicast(&msg->target)) {
856                 ND_PRINTK2(KERN_WARNING
857                            "ICMPv6 NA: target address is multicast.\n");
858                 return;
859         }
860
861         if (ipv6_addr_is_multicast(daddr) &&
862             msg->icmph.icmp6_solicited) {
863                 ND_PRINTK2(KERN_WARNING
864                            "ICMPv6 NA: solicited NA is multicasted.\n");
865                 return;
866         }
867                 
868         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
869                 ND_PRINTK2(KERN_WARNING
870                            "ICMPv6 NS: invalid ND option\n");
871                 return;
872         }
873         if (ndopts.nd_opts_tgt_lladdr) {
874                 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
875                 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
876                 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
877                         ND_PRINTK2(KERN_WARNING
878                                    "ICMPv6 NA: invalid link-layer address length\n");
879                         return;
880                 }
881         }
882         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
883                 if (ifp->flags & IFA_F_TENTATIVE) {
884                         addrconf_dad_failure(ifp);
885                         return;
886                 }
887                 /* What should we make now? The advertisement
888                    is invalid, but ndisc specs say nothing
889                    about it. It could be misconfiguration, or
890                    an smart proxy agent tries to help us :-)
891                  */
892                 ND_PRINTK1(KERN_WARNING
893                            "ICMPv6 NA: someone advertises our address on %s!\n",
894                            ifp->idev->dev->name);
895                 in6_ifa_put(ifp);
896                 return;
897         }
898         neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
899
900         if (neigh) {
901                 u8 old_flags = neigh->flags;
902
903                 neigh_update(neigh, lladdr,
904                              msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
905                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
906                              (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
907                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
908                              (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
909
910                 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
911                         /*
912                          * Change: router to host
913                          */
914                         struct rt6_info *rt;
915                         rt = rt6_get_dflt_router(saddr, dev);
916                         if (rt)
917                                 ip6_del_rt(rt, NULL, NULL);
918                 }
919
920                 neigh_release(neigh);
921         }
922 }
923
924 static void ndisc_recv_rs(struct sk_buff *skb)
925 {
926         struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
927         unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
928         struct neighbour *neigh;
929         struct inet6_dev *idev;
930         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
931         struct ndisc_options ndopts;
932         u8 *lladdr = NULL;
933         int lladdrlen = 0;
934
935         if (skb->len < sizeof(*rs_msg))
936                 return;
937
938         idev = in6_dev_get(skb->dev);
939         if (!idev) {
940                 if (net_ratelimit())
941                         ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
942                 return;
943         }
944
945         /* Don't accept RS if we're not in router mode */
946         if (!idev->cnf.forwarding)
947                 goto out;
948
949         /*
950          * Don't update NCE if src = ::;
951          * this implies that the source node has no ip address assigned yet.
952          */
953         if (ipv6_addr_any(saddr))
954                 goto out;
955
956         /* Parse ND options */
957         if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
958                 if (net_ratelimit())
959                         ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
960                 goto out;
961         }
962
963         if (ndopts.nd_opts_src_lladdr) {
964                 lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1);
965                 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
966                 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
967                         goto out;
968         }
969
970         neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
971         if (neigh) {
972                 neigh_update(neigh, lladdr, NUD_STALE,
973                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
974                              NEIGH_UPDATE_F_OVERRIDE|
975                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
976                 neigh_release(neigh);
977         }
978 out:
979         in6_dev_put(idev);
980 }
981
982 static void ndisc_router_discovery(struct sk_buff *skb)
983 {
984         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
985         struct neighbour *neigh;
986         struct inet6_dev *in6_dev;
987         struct rt6_info *rt;
988         int lifetime;
989         struct ndisc_options ndopts;
990         int optlen;
991
992         __u8 * opt = (__u8 *)(ra_msg + 1);
993
994         optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
995
996         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
997                 ND_PRINTK2(KERN_WARNING
998                            "ICMPv6 RA: source address is not link-local.\n");
999                 return;
1000         }
1001         if (optlen < 0) {
1002                 ND_PRINTK2(KERN_WARNING 
1003                            "ICMPv6 RA: packet too short\n");
1004                 return;
1005         }
1006
1007         /*
1008          *      set the RA_RECV flag in the interface
1009          */
1010
1011         in6_dev = in6_dev_get(skb->dev);
1012         if (in6_dev == NULL) {
1013                 ND_PRINTK0(KERN_ERR
1014                            "ICMPv6 RA: can't find inet6 device for %s.\n",
1015                            skb->dev->name);
1016                 return;
1017         }
1018         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1019                 in6_dev_put(in6_dev);
1020                 return;
1021         }
1022
1023         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1024                 in6_dev_put(in6_dev);
1025                 ND_PRINTK2(KERN_WARNING
1026                            "ICMP6 RA: invalid ND options\n");
1027                 return;
1028         }
1029
1030         if (in6_dev->if_flags & IF_RS_SENT) {
1031                 /*
1032                  *      flag that an RA was received after an RS was sent
1033                  *      out on this interface.
1034                  */
1035                 in6_dev->if_flags |= IF_RA_RCVD;
1036         }
1037
1038         /*
1039          * Remember the managed/otherconf flags from most recently
1040          * received RA message (RFC 2462) -- yoshfuji
1041          */
1042         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1043                                 IF_RA_OTHERCONF)) |
1044                                 (ra_msg->icmph.icmp6_addrconf_managed ?
1045                                         IF_RA_MANAGED : 0) |
1046                                 (ra_msg->icmph.icmp6_addrconf_other ?
1047                                         IF_RA_OTHERCONF : 0);
1048
1049         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1050
1051         rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1052
1053         if (rt && lifetime == 0) {
1054                 ip6_del_rt(rt, NULL, NULL);
1055                 rt = NULL;
1056         }
1057
1058         if (rt == NULL && lifetime) {
1059                 ND_PRINTK3(KERN_DEBUG
1060                            "ICMPv6 RA: adding default router.\n");
1061
1062                 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1063                 if (rt == NULL) {
1064                         ND_PRINTK0(KERN_ERR
1065                                    "ICMPv6 RA: %s() failed to add default route.\n",
1066                                    __FUNCTION__);
1067                         in6_dev_put(in6_dev);
1068                         return;
1069                 }
1070
1071                 neigh = rt->rt6i_nexthop;
1072                 if (neigh == NULL) {
1073                         ND_PRINTK0(KERN_ERR
1074                                    "ICMPv6 RA: %s() got default router without neighbour.\n",
1075                                    __FUNCTION__);
1076                         dst_release(&rt->u.dst);
1077                         in6_dev_put(in6_dev);
1078                         return;
1079                 }
1080                 neigh->flags |= NTF_ROUTER;
1081         }
1082
1083         if (rt)
1084                 rt->rt6i_expires = jiffies + (HZ * lifetime);
1085
1086         if (ra_msg->icmph.icmp6_hop_limit)
1087                 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1088
1089         /*
1090          *      Update Reachable Time and Retrans Timer
1091          */
1092
1093         if (in6_dev->nd_parms) {
1094                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1095
1096                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1097                         rtime = (rtime*HZ)/1000;
1098                         if (rtime < HZ/10)
1099                                 rtime = HZ/10;
1100                         in6_dev->nd_parms->retrans_time = rtime;
1101                         in6_dev->tstamp = jiffies;
1102                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1103                 }
1104
1105                 rtime = ntohl(ra_msg->reachable_time);
1106                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1107                         rtime = (rtime*HZ)/1000;
1108
1109                         if (rtime < HZ/10)
1110                                 rtime = HZ/10;
1111
1112                         if (rtime != in6_dev->nd_parms->base_reachable_time) {
1113                                 in6_dev->nd_parms->base_reachable_time = rtime;
1114                                 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1115                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1116                                 in6_dev->tstamp = jiffies;
1117                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1118                         }
1119                 }
1120         }
1121
1122         /*
1123          *      Process options.
1124          */
1125
1126         if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
1127                 u8 *lladdr = NULL;
1128                 int lladdrlen;
1129                 if (ndopts.nd_opts_src_lladdr) {
1130                         lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
1131                         lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
1132                         if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1133                                 ND_PRINTK2(KERN_WARNING
1134                                            "ICMPv6 RA: invalid link-layer address length\n");
1135                                 goto out;
1136                         }
1137                 }
1138                 neigh_update(neigh, lladdr, NUD_STALE,
1139                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1140                              NEIGH_UPDATE_F_OVERRIDE|
1141                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1142                              NEIGH_UPDATE_F_ISROUTER);
1143         }
1144
1145         if (ndopts.nd_opts_pi) {
1146                 struct nd_opt_hdr *p;
1147                 for (p = ndopts.nd_opts_pi;
1148                      p;
1149                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1150                         addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1151                 }
1152         }
1153
1154         if (ndopts.nd_opts_mtu) {
1155                 u32 mtu;
1156
1157                 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1158                 mtu = ntohl(mtu);
1159
1160                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1161                         ND_PRINTK2(KERN_WARNING
1162                                    "ICMPv6 RA: invalid mtu: %d\n",
1163                                    mtu);
1164                 } else if (in6_dev->cnf.mtu6 != mtu) {
1165                         in6_dev->cnf.mtu6 = mtu;
1166
1167                         if (rt)
1168                                 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1169
1170                         rt6_mtu_change(skb->dev, mtu);
1171                 }
1172         }
1173                         
1174         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1175                 ND_PRINTK2(KERN_WARNING
1176                            "ICMPv6 RA: invalid RA options");
1177         }
1178 out:
1179         if (rt)
1180                 dst_release(&rt->u.dst);
1181         in6_dev_put(in6_dev);
1182 }
1183
1184 static void ndisc_redirect_rcv(struct sk_buff *skb)
1185 {
1186         struct inet6_dev *in6_dev;
1187         struct icmp6hdr *icmph;
1188         struct in6_addr *dest;
1189         struct in6_addr *target;        /* new first hop to destination */
1190         struct neighbour *neigh;
1191         int on_link = 0;
1192         struct ndisc_options ndopts;
1193         int optlen;
1194         u8 *lladdr = NULL;
1195         int lladdrlen;
1196
1197         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1198                 ND_PRINTK2(KERN_WARNING
1199                            "ICMPv6 Redirect: source address is not link-local.\n");
1200                 return;
1201         }
1202
1203         optlen = skb->tail - skb->h.raw;
1204         optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1205
1206         if (optlen < 0) {
1207                 ND_PRINTK2(KERN_WARNING
1208                            "ICMPv6 Redirect: packet too short\n");
1209                 return;
1210         }
1211
1212         icmph = (struct icmp6hdr *) skb->h.raw;
1213         target = (struct in6_addr *) (icmph + 1);
1214         dest = target + 1;
1215
1216         if (ipv6_addr_is_multicast(dest)) {
1217                 ND_PRINTK2(KERN_WARNING
1218                            "ICMPv6 Redirect: destination address is multicast.\n");
1219                 return;
1220         }
1221
1222         if (ipv6_addr_equal(dest, target)) {
1223                 on_link = 1;
1224         } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1225                 ND_PRINTK2(KERN_WARNING 
1226                            "ICMPv6 Redirect: target address is not link-local.\n");
1227                 return;
1228         }
1229
1230         in6_dev = in6_dev_get(skb->dev);
1231         if (!in6_dev)
1232                 return;
1233         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1234                 in6_dev_put(in6_dev);
1235                 return;
1236         }
1237
1238         /* RFC2461 8.1: 
1239          *      The IP source address of the Redirect MUST be the same as the current
1240          *      first-hop router for the specified ICMP Destination Address.
1241          */
1242                 
1243         if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1244                 ND_PRINTK2(KERN_WARNING
1245                            "ICMPv6 Redirect: invalid ND options\n");
1246                 in6_dev_put(in6_dev);
1247                 return;
1248         }
1249         if (ndopts.nd_opts_tgt_lladdr) {
1250                 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
1251                 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1252                 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1253                         ND_PRINTK2(KERN_WARNING
1254                                    "ICMPv6 Redirect: invalid link-layer address length\n");
1255                         in6_dev_put(in6_dev);
1256                         return;
1257                 }
1258         }
1259
1260         neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1261         if (neigh) {
1262                 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, 
1263                              on_link);
1264                 neigh_release(neigh);
1265         }
1266         in6_dev_put(in6_dev);
1267 }
1268
1269 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1270                          struct in6_addr *target)
1271 {
1272         struct sock *sk = ndisc_socket->sk;
1273         int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1274         struct sk_buff *buff;
1275         struct icmp6hdr *icmph;
1276         struct in6_addr saddr_buf;
1277         struct in6_addr *addrp;
1278         struct net_device *dev;
1279         struct rt6_info *rt;
1280         struct dst_entry *dst;
1281         struct inet6_dev *idev;
1282         struct flowi fl;
1283         u8 *opt;
1284         int rd_len;
1285         int err;
1286         int hlen;
1287
1288         dev = skb->dev;
1289
1290         if (ipv6_get_lladdr(dev, &saddr_buf)) {
1291                 ND_PRINTK2(KERN_WARNING
1292                            "ICMPv6 Redirect: no link-local address on %s\n",
1293                            dev->name);
1294                 return;
1295         }
1296
1297         ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1298
1299         rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
1300         if (rt == NULL)
1301                 return;
1302         dst = &rt->u.dst;
1303
1304         err = xfrm_lookup(&dst, &fl, NULL, 0);
1305         if (err) {
1306                 dst_release(dst);
1307                 return;
1308         }
1309
1310         rt = (struct rt6_info *) dst;
1311
1312         if (rt->rt6i_flags & RTF_GATEWAY) {
1313                 ND_PRINTK2(KERN_WARNING
1314                            "ICMPv6 Redirect: destination is not a neighbour.\n");
1315                 dst_release(dst);
1316                 return;
1317         }
1318         if (!xrlim_allow(dst, 1*HZ)) {
1319                 dst_release(dst);
1320                 return;
1321         }
1322
1323         if (dev->addr_len) {
1324                 if (neigh->nud_state&NUD_VALID) {
1325                         len  += NDISC_OPT_SPACE(dev->addr_len);
1326                 } else {
1327                         /* If nexthop is not valid, do not redirect!
1328                            We will make it later, when will be sure,
1329                            that it is alive.
1330                          */
1331                         dst_release(dst);
1332                         return;
1333                 }
1334         }
1335
1336         rd_len = min_t(unsigned int,
1337                      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1338         rd_len &= ~0x7;
1339         len += rd_len;
1340
1341         buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1342                                    1, &err);
1343         if (buff == NULL) {
1344                 ND_PRINTK0(KERN_ERR
1345                            "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1346                            __FUNCTION__);
1347                 dst_release(dst);
1348                 return;
1349         }
1350
1351         hlen = 0;
1352
1353         skb_reserve(buff, LL_RESERVED_SPACE(dev));
1354         ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1355                    IPPROTO_ICMPV6, len);
1356
1357         icmph = (struct icmp6hdr *)skb_put(buff, len);
1358         buff->h.raw = (unsigned char*)icmph;
1359
1360         memset(icmph, 0, sizeof(struct icmp6hdr));
1361         icmph->icmp6_type = NDISC_REDIRECT;
1362
1363         /*
1364          *      copy target and destination addresses
1365          */
1366
1367         addrp = (struct in6_addr *)(icmph + 1);
1368         ipv6_addr_copy(addrp, target);
1369         addrp++;
1370         ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1371
1372         opt = (u8*) (addrp + 1);
1373
1374         /*
1375          *      include target_address option
1376          */
1377
1378         if (dev->addr_len)
1379                 opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
1380
1381         /*
1382          *      build redirect option and copy skb over to the new packet.
1383          */
1384
1385         memset(opt, 0, 8);      
1386         *(opt++) = ND_OPT_REDIRECT_HDR;
1387         *(opt++) = (rd_len >> 3);
1388         opt += 6;
1389
1390         memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1391
1392         icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1393                                              len, IPPROTO_ICMPV6,
1394                                              csum_partial((u8 *) icmph, len, 0));
1395
1396         buff->dst = dst;
1397         idev = in6_dev_get(dst->dev);
1398         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1399         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1400         if (!err) {
1401                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1402                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1403         }
1404
1405         if (likely(idev != NULL))
1406                 in6_dev_put(idev);
1407 }
1408
1409 static void pndisc_redo(struct sk_buff *skb)
1410 {
1411         ndisc_rcv(skb);
1412         kfree_skb(skb);
1413 }
1414
1415 int ndisc_rcv(struct sk_buff *skb)
1416 {
1417         struct nd_msg *msg;
1418
1419         if (!pskb_may_pull(skb, skb->len))
1420                 return 0;
1421
1422         msg = (struct nd_msg *) skb->h.raw;
1423
1424         __skb_push(skb, skb->data-skb->h.raw);
1425
1426         if (skb->nh.ipv6h->hop_limit != 255) {
1427                 ND_PRINTK2(KERN_WARNING
1428                            "ICMPv6 NDISC: invalid hop-limit: %d\n",
1429                            skb->nh.ipv6h->hop_limit);
1430                 return 0;
1431         }
1432
1433         if (msg->icmph.icmp6_code != 0) {
1434                 ND_PRINTK2(KERN_WARNING 
1435                            "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1436                            msg->icmph.icmp6_code);
1437                 return 0;
1438         }
1439
1440         switch (msg->icmph.icmp6_type) {
1441         case NDISC_NEIGHBOUR_SOLICITATION:
1442                 ndisc_recv_ns(skb);
1443                 break;
1444
1445         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1446                 ndisc_recv_na(skb);
1447                 break;
1448
1449         case NDISC_ROUTER_SOLICITATION:
1450                 ndisc_recv_rs(skb);
1451                 break;
1452
1453         case NDISC_ROUTER_ADVERTISEMENT:
1454                 ndisc_router_discovery(skb);
1455                 break;
1456
1457         case NDISC_REDIRECT:
1458                 ndisc_redirect_rcv(skb);
1459                 break;
1460         };
1461
1462         return 0;
1463 }
1464
1465 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1466 {
1467         struct net_device *dev = ptr;
1468
1469         switch (event) {
1470         case NETDEV_CHANGEADDR:
1471                 neigh_changeaddr(&nd_tbl, dev);
1472                 fib6_run_gc(0);
1473                 break;
1474         case NETDEV_DOWN:
1475                 neigh_ifdown(&nd_tbl, dev);
1476                 fib6_run_gc(0);
1477                 break;
1478         default:
1479                 break;
1480         }
1481
1482         return NOTIFY_DONE;
1483 }
1484
1485 static struct notifier_block ndisc_netdev_notifier = {
1486         .notifier_call = ndisc_netdev_event,
1487 };
1488
1489 #ifdef CONFIG_SYSCTL
1490 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1491 {
1492         struct net_device *dev = ctl->extra1;
1493         struct inet6_dev *idev;
1494
1495         if (write && dev && (idev = in6_dev_get(dev)) != NULL) {
1496                 idev->tstamp = jiffies;
1497                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1498                 in6_dev_put(idev);
1499         }
1500         return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1501 }
1502 #endif
1503
1504 int __init ndisc_init(struct net_proto_family *ops)
1505 {
1506         struct ipv6_pinfo *np;
1507         struct sock *sk;
1508         int err;
1509
1510         err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1511         if (err < 0) {
1512                 ND_PRINTK0(KERN_ERR
1513                            "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 
1514                            err);
1515                 ndisc_socket = NULL; /* For safety. */
1516                 return err;
1517         }
1518
1519         sk = ndisc_socket->sk;
1520         np = inet6_sk(sk);
1521         sk->sk_allocation = GFP_ATOMIC;
1522         np->hop_limit = 255;
1523         /* Do not loopback ndisc messages */
1524         np->mc_loop = 0;
1525         sk->sk_prot->unhash(sk);
1526
1527         /*
1528          * Initialize the neighbour table
1529          */
1530         
1531         neigh_table_init(&nd_tbl);
1532
1533 #ifdef CONFIG_SYSCTL
1534         neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 
1535                               "ipv6", &ndisc_ifinfo_sysctl_change);
1536 #endif
1537
1538         register_netdevice_notifier(&ndisc_netdev_notifier);
1539         return 0;
1540 }
1541
1542 void ndisc_cleanup(void)
1543 {
1544 #ifdef CONFIG_SYSCTL
1545         neigh_sysctl_unregister(&nd_tbl.parms);
1546 #endif
1547         neigh_table_clear(&nd_tbl);
1548         sock_release(ndisc_socket);
1549         ndisc_socket = NULL; /* For safety. */
1550 }