]> bbs.cooldavid.org Git - net-next-2.6.git/blob - net/ipv6/ndisc.c
[IPv4]: Move interface address bits to linux/if_addr.h
[net-next-2.6.git] / net / ipv6 / ndisc.c
1 /*
2  *      Neighbour Discovery for IPv6
3  *      Linux INET6 implementation 
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>     
7  *      Mike Shaver             <shaver@ingenia.com>
8  *
9  *      This program is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU General Public License
11  *      as published by the Free Software Foundation; either version
12  *      2 of the License, or (at your option) any later version.
13  */
14
15 /*
16  *      Changes:
17  *
18  *      Lars Fenneberg                  :       fixed MTU setting on receipt
19  *                                              of an RA.
20  *
21  *      Janos Farkas                    :       kmalloc failure checks
22  *      Alexey Kuznetsov                :       state machine reworked
23  *                                              and moved to net/core.
24  *      Pekka Savola                    :       RFC2461 validation
25  *      YOSHIFUJI Hideaki @USAGI        :       Verify ND options properly
26  */
27
28 /* Set to 3 to get tracing... */
29 #define ND_DEBUG 1
30
31 #define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0)
32 #define ND_NOPRINTK(x...) do { ; } while(0)
33 #define ND_PRINTK0 ND_PRINTK
34 #define ND_PRINTK1 ND_NOPRINTK
35 #define ND_PRINTK2 ND_NOPRINTK
36 #define ND_PRINTK3 ND_NOPRINTK
37 #if ND_DEBUG >= 1
38 #undef ND_PRINTK1
39 #define ND_PRINTK1 ND_PRINTK
40 #endif
41 #if ND_DEBUG >= 2
42 #undef ND_PRINTK2
43 #define ND_PRINTK2 ND_PRINTK
44 #endif
45 #if ND_DEBUG >= 3
46 #undef ND_PRINTK3
47 #define ND_PRINTK3 ND_PRINTK
48 #endif
49
50 #include <linux/module.h>
51 #include <linux/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 {
417         memset(fl, 0, sizeof(*fl));
418         ipv6_addr_copy(&fl->fl6_src, saddr);
419         ipv6_addr_copy(&fl->fl6_dst, daddr);
420         fl->proto               = IPPROTO_ICMPV6;
421         fl->fl_icmp_type        = type;
422         fl->fl_icmp_code        = 0;
423         security_sk_classify_flow(ndisc_socket->sk, fl);
424 }
425
426 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
427                    struct in6_addr *daddr, struct in6_addr *solicited_addr,
428                    int router, int solicited, int override, int inc_opt) 
429 {
430         struct in6_addr tmpaddr;
431         struct inet6_ifaddr *ifp;
432         struct inet6_dev *idev;
433         struct flowi fl;
434         struct dst_entry* dst;
435         struct sock *sk = ndisc_socket->sk;
436         struct in6_addr *src_addr;
437         struct nd_msg *msg;
438         int len;
439         struct sk_buff *skb;
440         int err;
441
442         len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
443
444         /* for anycast or proxy, solicited_addr != src_addr */
445         ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
446         if (ifp) {
447                 src_addr = solicited_addr;
448                 in6_ifa_put(ifp);
449         } else {
450                 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
451                         return;
452                 src_addr = &tmpaddr;
453         }
454
455         ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
456
457         dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
458         if (!dst)
459                 return;
460
461         err = xfrm_lookup(&dst, &fl, NULL, 0);
462         if (err < 0)
463                 return;
464
465         if (inc_opt) {
466                 if (dev->addr_len)
467                         len += ndisc_opt_addr_space(dev);
468                 else
469                         inc_opt = 0;
470         }
471
472         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
473                                   1, &err);
474
475         if (skb == NULL) {
476                 ND_PRINTK0(KERN_ERR
477                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
478                            __FUNCTION__);
479                 dst_release(dst);
480                 return;
481         }
482
483         skb_reserve(skb, LL_RESERVED_SPACE(dev));
484         ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
485
486         msg = (struct nd_msg *)skb_put(skb, len);
487         skb->h.raw = (unsigned char*)msg;
488
489         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
490         msg->icmph.icmp6_code = 0;
491         msg->icmph.icmp6_cksum = 0;
492
493         msg->icmph.icmp6_unused = 0;
494         msg->icmph.icmp6_router    = router;
495         msg->icmph.icmp6_solicited = solicited;
496         msg->icmph.icmp6_override  = !!override;
497
498         /* Set the target address. */
499         ipv6_addr_copy(&msg->target, solicited_addr);
500
501         if (inc_opt)
502                 ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
503                                        dev->addr_len, dev->type);
504
505         /* checksum */
506         msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len, 
507                                                  IPPROTO_ICMPV6,
508                                                  csum_partial((__u8 *) msg, 
509                                                               len, 0));
510
511         skb->dst = dst;
512         idev = in6_dev_get(dst->dev);
513         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
514         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
515         if (!err) {
516                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
517                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
518         }
519
520         if (likely(idev != NULL))
521                 in6_dev_put(idev);
522 }        
523
524 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
525                    struct in6_addr *solicit,
526                    struct in6_addr *daddr, struct in6_addr *saddr) 
527 {
528         struct flowi fl;
529         struct dst_entry* dst;
530         struct inet6_dev *idev;
531         struct sock *sk = ndisc_socket->sk;
532         struct sk_buff *skb;
533         struct nd_msg *msg;
534         struct in6_addr addr_buf;
535         int len;
536         int err;
537         int send_llinfo;
538
539         if (saddr == NULL) {
540                 if (ipv6_get_lladdr(dev, &addr_buf))
541                         return;
542                 saddr = &addr_buf;
543         }
544
545         ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
546
547         dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
548         if (!dst)
549                 return;
550
551         err = xfrm_lookup(&dst, &fl, NULL, 0);
552         if (err < 0)
553                 return;
554
555         len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
556         send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
557         if (send_llinfo)
558                 len += ndisc_opt_addr_space(dev);
559
560         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
561                                   1, &err);
562         if (skb == NULL) {
563                 ND_PRINTK0(KERN_ERR
564                            "ICMPv6 NA: %s() failed to allocate an skb.\n", 
565                            __FUNCTION__);
566                 dst_release(dst);
567                 return;
568         }
569
570         skb_reserve(skb, LL_RESERVED_SPACE(dev));
571         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
572
573         msg = (struct nd_msg *)skb_put(skb, len);
574         skb->h.raw = (unsigned char*)msg;
575         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
576         msg->icmph.icmp6_code = 0;
577         msg->icmph.icmp6_cksum = 0;
578         msg->icmph.icmp6_unused = 0;
579
580         /* Set the target address. */
581         ipv6_addr_copy(&msg->target, solicit);
582
583         if (send_llinfo)
584                 ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
585                                        dev->addr_len, dev->type);
586
587         /* checksum */
588         msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
589                                                  daddr, len, 
590                                                  IPPROTO_ICMPV6,
591                                                  csum_partial((__u8 *) msg, 
592                                                               len, 0));
593         /* send it! */
594         skb->dst = dst;
595         idev = in6_dev_get(dst->dev);
596         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
597         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
598         if (!err) {
599                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
600                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
601         }
602
603         if (likely(idev != NULL))
604                 in6_dev_put(idev);
605 }
606
607 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
608                    struct in6_addr *daddr)
609 {
610         struct flowi fl;
611         struct dst_entry* dst;
612         struct inet6_dev *idev;
613         struct sock *sk = ndisc_socket->sk;
614         struct sk_buff *skb;
615         struct icmp6hdr *hdr;
616         __u8 * opt;
617         int len;
618         int err;
619
620         ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
621
622         dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
623         if (!dst)
624                 return;
625
626         err = xfrm_lookup(&dst, &fl, NULL, 0);
627         if (err < 0)
628                 return;
629
630         len = sizeof(struct icmp6hdr);
631         if (dev->addr_len)
632                 len += ndisc_opt_addr_space(dev);
633
634         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
635                                   1, &err);
636         if (skb == NULL) {
637                 ND_PRINTK0(KERN_ERR
638                            "ICMPv6 RS: %s() failed to allocate an skb.\n", 
639                            __FUNCTION__);
640                 dst_release(dst);
641                 return;
642         }
643
644         skb_reserve(skb, LL_RESERVED_SPACE(dev));
645         ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
646
647         hdr = (struct icmp6hdr *)skb_put(skb, len);
648         skb->h.raw = (unsigned char*)hdr;
649         hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
650         hdr->icmp6_code = 0;
651         hdr->icmp6_cksum = 0;
652         hdr->icmp6_unused = 0;
653
654         opt = (u8*) (hdr + 1);
655
656         if (dev->addr_len)
657                 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
658                                        dev->addr_len, dev->type);
659
660         /* checksum */
661         hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
662                                            IPPROTO_ICMPV6,
663                                            csum_partial((__u8 *) hdr, len, 0));
664
665         /* send it! */
666         skb->dst = dst;
667         idev = in6_dev_get(dst->dev);
668         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 
669         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
670         if (!err) {
671                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
672                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
673         }
674
675         if (likely(idev != NULL))
676                 in6_dev_put(idev);
677 }
678                    
679
680 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
681 {
682         /*
683          *      "The sender MUST return an ICMP
684          *       destination unreachable"
685          */
686         dst_link_failure(skb);
687         kfree_skb(skb);
688 }
689
690 /* Called with locked neigh: either read or both */
691
692 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
693 {
694         struct in6_addr *saddr = NULL;
695         struct in6_addr mcaddr;
696         struct net_device *dev = neigh->dev;
697         struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
698         int probes = atomic_read(&neigh->probes);
699
700         if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
701                 saddr = &skb->nh.ipv6h->saddr;
702
703         if ((probes -= neigh->parms->ucast_probes) < 0) {
704                 if (!(neigh->nud_state & NUD_VALID)) {
705                         ND_PRINTK1(KERN_DEBUG
706                                    "%s(): trying to ucast probe in NUD_INVALID: "
707                                    NIP6_FMT "\n",
708                                    __FUNCTION__,
709                                    NIP6(*target));
710                 }
711                 ndisc_send_ns(dev, neigh, target, target, saddr);
712         } else if ((probes -= neigh->parms->app_probes) < 0) {
713 #ifdef CONFIG_ARPD
714                 neigh_app_ns(neigh);
715 #endif
716         } else {
717                 addrconf_addr_solict_mult(target, &mcaddr);
718                 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
719         }
720 }
721
722 static void ndisc_recv_ns(struct sk_buff *skb)
723 {
724         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
725         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
726         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
727         u8 *lladdr = NULL;
728         u32 ndoptlen = skb->tail - msg->opt;
729         struct ndisc_options ndopts;
730         struct net_device *dev = skb->dev;
731         struct inet6_ifaddr *ifp;
732         struct inet6_dev *idev = NULL;
733         struct neighbour *neigh;
734         int dad = ipv6_addr_any(saddr);
735         int inc;
736
737         if (ipv6_addr_is_multicast(&msg->target)) {
738                 ND_PRINTK2(KERN_WARNING 
739                            "ICMPv6 NS: multicast target address");
740                 return;
741         }
742
743         /*
744          * RFC2461 7.1.1:
745          * DAD has to be destined for solicited node multicast address.
746          */
747         if (dad &&
748             !(daddr->s6_addr32[0] == htonl(0xff020000) &&
749               daddr->s6_addr32[1] == htonl(0x00000000) &&
750               daddr->s6_addr32[2] == htonl(0x00000001) &&
751               daddr->s6_addr [12] == 0xff )) {
752                 ND_PRINTK2(KERN_WARNING
753                            "ICMPv6 NS: bad DAD packet (wrong destination)\n");
754                 return;
755         }
756
757         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
758                 ND_PRINTK2(KERN_WARNING 
759                            "ICMPv6 NS: invalid ND options\n");
760                 return;
761         }
762
763         if (ndopts.nd_opts_src_lladdr) {
764                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
765                 if (!lladdr) {
766                         ND_PRINTK2(KERN_WARNING
767                                    "ICMPv6 NS: invalid link-layer address length\n");
768                         return;
769                 }
770
771                 /* RFC2461 7.1.1:
772                  *      If the IP source address is the unspecified address, 
773                  *      there MUST NOT be source link-layer address option 
774                  *      in the message.
775                  */
776                 if (dad) {
777                         ND_PRINTK2(KERN_WARNING 
778                                    "ICMPv6 NS: bad DAD packet (link-layer address option)\n");
779                         return;
780                 }
781         }
782
783         inc = ipv6_addr_is_multicast(daddr);
784
785         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
786                 if (ifp->flags & IFA_F_TENTATIVE) {
787                         /* Address is tentative. If the source
788                            is unspecified address, it is someone
789                            does DAD, otherwise we ignore solicitations
790                            until DAD timer expires.
791                          */
792                         if (!dad)
793                                 goto out;
794                         if (dev->type == ARPHRD_IEEE802_TR) {
795                                 unsigned char *sadr = skb->mac.raw;
796                                 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
797                                     sadr[9] == dev->dev_addr[1] &&
798                                     sadr[10] == dev->dev_addr[2] &&
799                                     sadr[11] == dev->dev_addr[3] &&
800                                     sadr[12] == dev->dev_addr[4] &&
801                                     sadr[13] == dev->dev_addr[5]) {
802                                         /* looped-back to us */
803                                         goto out;
804                                 }
805                         }
806                         addrconf_dad_failure(ifp); 
807                         return;
808                 }
809
810                 idev = ifp->idev;
811         } else {
812                 idev = in6_dev_get(dev);
813                 if (!idev) {
814                         /* XXX: count this drop? */
815                         return;
816                 }
817
818                 if (ipv6_chk_acast_addr(dev, &msg->target) ||
819                     (idev->cnf.forwarding && 
820                      pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
821                         if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
822                             skb->pkt_type != PACKET_HOST &&
823                             inc != 0 &&
824                             idev->nd_parms->proxy_delay != 0) {
825                                 /*
826                                  * for anycast or proxy,
827                                  * sender should delay its response 
828                                  * by a random time between 0 and 
829                                  * MAX_ANYCAST_DELAY_TIME seconds.
830                                  * (RFC2461) -- yoshfuji
831                                  */
832                                 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
833                                 if (n)
834                                         pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
835                                 goto out;
836                         }
837                 } else
838                         goto out;
839         }
840
841         if (dad) {
842                 struct in6_addr maddr;
843
844                 ipv6_addr_all_nodes(&maddr);
845                 ndisc_send_na(dev, NULL, &maddr, &msg->target,
846                               idev->cnf.forwarding, 0, (ifp != NULL), 1);
847                 goto out;
848         }
849
850         if (inc)
851                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
852         else
853                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
854
855         /* 
856          *      update / create cache entry
857          *      for the source address
858          */
859         neigh = __neigh_lookup(&nd_tbl, saddr, dev,
860                                !inc || lladdr || !dev->addr_len);
861         if (neigh)
862                 neigh_update(neigh, lladdr, NUD_STALE, 
863                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
864                              NEIGH_UPDATE_F_OVERRIDE);
865         if (neigh || !dev->hard_header) {
866                 ndisc_send_na(dev, neigh, saddr, &msg->target,
867                               idev->cnf.forwarding, 
868                               1, (ifp != NULL && inc), inc);
869                 if (neigh)
870                         neigh_release(neigh);
871         }
872
873 out:
874         if (ifp)
875                 in6_ifa_put(ifp);
876         else
877                 in6_dev_put(idev);
878
879         return;
880 }
881
882 static void ndisc_recv_na(struct sk_buff *skb)
883 {
884         struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
885         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
886         struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
887         u8 *lladdr = NULL;
888         u32 ndoptlen = skb->tail - msg->opt;
889         struct ndisc_options ndopts;
890         struct net_device *dev = skb->dev;
891         struct inet6_ifaddr *ifp;
892         struct neighbour *neigh;
893
894         if (skb->len < sizeof(struct nd_msg)) {
895                 ND_PRINTK2(KERN_WARNING
896                            "ICMPv6 NA: packet too short\n");
897                 return;
898         }
899
900         if (ipv6_addr_is_multicast(&msg->target)) {
901                 ND_PRINTK2(KERN_WARNING
902                            "ICMPv6 NA: target address is multicast.\n");
903                 return;
904         }
905
906         if (ipv6_addr_is_multicast(daddr) &&
907             msg->icmph.icmp6_solicited) {
908                 ND_PRINTK2(KERN_WARNING
909                            "ICMPv6 NA: solicited NA is multicasted.\n");
910                 return;
911         }
912                 
913         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
914                 ND_PRINTK2(KERN_WARNING
915                            "ICMPv6 NS: invalid ND option\n");
916                 return;
917         }
918         if (ndopts.nd_opts_tgt_lladdr) {
919                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
920                 if (!lladdr) {
921                         ND_PRINTK2(KERN_WARNING
922                                    "ICMPv6 NA: invalid link-layer address length\n");
923                         return;
924                 }
925         }
926         if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
927                 if (ifp->flags & IFA_F_TENTATIVE) {
928                         addrconf_dad_failure(ifp);
929                         return;
930                 }
931                 /* What should we make now? The advertisement
932                    is invalid, but ndisc specs say nothing
933                    about it. It could be misconfiguration, or
934                    an smart proxy agent tries to help us :-)
935                  */
936                 ND_PRINTK1(KERN_WARNING
937                            "ICMPv6 NA: someone advertises our address on %s!\n",
938                            ifp->idev->dev->name);
939                 in6_ifa_put(ifp);
940                 return;
941         }
942         neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
943
944         if (neigh) {
945                 u8 old_flags = neigh->flags;
946
947                 if (neigh->nud_state & NUD_FAILED)
948                         goto out;
949
950                 neigh_update(neigh, lladdr,
951                              msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
952                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
953                              (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
954                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
955                              (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
956
957                 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
958                         /*
959                          * Change: router to host
960                          */
961                         struct rt6_info *rt;
962                         rt = rt6_get_dflt_router(saddr, dev);
963                         if (rt)
964                                 ip6_del_rt(rt, NULL, NULL, NULL);
965                 }
966
967 out:
968                 neigh_release(neigh);
969         }
970 }
971
972 static void ndisc_recv_rs(struct sk_buff *skb)
973 {
974         struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
975         unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
976         struct neighbour *neigh;
977         struct inet6_dev *idev;
978         struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
979         struct ndisc_options ndopts;
980         u8 *lladdr = NULL;
981
982         if (skb->len < sizeof(*rs_msg))
983                 return;
984
985         idev = in6_dev_get(skb->dev);
986         if (!idev) {
987                 if (net_ratelimit())
988                         ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
989                 return;
990         }
991
992         /* Don't accept RS if we're not in router mode */
993         if (!idev->cnf.forwarding)
994                 goto out;
995
996         /*
997          * Don't update NCE if src = ::;
998          * this implies that the source node has no ip address assigned yet.
999          */
1000         if (ipv6_addr_any(saddr))
1001                 goto out;
1002
1003         /* Parse ND options */
1004         if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
1005                 if (net_ratelimit())
1006                         ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
1007                 goto out;
1008         }
1009
1010         if (ndopts.nd_opts_src_lladdr) {
1011                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1012                                              skb->dev);
1013                 if (!lladdr)
1014                         goto out;
1015         }
1016
1017         neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1018         if (neigh) {
1019                 neigh_update(neigh, lladdr, NUD_STALE,
1020                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1021                              NEIGH_UPDATE_F_OVERRIDE|
1022                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1023                 neigh_release(neigh);
1024         }
1025 out:
1026         in6_dev_put(idev);
1027 }
1028
1029 static void ndisc_router_discovery(struct sk_buff *skb)
1030 {
1031         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
1032         struct neighbour *neigh = NULL;
1033         struct inet6_dev *in6_dev;
1034         struct rt6_info *rt = NULL;
1035         int lifetime;
1036         struct ndisc_options ndopts;
1037         int optlen;
1038         unsigned int pref = 0;
1039
1040         __u8 * opt = (__u8 *)(ra_msg + 1);
1041
1042         optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
1043
1044         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1045                 ND_PRINTK2(KERN_WARNING
1046                            "ICMPv6 RA: source address is not link-local.\n");
1047                 return;
1048         }
1049         if (optlen < 0) {
1050                 ND_PRINTK2(KERN_WARNING 
1051                            "ICMPv6 RA: packet too short\n");
1052                 return;
1053         }
1054
1055         /*
1056          *      set the RA_RECV flag in the interface
1057          */
1058
1059         in6_dev = in6_dev_get(skb->dev);
1060         if (in6_dev == NULL) {
1061                 ND_PRINTK0(KERN_ERR
1062                            "ICMPv6 RA: can't find inet6 device for %s.\n",
1063                            skb->dev->name);
1064                 return;
1065         }
1066         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
1067                 in6_dev_put(in6_dev);
1068                 return;
1069         }
1070
1071         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1072                 in6_dev_put(in6_dev);
1073                 ND_PRINTK2(KERN_WARNING
1074                            "ICMP6 RA: invalid ND options\n");
1075                 return;
1076         }
1077
1078         if (in6_dev->if_flags & IF_RS_SENT) {
1079                 /*
1080                  *      flag that an RA was received after an RS was sent
1081                  *      out on this interface.
1082                  */
1083                 in6_dev->if_flags |= IF_RA_RCVD;
1084         }
1085
1086         /*
1087          * Remember the managed/otherconf flags from most recently
1088          * received RA message (RFC 2462) -- yoshfuji
1089          */
1090         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1091                                 IF_RA_OTHERCONF)) |
1092                                 (ra_msg->icmph.icmp6_addrconf_managed ?
1093                                         IF_RA_MANAGED : 0) |
1094                                 (ra_msg->icmph.icmp6_addrconf_other ?
1095                                         IF_RA_OTHERCONF : 0);
1096
1097         if (!in6_dev->cnf.accept_ra_defrtr)
1098                 goto skip_defrtr;
1099
1100         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1101
1102 #ifdef CONFIG_IPV6_ROUTER_PREF
1103         pref = ra_msg->icmph.icmp6_router_pref;
1104         /* 10b is handled as if it were 00b (medium) */
1105         if (pref == ICMPV6_ROUTER_PREF_INVALID ||
1106             in6_dev->cnf.accept_ra_rtr_pref)
1107                 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1108 #endif
1109
1110         rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
1111
1112         if (rt)
1113                 neigh = rt->rt6i_nexthop;
1114
1115         if (rt && lifetime == 0) {
1116                 neigh_clone(neigh);
1117                 ip6_del_rt(rt, NULL, NULL, NULL);
1118                 rt = NULL;
1119         }
1120
1121         if (rt == NULL && lifetime) {
1122                 ND_PRINTK3(KERN_DEBUG
1123                            "ICMPv6 RA: adding default router.\n");
1124
1125                 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
1126                 if (rt == NULL) {
1127                         ND_PRINTK0(KERN_ERR
1128                                    "ICMPv6 RA: %s() failed to add default route.\n",
1129                                    __FUNCTION__);
1130                         in6_dev_put(in6_dev);
1131                         return;
1132                 }
1133
1134                 neigh = rt->rt6i_nexthop;
1135                 if (neigh == NULL) {
1136                         ND_PRINTK0(KERN_ERR
1137                                    "ICMPv6 RA: %s() got default router without neighbour.\n",
1138                                    __FUNCTION__);
1139                         dst_release(&rt->u.dst);
1140                         in6_dev_put(in6_dev);
1141                         return;
1142                 }
1143                 neigh->flags |= NTF_ROUTER;
1144         } else if (rt) {
1145                 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1146         }
1147
1148         if (rt)
1149                 rt->rt6i_expires = jiffies + (HZ * lifetime);
1150
1151         if (ra_msg->icmph.icmp6_hop_limit) {
1152                 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1153                 if (rt)
1154                         rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1155         }
1156
1157 skip_defrtr:
1158
1159         /*
1160          *      Update Reachable Time and Retrans Timer
1161          */
1162
1163         if (in6_dev->nd_parms) {
1164                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1165
1166                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1167                         rtime = (rtime*HZ)/1000;
1168                         if (rtime < HZ/10)
1169                                 rtime = HZ/10;
1170                         in6_dev->nd_parms->retrans_time = rtime;
1171                         in6_dev->tstamp = jiffies;
1172                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1173                 }
1174
1175                 rtime = ntohl(ra_msg->reachable_time);
1176                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1177                         rtime = (rtime*HZ)/1000;
1178
1179                         if (rtime < HZ/10)
1180                                 rtime = HZ/10;
1181
1182                         if (rtime != in6_dev->nd_parms->base_reachable_time) {
1183                                 in6_dev->nd_parms->base_reachable_time = rtime;
1184                                 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1185                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1186                                 in6_dev->tstamp = jiffies;
1187                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1188                         }
1189                 }
1190         }
1191
1192         /*
1193          *      Process options.
1194          */
1195
1196         if (!neigh)
1197                 neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
1198                                        skb->dev, 1);
1199         if (neigh) {
1200                 u8 *lladdr = NULL;
1201                 if (ndopts.nd_opts_src_lladdr) {
1202                         lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1203                                                      skb->dev);
1204                         if (!lladdr) {
1205                                 ND_PRINTK2(KERN_WARNING
1206                                            "ICMPv6 RA: invalid link-layer address length\n");
1207                                 goto out;
1208                         }
1209                 }
1210                 neigh_update(neigh, lladdr, NUD_STALE,
1211                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1212                              NEIGH_UPDATE_F_OVERRIDE|
1213                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1214                              NEIGH_UPDATE_F_ISROUTER);
1215         }
1216
1217 #ifdef CONFIG_IPV6_ROUTE_INFO
1218         if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1219                 struct nd_opt_hdr *p;
1220                 for (p = ndopts.nd_opts_ri;
1221                      p;
1222                      p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1223                         if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1224                                 continue;
1225                         rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
1226                                       &skb->nh.ipv6h->saddr);
1227                 }
1228         }
1229 #endif
1230
1231         if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1232                 struct nd_opt_hdr *p;
1233                 for (p = ndopts.nd_opts_pi;
1234                      p;
1235                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1236                         addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1237                 }
1238         }
1239
1240         if (ndopts.nd_opts_mtu) {
1241                 u32 mtu;
1242
1243                 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1244                 mtu = ntohl(mtu);
1245
1246                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1247                         ND_PRINTK2(KERN_WARNING
1248                                    "ICMPv6 RA: invalid mtu: %d\n",
1249                                    mtu);
1250                 } else if (in6_dev->cnf.mtu6 != mtu) {
1251                         in6_dev->cnf.mtu6 = mtu;
1252
1253                         if (rt)
1254                                 rt->u.dst.metrics[RTAX_MTU-1] = mtu;
1255
1256                         rt6_mtu_change(skb->dev, mtu);
1257                 }
1258         }
1259                         
1260         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1261                 ND_PRINTK2(KERN_WARNING
1262                            "ICMPv6 RA: invalid RA options");
1263         }
1264 out:
1265         if (rt)
1266                 dst_release(&rt->u.dst);
1267         else if (neigh)
1268                 neigh_release(neigh);
1269         in6_dev_put(in6_dev);
1270 }
1271
1272 static void ndisc_redirect_rcv(struct sk_buff *skb)
1273 {
1274         struct inet6_dev *in6_dev;
1275         struct icmp6hdr *icmph;
1276         struct in6_addr *dest;
1277         struct in6_addr *target;        /* new first hop to destination */
1278         struct neighbour *neigh;
1279         int on_link = 0;
1280         struct ndisc_options ndopts;
1281         int optlen;
1282         u8 *lladdr = NULL;
1283
1284         if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1285                 ND_PRINTK2(KERN_WARNING
1286                            "ICMPv6 Redirect: source address is not link-local.\n");
1287                 return;
1288         }
1289
1290         optlen = skb->tail - skb->h.raw;
1291         optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1292
1293         if (optlen < 0) {
1294                 ND_PRINTK2(KERN_WARNING
1295                            "ICMPv6 Redirect: packet too short\n");
1296                 return;
1297         }
1298
1299         icmph = (struct icmp6hdr *) skb->h.raw;
1300         target = (struct in6_addr *) (icmph + 1);
1301         dest = target + 1;
1302
1303         if (ipv6_addr_is_multicast(dest)) {
1304                 ND_PRINTK2(KERN_WARNING
1305                            "ICMPv6 Redirect: destination address is multicast.\n");
1306                 return;
1307         }
1308
1309         if (ipv6_addr_equal(dest, target)) {
1310                 on_link = 1;
1311         } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1312                 ND_PRINTK2(KERN_WARNING 
1313                            "ICMPv6 Redirect: target address is not link-local.\n");
1314                 return;
1315         }
1316
1317         in6_dev = in6_dev_get(skb->dev);
1318         if (!in6_dev)
1319                 return;
1320         if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1321                 in6_dev_put(in6_dev);
1322                 return;
1323         }
1324
1325         /* RFC2461 8.1: 
1326          *      The IP source address of the Redirect MUST be the same as the current
1327          *      first-hop router for the specified ICMP Destination Address.
1328          */
1329                 
1330         if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1331                 ND_PRINTK2(KERN_WARNING
1332                            "ICMPv6 Redirect: invalid ND options\n");
1333                 in6_dev_put(in6_dev);
1334                 return;
1335         }
1336         if (ndopts.nd_opts_tgt_lladdr) {
1337                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr,
1338                                              skb->dev);
1339                 if (!lladdr) {
1340                         ND_PRINTK2(KERN_WARNING
1341                                    "ICMPv6 Redirect: invalid link-layer address length\n");
1342                         in6_dev_put(in6_dev);
1343                         return;
1344                 }
1345         }
1346
1347         neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1348         if (neigh) {
1349                 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, 
1350                              on_link);
1351                 neigh_release(neigh);
1352         }
1353         in6_dev_put(in6_dev);
1354 }
1355
1356 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1357                          struct in6_addr *target)
1358 {
1359         struct sock *sk = ndisc_socket->sk;
1360         int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1361         struct sk_buff *buff;
1362         struct icmp6hdr *icmph;
1363         struct in6_addr saddr_buf;
1364         struct in6_addr *addrp;
1365         struct net_device *dev;
1366         struct rt6_info *rt;
1367         struct dst_entry *dst;
1368         struct inet6_dev *idev;
1369         struct flowi fl;
1370         u8 *opt;
1371         int rd_len;
1372         int err;
1373         int hlen;
1374         u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1375
1376         dev = skb->dev;
1377
1378         if (ipv6_get_lladdr(dev, &saddr_buf)) {
1379                 ND_PRINTK2(KERN_WARNING
1380                            "ICMPv6 Redirect: no link-local address on %s\n",
1381                            dev->name);
1382                 return;
1383         }
1384
1385         ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr);
1386
1387         dst = ip6_route_output(NULL, &fl);
1388         if (dst == NULL)
1389                 return;
1390
1391         err = xfrm_lookup(&dst, &fl, NULL, 0);
1392         if (err)
1393                 return;
1394
1395         rt = (struct rt6_info *) dst;
1396
1397         if (rt->rt6i_flags & RTF_GATEWAY) {
1398                 ND_PRINTK2(KERN_WARNING
1399                            "ICMPv6 Redirect: destination is not a neighbour.\n");
1400                 dst_release(dst);
1401                 return;
1402         }
1403         if (!xrlim_allow(dst, 1*HZ)) {
1404                 dst_release(dst);
1405                 return;
1406         }
1407
1408         if (dev->addr_len) {
1409                 read_lock_bh(&neigh->lock);
1410                 if (neigh->nud_state & NUD_VALID) {
1411                         memcpy(ha_buf, neigh->ha, dev->addr_len);
1412                         read_unlock_bh(&neigh->lock);
1413                         ha = ha_buf;
1414                         len += ndisc_opt_addr_space(dev);
1415                 } else
1416                         read_unlock_bh(&neigh->lock);
1417         }
1418
1419         rd_len = min_t(unsigned int,
1420                      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1421         rd_len &= ~0x7;
1422         len += rd_len;
1423
1424         buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
1425                                    1, &err);
1426         if (buff == NULL) {
1427                 ND_PRINTK0(KERN_ERR
1428                            "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1429                            __FUNCTION__);
1430                 dst_release(dst);
1431                 return;
1432         }
1433
1434         hlen = 0;
1435
1436         skb_reserve(buff, LL_RESERVED_SPACE(dev));
1437         ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1438                    IPPROTO_ICMPV6, len);
1439
1440         icmph = (struct icmp6hdr *)skb_put(buff, len);
1441         buff->h.raw = (unsigned char*)icmph;
1442
1443         memset(icmph, 0, sizeof(struct icmp6hdr));
1444         icmph->icmp6_type = NDISC_REDIRECT;
1445
1446         /*
1447          *      copy target and destination addresses
1448          */
1449
1450         addrp = (struct in6_addr *)(icmph + 1);
1451         ipv6_addr_copy(addrp, target);
1452         addrp++;
1453         ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1454
1455         opt = (u8*) (addrp + 1);
1456
1457         /*
1458          *      include target_address option
1459          */
1460
1461         if (ha)
1462                 opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha,
1463                                              dev->addr_len, dev->type);
1464
1465         /*
1466          *      build redirect option and copy skb over to the new packet.
1467          */
1468
1469         memset(opt, 0, 8);      
1470         *(opt++) = ND_OPT_REDIRECT_HDR;
1471         *(opt++) = (rd_len >> 3);
1472         opt += 6;
1473
1474         memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1475
1476         icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1477                                              len, IPPROTO_ICMPV6,
1478                                              csum_partial((u8 *) icmph, len, 0));
1479
1480         buff->dst = dst;
1481         idev = in6_dev_get(dst->dev);
1482         IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
1483         err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1484         if (!err) {
1485                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
1486                 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1487         }
1488
1489         if (likely(idev != NULL))
1490                 in6_dev_put(idev);
1491 }
1492
1493 static void pndisc_redo(struct sk_buff *skb)
1494 {
1495         ndisc_recv_ns(skb);
1496         kfree_skb(skb);
1497 }
1498
1499 int ndisc_rcv(struct sk_buff *skb)
1500 {
1501         struct nd_msg *msg;
1502
1503         if (!pskb_may_pull(skb, skb->len))
1504                 return 0;
1505
1506         msg = (struct nd_msg *) skb->h.raw;
1507
1508         __skb_push(skb, skb->data-skb->h.raw);
1509
1510         if (skb->nh.ipv6h->hop_limit != 255) {
1511                 ND_PRINTK2(KERN_WARNING
1512                            "ICMPv6 NDISC: invalid hop-limit: %d\n",
1513                            skb->nh.ipv6h->hop_limit);
1514                 return 0;
1515         }
1516
1517         if (msg->icmph.icmp6_code != 0) {
1518                 ND_PRINTK2(KERN_WARNING 
1519                            "ICMPv6 NDISC: invalid ICMPv6 code: %d\n",
1520                            msg->icmph.icmp6_code);
1521                 return 0;
1522         }
1523
1524         memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1525
1526         switch (msg->icmph.icmp6_type) {
1527         case NDISC_NEIGHBOUR_SOLICITATION:
1528                 ndisc_recv_ns(skb);
1529                 break;
1530
1531         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1532                 ndisc_recv_na(skb);
1533                 break;
1534
1535         case NDISC_ROUTER_SOLICITATION:
1536                 ndisc_recv_rs(skb);
1537                 break;
1538
1539         case NDISC_ROUTER_ADVERTISEMENT:
1540                 ndisc_router_discovery(skb);
1541                 break;
1542
1543         case NDISC_REDIRECT:
1544                 ndisc_redirect_rcv(skb);
1545                 break;
1546         };
1547
1548         return 0;
1549 }
1550
1551 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1552 {
1553         struct net_device *dev = ptr;
1554
1555         switch (event) {
1556         case NETDEV_CHANGEADDR:
1557                 neigh_changeaddr(&nd_tbl, dev);
1558                 fib6_run_gc(~0UL);
1559                 break;
1560         case NETDEV_DOWN:
1561                 neigh_ifdown(&nd_tbl, dev);
1562                 fib6_run_gc(~0UL);
1563                 break;
1564         default:
1565                 break;
1566         }
1567
1568         return NOTIFY_DONE;
1569 }
1570
1571 static struct notifier_block ndisc_netdev_notifier = {
1572         .notifier_call = ndisc_netdev_event,
1573 };
1574
1575 #ifdef CONFIG_SYSCTL
1576 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1577                                          const char *func, const char *dev_name)
1578 {
1579         static char warncomm[TASK_COMM_LEN];
1580         static int warned;
1581         if (strcmp(warncomm, current->comm) && warned < 5) {
1582                 strcpy(warncomm, current->comm);
1583                 printk(KERN_WARNING
1584                         "process `%s' is using deprecated sysctl (%s) "
1585                         "net.ipv6.neigh.%s.%s; "
1586                         "Use net.ipv6.neigh.%s.%s_ms "
1587                         "instead.\n",
1588                         warncomm, func,
1589                         dev_name, ctl->procname,
1590                         dev_name, ctl->procname);
1591                 warned++;
1592         }
1593 }
1594
1595 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos)
1596 {
1597         struct net_device *dev = ctl->extra1;
1598         struct inet6_dev *idev;
1599         int ret;
1600
1601         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1602             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1603                 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1604
1605         switch (ctl->ctl_name) {
1606         case NET_NEIGH_RETRANS_TIME:
1607                 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1608                 break;
1609         case NET_NEIGH_REACHABLE_TIME:
1610                 ret = proc_dointvec_jiffies(ctl, write,
1611                                             filp, buffer, lenp, ppos);
1612                 break;
1613         case NET_NEIGH_RETRANS_TIME_MS:
1614         case NET_NEIGH_REACHABLE_TIME_MS:
1615                 ret = proc_dointvec_ms_jiffies(ctl, write,
1616                                                filp, buffer, lenp, ppos);
1617                 break;
1618         default:
1619                 ret = -1;
1620         }
1621
1622         if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1623                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1624                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1625                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1626                 idev->tstamp = jiffies;
1627                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1628                 in6_dev_put(idev);
1629         }
1630         return ret;
1631 }
1632
1633 static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1634                                         int nlen, void __user *oldval,
1635                                         size_t __user *oldlenp,
1636                                         void __user *newval, size_t newlen,
1637                                         void **context)
1638 {
1639         struct net_device *dev = ctl->extra1;
1640         struct inet6_dev *idev;
1641         int ret;
1642
1643         if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
1644             ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
1645                 ndisc_warn_deprecated_sysctl(ctl, "procfs", dev ? dev->name : "default");
1646
1647         switch (ctl->ctl_name) {
1648         case NET_NEIGH_REACHABLE_TIME:
1649                 ret = sysctl_jiffies(ctl, name, nlen,
1650                                      oldval, oldlenp, newval, newlen,
1651                                      context);
1652                 break;
1653         case NET_NEIGH_RETRANS_TIME_MS:
1654         case NET_NEIGH_REACHABLE_TIME_MS:
1655                  ret = sysctl_ms_jiffies(ctl, name, nlen,
1656                                          oldval, oldlenp, newval, newlen,
1657                                          context);
1658                  break;
1659         default:
1660                 ret = 0;
1661         }
1662
1663         if (newval && newlen && ret > 0 &&
1664             dev && (idev = in6_dev_get(dev)) != NULL) {
1665                 if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
1666                     ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
1667                         idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
1668                 idev->tstamp = jiffies;
1669                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1670                 in6_dev_put(idev);
1671         }
1672
1673         return ret;
1674 }
1675
1676 #endif
1677
1678 int __init ndisc_init(struct net_proto_family *ops)
1679 {
1680         struct ipv6_pinfo *np;
1681         struct sock *sk;
1682         int err;
1683
1684         err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
1685         if (err < 0) {
1686                 ND_PRINTK0(KERN_ERR
1687                            "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 
1688                            err);
1689                 ndisc_socket = NULL; /* For safety. */
1690                 return err;
1691         }
1692
1693         sk = ndisc_socket->sk;
1694         np = inet6_sk(sk);
1695         sk->sk_allocation = GFP_ATOMIC;
1696         np->hop_limit = 255;
1697         /* Do not loopback ndisc messages */
1698         np->mc_loop = 0;
1699         sk->sk_prot->unhash(sk);
1700
1701         /*
1702          * Initialize the neighbour table
1703          */
1704         
1705         neigh_table_init(&nd_tbl);
1706
1707 #ifdef CONFIG_SYSCTL
1708         neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 
1709                               "ipv6",
1710                               &ndisc_ifinfo_sysctl_change,
1711                               &ndisc_ifinfo_sysctl_strategy);
1712 #endif
1713
1714         register_netdevice_notifier(&ndisc_netdev_notifier);
1715         return 0;
1716 }
1717
1718 void ndisc_cleanup(void)
1719 {
1720 #ifdef CONFIG_SYSCTL
1721         neigh_sysctl_unregister(&nd_tbl.parms);
1722 #endif
1723         neigh_table_clear(&nd_tbl);
1724         sock_release(ndisc_socket);
1725         ndisc_socket = NULL; /* For safety. */
1726 }