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