]> bbs.cooldavid.org Git - net-next-2.6.git/blob - net/ipv6/ndisc.c
[IPV6]: ROUTE: Add support for Router Preference (RFC4191).
[net-next-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_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 = NULL;
1023         int lifetime;
1024         struct ndisc_options ndopts;
1025         int optlen;
1026         unsigned int pref = 0;
1027
1028         __u8 * opt = (__u8 *)(ra_msg + 1);
1029
1030         optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
1031
1032         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1033                 ND_PRINTK2(KERN_WARNING
1034                            "ICMPv6 RA: source address is not link-local.\n");
1035                 return;
1036         }
1037         if (optlen < 0) {
1038                 ND_PRINTK2(KERN_WARNING 
1039                            "ICMPv6 RA: packet too short\n");
1040                 return;
1041         }
1042
1043         /*
1044          *      set the RA_RECV flag in the interface
1045          */
1046
1047         in6_dev = in6_dev_get(skb->dev);
1048         if (in6_dev == NULL) {
1049                 ND_PRINTK0(KERN_ERR
1050                            "ICMPv6 RA: can't find inet6 device for %s.\n",
1051                            skb->dev->name);
1052                 return;
1053         }
1054         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1055                 in6_dev_put(in6_dev);
1056                 return;
1057         }
1058
1059         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1060                 in6_dev_put(in6_dev);
1061                 ND_PRINTK2(KERN_WARNING
1062                            "ICMP6 RA: invalid ND options\n");
1063                 return;
1064         }
1065
1066         if (in6_dev->if_flags & IF_RS_SENT) {
1067                 /*
1068                  *      flag that an RA was received after an RS was sent
1069                  *      out on this interface.
1070                  */
1071                 in6_dev->if_flags |= IF_RA_RCVD;
1072         }
1073
1074         /*
1075          * Remember the managed/otherconf flags from most recently
1076          * received RA message (RFC 2462) -- yoshfuji
1077          */
1078         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1079                                 IF_RA_OTHERCONF)) |
1080                                 (ra_msg->icmph.icmp6_addrconf_managed ?
1081                                         IF_RA_MANAGED : 0) |
1082                                 (ra_msg->icmph.icmp6_addrconf_other ?
1083                                         IF_RA_OTHERCONF : 0);
1084
1085         if (!in6_dev->cnf.accept_ra_defrtr)
1086                 goto skip_defrtr;
1087
1088         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1089
1090 #ifdef CONFIG_IPV6_ROUTER_PREF
1091         pref = ra_msg->icmph.icmp6_router_pref;
1092         /* 10b is handled as if it were 00b (medium) */
1093         if (pref == ICMPV6_ROUTER_PREF_INVALID)
1094                 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1095 #endif
1096
1097         rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1098
1099         if (rt)
1100                 neigh = rt->rt6i_nexthop;
1101
1102         if (rt && lifetime == 0) {
1103                 neigh_clone(neigh);
1104                 ip6_del_rt(rt, NULL, NULL, NULL);
1105                 rt = NULL;
1106         }
1107
1108         if (rt == NULL && lifetime) {
1109                 ND_PRINTK3(KERN_DEBUG
1110                            "ICMPv6 RA: adding default router.\n");
1111
1112                 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
1113                 if (rt == NULL) {
1114                         ND_PRINTK0(KERN_ERR
1115                                    "ICMPv6 RA: %s() failed to add default route.\n",
1116                                    __FUNCTION__);
1117                         in6_dev_put(in6_dev);
1118                         return;
1119                 }
1120
1121                 neigh = rt->rt6i_nexthop;
1122                 if (neigh == NULL) {
1123                         ND_PRINTK0(KERN_ERR
1124                                    "ICMPv6 RA: %s() got default router without neighbour.\n",
1125                                    __FUNCTION__);
1126                         dst_release(&rt->u.dst);
1127                         in6_dev_put(in6_dev);
1128                         return;
1129                 }
1130                 neigh->flags |= NTF_ROUTER;
1131         } else if (rt) {
1132                 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1133         }
1134
1135         if (rt)
1136                 rt->rt6i_expires = jiffies + (HZ * lifetime);
1137
1138         if (ra_msg->icmph.icmp6_hop_limit) {
1139                 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1140                 if (rt)
1141                         rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1142         }
1143
1144 skip_defrtr:
1145
1146         /*
1147          *      Update Reachable Time and Retrans Timer
1148          */
1149
1150         if (in6_dev->nd_parms) {
1151                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1152
1153                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1154                         rtime = (rtime*HZ)/1000;
1155                         if (rtime < HZ/10)
1156                                 rtime = HZ/10;
1157                         in6_dev->nd_parms->retrans_time = rtime;
1158                         in6_dev->tstamp = jiffies;
1159                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1160                 }
1161
1162                 rtime = ntohl(ra_msg->reachable_time);
1163                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1164                         rtime = (rtime*HZ)/1000;
1165
1166                         if (rtime < HZ/10)
1167                                 rtime = HZ/10;
1168
1169                         if (rtime != in6_dev->nd_parms->base_reachable_time) {
1170                                 in6_dev->nd_parms->base_reachable_time = rtime;
1171                                 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1172                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1173                                 in6_dev->tstamp = jiffies;
1174                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1175                         }
1176                 }
1177         }
1178
1179         /*
1180          *      Process options.
1181          */
1182
1183         if (!neigh)
1184                 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1185                                        skb->dev, 1);
1186         if (neigh) {
1187                 u8 *lladdr = NULL;
1188                 if (ndopts.nd_opts_src_lladdr) {
1189                         lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1190                                                      skb->dev);
1191                         if (!lladdr) {
1192                                 ND_PRINTK2(KERN_WARNING
1193                                            "ICMPv6 RA: invalid link-layer address length\n");
1194                                 goto out;
1195                         }
1196                 }
1197                 neigh_update(neigh, lladdr, NUD_STALE,
1198                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1199                              NEIGH_UPDATE_F_OVERRIDE|
1200                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1201                              NEIGH_UPDATE_F_ISROUTER);
1202         }
1203
1204         if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1205                 struct nd_opt_hdr *p;
1206                 for (p = ndopts.nd_opts_pi;
1207                      p;
1208                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1209                         addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1210                 }
1211         }
1212
1213         if (ndopts.nd_opts_mtu) {
1214                 u32 mtu;
1215
1216                 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1217                 mtu = ntohl(mtu);
1218
1219                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1220                         ND_PRINTK2(KERN_WARNING
1221                                    "ICMPv6 RA: invalid mtu: %d\n",
1222                                    mtu);
1223                 } else if (in6_dev->cnf.mtu6 != mtu) {
1224                         in6_dev->cnf.mtu6 = mtu;
1225
1226                         if (rt)
1227                                 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1228
1229                         rt6_mtu_change(skb->dev, mtu);
1230                 }
1231         }
1232                         
1233         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1234                 ND_PRINTK2(KERN_WARNING
1235                            "ICMPv6 RA: invalid RA options");
1236         }
1237 out:
1238         if (rt)
1239                 dst_release(&rt->u.dst);
1240         else if (neigh)
1241                 neigh_release(neigh);
1242         in6_dev_put(in6_dev);
1243 }
1244
1245 static void ndisc_redirect_rcv(struct sk_buff *skb)
1246 {
1247         struct inet6_dev *in6_dev;
1248         struct icmp6hdr *icmph;
1249         struct in6_addr *dest;
1250         struct in6_addr *target;        /* new first hop to destination */
1251         struct neighbour *neigh;
1252         int on_link = 0;
1253         struct ndisc_options ndopts;
1254         int optlen;
1255         u8 *lladdr = NULL;
1256
1257         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1258                 ND_PRINTK2(KERN_WARNING
1259                            "ICMPv6 Redirect: source address is not link-local.\n");
1260                 return;
1261         }
1262
1263         optlen = skb->tail - skb->h.raw;
1264         optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1265
1266         if (optlen < 0) {
1267                 ND_PRINTK2(KERN_WARNING
1268                            "ICMPv6 Redirect: packet too short\n");
1269                 return;
1270         }
1271
1272         icmph = (struct icmp6hdr *) skb->h.raw;
1273         target = (struct in6_addr *) (icmph + 1);
1274         dest = target + 1;
1275
1276         if (ipv6_addr_is_multicast(dest)) {
1277                 ND_PRINTK2(KERN_WARNING
1278                            "ICMPv6 Redirect: destination address is multicast.\n");
1279                 return;
1280         }
1281
1282         if (ipv6_addr_equal(dest, target)) {
1283                 on_link = 1;
1284         } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1285                 ND_PRINTK2(KERN_WARNING 
1286                            "ICMPv6 Redirect: target address is not link-local.\n");
1287                 return;
1288         }
1289
1290         in6_dev = in6_dev_get(skb->dev);
1291         if (!in6_dev)
1292                 return;
1293         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1294                 in6_dev_put(in6_dev);
1295                 return;
1296         }
1297
1298         /* RFC2461 8.1: 
1299          *      The IP source address of the Redirect MUST be the same as the current
1300          *      first-hop router for the specified ICMP Destination Address.
1301          */
1302                 
1303         if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1304                 ND_PRINTK2(KERN_WARNING
1305                            "ICMPv6 Redirect: invalid ND options\n");
1306                 in6_dev_put(in6_dev);
1307                 return;
1308         }
1309         if (ndopts.nd_opts_tgt_lladdr) {
1310                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1311                                              skb->dev);
1312                 if (!lladdr) {
1313                         ND_PRINTK2(KERN_WARNING
1314                                    "ICMPv6 Redirect: invalid link-layer address length\n");
1315                         in6_dev_put(in6_dev);
1316                         return;
1317                 }
1318         }
1319
1320         neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1321         if (neigh) {
1322                 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, 
1323                              on_link);
1324                 neigh_release(neigh);
1325         }
1326         in6_dev_put(in6_dev);
1327 }
1328
1329 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1330                          struct in6_addr *target)
1331 {
1332         struct sock *sk = ndisc_socket->sk;
1333         int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1334         struct sk_buff *buff;
1335         struct icmp6hdr *icmph;
1336         struct in6_addr saddr_buf;
1337         struct in6_addr *addrp;
1338         struct net_device *dev;
1339         struct rt6_info *rt;
1340         struct dst_entry *dst;
1341         struct inet6_dev *idev;
1342         struct flowi fl;
1343         u8 *opt;
1344         int rd_len;
1345         int err;
1346         int hlen;
1347         u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1348
1349         dev = skb->dev;
1350
1351         if (ipv6_get_lladdr(dev, &saddr_buf)) {
1352                 ND_PRINTK2(KERN_WARNING
1353                            "ICMPv6 Redirect: no link-local address on %s\n",
1354                            dev->name);
1355                 return;
1356         }
1357
1358         ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1359
1360         dst = ip6_route_output(NULL, &fl);
1361         if (dst == NULL)
1362                 return;
1363
1364         err = xfrm_lookup(&dst, &fl, NULL, 0);
1365         if (err)
1366                 return;
1367
1368         rt = (struct rt6_info *) dst;
1369
1370         if (rt->rt6i_flags & RTF_GATEWAY) {
1371                 ND_PRINTK2(KERN_WARNING
1372                            "ICMPv6 Redirect: destination is not a neighbour.\n");
1373                 dst_release(dst);
1374                 return;
1375         }
1376         if (!xrlim_allow(dst, 1*HZ)) {
1377                 dst_release(dst);
1378                 return;
1379         }
1380
1381         if (dev->addr_len) {
1382                 read_lock_bh(&neigh->lock);
1383                 if (neigh->nud_state & NUD_VALID) {
1384                         memcpy(ha_buf, neigh->ha, dev->addr_len);
1385                         read_unlock_bh(&neigh->lock);
1386                         ha = ha_buf;
1387                         len += ndisc_opt_addr_space(dev);
1388                 } else
1389                         read_unlock_bh(&neigh->lock);
1390         }
1391
1392         rd_len = min_t(unsigned int,
1393                      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1394         rd_len &= ~0x7;
1395         len += rd_len;
1396
1397         buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1398                                    1, &err);
1399         if (buff == NULL) {
1400                 ND_PRINTK0(KERN_ERR
1401                            "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1402                            __FUNCTION__);
1403                 dst_release(dst);
1404                 return;
1405         }
1406
1407         hlen = 0;
1408
1409         skb_reserve(buff, LL_RESERVED_SPACE(dev));
1410         ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1411                    IPPROTO_ICMPV6, len);
1412
1413         icmph = (struct icmp6hdr *)skb_put(buff, len);
1414         buff->h.raw = (unsigned char*)icmph;
1415
1416         memset(icmph, 0, sizeof(struct icmp6hdr));
1417         icmph->icmp6_type = NDISC_REDIRECT;
1418
1419         /*
1420          *      copy target and destination addresses
1421          */
1422
1423         addrp = (struct in6_addr *)(icmph + 1);
1424         ipv6_addr_copy(addrp, target);
1425         addrp++;
1426         ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1427
1428         opt = (u8*) (addrp + 1);
1429
1430         /*
1431          *      include target_address option
1432          */
1433
1434         if (ha)
1435                 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1436                                              dev->addr_len, dev->type);
1437
1438         /*
1439          *      build redirect option and copy skb over to the new packet.
1440          */
1441
1442         memset(opt, 0, 8);      
1443         *(opt++) = ND_OPT_REDIRECT_HDR;
1444         *(opt++) = (rd_len >> 3);
1445         opt += 6;
1446
1447         memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1448
1449         icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1450                                              len, IPPROTO_ICMPV6,
1451                                              csum_partial((u8 *) icmph, len, 0));
1452
1453         buff->dst = dst;
1454         idev = in6_dev_get(dst->dev);
1455         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1456         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1457         if (!err) {
1458                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1459                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1460         }
1461
1462         if (likely(idev != NULL))
1463                 in6_dev_put(idev);
1464 }
1465
1466 static void pndisc_redo(struct sk_buff *skb)
1467 {
1468         ndisc_recv_ns(skb);
1469         kfree_skb(skb);
1470 }
1471
1472 int ndisc_rcv(struct sk_buff *skb)
1473 {
1474         struct nd_msg *msg;
1475
1476         if (!pskb_may_pull(skb, skb->len))
1477                 return 0;
1478
1479         msg = (struct nd_msg *) skb->h.raw;
1480
1481         __skb_push(skb, skb->data-skb->h.raw);
1482
1483         if (skb->nh.ipv6h->hop_limit != 255) {
1484                 ND_PRINTK2(KERN_WARNING
1485                            "ICMPv6 NDISC: invalid hop-limit: %d\n",
1486                            skb->nh.ipv6h->hop_limit);
1487                 return 0;
1488         }
1489
1490         if (msg->icmph.icmp6_code != 0) {
1491                 ND_PRINTK2(KERN_WARNING 
1492                            "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1493                            msg->icmph.icmp6_code);
1494                 return 0;
1495         }
1496
1497         memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1498
1499         switch (msg->icmph.icmp6_type) {
1500         case NDISC_NEIGHBOUR_SOLICITATION:
1501                 ndisc_recv_ns(skb);
1502                 break;
1503
1504         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1505                 ndisc_recv_na(skb);
1506                 break;
1507
1508         case NDISC_ROUTER_SOLICITATION:
1509                 ndisc_recv_rs(skb);
1510                 break;
1511
1512         case NDISC_ROUTER_ADVERTISEMENT:
1513                 ndisc_router_discovery(skb);
1514                 break;
1515
1516         case NDISC_REDIRECT:
1517                 ndisc_redirect_rcv(skb);
1518                 break;
1519         };
1520
1521         return 0;
1522 }
1523
1524 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1525 {
1526         struct net_device *dev = ptr;
1527
1528         switch (event) {
1529         case NETDEV_CHANGEADDR:
1530                 neigh_changeaddr(&nd_tbl, dev);
1531                 fib6_run_gc(~0UL);
1532                 break;
1533         case NETDEV_DOWN:
1534                 neigh_ifdown(&nd_tbl, dev);
1535                 fib6_run_gc(~0UL);
1536                 break;
1537         default:
1538                 break;
1539         }
1540
1541         return NOTIFY_DONE;
1542 }
1543
1544 static struct notifier_block ndisc_netdev_notifier = {
1545         .notifier_call = ndisc_netdev_event,
1546 };
1547
1548 #ifdef CONFIG_SYSCTL
1549 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1550                                          const char *func, const char *dev_name)
1551 {
1552         static char warncomm[TASK_COMM_LEN];
1553         static int warned;
1554         if (strcmp(warncomm, current->comm) && warned < 5) {
1555                 strcpy(warncomm, current->comm);
1556                 printk(KERN_WARNING
1557                         "process `%s' is using deprecated sysctl (%s) "
1558                         "net.ipv6.neigh.%s.%s; "
1559                         "Use net.ipv6.neigh.%s.%s_ms "
1560                         "instead.\n",
1561                         warncomm, func,
1562                         dev_name, ctl->procname,
1563                         dev_name, ctl->procname);
1564                 warned++;
1565         }
1566 }
1567
1568 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1569 {
1570         struct net_device *dev = ctl->extra1;
1571         struct inet6_dev *idev;
1572         int ret;
1573
1574         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1575             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1576                 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1577
1578         switch (ctl->ctl_name) {
1579         case NET_NEIGH_RETRANS_TIME:
1580                 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1581                 break;
1582         case NET_NEIGH_REACHABLE_TIME:
1583                 ret = proc_dointvec_jiffies(ctl, write,
1584                                             filp, buffer, lenp, ppos);
1585                 break;
1586         case NET_NEIGH_RETRANS_TIME_MS:
1587         case NET_NEIGH_REACHABLE_TIME_MS:
1588                 ret = proc_dointvec_ms_jiffies(ctl, write,
1589                                                filp, buffer, lenp, ppos);
1590                 break;
1591         default:
1592                 ret = -1;
1593         }
1594
1595         if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1596                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1597                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1598                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1599                 idev->tstamp = jiffies;
1600                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1601                 in6_dev_put(idev);
1602         }
1603         return ret;
1604 }
1605
1606 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1607                                         int nlen, void __user *oldval,
1608                                         size_t __user *oldlenp,
1609                                         void __user *newval, size_t newlen,
1610                                         void **context)
1611 {
1612         struct net_device *dev = ctl->extra1;
1613         struct inet6_dev *idev;
1614         int ret;
1615
1616         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1617             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1618                 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1619
1620         switch (ctl->ctl_name) {
1621         case NET_NEIGH_REACHABLE_TIME:
1622                 ret = sysctl_jiffies(ctl, name, nlen,
1623                                      oldval, oldlenp, newval, newlen,
1624                                      context);
1625                 break;
1626         case NET_NEIGH_RETRANS_TIME_MS:
1627         case NET_NEIGH_REACHABLE_TIME_MS:
1628                  ret = sysctl_ms_jiffies(ctl, name, nlen,
1629                                          oldval, oldlenp, newval, newlen,
1630                                          context);
1631                  break;
1632         default:
1633                 ret = 0;
1634         }
1635
1636         if (newval && newlen && ret > 0 &&
1637             dev && (idev = in6_dev_get(dev)) != NULL) {
1638                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1639                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1640                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1641                 idev->tstamp = jiffies;
1642                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1643                 in6_dev_put(idev);
1644         }
1645
1646         return ret;
1647 }
1648
1649 #endif
1650
1651 int __init ndisc_init(struct net_proto_family *ops)
1652 {
1653         struct ipv6_pinfo *np;
1654         struct sock *sk;
1655         int err;
1656
1657         err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1658         if (err < 0) {
1659                 ND_PRINTK0(KERN_ERR
1660                            "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 
1661                            err);
1662                 ndisc_socket = NULL; /* For safety. */
1663                 return err;
1664         }
1665
1666         sk = ndisc_socket->sk;
1667         np = inet6_sk(sk);
1668         sk->sk_allocation = GFP_ATOMIC;
1669         np->hop_limit = 255;
1670         /* Do not loopback ndisc messages */
1671         np->mc_loop = 0;
1672         sk->sk_prot->unhash(sk);
1673
1674         /*
1675          * Initialize the neighbour table
1676          */
1677         
1678         neigh_table_init(&nd_tbl);
1679
1680 #ifdef CONFIG_SYSCTL
1681         neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 
1682                               "ipv6",
1683                               &ndisc_ifinfo_sysctl_change,
1684                               &ndisc_ifinfo_sysctl_strategy);
1685 #endif
1686
1687         register_netdevice_notifier(&ndisc_netdev_notifier);
1688         return 0;
1689 }
1690
1691 void ndisc_cleanup(void)
1692 {
1693 #ifdef CONFIG_SYSCTL
1694         neigh_sysctl_unregister(&nd_tbl.parms);
1695 #endif
1696         neigh_table_clear(&nd_tbl);
1697         sock_release(ndisc_socket);
1698         ndisc_socket = NULL; /* For safety. */
1699 }