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