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