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