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