NetLabel: correct CIPSO tag handling when adding new DOI definitions
[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,
476                                   (MAX_HEADER + sizeof(struct ipv6hdr) +
477                                    len + LL_RESERVED_SPACE(dev)),
478                                   1, &err);
479
480         if (skb == NULL) {
481                 ND_PRINTK0(KERN_ERR
482                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
483                            __FUNCTION__);
484                 dst_release(dst);
485                 return;
486         }
487
488         skb_reserve(skb, LL_RESERVED_SPACE(dev));
489         ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
490
491         msg = (struct nd_msg *)skb_put(skb, len);
492         skb->h.raw = (unsigned char*)msg;
493
494         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
495         msg->icmph.icmp6_code = 0;
496         msg->icmph.icmp6_cksum = 0;
497
498         msg->icmph.icmp6_unused = 0;
499         msg->icmph.icmp6_router    = router;
500         msg->icmph.icmp6_solicited = solicited;
501         msg->icmph.icmp6_override  = override;
502
503         /* Set the target address. */
504         ipv6_addr_copy(&msg->target, solicited_addr);
505
506         if (inc_opt)
507                 ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
508                                        dev->addr_len, dev->type);
509
510         /* checksum */
511         msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len, 
512                                                  IPPROTO_ICMPV6,
513                                                  csum_partial((__u8 *) msg, 
514                                                               len, 0));
515
516         skb->dst = dst;
517         idev = in6_dev_get(dst->dev);
518         IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
519         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
520         if (!err) {
521                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
522                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
523         }
524
525         if (likely(idev != NULL))
526                 in6_dev_put(idev);
527 }        
528
529 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
530                    struct in6_addr *solicit,
531                    struct in6_addr *daddr, struct in6_addr *saddr) 
532 {
533         struct flowi fl;
534         struct dst_entry* dst;
535         struct inet6_dev *idev;
536         struct sock *sk = ndisc_socket->sk;
537         struct sk_buff *skb;
538         struct nd_msg *msg;
539         struct in6_addr addr_buf;
540         int len;
541         int err;
542         int send_llinfo;
543
544         if (saddr == NULL) {
545                 if (ipv6_get_lladdr(dev, &addr_buf))
546                         return;
547                 saddr = &addr_buf;
548         }
549
550         ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr,
551                         dev->ifindex);
552
553         dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
554         if (!dst)
555                 return;
556
557         err = xfrm_lookup(&dst, &fl, NULL, 0);
558         if (err < 0)
559                 return;
560
561         len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
562         send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
563         if (send_llinfo)
564                 len += ndisc_opt_addr_space(dev);
565
566         skb = sock_alloc_send_skb(sk,
567                                   (MAX_HEADER + sizeof(struct ipv6hdr) +
568                                    len + LL_RESERVED_SPACE(dev)),
569                                   1, &err);
570         if (skb == NULL) {
571                 ND_PRINTK0(KERN_ERR
572                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
573                            __FUNCTION__);
574                 dst_release(dst);
575                 return;
576         }
577
578         skb_reserve(skb, LL_RESERVED_SPACE(dev));
579         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
580
581         msg = (struct nd_msg *)skb_put(skb, len);
582         skb->h.raw = (unsigned char*)msg;
583         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
584         msg->icmph.icmp6_code = 0;
585         msg->icmph.icmp6_cksum = 0;
586         msg->icmph.icmp6_unused = 0;
587
588         /* Set the target address. */
589         ipv6_addr_copy(&msg->target, solicit);
590
591         if (send_llinfo)
592                 ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
593                                        dev->addr_len, dev->type);
594
595         /* checksum */
596         msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
597                                                  daddr, len, 
598                                                  IPPROTO_ICMPV6,
599                                                  csum_partial((__u8 *) msg, 
600                                                               len, 0));
601         /* send it! */
602         skb->dst = dst;
603         idev = in6_dev_get(dst->dev);
604         IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
605         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
606         if (!err) {
607                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
608                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
609         }
610
611         if (likely(idev != NULL))
612                 in6_dev_put(idev);
613 }
614
615 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
616                    struct in6_addr *daddr)
617 {
618         struct flowi fl;
619         struct dst_entry* dst;
620         struct inet6_dev *idev;
621         struct sock *sk = ndisc_socket->sk;
622         struct sk_buff *skb;
623         struct icmp6hdr *hdr;
624         __u8 * opt;
625         int len;
626         int err;
627
628         ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr,
629                         dev->ifindex);
630
631         dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
632         if (!dst)
633                 return;
634
635         err = xfrm_lookup(&dst, &fl, NULL, 0);
636         if (err < 0)
637                 return;
638
639         len = sizeof(struct icmp6hdr);
640         if (dev->addr_len)
641                 len += ndisc_opt_addr_space(dev);
642
643         skb = sock_alloc_send_skb(sk,
644                                   (MAX_HEADER + sizeof(struct ipv6hdr) +
645                                    len + LL_RESERVED_SPACE(dev)),
646                                   1, &err);
647         if (skb == NULL) {
648                 ND_PRINTK0(KERN_ERR
649                            "ICMPv6 RS: %s() failed to allocate an skb.\n", 
650                            __FUNCTION__);
651                 dst_release(dst);
652                 return;
653         }
654
655         skb_reserve(skb, LL_RESERVED_SPACE(dev));
656         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
657
658         hdr = (struct icmp6hdr *)skb_put(skb, len);
659         skb->h.raw = (unsigned char*)hdr;
660         hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
661         hdr->icmp6_code = 0;
662         hdr->icmp6_cksum = 0;
663         hdr->icmp6_unused = 0;
664
665         opt = (u8*) (hdr + 1);
666
667         if (dev->addr_len)
668                 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
669                                        dev->addr_len, dev->type);
670
671         /* checksum */
672         hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
673                                            IPPROTO_ICMPV6,
674                                            csum_partial((__u8 *) hdr, len, 0));
675
676         /* send it! */
677         skb->dst = dst;
678         idev = in6_dev_get(dst->dev);
679         IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
680         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
681         if (!err) {
682                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
683                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
684         }
685
686         if (likely(idev != NULL))
687                 in6_dev_put(idev);
688 }
689                    
690
691 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
692 {
693         /*
694          *      "The sender MUST return an ICMP
695          *       destination unreachable"
696          */
697         dst_link_failure(skb);
698         kfree_skb(skb);
699 }
700
701 /* Called with locked neigh: either read or both */
702
703 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
704 {
705         struct in6_addr *saddr = NULL;
706         struct in6_addr mcaddr;
707         struct net_device *dev = neigh->dev;
708         struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
709         int probes = atomic_read(&neigh->probes);
710
711         if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
712                 saddr = &skb->nh.ipv6h->saddr;
713
714         if ((probes -= neigh->parms->ucast_probes) < 0) {
715                 if (!(neigh->nud_state & NUD_VALID)) {
716                         ND_PRINTK1(KERN_DEBUG
717                                    "%s(): trying to ucast probe in NUD_INVALID: "
718                                    NIP6_FMT "\n",
719                                    __FUNCTION__,
720                                    NIP6(*target));
721                 }
722                 ndisc_send_ns(dev, neigh, target, target, saddr);
723         } else if ((probes -= neigh->parms->app_probes) < 0) {
724 #ifdef CONFIG_ARPD
725                 neigh_app_ns(neigh);
726 #endif
727         } else {
728                 addrconf_addr_solict_mult(target, &mcaddr);
729                 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
730         }
731 }
732
733 static void ndisc_recv_ns(struct sk_buff *skb)
734 {
735         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
736         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
737         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
738         u8 *lladdr = NULL;
739         u32 ndoptlen = skb->tail - msg->opt;
740         struct ndisc_options ndopts;
741         struct net_device *dev = skb->dev;
742         struct inet6_ifaddr *ifp;
743         struct inet6_dev *idev = NULL;
744         struct neighbour *neigh;
745         struct pneigh_entry *pneigh = NULL;
746         int dad = ipv6_addr_any(saddr);
747         int inc;
748         int is_router;
749
750         if (ipv6_addr_is_multicast(&msg->target)) {
751                 ND_PRINTK2(KERN_WARNING 
752                            "ICMPv6 NS: multicast target address");
753                 return;
754         }
755
756         /*
757          * RFC2461 7.1.1:
758          * DAD has to be destined for solicited node multicast address.
759          */
760         if (dad &&
761             !(daddr->s6_addr32[0] == htonl(0xff020000) &&
762               daddr->s6_addr32[1] == htonl(0x00000000) &&
763               daddr->s6_addr32[2] == htonl(0x00000001) &&
764               daddr->s6_addr [12] == 0xff )) {
765                 ND_PRINTK2(KERN_WARNING
766                            "ICMPv6 NS: bad DAD packet (wrong destination)\n");
767                 return;
768         }
769
770         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
771                 ND_PRINTK2(KERN_WARNING 
772                            "ICMPv6 NS: invalid ND options\n");
773                 return;
774         }
775
776         if (ndopts.nd_opts_src_lladdr) {
777                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
778                 if (!lladdr) {
779                         ND_PRINTK2(KERN_WARNING
780                                    "ICMPv6 NS: invalid link-layer address length\n");
781                         return;
782                 }
783
784                 /* RFC2461 7.1.1:
785                  *      If the IP source address is the unspecified address, 
786                  *      there MUST NOT be source link-layer address option 
787                  *      in the message.
788                  */
789                 if (dad) {
790                         ND_PRINTK2(KERN_WARNING 
791                                    "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
792                         return;
793                 }
794         }
795
796         inc = ipv6_addr_is_multicast(daddr);
797
798         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
799                 if (ifp->flags & IFA_F_TENTATIVE) {
800                         /* Address is tentative. If the source
801                            is unspecified address, it is someone
802                            does DAD, otherwise we ignore solicitations
803                            until DAD timer expires.
804                          */
805                         if (!dad)
806                                 goto out;
807                         if (dev->type == ARPHRD_IEEE802_TR) {
808                                 unsigned char *sadr = skb->mac.raw;
809                                 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
810                                     sadr[9] == dev->dev_addr[1] &&
811                                     sadr[10] == dev->dev_addr[2] &&
812                                     sadr[11] == dev->dev_addr[3] &&
813                                     sadr[12] == dev->dev_addr[4] &&
814                                     sadr[13] == dev->dev_addr[5]) {
815                                         /* looped-back to us */
816                                         goto out;
817                                 }
818                         }
819                         addrconf_dad_failure(ifp); 
820                         return;
821                 }
822
823                 idev = ifp->idev;
824         } else {
825                 idev = in6_dev_get(dev);
826                 if (!idev) {
827                         /* XXX: count this drop? */
828                         return;
829                 }
830
831                 if (ipv6_chk_acast_addr(dev, &msg->target) ||
832                     (idev->cnf.forwarding && 
833                      (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
834                      (pneigh = pneigh_lookup(&nd_tbl,
835                                              &msg->target, dev, 0)) != NULL)) {
836                         if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
837                             skb->pkt_type != PACKET_HOST &&
838                             inc != 0 &&
839                             idev->nd_parms->proxy_delay != 0) {
840                                 /*
841                                  * for anycast or proxy,
842                                  * sender should delay its response 
843                                  * by a random time between 0 and 
844                                  * MAX_ANYCAST_DELAY_TIME seconds.
845                                  * (RFC2461) -- yoshfuji
846                                  */
847                                 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
848                                 if (n)
849                                         pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
850                                 goto out;
851                         }
852                 } else
853                         goto out;
854         }
855
856         is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding);
857
858         if (dad) {
859                 struct in6_addr maddr;
860
861                 ipv6_addr_all_nodes(&maddr);
862                 ndisc_send_na(dev, NULL, &maddr, &msg->target,
863                               is_router, 0, (ifp != NULL), 1);
864                 goto out;
865         }
866
867         if (inc)
868                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
869         else
870                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
871
872         /* 
873          *      update / create cache entry
874          *      for the source address
875          */
876         neigh = __neigh_lookup(&nd_tbl, saddr, dev,
877                                !inc || lladdr || !dev->addr_len);
878         if (neigh)
879                 neigh_update(neigh, lladdr, NUD_STALE, 
880                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
881                              NEIGH_UPDATE_F_OVERRIDE);
882         if (neigh || !dev->hard_header) {
883                 ndisc_send_na(dev, neigh, saddr, &msg->target,
884                               is_router,
885                               1, (ifp != NULL && inc), inc);
886                 if (neigh)
887                         neigh_release(neigh);
888         }
889
890 out:
891         if (ifp)
892                 in6_ifa_put(ifp);
893         else
894                 in6_dev_put(idev);
895
896         return;
897 }
898
899 static void ndisc_recv_na(struct sk_buff *skb)
900 {
901         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
902         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
903         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
904         u8 *lladdr = NULL;
905         u32 ndoptlen = skb->tail - msg->opt;
906         struct ndisc_options ndopts;
907         struct net_device *dev = skb->dev;
908         struct inet6_ifaddr *ifp;
909         struct neighbour *neigh;
910
911         if (skb->len < sizeof(struct nd_msg)) {
912                 ND_PRINTK2(KERN_WARNING
913                            "ICMPv6 NA: packet too short\n");
914                 return;
915         }
916
917         if (ipv6_addr_is_multicast(&msg->target)) {
918                 ND_PRINTK2(KERN_WARNING
919                            "ICMPv6 NA: target address is multicast.\n");
920                 return;
921         }
922
923         if (ipv6_addr_is_multicast(daddr) &&
924             msg->icmph.icmp6_solicited) {
925                 ND_PRINTK2(KERN_WARNING
926                            "ICMPv6 NA: solicited NA is multicasted.\n");
927                 return;
928         }
929                 
930         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
931                 ND_PRINTK2(KERN_WARNING
932                            "ICMPv6 NS: invalid ND option\n");
933                 return;
934         }
935         if (ndopts.nd_opts_tgt_lladdr) {
936                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
937                 if (!lladdr) {
938                         ND_PRINTK2(KERN_WARNING
939                                    "ICMPv6 NA: invalid link-layer address length\n");
940                         return;
941                 }
942         }
943         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
944                 if (ifp->flags & IFA_F_TENTATIVE) {
945                         addrconf_dad_failure(ifp);
946                         return;
947                 }
948                 /* What should we make now? The advertisement
949                    is invalid, but ndisc specs say nothing
950                    about it. It could be misconfiguration, or
951                    an smart proxy agent tries to help us :-)
952                  */
953                 ND_PRINTK1(KERN_WARNING
954                            "ICMPv6 NA: someone advertises our address on %s!\n",
955                            ifp->idev->dev->name);
956                 in6_ifa_put(ifp);
957                 return;
958         }
959         neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
960
961         if (neigh) {
962                 u8 old_flags = neigh->flags;
963
964                 if (neigh->nud_state & NUD_FAILED)
965                         goto out;
966
967                 /*
968                  * Don't update the neighbor cache entry on a proxy NA from
969                  * ourselves because either the proxied node is off link or it
970                  * has already sent a NA to us.
971                  */
972                 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
973                     ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
974                     pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
975                         /* XXX: idev->cnf.prixy_ndp */
976                         goto out;
977                 }
978
979                 neigh_update(neigh, lladdr,
980                              msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
981                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
982                              (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
983                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
984                              (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
985
986                 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
987                         /*
988                          * Change: router to host
989                          */
990                         struct rt6_info *rt;
991                         rt = rt6_get_dflt_router(saddr, dev);
992                         if (rt)
993                                 ip6_del_rt(rt);
994                 }
995
996 out:
997                 neigh_release(neigh);
998         }
999 }
1000
1001 static void ndisc_recv_rs(struct sk_buff *skb)
1002 {
1003         struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
1004         unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
1005         struct neighbour *neigh;
1006         struct inet6_dev *idev;
1007         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
1008         struct ndisc_options ndopts;
1009         u8 *lladdr = NULL;
1010
1011         if (skb->len < sizeof(*rs_msg))
1012                 return;
1013
1014         idev = in6_dev_get(skb->dev);
1015         if (!idev) {
1016                 if (net_ratelimit())
1017                         ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
1018                 return;
1019         }
1020
1021         /* Don't accept RS if we're not in router mode */
1022         if (!idev->cnf.forwarding)
1023                 goto out;
1024
1025         /*
1026          * Don't update NCE if src = ::;
1027          * this implies that the source node has no ip address assigned yet.
1028          */
1029         if (ipv6_addr_any(saddr))
1030                 goto out;
1031
1032         /* Parse ND options */
1033         if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
1034                 if (net_ratelimit())
1035                         ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
1036                 goto out;
1037         }
1038
1039         if (ndopts.nd_opts_src_lladdr) {
1040                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1041                                              skb->dev);
1042                 if (!lladdr)
1043                         goto out;
1044         }
1045
1046         neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1047         if (neigh) {
1048                 neigh_update(neigh, lladdr, NUD_STALE,
1049                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1050                              NEIGH_UPDATE_F_OVERRIDE|
1051                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1052                 neigh_release(neigh);
1053         }
1054 out:
1055         in6_dev_put(idev);
1056 }
1057
1058 static void ndisc_router_discovery(struct sk_buff *skb)
1059 {
1060         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
1061         struct neighbour *neigh = NULL;
1062         struct inet6_dev *in6_dev;
1063         struct rt6_info *rt = NULL;
1064         int lifetime;
1065         struct ndisc_options ndopts;
1066         int optlen;
1067         unsigned int pref = 0;
1068
1069         __u8 * opt = (__u8 *)(ra_msg + 1);
1070
1071         optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
1072
1073         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1074                 ND_PRINTK2(KERN_WARNING
1075                            "ICMPv6 RA: source address is not link-local.\n");
1076                 return;
1077         }
1078         if (optlen < 0) {
1079                 ND_PRINTK2(KERN_WARNING 
1080                            "ICMPv6 RA: packet too short\n");
1081                 return;
1082         }
1083
1084         /*
1085          *      set the RA_RECV flag in the interface
1086          */
1087
1088         in6_dev = in6_dev_get(skb->dev);
1089         if (in6_dev == NULL) {
1090                 ND_PRINTK0(KERN_ERR
1091                            "ICMPv6 RA: can't find inet6 device for %s.\n",
1092                            skb->dev->name);
1093                 return;
1094         }
1095         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1096                 in6_dev_put(in6_dev);
1097                 return;
1098         }
1099
1100         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1101                 in6_dev_put(in6_dev);
1102                 ND_PRINTK2(KERN_WARNING
1103                            "ICMP6 RA: invalid ND options\n");
1104                 return;
1105         }
1106
1107         if (in6_dev->if_flags & IF_RS_SENT) {
1108                 /*
1109                  *      flag that an RA was received after an RS was sent
1110                  *      out on this interface.
1111                  */
1112                 in6_dev->if_flags |= IF_RA_RCVD;
1113         }
1114
1115         /*
1116          * Remember the managed/otherconf flags from most recently
1117          * received RA message (RFC 2462) -- yoshfuji
1118          */
1119         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1120                                 IF_RA_OTHERCONF)) |
1121                                 (ra_msg->icmph.icmp6_addrconf_managed ?
1122                                         IF_RA_MANAGED : 0) |
1123                                 (ra_msg->icmph.icmp6_addrconf_other ?
1124                                         IF_RA_OTHERCONF : 0);
1125
1126         if (!in6_dev->cnf.accept_ra_defrtr)
1127                 goto skip_defrtr;
1128
1129         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1130
1131 #ifdef CONFIG_IPV6_ROUTER_PREF
1132         pref = ra_msg->icmph.icmp6_router_pref;
1133         /* 10b is handled as if it were 00b (medium) */
1134         if (pref == ICMPV6_ROUTER_PREF_INVALID ||
1135             in6_dev->cnf.accept_ra_rtr_pref)
1136                 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1137 #endif
1138
1139         rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1140
1141         if (rt)
1142                 neigh = rt->rt6i_nexthop;
1143
1144         if (rt && lifetime == 0) {
1145                 neigh_clone(neigh);
1146                 ip6_del_rt(rt);
1147                 rt = NULL;
1148         }
1149
1150         if (rt == NULL && lifetime) {
1151                 ND_PRINTK3(KERN_DEBUG
1152                            "ICMPv6 RA: adding default router.\n");
1153
1154                 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
1155                 if (rt == NULL) {
1156                         ND_PRINTK0(KERN_ERR
1157                                    "ICMPv6 RA: %s() failed to add default route.\n",
1158                                    __FUNCTION__);
1159                         in6_dev_put(in6_dev);
1160                         return;
1161                 }
1162
1163                 neigh = rt->rt6i_nexthop;
1164                 if (neigh == NULL) {
1165                         ND_PRINTK0(KERN_ERR
1166                                    "ICMPv6 RA: %s() got default router without neighbour.\n",
1167                                    __FUNCTION__);
1168                         dst_release(&rt->u.dst);
1169                         in6_dev_put(in6_dev);
1170                         return;
1171                 }
1172                 neigh->flags |= NTF_ROUTER;
1173         } else if (rt) {
1174                 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1175         }
1176
1177         if (rt)
1178                 rt->rt6i_expires = jiffies + (HZ * lifetime);
1179
1180         if (ra_msg->icmph.icmp6_hop_limit) {
1181                 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1182                 if (rt)
1183                         rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1184         }
1185
1186 skip_defrtr:
1187
1188         /*
1189          *      Update Reachable Time and Retrans Timer
1190          */
1191
1192         if (in6_dev->nd_parms) {
1193                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1194
1195                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1196                         rtime = (rtime*HZ)/1000;
1197                         if (rtime < HZ/10)
1198                                 rtime = HZ/10;
1199                         in6_dev->nd_parms->retrans_time = rtime;
1200                         in6_dev->tstamp = jiffies;
1201                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1202                 }
1203
1204                 rtime = ntohl(ra_msg->reachable_time);
1205                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1206                         rtime = (rtime*HZ)/1000;
1207
1208                         if (rtime < HZ/10)
1209                                 rtime = HZ/10;
1210
1211                         if (rtime != in6_dev->nd_parms->base_reachable_time) {
1212                                 in6_dev->nd_parms->base_reachable_time = rtime;
1213                                 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1214                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1215                                 in6_dev->tstamp = jiffies;
1216                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1217                         }
1218                 }
1219         }
1220
1221         /*
1222          *      Process options.
1223          */
1224
1225         if (!neigh)
1226                 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1227                                        skb->dev, 1);
1228         if (neigh) {
1229                 u8 *lladdr = NULL;
1230                 if (ndopts.nd_opts_src_lladdr) {
1231                         lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1232                                                      skb->dev);
1233                         if (!lladdr) {
1234                                 ND_PRINTK2(KERN_WARNING
1235                                            "ICMPv6 RA: invalid link-layer address length\n");
1236                                 goto out;
1237                         }
1238                 }
1239                 neigh_update(neigh, lladdr, NUD_STALE,
1240                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1241                              NEIGH_UPDATE_F_OVERRIDE|
1242                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1243                              NEIGH_UPDATE_F_ISROUTER);
1244         }
1245
1246 #ifdef CONFIG_IPV6_ROUTE_INFO
1247         if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1248                 struct nd_opt_hdr *p;
1249                 for (p = ndopts.nd_opts_ri;
1250                      p;
1251                      p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1252                         if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1253                                 continue;
1254                         rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
1255                                       &skb->nh.ipv6h->saddr);
1256                 }
1257         }
1258 #endif
1259
1260         if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1261                 struct nd_opt_hdr *p;
1262                 for (p = ndopts.nd_opts_pi;
1263                      p;
1264                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1265                         addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1266                 }
1267         }
1268
1269         if (ndopts.nd_opts_mtu) {
1270                 __be32 n;
1271                 u32 mtu;
1272
1273                 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1274                 mtu = ntohl(n);
1275
1276                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1277                         ND_PRINTK2(KERN_WARNING
1278                                    "ICMPv6 RA: invalid mtu: %d\n",
1279                                    mtu);
1280                 } else if (in6_dev->cnf.mtu6 != mtu) {
1281                         in6_dev->cnf.mtu6 = mtu;
1282
1283                         if (rt)
1284                                 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1285
1286                         rt6_mtu_change(skb->dev, mtu);
1287                 }
1288         }
1289                         
1290         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1291                 ND_PRINTK2(KERN_WARNING
1292                            "ICMPv6 RA: invalid RA options");
1293         }
1294 out:
1295         if (rt)
1296                 dst_release(&rt->u.dst);
1297         else if (neigh)
1298                 neigh_release(neigh);
1299         in6_dev_put(in6_dev);
1300 }
1301
1302 static void ndisc_redirect_rcv(struct sk_buff *skb)
1303 {
1304         struct inet6_dev *in6_dev;
1305         struct icmp6hdr *icmph;
1306         struct in6_addr *dest;
1307         struct in6_addr *target;        /* new first hop to destination */
1308         struct neighbour *neigh;
1309         int on_link = 0;
1310         struct ndisc_options ndopts;
1311         int optlen;
1312         u8 *lladdr = NULL;
1313
1314         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1315                 ND_PRINTK2(KERN_WARNING
1316                            "ICMPv6 Redirect: source address is not link-local.\n");
1317                 return;
1318         }
1319
1320         optlen = skb->tail - skb->h.raw;
1321         optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1322
1323         if (optlen < 0) {
1324                 ND_PRINTK2(KERN_WARNING
1325                            "ICMPv6 Redirect: packet too short\n");
1326                 return;
1327         }
1328
1329         icmph = (struct icmp6hdr *) skb->h.raw;
1330         target = (struct in6_addr *) (icmph + 1);
1331         dest = target + 1;
1332
1333         if (ipv6_addr_is_multicast(dest)) {
1334                 ND_PRINTK2(KERN_WARNING
1335                            "ICMPv6 Redirect: destination address is multicast.\n");
1336                 return;
1337         }
1338
1339         if (ipv6_addr_equal(dest, target)) {
1340                 on_link = 1;
1341         } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1342                 ND_PRINTK2(KERN_WARNING 
1343                            "ICMPv6 Redirect: target address is not link-local.\n");
1344                 return;
1345         }
1346
1347         in6_dev = in6_dev_get(skb->dev);
1348         if (!in6_dev)
1349                 return;
1350         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1351                 in6_dev_put(in6_dev);
1352                 return;
1353         }
1354
1355         /* RFC2461 8.1: 
1356          *      The IP source address of the Redirect MUST be the same as the current
1357          *      first-hop router for the specified ICMP Destination Address.
1358          */
1359                 
1360         if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1361                 ND_PRINTK2(KERN_WARNING
1362                            "ICMPv6 Redirect: invalid ND options\n");
1363                 in6_dev_put(in6_dev);
1364                 return;
1365         }
1366         if (ndopts.nd_opts_tgt_lladdr) {
1367                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1368                                              skb->dev);
1369                 if (!lladdr) {
1370                         ND_PRINTK2(KERN_WARNING
1371                                    "ICMPv6 Redirect: invalid link-layer address length\n");
1372                         in6_dev_put(in6_dev);
1373                         return;
1374                 }
1375         }
1376
1377         neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1378         if (neigh) {
1379                 rt6_redirect(dest, &skb->nh.ipv6h->daddr,
1380                              &skb->nh.ipv6h->saddr, neigh, lladdr,
1381                              on_link);
1382                 neigh_release(neigh);
1383         }
1384         in6_dev_put(in6_dev);
1385 }
1386
1387 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1388                          struct in6_addr *target)
1389 {
1390         struct sock *sk = ndisc_socket->sk;
1391         int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1392         struct sk_buff *buff;
1393         struct icmp6hdr *icmph;
1394         struct in6_addr saddr_buf;
1395         struct in6_addr *addrp;
1396         struct net_device *dev;
1397         struct rt6_info *rt;
1398         struct dst_entry *dst;
1399         struct inet6_dev *idev;
1400         struct flowi fl;
1401         u8 *opt;
1402         int rd_len;
1403         int err;
1404         int hlen;
1405         u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1406
1407         dev = skb->dev;
1408
1409         if (ipv6_get_lladdr(dev, &saddr_buf)) {
1410                 ND_PRINTK2(KERN_WARNING
1411                            "ICMPv6 Redirect: no link-local address on %s\n",
1412                            dev->name);
1413                 return;
1414         }
1415
1416         ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr,
1417                         dev->ifindex);
1418
1419         dst = ip6_route_output(NULL, &fl);
1420         if (dst == NULL)
1421                 return;
1422
1423         err = xfrm_lookup(&dst, &fl, NULL, 0);
1424         if (err)
1425                 return;
1426
1427         rt = (struct rt6_info *) dst;
1428
1429         if (rt->rt6i_flags & RTF_GATEWAY) {
1430                 ND_PRINTK2(KERN_WARNING
1431                            "ICMPv6 Redirect: destination is not a neighbour.\n");
1432                 dst_release(dst);
1433                 return;
1434         }
1435         if (!xrlim_allow(dst, 1*HZ)) {
1436                 dst_release(dst);
1437                 return;
1438         }
1439
1440         if (dev->addr_len) {
1441                 read_lock_bh(&neigh->lock);
1442                 if (neigh->nud_state & NUD_VALID) {
1443                         memcpy(ha_buf, neigh->ha, dev->addr_len);
1444                         read_unlock_bh(&neigh->lock);
1445                         ha = ha_buf;
1446                         len += ndisc_opt_addr_space(dev);
1447                 } else
1448                         read_unlock_bh(&neigh->lock);
1449         }
1450
1451         rd_len = min_t(unsigned int,
1452                      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1453         rd_len &= ~0x7;
1454         len += rd_len;
1455
1456         buff = sock_alloc_send_skb(sk,
1457                                    (MAX_HEADER + sizeof(struct ipv6hdr) +
1458                                     len + LL_RESERVED_SPACE(dev)),
1459                                    1, &err);
1460         if (buff == NULL) {
1461                 ND_PRINTK0(KERN_ERR
1462                            "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1463                            __FUNCTION__);
1464                 dst_release(dst);
1465                 return;
1466         }
1467
1468         hlen = 0;
1469
1470         skb_reserve(buff, LL_RESERVED_SPACE(dev));
1471         ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1472                    IPPROTO_ICMPV6, len);
1473
1474         icmph = (struct icmp6hdr *)skb_put(buff, len);
1475         buff->h.raw = (unsigned char*)icmph;
1476
1477         memset(icmph, 0, sizeof(struct icmp6hdr));
1478         icmph->icmp6_type = NDISC_REDIRECT;
1479
1480         /*
1481          *      copy target and destination addresses
1482          */
1483
1484         addrp = (struct in6_addr *)(icmph + 1);
1485         ipv6_addr_copy(addrp, target);
1486         addrp++;
1487         ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1488
1489         opt = (u8*) (addrp + 1);
1490
1491         /*
1492          *      include target_address option
1493          */
1494
1495         if (ha)
1496                 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1497                                              dev->addr_len, dev->type);
1498
1499         /*
1500          *      build redirect option and copy skb over to the new packet.
1501          */
1502
1503         memset(opt, 0, 8);      
1504         *(opt++) = ND_OPT_REDIRECT_HDR;
1505         *(opt++) = (rd_len >> 3);
1506         opt += 6;
1507
1508         memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1509
1510         icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1511                                              len, IPPROTO_ICMPV6,
1512                                              csum_partial((u8 *) icmph, len, 0));
1513
1514         buff->dst = dst;
1515         idev = in6_dev_get(dst->dev);
1516         IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1517         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1518         if (!err) {
1519                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1520                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1521         }
1522
1523         if (likely(idev != NULL))
1524                 in6_dev_put(idev);
1525 }
1526
1527 static void pndisc_redo(struct sk_buff *skb)
1528 {
1529         ndisc_recv_ns(skb);
1530         kfree_skb(skb);
1531 }
1532
1533 int ndisc_rcv(struct sk_buff *skb)
1534 {
1535         struct nd_msg *msg;
1536
1537         if (!pskb_may_pull(skb, skb->len))
1538                 return 0;
1539
1540         msg = (struct nd_msg *) skb->h.raw;
1541
1542         __skb_push(skb, skb->data-skb->h.raw);
1543
1544         if (skb->nh.ipv6h->hop_limit != 255) {
1545                 ND_PRINTK2(KERN_WARNING
1546                            "ICMPv6 NDISC: invalid hop-limit: %d\n",
1547                            skb->nh.ipv6h->hop_limit);
1548                 return 0;
1549         }
1550
1551         if (msg->icmph.icmp6_code != 0) {
1552                 ND_PRINTK2(KERN_WARNING 
1553                            "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1554                            msg->icmph.icmp6_code);
1555                 return 0;
1556         }
1557
1558         memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1559
1560         switch (msg->icmph.icmp6_type) {
1561         case NDISC_NEIGHBOUR_SOLICITATION:
1562                 ndisc_recv_ns(skb);
1563                 break;
1564
1565         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1566                 ndisc_recv_na(skb);
1567                 break;
1568
1569         case NDISC_ROUTER_SOLICITATION:
1570                 ndisc_recv_rs(skb);
1571                 break;
1572
1573         case NDISC_ROUTER_ADVERTISEMENT:
1574                 ndisc_router_discovery(skb);
1575                 break;
1576
1577         case NDISC_REDIRECT:
1578                 ndisc_redirect_rcv(skb);
1579                 break;
1580         };
1581
1582         return 0;
1583 }
1584
1585 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1586 {
1587         struct net_device *dev = ptr;
1588
1589         switch (event) {
1590         case NETDEV_CHANGEADDR:
1591                 neigh_changeaddr(&nd_tbl, dev);
1592                 fib6_run_gc(~0UL);
1593                 break;
1594         case NETDEV_DOWN:
1595                 neigh_ifdown(&nd_tbl, dev);
1596                 fib6_run_gc(~0UL);
1597                 break;
1598         default:
1599                 break;
1600         }
1601
1602         return NOTIFY_DONE;
1603 }
1604
1605 static struct notifier_block ndisc_netdev_notifier = {
1606         .notifier_call = ndisc_netdev_event,
1607 };
1608
1609 #ifdef CONFIG_SYSCTL
1610 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1611                                          const char *func, const char *dev_name)
1612 {
1613         static char warncomm[TASK_COMM_LEN];
1614         static int warned;
1615         if (strcmp(warncomm, current->comm) && warned < 5) {
1616                 strcpy(warncomm, current->comm);
1617                 printk(KERN_WARNING
1618                         "process `%s' is using deprecated sysctl (%s) "
1619                         "net.ipv6.neigh.%s.%s; "
1620                         "Use net.ipv6.neigh.%s.%s_ms "
1621                         "instead.\n",
1622                         warncomm, func,
1623                         dev_name, ctl->procname,
1624                         dev_name, ctl->procname);
1625                 warned++;
1626         }
1627 }
1628
1629 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1630 {
1631         struct net_device *dev = ctl->extra1;
1632         struct inet6_dev *idev;
1633         int ret;
1634
1635         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1636             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1637                 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1638
1639         switch (ctl->ctl_name) {
1640         case NET_NEIGH_RETRANS_TIME:
1641                 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1642                 break;
1643         case NET_NEIGH_REACHABLE_TIME:
1644                 ret = proc_dointvec_jiffies(ctl, write,
1645                                             filp, buffer, lenp, ppos);
1646                 break;
1647         case NET_NEIGH_RETRANS_TIME_MS:
1648         case NET_NEIGH_REACHABLE_TIME_MS:
1649                 ret = proc_dointvec_ms_jiffies(ctl, write,
1650                                                filp, buffer, lenp, ppos);
1651                 break;
1652         default:
1653                 ret = -1;
1654         }
1655
1656         if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1657                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1658                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1659                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1660                 idev->tstamp = jiffies;
1661                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1662                 in6_dev_put(idev);
1663         }
1664         return ret;
1665 }
1666
1667 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1668                                         int nlen, void __user *oldval,
1669                                         size_t __user *oldlenp,
1670                                         void __user *newval, size_t newlen)
1671 {
1672         struct net_device *dev = ctl->extra1;
1673         struct inet6_dev *idev;
1674         int ret;
1675
1676         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1677             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1678                 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1679
1680         switch (ctl->ctl_name) {
1681         case NET_NEIGH_REACHABLE_TIME:
1682                 ret = sysctl_jiffies(ctl, name, nlen,
1683                                      oldval, oldlenp, newval, newlen);
1684                 break;
1685         case NET_NEIGH_RETRANS_TIME_MS:
1686         case NET_NEIGH_REACHABLE_TIME_MS:
1687                  ret = sysctl_ms_jiffies(ctl, name, nlen,
1688                                          oldval, oldlenp, newval, newlen);
1689                  break;
1690         default:
1691                 ret = 0;
1692         }
1693
1694         if (newval && newlen && ret > 0 &&
1695             dev && (idev = in6_dev_get(dev)) != NULL) {
1696                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1697                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1698                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1699                 idev->tstamp = jiffies;
1700                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1701                 in6_dev_put(idev);
1702         }
1703
1704         return ret;
1705 }
1706
1707 #endif
1708
1709 int __init ndisc_init(struct net_proto_family *ops)
1710 {
1711         struct ipv6_pinfo *np;
1712         struct sock *sk;
1713         int err;
1714
1715         err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1716         if (err < 0) {
1717                 ND_PRINTK0(KERN_ERR
1718                            "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 
1719                            err);
1720                 ndisc_socket = NULL; /* For safety. */
1721                 return err;
1722         }
1723
1724         sk = ndisc_socket->sk;
1725         np = inet6_sk(sk);
1726         sk->sk_allocation = GFP_ATOMIC;
1727         np->hop_limit = 255;
1728         /* Do not loopback ndisc messages */
1729         np->mc_loop = 0;
1730         sk->sk_prot->unhash(sk);
1731
1732         /*
1733          * Initialize the neighbour table
1734          */
1735         
1736         neigh_table_init(&nd_tbl);
1737
1738 #ifdef CONFIG_SYSCTL
1739         neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 
1740                               "ipv6",
1741                               &ndisc_ifinfo_sysctl_change,
1742                               &ndisc_ifinfo_sysctl_strategy);
1743 #endif
1744
1745         register_netdevice_notifier(&ndisc_netdev_notifier);
1746         return 0;
1747 }
1748
1749 void ndisc_cleanup(void)
1750 {
1751         unregister_netdevice_notifier(&ndisc_netdev_notifier);
1752 #ifdef CONFIG_SYSCTL
1753         neigh_sysctl_unregister(&nd_tbl.parms);
1754 #endif
1755         neigh_table_clear(&nd_tbl);
1756         sock_release(ndisc_socket);
1757         ndisc_socket = NULL; /* For safety. */
1758 }