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