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