Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[linux-2.6] / net / ipv6 / icmp.c
1 /*
2  *      Internet Control Message Protocol (ICMPv6)
3  *      Linux INET6 implementation
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>
7  *
8  *      $Id: icmp.c,v 1.38 2002/02/08 03:57:19 davem Exp $
9  *
10  *      Based on net/ipv4/icmp.c
11  *
12  *      RFC 1885
13  *
14  *      This program is free software; you can redistribute it and/or
15  *      modify it under the terms of the GNU General Public License
16  *      as published by the Free Software Foundation; either version
17  *      2 of the License, or (at your option) any later version.
18  */
19
20 /*
21  *      Changes:
22  *
23  *      Andi Kleen              :       exception handling
24  *      Andi Kleen                      add rate limits. never reply to a icmp.
25  *                                      add more length checks and other fixes.
26  *      yoshfuji                :       ensure to sent parameter problem for
27  *                                      fragments.
28  *      YOSHIFUJI Hideaki @USAGI:       added sysctl for icmp rate limit.
29  *      Randy Dunlap and
30  *      YOSHIFUJI Hideaki @USAGI:       Per-interface statistics support
31  *      Kazunori MIYAZAWA @USAGI:       change output process to use ip6_append_data
32  */
33
34 #include <linux/module.h>
35 #include <linux/errno.h>
36 #include <linux/types.h>
37 #include <linux/socket.h>
38 #include <linux/in.h>
39 #include <linux/kernel.h>
40 #include <linux/sockios.h>
41 #include <linux/net.h>
42 #include <linux/skbuff.h>
43 #include <linux/init.h>
44 #include <linux/netfilter.h>
45
46 #ifdef CONFIG_SYSCTL
47 #include <linux/sysctl.h>
48 #endif
49
50 #include <linux/inet.h>
51 #include <linux/netdevice.h>
52 #include <linux/icmpv6.h>
53
54 #include <net/ip.h>
55 #include <net/sock.h>
56
57 #include <net/ipv6.h>
58 #include <net/ip6_checksum.h>
59 #include <net/protocol.h>
60 #include <net/raw.h>
61 #include <net/rawv6.h>
62 #include <net/transp_v6.h>
63 #include <net/ip6_route.h>
64 #include <net/addrconf.h>
65 #include <net/icmp.h>
66
67 #include <asm/uaccess.h>
68 #include <asm/system.h>
69
70 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
71 EXPORT_SYMBOL(icmpv6_statistics);
72
73 /*
74  *      The ICMP socket(s). This is the most convenient way to flow control
75  *      our ICMP output as well as maintain a clean interface throughout
76  *      all layers. All Socketless IP sends will soon be gone.
77  *
78  *      On SMP we have one ICMP socket per-cpu.
79  */
80 static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL;
81 #define icmpv6_socket   __get_cpu_var(__icmpv6_socket)
82
83 static int icmpv6_rcv(struct sk_buff **pskb);
84
85 static struct inet6_protocol icmpv6_protocol = {
86         .handler        =       icmpv6_rcv,
87         .flags          =       INET6_PROTO_FINAL,
88 };
89
90 static __inline__ int icmpv6_xmit_lock(void)
91 {
92         local_bh_disable();
93
94         if (unlikely(!spin_trylock(&icmpv6_socket->sk->sk_lock.slock))) {
95                 /* This can happen if the output path (f.e. SIT or
96                  * ip6ip6 tunnel) signals dst_link_failure() for an
97                  * outgoing ICMP6 packet.
98                  */
99                 local_bh_enable();
100                 return 1;
101         }
102         return 0;
103 }
104
105 static __inline__ void icmpv6_xmit_unlock(void)
106 {
107         spin_unlock_bh(&icmpv6_socket->sk->sk_lock.slock);
108 }
109
110 /*
111  * Slightly more convenient version of icmpv6_send.
112  */
113 void icmpv6_param_prob(struct sk_buff *skb, int code, int pos)
114 {
115         icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev);
116         kfree_skb(skb);
117 }
118
119 /*
120  * Figure out, may we reply to this packet with icmp error.
121  *
122  * We do not reply, if:
123  *      - it was icmp error message.
124  *      - it is truncated, so that it is known, that protocol is ICMPV6
125  *        (i.e. in the middle of some exthdr)
126  *
127  *      --ANK (980726)
128  */
129
130 static int is_ineligible(struct sk_buff *skb)
131 {
132         int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
133         int len = skb->len - ptr;
134         __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
135
136         if (len < 0)
137                 return 1;
138
139         ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr);
140         if (ptr < 0)
141                 return 0;
142         if (nexthdr == IPPROTO_ICMPV6) {
143                 u8 _type, *tp;
144                 tp = skb_header_pointer(skb,
145                         ptr+offsetof(struct icmp6hdr, icmp6_type),
146                         sizeof(_type), &_type);
147                 if (tp == NULL ||
148                     !(*tp & ICMPV6_INFOMSG_MASK))
149                         return 1;
150         }
151         return 0;
152 }
153
154 static int sysctl_icmpv6_time __read_mostly = 1*HZ;
155
156 /*
157  * Check the ICMP output rate limit
158  */
159 static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
160                                      struct flowi *fl)
161 {
162         struct dst_entry *dst;
163         int res = 0;
164
165         /* Informational messages are not limited. */
166         if (type & ICMPV6_INFOMSG_MASK)
167                 return 1;
168
169         /* Do not limit pmtu discovery, it would break it. */
170         if (type == ICMPV6_PKT_TOOBIG)
171                 return 1;
172
173         /*
174          * Look up the output route.
175          * XXX: perhaps the expire for routing entries cloned by
176          * this lookup should be more aggressive (not longer than timeout).
177          */
178         dst = ip6_route_output(sk, fl);
179         if (dst->error) {
180                 IP6_INC_STATS(ip6_dst_idev(dst),
181                               IPSTATS_MIB_OUTNOROUTES);
182         } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
183                 res = 1;
184         } else {
185                 struct rt6_info *rt = (struct rt6_info *)dst;
186                 int tmo = sysctl_icmpv6_time;
187
188                 /* Give more bandwidth to wider prefixes. */
189                 if (rt->rt6i_dst.plen < 128)
190                         tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
191
192                 res = xrlim_allow(dst, tmo);
193         }
194         dst_release(dst);
195         return res;
196 }
197
198 /*
199  *      an inline helper for the "simple" if statement below
200  *      checks if parameter problem report is caused by an
201  *      unrecognized IPv6 option that has the Option Type
202  *      highest-order two bits set to 10
203  */
204
205 static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
206 {
207         u8 _optval, *op;
208
209         offset += skb_network_offset(skb);
210         op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
211         if (op == NULL)
212                 return 1;
213         return (*op & 0xC0) == 0x80;
214 }
215
216 static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
217 {
218         struct sk_buff *skb;
219         struct icmp6hdr *icmp6h;
220         int err = 0;
221
222         if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
223                 goto out;
224
225         icmp6h = icmp6_hdr(skb);
226         memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
227         icmp6h->icmp6_cksum = 0;
228
229         if (skb_queue_len(&sk->sk_write_queue) == 1) {
230                 skb->csum = csum_partial((char *)icmp6h,
231                                         sizeof(struct icmp6hdr), skb->csum);
232                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
233                                                       &fl->fl6_dst,
234                                                       len, fl->proto,
235                                                       skb->csum);
236         } else {
237                 __wsum tmp_csum = 0;
238
239                 skb_queue_walk(&sk->sk_write_queue, skb) {
240                         tmp_csum = csum_add(tmp_csum, skb->csum);
241                 }
242
243                 tmp_csum = csum_partial((char *)icmp6h,
244                                         sizeof(struct icmp6hdr), tmp_csum);
245                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
246                                                       &fl->fl6_dst,
247                                                       len, fl->proto,
248                                                       tmp_csum);
249         }
250         ip6_push_pending_frames(sk);
251 out:
252         return err;
253 }
254
255 struct icmpv6_msg {
256         struct sk_buff  *skb;
257         int             offset;
258         uint8_t         type;
259 };
260
261 static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
262 {
263         struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
264         struct sk_buff *org_skb = msg->skb;
265         __wsum csum = 0;
266
267         csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
268                                       to, len, csum);
269         skb->csum = csum_block_add(skb->csum, csum, odd);
270         if (!(msg->type & ICMPV6_INFOMSG_MASK))
271                 nf_ct_attach(skb, org_skb);
272         return 0;
273 }
274
275 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
276 static void mip6_addr_swap(struct sk_buff *skb)
277 {
278         struct ipv6hdr *iph = ipv6_hdr(skb);
279         struct inet6_skb_parm *opt = IP6CB(skb);
280         struct ipv6_destopt_hao *hao;
281         struct in6_addr tmp;
282         int off;
283
284         if (opt->dsthao) {
285                 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
286                 if (likely(off >= 0)) {
287                         hao = (struct ipv6_destopt_hao *)
288                                         (skb_network_header(skb) + off);
289                         ipv6_addr_copy(&tmp, &iph->saddr);
290                         ipv6_addr_copy(&iph->saddr, &hao->addr);
291                         ipv6_addr_copy(&hao->addr, &tmp);
292                 }
293         }
294 }
295 #else
296 static inline void mip6_addr_swap(struct sk_buff *skb) {}
297 #endif
298
299 /*
300  *      Send an ICMP message in response to a packet in error
301  */
302 void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
303                  struct net_device *dev)
304 {
305         struct inet6_dev *idev = NULL;
306         struct ipv6hdr *hdr = ipv6_hdr(skb);
307         struct sock *sk;
308         struct ipv6_pinfo *np;
309         struct in6_addr *saddr = NULL;
310         struct dst_entry *dst;
311         struct icmp6hdr tmp_hdr;
312         struct flowi fl;
313         struct icmpv6_msg msg;
314         int iif = 0;
315         int addr_type = 0;
316         int len;
317         int hlimit, tclass;
318         int err = 0;
319
320         if ((u8 *)hdr < skb->head ||
321             (skb->network_header + sizeof(*hdr)) > skb->tail)
322                 return;
323
324         /*
325          *      Make sure we respect the rules
326          *      i.e. RFC 1885 2.4(e)
327          *      Rule (e.1) is enforced by not using icmpv6_send
328          *      in any code that processes icmp errors.
329          */
330         addr_type = ipv6_addr_type(&hdr->daddr);
331
332         if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0))
333                 saddr = &hdr->daddr;
334
335         /*
336          *      Dest addr check
337          */
338
339         if ((addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST)) {
340                 if (type != ICMPV6_PKT_TOOBIG &&
341                     !(type == ICMPV6_PARAMPROB &&
342                       code == ICMPV6_UNK_OPTION &&
343                       (opt_unrec(skb, info))))
344                         return;
345
346                 saddr = NULL;
347         }
348
349         addr_type = ipv6_addr_type(&hdr->saddr);
350
351         /*
352          *      Source addr check
353          */
354
355         if (addr_type & IPV6_ADDR_LINKLOCAL)
356                 iif = skb->dev->ifindex;
357
358         /*
359          *      Must not send error if the source does not uniquely
360          *      identify a single node (RFC2463 Section 2.4).
361          *      We check unspecified / multicast addresses here,
362          *      and anycast addresses will be checked later.
363          */
364         if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
365                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
366                 return;
367         }
368
369         /*
370          *      Never answer to a ICMP packet.
371          */
372         if (is_ineligible(skb)) {
373                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: no reply to icmp error\n");
374                 return;
375         }
376
377         mip6_addr_swap(skb);
378
379         memset(&fl, 0, sizeof(fl));
380         fl.proto = IPPROTO_ICMPV6;
381         ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
382         if (saddr)
383                 ipv6_addr_copy(&fl.fl6_src, saddr);
384         fl.oif = iif;
385         fl.fl_icmp_type = type;
386         fl.fl_icmp_code = code;
387         security_skb_classify_flow(skb, &fl);
388
389         if (icmpv6_xmit_lock())
390                 return;
391
392         sk = icmpv6_socket->sk;
393         np = inet6_sk(sk);
394
395         if (!icmpv6_xrlim_allow(sk, type, &fl))
396                 goto out;
397
398         tmp_hdr.icmp6_type = type;
399         tmp_hdr.icmp6_code = code;
400         tmp_hdr.icmp6_cksum = 0;
401         tmp_hdr.icmp6_pointer = htonl(info);
402
403         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
404                 fl.oif = np->mcast_oif;
405
406         err = ip6_dst_lookup(sk, &dst, &fl);
407         if (err)
408                 goto out;
409
410         /*
411          * We won't send icmp if the destination is known
412          * anycast.
413          */
414         if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) {
415                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n");
416                 goto out_dst_release;
417         }
418
419         if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
420                 goto out;
421
422         if (ipv6_addr_is_multicast(&fl.fl6_dst))
423                 hlimit = np->mcast_hops;
424         else
425                 hlimit = np->hop_limit;
426         if (hlimit < 0)
427                 hlimit = dst_metric(dst, RTAX_HOPLIMIT);
428         if (hlimit < 0)
429                 hlimit = ipv6_get_hoplimit(dst->dev);
430
431         tclass = np->tclass;
432         if (tclass < 0)
433                 tclass = 0;
434
435         msg.skb = skb;
436         msg.offset = skb_network_offset(skb);
437         msg.type = type;
438
439         len = skb->len - msg.offset;
440         len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
441         if (len < 0) {
442                 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
443                 goto out_dst_release;
444         }
445
446         idev = in6_dev_get(skb->dev);
447
448         err = ip6_append_data(sk, icmpv6_getfrag, &msg,
449                               len + sizeof(struct icmp6hdr),
450                               sizeof(struct icmp6hdr),
451                               hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
452                               MSG_DONTWAIT);
453         if (err) {
454                 ip6_flush_pending_frames(sk);
455                 goto out_put;
456         }
457         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
458
459         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
460                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
461         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
462
463 out_put:
464         if (likely(idev != NULL))
465                 in6_dev_put(idev);
466 out_dst_release:
467         dst_release(dst);
468 out:
469         icmpv6_xmit_unlock();
470 }
471
472 EXPORT_SYMBOL(icmpv6_send);
473
474 static void icmpv6_echo_reply(struct sk_buff *skb)
475 {
476         struct sock *sk;
477         struct inet6_dev *idev;
478         struct ipv6_pinfo *np;
479         struct in6_addr *saddr = NULL;
480         struct icmp6hdr *icmph = icmp6_hdr(skb);
481         struct icmp6hdr tmp_hdr;
482         struct flowi fl;
483         struct icmpv6_msg msg;
484         struct dst_entry *dst;
485         int err = 0;
486         int hlimit;
487         int tclass;
488
489         saddr = &ipv6_hdr(skb)->daddr;
490
491         if (!ipv6_unicast_destination(skb))
492                 saddr = NULL;
493
494         memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
495         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
496
497         memset(&fl, 0, sizeof(fl));
498         fl.proto = IPPROTO_ICMPV6;
499         ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
500         if (saddr)
501                 ipv6_addr_copy(&fl.fl6_src, saddr);
502         fl.oif = skb->dev->ifindex;
503         fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
504         security_skb_classify_flow(skb, &fl);
505
506         if (icmpv6_xmit_lock())
507                 return;
508
509         sk = icmpv6_socket->sk;
510         np = inet6_sk(sk);
511
512         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
513                 fl.oif = np->mcast_oif;
514
515         err = ip6_dst_lookup(sk, &dst, &fl);
516         if (err)
517                 goto out;
518         if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
519                 goto out;
520
521         if (ipv6_addr_is_multicast(&fl.fl6_dst))
522                 hlimit = np->mcast_hops;
523         else
524                 hlimit = np->hop_limit;
525         if (hlimit < 0)
526                 hlimit = dst_metric(dst, RTAX_HOPLIMIT);
527         if (hlimit < 0)
528                 hlimit = ipv6_get_hoplimit(dst->dev);
529
530         tclass = np->tclass;
531         if (tclass < 0)
532                 tclass = 0;
533
534         idev = in6_dev_get(skb->dev);
535
536         msg.skb = skb;
537         msg.offset = 0;
538         msg.type = ICMPV6_ECHO_REPLY;
539
540         err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
541                                 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
542                                 (struct rt6_info*)dst, MSG_DONTWAIT);
543
544         if (err) {
545                 ip6_flush_pending_frames(sk);
546                 goto out_put;
547         }
548         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
549
550         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
551         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
552
553 out_put:
554         if (likely(idev != NULL))
555                 in6_dev_put(idev);
556         dst_release(dst);
557 out:
558         icmpv6_xmit_unlock();
559 }
560
561 static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
562 {
563         struct in6_addr *saddr, *daddr;
564         struct inet6_protocol *ipprot;
565         struct sock *sk;
566         int inner_offset;
567         int hash;
568         u8 nexthdr;
569
570         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
571                 return;
572
573         nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
574         if (ipv6_ext_hdr(nexthdr)) {
575                 /* now skip over extension headers */
576                 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
577                 if (inner_offset<0)
578                         return;
579         } else {
580                 inner_offset = sizeof(struct ipv6hdr);
581         }
582
583         /* Checkin header including 8 bytes of inner protocol header. */
584         if (!pskb_may_pull(skb, inner_offset+8))
585                 return;
586
587         saddr = &ipv6_hdr(skb)->saddr;
588         daddr = &ipv6_hdr(skb)->daddr;
589
590         /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
591            Without this we will not able f.e. to make source routed
592            pmtu discovery.
593            Corresponding argument (opt) to notifiers is already added.
594            --ANK (980726)
595          */
596
597         hash = nexthdr & (MAX_INET_PROTOS - 1);
598
599         rcu_read_lock();
600         ipprot = rcu_dereference(inet6_protos[hash]);
601         if (ipprot && ipprot->err_handler)
602                 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
603         rcu_read_unlock();
604
605         read_lock(&raw_v6_lock);
606         if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
607                 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
608                                             IP6CB(skb)->iif))) {
609                         rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
610                         sk = sk_next(sk);
611                 }
612         }
613         read_unlock(&raw_v6_lock);
614 }
615
616 /*
617  *      Handle icmp messages
618  */
619
620 static int icmpv6_rcv(struct sk_buff **pskb)
621 {
622         struct sk_buff *skb = *pskb;
623         struct net_device *dev = skb->dev;
624         struct inet6_dev *idev = __in6_dev_get(dev);
625         struct in6_addr *saddr, *daddr;
626         struct ipv6hdr *orig_hdr;
627         struct icmp6hdr *hdr;
628         int type;
629
630         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
631
632         saddr = &ipv6_hdr(skb)->saddr;
633         daddr = &ipv6_hdr(skb)->daddr;
634
635         /* Perform checksum. */
636         switch (skb->ip_summed) {
637         case CHECKSUM_COMPLETE:
638                 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
639                                      skb->csum))
640                         break;
641                 /* fall through */
642         case CHECKSUM_NONE:
643                 skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
644                                              IPPROTO_ICMPV6, 0));
645                 if (__skb_checksum_complete(skb)) {
646                         LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
647                                        NIP6(*saddr), NIP6(*daddr));
648                         goto discard_it;
649                 }
650         }
651
652         if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
653                 goto discard_it;
654
655         hdr = icmp6_hdr(skb);
656
657         type = hdr->icmp6_type;
658
659         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
660                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
661         else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
662                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST);
663
664         switch (type) {
665         case ICMPV6_ECHO_REQUEST:
666                 icmpv6_echo_reply(skb);
667                 break;
668
669         case ICMPV6_ECHO_REPLY:
670                 /* we couldn't care less */
671                 break;
672
673         case ICMPV6_PKT_TOOBIG:
674                 /* BUGGG_FUTURE: if packet contains rthdr, we cannot update
675                    standard destination cache. Seems, only "advanced"
676                    destination cache will allow to solve this problem
677                    --ANK (980726)
678                  */
679                 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
680                         goto discard_it;
681                 hdr = icmp6_hdr(skb);
682                 orig_hdr = (struct ipv6hdr *) (hdr + 1);
683                 rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
684                                    ntohl(hdr->icmp6_mtu));
685
686                 /*
687                  *      Drop through to notify
688                  */
689
690         case ICMPV6_DEST_UNREACH:
691         case ICMPV6_TIME_EXCEED:
692         case ICMPV6_PARAMPROB:
693                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
694                 break;
695
696         case NDISC_ROUTER_SOLICITATION:
697         case NDISC_ROUTER_ADVERTISEMENT:
698         case NDISC_NEIGHBOUR_SOLICITATION:
699         case NDISC_NEIGHBOUR_ADVERTISEMENT:
700         case NDISC_REDIRECT:
701                 ndisc_rcv(skb);
702                 break;
703
704         case ICMPV6_MGM_QUERY:
705                 igmp6_event_query(skb);
706                 break;
707
708         case ICMPV6_MGM_REPORT:
709                 igmp6_event_report(skb);
710                 break;
711
712         case ICMPV6_MGM_REDUCTION:
713         case ICMPV6_NI_QUERY:
714         case ICMPV6_NI_REPLY:
715         case ICMPV6_MLD2_REPORT:
716         case ICMPV6_DHAAD_REQUEST:
717         case ICMPV6_DHAAD_REPLY:
718         case ICMPV6_MOBILE_PREFIX_SOL:
719         case ICMPV6_MOBILE_PREFIX_ADV:
720                 break;
721
722         default:
723                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
724
725                 /* informational */
726                 if (type & ICMPV6_INFOMSG_MASK)
727                         break;
728
729                 /*
730                  * error of unknown type.
731                  * must pass to upper level
732                  */
733
734                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
735         }
736
737         kfree_skb(skb);
738         return 0;
739
740 discard_it:
741         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS);
742         kfree_skb(skb);
743         return 0;
744 }
745
746 /*
747  * Special lock-class for __icmpv6_socket:
748  */
749 static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
750
751 int __init icmpv6_init(struct net_proto_family *ops)
752 {
753         struct sock *sk;
754         int err, i, j;
755
756         for_each_possible_cpu(i) {
757                 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
758                                        &per_cpu(__icmpv6_socket, i));
759                 if (err < 0) {
760                         printk(KERN_ERR
761                                "Failed to initialize the ICMP6 control socket "
762                                "(err %d).\n",
763                                err);
764                         goto fail;
765                 }
766
767                 sk = per_cpu(__icmpv6_socket, i)->sk;
768                 sk->sk_allocation = GFP_ATOMIC;
769                 /*
770                  * Split off their lock-class, because sk->sk_dst_lock
771                  * gets used from softirqs, which is safe for
772                  * __icmpv6_socket (because those never get directly used
773                  * via userspace syscalls), but unsafe for normal sockets.
774                  */
775                 lockdep_set_class(&sk->sk_dst_lock,
776                                   &icmpv6_socket_sk_dst_lock_key);
777
778                 /* Enough space for 2 64K ICMP packets, including
779                  * sk_buff struct overhead.
780                  */
781                 sk->sk_sndbuf =
782                         (2 * ((64 * 1024) + sizeof(struct sk_buff)));
783
784                 sk->sk_prot->unhash(sk);
785         }
786
787
788         if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) {
789                 printk(KERN_ERR "Failed to register ICMP6 protocol\n");
790                 err = -EAGAIN;
791                 goto fail;
792         }
793
794         return 0;
795
796  fail:
797         for (j = 0; j < i; j++) {
798                 if (!cpu_possible(j))
799                         continue;
800                 sock_release(per_cpu(__icmpv6_socket, j));
801         }
802
803         return err;
804 }
805
806 void icmpv6_cleanup(void)
807 {
808         int i;
809
810         for_each_possible_cpu(i) {
811                 sock_release(per_cpu(__icmpv6_socket, i));
812         }
813         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
814 }
815
816 static const struct icmp6_err {
817         int err;
818         int fatal;
819 } tab_unreach[] = {
820         {       /* NOROUTE */
821                 .err    = ENETUNREACH,
822                 .fatal  = 0,
823         },
824         {       /* ADM_PROHIBITED */
825                 .err    = EACCES,
826                 .fatal  = 1,
827         },
828         {       /* Was NOT_NEIGHBOUR, now reserved */
829                 .err    = EHOSTUNREACH,
830                 .fatal  = 0,
831         },
832         {       /* ADDR_UNREACH */
833                 .err    = EHOSTUNREACH,
834                 .fatal  = 0,
835         },
836         {       /* PORT_UNREACH */
837                 .err    = ECONNREFUSED,
838                 .fatal  = 1,
839         },
840 };
841
842 int icmpv6_err_convert(int type, int code, int *err)
843 {
844         int fatal = 0;
845
846         *err = EPROTO;
847
848         switch (type) {
849         case ICMPV6_DEST_UNREACH:
850                 fatal = 1;
851                 if (code <= ICMPV6_PORT_UNREACH) {
852                         *err  = tab_unreach[code].err;
853                         fatal = tab_unreach[code].fatal;
854                 }
855                 break;
856
857         case ICMPV6_PKT_TOOBIG:
858                 *err = EMSGSIZE;
859                 break;
860
861         case ICMPV6_PARAMPROB:
862                 *err = EPROTO;
863                 fatal = 1;
864                 break;
865
866         case ICMPV6_TIME_EXCEED:
867                 *err = EHOSTUNREACH;
868                 break;
869         }
870
871         return fatal;
872 }
873
874 EXPORT_SYMBOL(icmpv6_err_convert);
875
876 #ifdef CONFIG_SYSCTL
877 ctl_table ipv6_icmp_table[] = {
878         {
879                 .ctl_name       = NET_IPV6_ICMP_RATELIMIT,
880                 .procname       = "ratelimit",
881                 .data           = &sysctl_icmpv6_time,
882                 .maxlen         = sizeof(int),
883                 .mode           = 0644,
884                 .proc_handler   = &proc_dointvec
885         },
886         { .ctl_name = 0 },
887 };
888 #endif
889