vserver 1.9.3
[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, 0))
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_router_discovery(struct sk_buff *skb)
925 {
926         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
927         struct neighbour *neigh;
928         struct inet6_dev *in6_dev;
929         struct rt6_info *rt;
930         int lifetime;
931         struct ndisc_options ndopts;
932         int optlen;
933
934         __u8 * opt = (__u8 *)(ra_msg + 1);
935
936         optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
937
938         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
939                 ND_PRINTK2(KERN_WARNING
940                            "ICMPv6 RA: source address is not link-local.\n");
941                 return;
942         }
943         if (optlen < 0) {
944                 ND_PRINTK2(KERN_WARNING 
945                            "ICMPv6 RA: packet too short\n");
946                 return;
947         }
948
949         /*
950          *      set the RA_RECV flag in the interface
951          */
952
953         in6_dev = in6_dev_get(skb->dev);
954         if (in6_dev == NULL) {
955                 ND_PRINTK0(KERN_ERR
956                            "ICMPv6 RA: can't find inet6 device for %s.\n",
957                            skb->dev->name);
958                 return;
959         }
960         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
961                 in6_dev_put(in6_dev);
962                 return;
963         }
964
965         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
966                 in6_dev_put(in6_dev);
967                 ND_PRINTK2(KERN_WARNING
968                            "ICMP6 RA: invalid ND options\n");
969                 return;
970         }
971
972         if (in6_dev->if_flags & IF_RS_SENT) {
973                 /*
974                  *      flag that an RA was received after an RS was sent
975                  *      out on this interface.
976                  */
977                 in6_dev->if_flags |= IF_RA_RCVD;
978         }
979
980         /*
981          * Remember the managed/otherconf flags from most recently
982          * received RA message (RFC 2462) -- yoshfuji
983          */
984         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
985                                 IF_RA_OTHERCONF)) |
986                                 (ra_msg->icmph.icmp6_addrconf_managed ?
987                                         IF_RA_MANAGED : 0) |
988                                 (ra_msg->icmph.icmp6_addrconf_other ?
989                                         IF_RA_OTHERCONF : 0);
990
991         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
992
993         rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
994
995         if (rt && lifetime == 0) {
996                 ip6_del_rt(rt, NULL, NULL);
997                 rt = NULL;
998         }
999
1000         if (rt == NULL && lifetime) {
1001                 ND_PRINTK3(KERN_DEBUG
1002                            "ICMPv6 RA: adding default router.\n");
1003
1004                 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1005                 if (rt == NULL) {
1006                         ND_PRINTK0(KERN_ERR
1007                                    "ICMPv6 RA: %s() failed to add default route.\n",
1008                                    __FUNCTION__);
1009                         in6_dev_put(in6_dev);
1010                         return;
1011                 }
1012
1013                 neigh = rt->rt6i_nexthop;
1014                 if (neigh == NULL) {
1015                         ND_PRINTK0(KERN_ERR
1016                                    "ICMPv6 RA: %s() got default router without neighbour.\n",
1017                                    __FUNCTION__);
1018                         dst_release(&rt->u.dst);
1019                         in6_dev_put(in6_dev);
1020                         return;
1021                 }
1022                 neigh->flags |= NTF_ROUTER;
1023
1024                 /*
1025                  *      If we where using an "all destinations on link" route
1026                  *      delete it
1027                  */
1028
1029                 rt6_purge_dflt_routers(RTF_ALLONLINK);
1030         }
1031
1032         if (rt)
1033                 rt->rt6i_expires = jiffies + (HZ * lifetime);
1034
1035         if (ra_msg->icmph.icmp6_hop_limit)
1036                 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1037
1038         /*
1039          *      Update Reachable Time and Retrans Timer
1040          */
1041
1042         if (in6_dev->nd_parms) {
1043                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1044
1045                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1046                         rtime = (rtime*HZ)/1000;
1047                         if (rtime < HZ/10)
1048                                 rtime = HZ/10;
1049                         in6_dev->nd_parms->retrans_time = rtime;
1050                         in6_dev->tstamp = jiffies;
1051                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1052                 }
1053
1054                 rtime = ntohl(ra_msg->reachable_time);
1055                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1056                         rtime = (rtime*HZ)/1000;
1057
1058                         if (rtime < HZ/10)
1059                                 rtime = HZ/10;
1060
1061                         if (rtime != in6_dev->nd_parms->base_reachable_time) {
1062                                 in6_dev->nd_parms->base_reachable_time = rtime;
1063                                 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1064                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1065                                 in6_dev->tstamp = jiffies;
1066                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1067                         }
1068                 }
1069         }
1070
1071         /*
1072          *      Process options.
1073          */
1074
1075         if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
1076                 u8 *lladdr = NULL;
1077                 int lladdrlen;
1078                 if (ndopts.nd_opts_src_lladdr) {
1079                         lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
1080                         lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
1081                         if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1082                                 ND_PRINTK2(KERN_WARNING
1083                                            "ICMPv6 RA: invalid link-layer address length\n");
1084                                 goto out;
1085                         }
1086                 }
1087                 neigh_update(neigh, lladdr, NUD_STALE,
1088                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1089                              NEIGH_UPDATE_F_OVERRIDE|
1090                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1091                              NEIGH_UPDATE_F_ISROUTER);
1092         }
1093
1094         if (ndopts.nd_opts_pi) {
1095                 struct nd_opt_hdr *p;
1096                 for (p = ndopts.nd_opts_pi;
1097                      p;
1098                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1099                         addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1100                 }
1101         }
1102
1103         if (ndopts.nd_opts_mtu) {
1104                 u32 mtu;
1105
1106                 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1107                 mtu = ntohl(mtu);
1108
1109                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1110                         ND_PRINTK2(KERN_WARNING
1111                                    "ICMPv6 RA: invalid mtu: %d\n",
1112                                    mtu);
1113                 } else if (in6_dev->cnf.mtu6 != mtu) {
1114                         in6_dev->cnf.mtu6 = mtu;
1115
1116                         if (rt)
1117                                 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1118
1119                         rt6_mtu_change(skb->dev, mtu);
1120                 }
1121         }
1122                         
1123         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1124                 ND_PRINTK2(KERN_WARNING
1125                            "ICMPv6 RA: invalid RA options");
1126         }
1127 out:
1128         if (rt)
1129                 dst_release(&rt->u.dst);
1130         in6_dev_put(in6_dev);
1131 }
1132
1133 static void ndisc_redirect_rcv(struct sk_buff *skb)
1134 {
1135         struct inet6_dev *in6_dev;
1136         struct icmp6hdr *icmph;
1137         struct in6_addr *dest;
1138         struct in6_addr *target;        /* new first hop to destination */
1139         struct neighbour *neigh;
1140         int on_link = 0;
1141         struct ndisc_options ndopts;
1142         int optlen;
1143         u8 *lladdr = NULL;
1144         int lladdrlen;
1145
1146         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1147                 ND_PRINTK2(KERN_WARNING
1148                            "ICMPv6 Redirect: source address is not link-local.\n");
1149                 return;
1150         }
1151
1152         optlen = skb->tail - skb->h.raw;
1153         optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1154
1155         if (optlen < 0) {
1156                 ND_PRINTK2(KERN_WARNING
1157                            "ICMPv6 Redirect: packet too short\n");
1158                 return;
1159         }
1160
1161         icmph = (struct icmp6hdr *) skb->h.raw;
1162         target = (struct in6_addr *) (icmph + 1);
1163         dest = target + 1;
1164
1165         if (ipv6_addr_is_multicast(dest)) {
1166                 ND_PRINTK2(KERN_WARNING
1167                            "ICMPv6 Redirect: destination address is multicast.\n");
1168                 return;
1169         }
1170
1171         if (ipv6_addr_cmp(dest, target) == 0) {
1172                 on_link = 1;
1173         } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1174                 ND_PRINTK2(KERN_WARNING 
1175                            "ICMPv6 Redirect: target address is not link-local.\n");
1176                 return;
1177         }
1178
1179         in6_dev = in6_dev_get(skb->dev);
1180         if (!in6_dev)
1181                 return;
1182         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1183                 in6_dev_put(in6_dev);
1184                 return;
1185         }
1186
1187         /* RFC2461 8.1: 
1188          *      The IP source address of the Redirect MUST be the same as the current
1189          *      first-hop router for the specified ICMP Destination Address.
1190          */
1191                 
1192         if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1193                 ND_PRINTK2(KERN_WARNING
1194                            "ICMPv6 Redirect: invalid ND options\n");
1195                 in6_dev_put(in6_dev);
1196                 return;
1197         }
1198         if (ndopts.nd_opts_tgt_lladdr) {
1199                 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
1200                 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1201                 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1202                         ND_PRINTK2(KERN_WARNING
1203                                    "ICMPv6 Redirect: invalid link-layer address length\n");
1204                         in6_dev_put(in6_dev);
1205                         return;
1206                 }
1207         }
1208
1209         neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1210         if (neigh) {
1211                 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, 
1212                              on_link);
1213                 neigh_release(neigh);
1214         }
1215         in6_dev_put(in6_dev);
1216 }
1217
1218 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1219                          struct in6_addr *target)
1220 {
1221         struct sock *sk = ndisc_socket->sk;
1222         int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1223         struct sk_buff *buff;
1224         struct icmp6hdr *icmph;
1225         struct in6_addr saddr_buf;
1226         struct in6_addr *addrp;
1227         struct net_device *dev;
1228         struct rt6_info *rt;
1229         struct dst_entry *dst;
1230         struct inet6_dev *idev;
1231         struct flowi fl;
1232         u8 *opt;
1233         int rd_len;
1234         int err;
1235         int hlen;
1236
1237         dev = skb->dev;
1238
1239         if (ipv6_get_lladdr(dev, &saddr_buf)) {
1240                 ND_PRINTK2(KERN_WARNING
1241                            "ICMPv6 Redirect: no link-local address on %s\n",
1242                            dev->name);
1243                 return;
1244         }
1245
1246         ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1247
1248         rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
1249         if (rt == NULL)
1250                 return;
1251         dst = &rt->u.dst;
1252
1253         err = xfrm_lookup(&dst, &fl, NULL, 0);
1254         if (err) {
1255                 dst_release(dst);
1256                 return;
1257         }
1258
1259         rt = (struct rt6_info *) dst;
1260
1261         if (rt->rt6i_flags & RTF_GATEWAY) {
1262                 ND_PRINTK2(KERN_WARNING
1263                            "ICMPv6 Redirect: destination is not a neighbour.\n");
1264                 dst_release(dst);
1265                 return;
1266         }
1267         if (!xrlim_allow(dst, 1*HZ)) {
1268                 dst_release(dst);
1269                 return;
1270         }
1271
1272         if (dev->addr_len) {
1273                 if (neigh->nud_state&NUD_VALID) {
1274                         len  += NDISC_OPT_SPACE(dev->addr_len);
1275                 } else {
1276                         /* If nexthop is not valid, do not redirect!
1277                            We will make it later, when will be sure,
1278                            that it is alive.
1279                          */
1280                         dst_release(dst);
1281                         return;
1282                 }
1283         }
1284
1285         rd_len = min_t(unsigned int,
1286                      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1287         rd_len &= ~0x7;
1288         len += rd_len;
1289
1290         buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1291                                    1, &err);
1292         if (buff == NULL) {
1293                 ND_PRINTK0(KERN_ERR
1294                            "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1295                            __FUNCTION__);
1296                 dst_release(dst);
1297                 return;
1298         }
1299
1300         hlen = 0;
1301
1302         skb_reserve(buff, LL_RESERVED_SPACE(dev));
1303         ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1304                    IPPROTO_ICMPV6, len);
1305
1306         icmph = (struct icmp6hdr *)skb_put(buff, len);
1307         buff->h.raw = (unsigned char*)icmph;
1308
1309         memset(icmph, 0, sizeof(struct icmp6hdr));
1310         icmph->icmp6_type = NDISC_REDIRECT;
1311
1312         /*
1313          *      copy target and destination addresses
1314          */
1315
1316         addrp = (struct in6_addr *)(icmph + 1);
1317         ipv6_addr_copy(addrp, target);
1318         addrp++;
1319         ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1320
1321         opt = (u8*) (addrp + 1);
1322
1323         /*
1324          *      include target_address option
1325          */
1326
1327         if (dev->addr_len)
1328                 opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
1329
1330         /*
1331          *      build redirect option and copy skb over to the new packet.
1332          */
1333
1334         memset(opt, 0, 8);      
1335         *(opt++) = ND_OPT_REDIRECT_HDR;
1336         *(opt++) = (rd_len >> 3);
1337         opt += 6;
1338
1339         memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1340
1341         icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1342                                              len, IPPROTO_ICMPV6,
1343                                              csum_partial((u8 *) icmph, len, 0));
1344
1345         buff->dst = dst;
1346         idev = in6_dev_get(dst->dev);
1347         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1348         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1349         if (!err) {
1350                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1351                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1352         }
1353
1354         if (likely(idev != NULL))
1355                 in6_dev_put(idev);
1356 }
1357
1358 static void pndisc_redo(struct sk_buff *skb)
1359 {
1360         ndisc_rcv(skb);
1361         kfree_skb(skb);
1362 }
1363
1364 int ndisc_rcv(struct sk_buff *skb)
1365 {
1366         struct nd_msg *msg;
1367
1368         if (!pskb_may_pull(skb, skb->len))
1369                 return 0;
1370
1371         msg = (struct nd_msg *) skb->h.raw;
1372
1373         __skb_push(skb, skb->data-skb->h.raw);
1374
1375         if (skb->nh.ipv6h->hop_limit != 255) {
1376                 ND_PRINTK2(KERN_WARNING
1377                            "ICMPv6 NDISC: invalid hop-limit: %d\n",
1378                            skb->nh.ipv6h->hop_limit);
1379                 return 0;
1380         }
1381
1382         if (msg->icmph.icmp6_code != 0) {
1383                 ND_PRINTK2(KERN_WARNING 
1384                            "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1385                            msg->icmph.icmp6_code);
1386                 return 0;
1387         }
1388
1389         switch (msg->icmph.icmp6_type) {
1390         case NDISC_NEIGHBOUR_SOLICITATION:
1391                 ndisc_recv_ns(skb);
1392                 break;
1393
1394         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1395                 ndisc_recv_na(skb);
1396                 break;
1397
1398         case NDISC_ROUTER_ADVERTISEMENT:
1399                 ndisc_router_discovery(skb);
1400                 break;
1401
1402         case NDISC_REDIRECT:
1403                 ndisc_redirect_rcv(skb);
1404                 break;
1405         };
1406
1407         return 0;
1408 }
1409
1410 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1411 {
1412         struct net_device *dev = ptr;
1413
1414         switch (event) {
1415         case NETDEV_CHANGEADDR:
1416                 neigh_changeaddr(&nd_tbl, dev);
1417                 fib6_run_gc(0);
1418                 break;
1419         case NETDEV_DOWN:
1420                 neigh_ifdown(&nd_tbl, dev);
1421                 fib6_run_gc(0);
1422                 break;
1423         default:
1424                 break;
1425         }
1426
1427         return NOTIFY_DONE;
1428 }
1429
1430 static struct notifier_block ndisc_netdev_notifier = {
1431         .notifier_call = ndisc_netdev_event,
1432 };
1433
1434 #ifdef CONFIG_SYSCTL
1435 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1436 {
1437         struct net_device *dev = ctl->extra1;
1438         struct inet6_dev *idev;
1439
1440         if (write && dev && (idev = in6_dev_get(dev)) != NULL) {
1441                 idev->tstamp = jiffies;
1442                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1443                 in6_dev_put(idev);
1444         }
1445         return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1446 }
1447 #endif
1448
1449 int __init ndisc_init(struct net_proto_family *ops)
1450 {
1451         struct ipv6_pinfo *np;
1452         struct sock *sk;
1453         int err;
1454
1455         err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1456         if (err < 0) {
1457                 ND_PRINTK0(KERN_ERR
1458                            "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 
1459                            err);
1460                 ndisc_socket = NULL; /* For safety. */
1461                 return err;
1462         }
1463
1464         sk = ndisc_socket->sk;
1465         np = inet6_sk(sk);
1466         sk->sk_allocation = GFP_ATOMIC;
1467         np->hop_limit = 255;
1468         /* Do not loopback ndisc messages */
1469         np->mc_loop = 0;
1470         sk->sk_prot->unhash(sk);
1471
1472         /*
1473          * Initialize the neighbour table
1474          */
1475         
1476         neigh_table_init(&nd_tbl);
1477
1478 #ifdef CONFIG_SYSCTL
1479         neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 
1480                               "ipv6", &ndisc_ifinfo_sysctl_change);
1481 #endif
1482
1483         register_netdevice_notifier(&ndisc_netdev_notifier);
1484         return 0;
1485 }
1486
1487 void ndisc_cleanup(void)
1488 {
1489 #ifdef CONFIG_SYSCTL
1490         neigh_sysctl_unregister(&nd_tbl.parms);
1491 #endif
1492         neigh_table_clear(&nd_tbl);
1493         sock_release(ndisc_socket);
1494         ndisc_socket = NULL; /* For safety. */
1495 }