Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-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/sched.h>
41 #include <linux/sockios.h>
42 #include <linux/net.h>
43 #include <linux/skbuff.h>
44 #include <linux/init.h>
45 #include <linux/netfilter.h>
46
47 #ifdef CONFIG_SYSCTL
48 #include <linux/sysctl.h>
49 #endif
50
51 #include <linux/inet.h>
52 #include <linux/netdevice.h>
53 #include <linux/icmpv6.h>
54
55 #include <net/ip.h>
56 #include <net/sock.h>
57
58 #include <net/ipv6.h>
59 #include <net/ip6_checksum.h>
60 #include <net/protocol.h>
61 #include <net/raw.h>
62 #include <net/rawv6.h>
63 #include <net/transp_v6.h>
64 #include <net/ip6_route.h>
65 #include <net/addrconf.h>
66 #include <net/icmp.h>
67
68 #include <asm/uaccess.h>
69 #include <asm/system.h>
70
71 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
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*)(skb->nh.ipv6h+1) - skb->data;
133         int len = skb->len - ptr;
134         __u8 nexthdr = skb->nh.ipv6h->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 = 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(IPSTATS_MIB_OUTNOROUTES);
181         } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
182                 res = 1;
183         } else {
184                 struct rt6_info *rt = (struct rt6_info *)dst;
185                 int tmo = sysctl_icmpv6_time;
186
187                 /* Give more bandwidth to wider prefixes. */
188                 if (rt->rt6i_dst.plen < 128)
189                         tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
190
191                 res = xrlim_allow(dst, tmo);
192         }
193         dst_release(dst);
194         return res;
195 }
196
197 /*
198  *      an inline helper for the "simple" if statement below
199  *      checks if parameter problem report is caused by an
200  *      unrecognized IPv6 option that has the Option Type 
201  *      highest-order two bits set to 10
202  */
203
204 static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
205 {
206         u8 _optval, *op;
207
208         offset += skb->nh.raw - skb->data;
209         op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
210         if (op == NULL)
211                 return 1;
212         return (*op & 0xC0) == 0x80;
213 }
214
215 static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
216 {
217         struct sk_buff *skb;
218         struct icmp6hdr *icmp6h;
219         int err = 0;
220
221         if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
222                 goto out;
223
224         icmp6h = (struct icmp6hdr*) skb->h.raw;
225         memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
226         icmp6h->icmp6_cksum = 0;
227
228         if (skb_queue_len(&sk->sk_write_queue) == 1) {
229                 skb->csum = csum_partial((char *)icmp6h,
230                                         sizeof(struct icmp6hdr), skb->csum);
231                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
232                                                       &fl->fl6_dst,
233                                                       len, fl->proto,
234                                                       skb->csum);
235         } else {
236                 u32 tmp_csum = 0;
237
238                 skb_queue_walk(&sk->sk_write_queue, skb) {
239                         tmp_csum = csum_add(tmp_csum, skb->csum);
240                 }
241
242                 tmp_csum = csum_partial((char *)icmp6h,
243                                         sizeof(struct icmp6hdr), tmp_csum);
244                 tmp_csum = csum_ipv6_magic(&fl->fl6_src,
245                                            &fl->fl6_dst,
246                                            len, fl->proto, tmp_csum);
247                 icmp6h->icmp6_cksum = tmp_csum;
248         }
249         if (icmp6h->icmp6_cksum == 0)
250                 icmp6h->icmp6_cksum = -1;
251         ip6_push_pending_frames(sk);
252 out:
253         return err;
254 }
255
256 struct icmpv6_msg {
257         struct sk_buff  *skb;
258         int             offset;
259         uint8_t         type;
260 };
261
262 static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
263 {
264         struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
265         struct sk_buff *org_skb = msg->skb;
266         __u32 csum = 0;
267
268         csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
269                                       to, len, csum);
270         skb->csum = csum_block_add(skb->csum, csum, odd);
271         if (!(msg->type & ICMPV6_INFOMSG_MASK))
272                 nf_ct_attach(skb, org_skb);
273         return 0;
274 }
275
276 /*
277  *      Send an ICMP message in response to a packet in error
278  */
279 void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, 
280                  struct net_device *dev)
281 {
282         struct inet6_dev *idev = NULL;
283         struct ipv6hdr *hdr = skb->nh.ipv6h;
284         struct sock *sk;
285         struct ipv6_pinfo *np;
286         struct in6_addr *saddr = NULL;
287         struct dst_entry *dst;
288         struct icmp6hdr tmp_hdr;
289         struct flowi fl;
290         struct icmpv6_msg msg;
291         int iif = 0;
292         int addr_type = 0;
293         int len;
294         int hlimit, tclass;
295         int err = 0;
296
297         if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
298                 return;
299
300         /*
301          *      Make sure we respect the rules 
302          *      i.e. RFC 1885 2.4(e)
303          *      Rule (e.1) is enforced by not using icmpv6_send
304          *      in any code that processes icmp errors.
305          */
306         addr_type = ipv6_addr_type(&hdr->daddr);
307
308         if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0))
309                 saddr = &hdr->daddr;
310
311         /*
312          *      Dest addr check
313          */
314
315         if ((addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST)) {
316                 if (type != ICMPV6_PKT_TOOBIG &&
317                     !(type == ICMPV6_PARAMPROB && 
318                       code == ICMPV6_UNK_OPTION && 
319                       (opt_unrec(skb, info))))
320                         return;
321
322                 saddr = NULL;
323         }
324
325         addr_type = ipv6_addr_type(&hdr->saddr);
326
327         /*
328          *      Source addr check
329          */
330
331         if (addr_type & IPV6_ADDR_LINKLOCAL)
332                 iif = skb->dev->ifindex;
333
334         /*
335          *      Must not send error if the source does not uniquely
336          *      identify a single node (RFC2463 Section 2.4).
337          *      We check unspecified / multicast addresses here,
338          *      and anycast addresses will be checked later.
339          */
340         if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
341                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
342                 return;
343         }
344
345         /* 
346          *      Never answer to a ICMP packet.
347          */
348         if (is_ineligible(skb)) {
349                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: no reply to icmp error\n");
350                 return;
351         }
352
353         memset(&fl, 0, sizeof(fl));
354         fl.proto = IPPROTO_ICMPV6;
355         ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
356         if (saddr)
357                 ipv6_addr_copy(&fl.fl6_src, saddr);
358         fl.oif = iif;
359         fl.fl_icmp_type = type;
360         fl.fl_icmp_code = code;
361
362         if (icmpv6_xmit_lock())
363                 return;
364
365         sk = icmpv6_socket->sk;
366         np = inet6_sk(sk);
367
368         if (!icmpv6_xrlim_allow(sk, type, &fl))
369                 goto out;
370
371         tmp_hdr.icmp6_type = type;
372         tmp_hdr.icmp6_code = code;
373         tmp_hdr.icmp6_cksum = 0;
374         tmp_hdr.icmp6_pointer = htonl(info);
375
376         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
377                 fl.oif = np->mcast_oif;
378
379         err = ip6_dst_lookup(sk, &dst, &fl);
380         if (err)
381                 goto out;
382
383         /*
384          * We won't send icmp if the destination is known
385          * anycast.
386          */
387         if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) {
388                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n");
389                 goto out_dst_release;
390         }
391
392         if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
393                 goto out;
394
395         if (ipv6_addr_is_multicast(&fl.fl6_dst))
396                 hlimit = np->mcast_hops;
397         else
398                 hlimit = np->hop_limit;
399         if (hlimit < 0)
400                 hlimit = dst_metric(dst, RTAX_HOPLIMIT);
401         if (hlimit < 0)
402                 hlimit = ipv6_get_hoplimit(dst->dev);
403
404         tclass = np->cork.tclass;
405         if (tclass < 0)
406                 tclass = 0;
407
408         msg.skb = skb;
409         msg.offset = skb->nh.raw - skb->data;
410         msg.type = type;
411
412         len = skb->len - msg.offset;
413         len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
414         if (len < 0) {
415                 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
416                 goto out_dst_release;
417         }
418
419         idev = in6_dev_get(skb->dev);
420
421         err = ip6_append_data(sk, icmpv6_getfrag, &msg,
422                               len + sizeof(struct icmp6hdr),
423                               sizeof(struct icmp6hdr),
424                               hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
425                               MSG_DONTWAIT);
426         if (err) {
427                 ip6_flush_pending_frames(sk);
428                 goto out_put;
429         }
430         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
431
432         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
433                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
434         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
435
436 out_put:
437         if (likely(idev != NULL))
438                 in6_dev_put(idev);
439 out_dst_release:
440         dst_release(dst);
441 out:
442         icmpv6_xmit_unlock();
443 }
444
445 static void icmpv6_echo_reply(struct sk_buff *skb)
446 {
447         struct sock *sk;
448         struct inet6_dev *idev;
449         struct ipv6_pinfo *np;
450         struct in6_addr *saddr = NULL;
451         struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
452         struct icmp6hdr tmp_hdr;
453         struct flowi fl;
454         struct icmpv6_msg msg;
455         struct dst_entry *dst;
456         int err = 0;
457         int hlimit;
458         int tclass;
459
460         saddr = &skb->nh.ipv6h->daddr;
461
462         if (!ipv6_unicast_destination(skb))
463                 saddr = NULL;
464
465         memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
466         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
467
468         memset(&fl, 0, sizeof(fl));
469         fl.proto = IPPROTO_ICMPV6;
470         ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
471         if (saddr)
472                 ipv6_addr_copy(&fl.fl6_src, saddr);
473         fl.oif = skb->dev->ifindex;
474         fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
475
476         if (icmpv6_xmit_lock())
477                 return;
478
479         sk = icmpv6_socket->sk;
480         np = inet6_sk(sk);
481
482         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
483                 fl.oif = np->mcast_oif;
484
485         err = ip6_dst_lookup(sk, &dst, &fl);
486         if (err)
487                 goto out;
488         if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
489                 goto out;
490
491         if (ipv6_addr_is_multicast(&fl.fl6_dst))
492                 hlimit = np->mcast_hops;
493         else
494                 hlimit = np->hop_limit;
495         if (hlimit < 0)
496                 hlimit = dst_metric(dst, RTAX_HOPLIMIT);
497         if (hlimit < 0)
498                 hlimit = ipv6_get_hoplimit(dst->dev);
499
500         tclass = np->cork.tclass;
501         if (tclass < 0)
502                 tclass = 0;
503
504         idev = in6_dev_get(skb->dev);
505
506         msg.skb = skb;
507         msg.offset = 0;
508         msg.type = ICMPV6_ECHO_REPLY;
509
510         err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
511                                 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
512                                 (struct rt6_info*)dst, MSG_DONTWAIT);
513
514         if (err) {
515                 ip6_flush_pending_frames(sk);
516                 goto out_put;
517         }
518         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
519
520         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
521         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
522
523 out_put: 
524         if (likely(idev != NULL))
525                 in6_dev_put(idev);
526         dst_release(dst);
527 out: 
528         icmpv6_xmit_unlock();
529 }
530
531 static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
532 {
533         struct in6_addr *saddr, *daddr;
534         struct inet6_protocol *ipprot;
535         struct sock *sk;
536         int inner_offset;
537         int hash;
538         u8 nexthdr;
539
540         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
541                 return;
542
543         nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
544         if (ipv6_ext_hdr(nexthdr)) {
545                 /* now skip over extension headers */
546                 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
547                 if (inner_offset<0)
548                         return;
549         } else {
550                 inner_offset = sizeof(struct ipv6hdr);
551         }
552
553         /* Checkin header including 8 bytes of inner protocol header. */
554         if (!pskb_may_pull(skb, inner_offset+8))
555                 return;
556
557         saddr = &skb->nh.ipv6h->saddr;
558         daddr = &skb->nh.ipv6h->daddr;
559
560         /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
561            Without this we will not able f.e. to make source routed
562            pmtu discovery.
563            Corresponding argument (opt) to notifiers is already added.
564            --ANK (980726)
565          */
566
567         hash = nexthdr & (MAX_INET_PROTOS - 1);
568
569         rcu_read_lock();
570         ipprot = rcu_dereference(inet6_protos[hash]);
571         if (ipprot && ipprot->err_handler)
572                 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
573         rcu_read_unlock();
574
575         read_lock(&raw_v6_lock);
576         if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
577                 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
578                                             IP6CB(skb)->iif))) {
579                         rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
580                         sk = sk_next(sk);
581                 }
582         }
583         read_unlock(&raw_v6_lock);
584 }
585   
586 /*
587  *      Handle icmp messages
588  */
589
590 static int icmpv6_rcv(struct sk_buff **pskb)
591 {
592         struct sk_buff *skb = *pskb;
593         struct net_device *dev = skb->dev;
594         struct inet6_dev *idev = __in6_dev_get(dev);
595         struct in6_addr *saddr, *daddr;
596         struct ipv6hdr *orig_hdr;
597         struct icmp6hdr *hdr;
598         int type;
599
600         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
601
602         saddr = &skb->nh.ipv6h->saddr;
603         daddr = &skb->nh.ipv6h->daddr;
604
605         /* Perform checksum. */
606         switch (skb->ip_summed) {
607         case CHECKSUM_HW:
608                 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
609                                      skb->csum))
610                         break;
611                 /* fall through */
612         case CHECKSUM_NONE:
613                 skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len,
614                                              IPPROTO_ICMPV6, 0);
615                 if (__skb_checksum_complete(skb)) {
616                         LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
617                                        NIP6(*saddr), NIP6(*daddr));
618                         goto discard_it;
619                 }
620         }
621
622         if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
623                 goto discard_it;
624
625         hdr = (struct icmp6hdr *) skb->h.raw;
626
627         type = hdr->icmp6_type;
628
629         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
630                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
631         else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
632                 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST);
633
634         switch (type) {
635         case ICMPV6_ECHO_REQUEST:
636                 icmpv6_echo_reply(skb);
637                 break;
638
639         case ICMPV6_ECHO_REPLY:
640                 /* we couldn't care less */
641                 break;
642
643         case ICMPV6_PKT_TOOBIG:
644                 /* BUGGG_FUTURE: if packet contains rthdr, we cannot update
645                    standard destination cache. Seems, only "advanced"
646                    destination cache will allow to solve this problem
647                    --ANK (980726)
648                  */
649                 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
650                         goto discard_it;
651                 hdr = (struct icmp6hdr *) skb->h.raw;
652                 orig_hdr = (struct ipv6hdr *) (hdr + 1);
653                 rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
654                                    ntohl(hdr->icmp6_mtu));
655
656                 /*
657                  *      Drop through to notify
658                  */
659
660         case ICMPV6_DEST_UNREACH:
661         case ICMPV6_TIME_EXCEED:
662         case ICMPV6_PARAMPROB:
663                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
664                 break;
665
666         case NDISC_ROUTER_SOLICITATION:
667         case NDISC_ROUTER_ADVERTISEMENT:
668         case NDISC_NEIGHBOUR_SOLICITATION:
669         case NDISC_NEIGHBOUR_ADVERTISEMENT:
670         case NDISC_REDIRECT:
671                 ndisc_rcv(skb);
672                 break;
673
674         case ICMPV6_MGM_QUERY:
675                 igmp6_event_query(skb);
676                 break;
677
678         case ICMPV6_MGM_REPORT:
679                 igmp6_event_report(skb);
680                 break;
681
682         case ICMPV6_MGM_REDUCTION:
683         case ICMPV6_NI_QUERY:
684         case ICMPV6_NI_REPLY:
685         case ICMPV6_MLD2_REPORT:
686         case ICMPV6_DHAAD_REQUEST:
687         case ICMPV6_DHAAD_REPLY:
688         case ICMPV6_MOBILE_PREFIX_SOL:
689         case ICMPV6_MOBILE_PREFIX_ADV:
690                 break;
691
692         default:
693                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
694
695                 /* informational */
696                 if (type & ICMPV6_INFOMSG_MASK)
697                         break;
698
699                 /* 
700                  * error of unknown type. 
701                  * must pass to upper level 
702                  */
703
704                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
705         };
706         kfree_skb(skb);
707         return 0;
708
709 discard_it:
710         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS);
711         kfree_skb(skb);
712         return 0;
713 }
714
715 int __init icmpv6_init(struct net_proto_family *ops)
716 {
717         struct sock *sk;
718         int err, i, j;
719
720         for_each_possible_cpu(i) {
721                 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
722                                        &per_cpu(__icmpv6_socket, i));
723                 if (err < 0) {
724                         printk(KERN_ERR
725                                "Failed to initialize the ICMP6 control socket "
726                                "(err %d).\n",
727                                err);
728                         goto fail;
729                 }
730
731                 sk = per_cpu(__icmpv6_socket, i)->sk;
732                 sk->sk_allocation = GFP_ATOMIC;
733
734                 /* Enough space for 2 64K ICMP packets, including
735                  * sk_buff struct overhead.
736                  */
737                 sk->sk_sndbuf =
738                         (2 * ((64 * 1024) + sizeof(struct sk_buff)));
739
740                 sk->sk_prot->unhash(sk);
741         }
742
743
744         if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) {
745                 printk(KERN_ERR "Failed to register ICMP6 protocol\n");
746                 err = -EAGAIN;
747                 goto fail;
748         }
749
750         return 0;
751
752  fail:
753         for (j = 0; j < i; j++) {
754                 if (!cpu_possible(j))
755                         continue;
756                 sock_release(per_cpu(__icmpv6_socket, j));
757         }
758
759         return err;
760 }
761
762 void icmpv6_cleanup(void)
763 {
764         int i;
765
766         for_each_possible_cpu(i) {
767                 sock_release(per_cpu(__icmpv6_socket, i));
768         }
769         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
770 }
771
772 static const struct icmp6_err {
773         int err;
774         int fatal;
775 } tab_unreach[] = {
776         {       /* NOROUTE */
777                 .err    = ENETUNREACH,
778                 .fatal  = 0,
779         },
780         {       /* ADM_PROHIBITED */
781                 .err    = EACCES,
782                 .fatal  = 1,
783         },
784         {       /* Was NOT_NEIGHBOUR, now reserved */
785                 .err    = EHOSTUNREACH,
786                 .fatal  = 0,
787         },
788         {       /* ADDR_UNREACH */
789                 .err    = EHOSTUNREACH,
790                 .fatal  = 0,
791         },
792         {       /* PORT_UNREACH */
793                 .err    = ECONNREFUSED,
794                 .fatal  = 1,
795         },
796 };
797
798 int icmpv6_err_convert(int type, int code, int *err)
799 {
800         int fatal = 0;
801
802         *err = EPROTO;
803
804         switch (type) {
805         case ICMPV6_DEST_UNREACH:
806                 fatal = 1;
807                 if (code <= ICMPV6_PORT_UNREACH) {
808                         *err  = tab_unreach[code].err;
809                         fatal = tab_unreach[code].fatal;
810                 }
811                 break;
812
813         case ICMPV6_PKT_TOOBIG:
814                 *err = EMSGSIZE;
815                 break;
816                 
817         case ICMPV6_PARAMPROB:
818                 *err = EPROTO;
819                 fatal = 1;
820                 break;
821
822         case ICMPV6_TIME_EXCEED:
823                 *err = EHOSTUNREACH;
824                 break;
825         };
826
827         return fatal;
828 }
829
830 #ifdef CONFIG_SYSCTL
831 ctl_table ipv6_icmp_table[] = {
832         {
833                 .ctl_name       = NET_IPV6_ICMP_RATELIMIT,
834                 .procname       = "ratelimit",
835                 .data           = &sysctl_icmpv6_time,
836                 .maxlen         = sizeof(int),
837                 .mode           = 0644,
838                 .proc_handler   = &proc_dointvec
839         },
840         { .ctl_name = 0 },
841 };
842 #endif
843