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