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