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