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