patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / 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
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/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);
71
72 /*
73  *      The ICMP socket(s). This is the most convenient way to flow control
74  *      our ICMP output as well as maintain a clean interface throughout
75  *      all layers. All Socketless IP sends will soon be gone.
76  *
77  *      On SMP we have one ICMP socket per-cpu.
78  */
79 static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL;
80 #define icmpv6_socket   __get_cpu_var(__icmpv6_socket)
81
82 static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
83
84 static struct inet6_protocol icmpv6_protocol = {
85         .handler        =       icmpv6_rcv,
86         .flags          =       INET6_PROTO_FINAL,
87 };
88
89 static __inline__ int icmpv6_xmit_lock(void)
90 {
91         local_bh_disable();
92
93         if (unlikely(!spin_trylock(&icmpv6_socket->sk->sk_lock.slock))) {
94                 /* This can happen if the output path (f.e. SIT or
95                  * ip6ip6 tunnel) signals dst_link_failure() for an
96                  * outgoing ICMP6 packet.
97                  */
98                 local_bh_enable();
99                 return 1;
100         }
101         return 0;
102 }
103
104 static __inline__ void icmpv6_xmit_unlock(void)
105 {
106         spin_unlock_bh(&icmpv6_socket->sk->sk_lock.slock);
107 }
108
109 /* 
110  * Slightly more convenient version of icmpv6_send.
111  */
112 void icmpv6_param_prob(struct sk_buff *skb, int code, int pos)
113 {
114         icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev);
115         kfree_skb(skb);
116 }
117
118 /*
119  * Figure out, may we reply to this packet with icmp error.
120  *
121  * We do not reply, if:
122  *      - it was icmp error message.
123  *      - it is truncated, so that it is known, that protocol is ICMPV6
124  *        (i.e. in the middle of some exthdr)
125  *
126  *      --ANK (980726)
127  */
128
129 static int is_ineligible(struct sk_buff *skb)
130 {
131         int ptr = (u8*)(skb->nh.ipv6h+1) - skb->data;
132         int len = skb->len - ptr;
133         __u8 nexthdr = skb->nh.ipv6h->nexthdr;
134
135         if (len < 0)
136                 return 1;
137
138         ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, len);
139         if (ptr < 0)
140                 return 0;
141         if (nexthdr == IPPROTO_ICMPV6) {
142                 u8 type;
143                 if (skb_copy_bits(skb, ptr+offsetof(struct icmp6hdr, icmp6_type),
144                                   &type, 1)
145                     || !(type & ICMPV6_INFOMSG_MASK))
146                         return 1;
147         }
148         return 0;
149 }
150
151 static int sysctl_icmpv6_time = 1*HZ; 
152
153 /* 
154  * Check the ICMP output rate limit 
155  */
156 static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
157                                      struct flowi *fl)
158 {
159         struct dst_entry *dst;
160         int res = 0;
161
162         /* Informational messages are not limited. */
163         if (type & ICMPV6_INFOMSG_MASK)
164                 return 1;
165
166         /* Do not limit pmtu discovery, it would break it. */
167         if (type == ICMPV6_PKT_TOOBIG)
168                 return 1;
169
170         /* 
171          * Look up the output route.
172          * XXX: perhaps the expire for routing entries cloned by
173          * this lookup should be more aggressive (not longer than timeout).
174          */
175         dst = ip6_route_output(sk, fl);
176         if (dst->error) {
177                 IP6_INC_STATS(OutNoRoutes);
178         } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
179                 res = 1;
180         } else {
181                 struct rt6_info *rt = (struct rt6_info *)dst;
182                 int tmo = sysctl_icmpv6_time;
183
184                 /* Give more bandwidth to wider prefixes. */
185                 if (rt->rt6i_dst.plen < 128)
186                         tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
187
188                 res = xrlim_allow(dst, tmo);
189         }
190         dst_release(dst);
191         return res;
192 }
193
194 /*
195  *      an inline helper for the "simple" if statement below
196  *      checks if parameter problem report is caused by an
197  *      unrecognized IPv6 option that has the Option Type 
198  *      highest-order two bits set to 10
199  */
200
201 static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
202 {
203         u8 optval;
204
205         offset += skb->nh.raw - skb->data;
206         if (skb_copy_bits(skb, offset, &optval, 1))
207                 return 1;
208         return (optval&0xC0) == 0x80;
209 }
210
211 int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
212 {
213         struct sk_buff *skb;
214         struct icmp6hdr *icmp6h;
215         int err = 0;
216
217         if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
218                 goto out;
219
220         icmp6h = (struct icmp6hdr*) skb->h.raw;
221         memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
222         icmp6h->icmp6_cksum = 0;
223
224         if (skb_queue_len(&sk->sk_write_queue) == 1) {
225                 skb->csum = csum_partial((char *)icmp6h,
226                                         sizeof(struct icmp6hdr), skb->csum);
227                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
228                                                       &fl->fl6_dst,
229                                                       len, fl->proto,
230                                                       skb->csum);
231         } else {
232                 u32 tmp_csum = 0;
233
234                 skb_queue_walk(&sk->sk_write_queue, skb) {
235                         tmp_csum = csum_add(tmp_csum, skb->csum);
236                 }
237
238                 tmp_csum = csum_partial((char *)icmp6h,
239                                         sizeof(struct icmp6hdr), tmp_csum);
240                 tmp_csum = csum_ipv6_magic(&fl->fl6_src,
241                                            &fl->fl6_dst,
242                                            len, fl->proto, tmp_csum);
243                 icmp6h->icmp6_cksum = tmp_csum;
244         }
245         if (icmp6h->icmp6_cksum == 0)
246                 icmp6h->icmp6_cksum = -1;
247         ip6_push_pending_frames(sk);
248 out:
249         return err;
250 }
251
252 struct icmpv6_msg {
253         struct sk_buff  *skb;
254         int             offset;
255 };
256
257 static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
258 {
259         struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
260         struct sk_buff *org_skb = msg->skb;
261         __u32 csum = 0;
262
263         csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
264                                       to, len, csum);
265         skb->csum = csum_block_add(skb->csum, csum, odd);
266         return 0;
267 }
268
269 /*
270  *      Send an ICMP message in response to a packet in error
271  */
272 void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, 
273                  struct net_device *dev)
274 {
275         struct inet6_dev *idev = NULL;
276         struct ipv6hdr *hdr = skb->nh.ipv6h;
277         struct sock *sk = icmpv6_socket->sk;
278         struct ipv6_pinfo *np = inet6_sk(sk);
279         struct in6_addr *saddr = NULL;
280         struct dst_entry *dst;
281         struct icmp6hdr tmp_hdr;
282         struct flowi fl;
283         struct icmpv6_msg msg;
284         int iif = 0;
285         int addr_type = 0;
286         int len;
287         int hlimit = -1;
288         int err = 0;
289
290         if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
291                 return;
292
293         /*
294          *      Make sure we respect the rules 
295          *      i.e. RFC 1885 2.4(e)
296          *      Rule (e.1) is enforced by not using icmpv6_send
297          *      in any code that processes icmp errors.
298          */
299         addr_type = ipv6_addr_type(&hdr->daddr);
300
301         if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0))
302                 saddr = &hdr->daddr;
303
304         /*
305          *      Dest addr check
306          */
307
308         if ((addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST)) {
309                 if (type != ICMPV6_PKT_TOOBIG &&
310                     !(type == ICMPV6_PARAMPROB && 
311                       code == ICMPV6_UNK_OPTION && 
312                       (opt_unrec(skb, info))))
313                         return;
314
315                 saddr = NULL;
316         }
317
318         addr_type = ipv6_addr_type(&hdr->saddr);
319
320         /*
321          *      Source addr check
322          */
323
324         if (addr_type & IPV6_ADDR_LINKLOCAL)
325                 iif = skb->dev->ifindex;
326
327         /*
328          *      Must not send if we know that source is Anycast also.
329          *      for now we don't know that.
330          */
331         if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
332                 LIMIT_NETDEBUG(
333                         printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"));
334                 return;
335         }
336
337         /* 
338          *      Never answer to a ICMP packet.
339          */
340         if (is_ineligible(skb)) {
341                 LIMIT_NETDEBUG(
342                         printk(KERN_DEBUG "icmpv6_send: no reply to icmp error\n")); 
343                 return;
344         }
345
346         memset(&fl, 0, sizeof(fl));
347         fl.proto = IPPROTO_ICMPV6;
348         ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
349         if (saddr)
350                 ipv6_addr_copy(&fl.fl6_src, saddr);
351         fl.oif = iif;
352         fl.fl_icmp_type = type;
353         fl.fl_icmp_code = code;
354
355         if (icmpv6_xmit_lock())
356                 return;
357
358         if (!icmpv6_xrlim_allow(sk, type, &fl))
359                 goto out;
360
361         tmp_hdr.icmp6_type = type;
362         tmp_hdr.icmp6_code = code;
363         tmp_hdr.icmp6_cksum = 0;
364         tmp_hdr.icmp6_pointer = htonl(info);
365
366         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
367                 fl.oif = np->mcast_oif;
368
369         err = ip6_dst_lookup(sk, &dst, &fl);
370         if (err)
371                 goto out;
372
373         if (hlimit < 0) {
374                 if (ipv6_addr_is_multicast(&fl.fl6_dst))
375                         hlimit = np->mcast_hops;
376                 else
377                         hlimit = np->hop_limit;
378                 if (hlimit < 0)
379                         hlimit = dst_metric(dst, RTAX_HOPLIMIT);
380         }
381
382         msg.skb = skb;
383         msg.offset = skb->nh.raw - skb->data;
384
385         len = skb->len - msg.offset;
386         len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
387         if (len < 0) {
388                 LIMIT_NETDEBUG(
389                         printk(KERN_DEBUG "icmp: len problem\n"));
390                 goto out_dst_release;
391         }
392
393         idev = in6_dev_get(skb->dev);
394
395         err = ip6_append_data(sk, icmpv6_getfrag, &msg,
396                               len + sizeof(struct icmp6hdr),
397                               sizeof(struct icmp6hdr),
398                               hlimit, NULL, &fl, (struct rt6_info*)dst,
399                               MSG_DONTWAIT);
400         if (err) {
401                 ip6_flush_pending_frames(sk);
402                 goto out_put;
403         }
404         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
405
406         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
407                 ICMP6_INC_STATS_OFFSET_BH(idev, Icmp6OutDestUnreachs, type - ICMPV6_DEST_UNREACH);
408         ICMP6_INC_STATS_BH(idev, Icmp6OutMsgs);
409
410 out_put:
411         if (likely(idev != NULL))
412                 in6_dev_put(idev);
413 out_dst_release:
414         dst_release(dst);
415 out:
416         icmpv6_xmit_unlock();
417 }
418
419 static void icmpv6_echo_reply(struct sk_buff *skb)
420 {
421         struct sock *sk = icmpv6_socket->sk;
422         struct inet6_dev *idev;
423         struct ipv6_pinfo *np = inet6_sk(sk);
424         struct in6_addr *saddr = NULL;
425         struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
426         struct icmp6hdr tmp_hdr;
427         struct flowi fl;
428         struct icmpv6_msg msg;
429         struct dst_entry *dst;
430         int err = 0;
431         int hlimit = -1;
432
433         saddr = &skb->nh.ipv6h->daddr;
434
435         if (!ipv6_unicast_destination(skb))
436                 saddr = NULL;
437
438         memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
439         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
440
441         memset(&fl, 0, sizeof(fl));
442         fl.proto = IPPROTO_ICMPV6;
443         ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
444         if (saddr)
445                 ipv6_addr_copy(&fl.fl6_src, saddr);
446         fl.oif = skb->dev->ifindex;
447         fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
448
449         if (icmpv6_xmit_lock())
450                 return;
451
452         if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
453                 fl.oif = np->mcast_oif;
454
455         err = ip6_dst_lookup(sk, &dst, &fl);
456         if (err)
457                 goto out;
458
459         if (hlimit < 0) {
460                 if (ipv6_addr_is_multicast(&fl.fl6_dst))
461                         hlimit = np->mcast_hops;
462                 else
463                         hlimit = np->hop_limit;
464                 if (hlimit < 0)
465                         hlimit = dst_metric(dst, RTAX_HOPLIMIT);
466         }
467
468         idev = in6_dev_get(skb->dev);
469
470         msg.skb = skb;
471         msg.offset = 0;
472
473         err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
474                                 sizeof(struct icmp6hdr), hlimit, NULL, &fl,
475                                 (struct rt6_info*)dst, MSG_DONTWAIT);
476
477         if (err) {
478                 ip6_flush_pending_frames(sk);
479                 goto out_put;
480         }
481         err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
482
483         ICMP6_INC_STATS_BH(idev, Icmp6OutEchoReplies);
484         ICMP6_INC_STATS_BH(idev, Icmp6OutMsgs);
485
486 out_put: 
487         if (likely(idev != NULL))
488                 in6_dev_put(idev);
489         dst_release(dst);
490 out: 
491         icmpv6_xmit_unlock();
492 }
493
494 static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
495 {
496         struct in6_addr *saddr, *daddr;
497         struct inet6_protocol *ipprot;
498         struct sock *sk;
499         int inner_offset;
500         int hash;
501         u8 nexthdr;
502
503         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
504                 return;
505
506         nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
507         if (ipv6_ext_hdr(nexthdr)) {
508                 /* now skip over extension headers */
509                 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, skb->len - sizeof(struct ipv6hdr));
510                 if (inner_offset<0)
511                         return;
512         } else {
513                 inner_offset = sizeof(struct ipv6hdr);
514         }
515
516         /* Checkin header including 8 bytes of inner protocol header. */
517         if (!pskb_may_pull(skb, inner_offset+8))
518                 return;
519
520         saddr = &skb->nh.ipv6h->saddr;
521         daddr = &skb->nh.ipv6h->daddr;
522
523         /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
524            Without this we will not able f.e. to make source routed
525            pmtu discovery.
526            Corresponding argument (opt) to notifiers is already added.
527            --ANK (980726)
528          */
529
530         hash = nexthdr & (MAX_INET_PROTOS - 1);
531
532         rcu_read_lock();
533         ipprot = inet6_protos[hash];
534         smp_read_barrier_depends();
535         if (ipprot && ipprot->err_handler)
536                 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
537         rcu_read_unlock();
538
539         read_lock(&raw_v6_lock);
540         if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
541                 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr))) {
542                         rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
543                         sk = sk_next(sk);
544                 }
545         }
546         read_unlock(&raw_v6_lock);
547 }
548   
549 /*
550  *      Handle icmp messages
551  */
552
553 static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
554 {
555         struct sk_buff *skb = *pskb;
556         struct net_device *dev = skb->dev;
557         struct inet6_dev *idev = __in6_dev_get(dev);
558         struct in6_addr *saddr, *daddr;
559         struct ipv6hdr *orig_hdr;
560         struct icmp6hdr *hdr;
561         int type;
562
563         ICMP6_INC_STATS_BH(idev, Icmp6InMsgs);
564
565         saddr = &skb->nh.ipv6h->saddr;
566         daddr = &skb->nh.ipv6h->daddr;
567
568         /* Perform checksum. */
569         if (skb->ip_summed == CHECKSUM_HW) {
570                 skb->ip_summed = CHECKSUM_UNNECESSARY;
571                 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
572                                     skb->csum)) {
573                         LIMIT_NETDEBUG(
574                                 printk(KERN_DEBUG "ICMPv6 hw checksum failed\n"));
575                         skb->ip_summed = CHECKSUM_NONE;
576                 }
577         }
578         if (skb->ip_summed == CHECKSUM_NONE) {
579                 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
580                                     skb_checksum(skb, 0, skb->len, 0))) {
581                         LIMIT_NETDEBUG(
582                                 printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
583                                        NIP6(*saddr), NIP6(*daddr)));
584                         goto discard_it;
585                 }
586         }
587
588         if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
589                 goto discard_it;
590
591         hdr = (struct icmp6hdr *) skb->h.raw;
592
593         type = hdr->icmp6_type;
594
595         if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
596                 ICMP6_INC_STATS_OFFSET_BH(idev, Icmp6InDestUnreachs, type - ICMPV6_DEST_UNREACH);
597         else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
598                 ICMP6_INC_STATS_OFFSET_BH(idev, Icmp6InEchos, type - ICMPV6_ECHO_REQUEST);
599
600         switch (type) {
601         case ICMPV6_ECHO_REQUEST:
602                 icmpv6_echo_reply(skb);
603                 break;
604
605         case ICMPV6_ECHO_REPLY:
606                 /* we couldn't care less */
607                 break;
608
609         case ICMPV6_PKT_TOOBIG:
610                 /* BUGGG_FUTURE: if packet contains rthdr, we cannot update
611                    standard destination cache. Seems, only "advanced"
612                    destination cache will allow to solve this problem
613                    --ANK (980726)
614                  */
615                 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
616                         goto discard_it;
617                 hdr = (struct icmp6hdr *) skb->h.raw;
618                 orig_hdr = (struct ipv6hdr *) (hdr + 1);
619                 rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
620                                    ntohl(hdr->icmp6_mtu));
621
622                 /*
623                  *      Drop through to notify
624                  */
625
626         case ICMPV6_DEST_UNREACH:
627         case ICMPV6_TIME_EXCEED:
628         case ICMPV6_PARAMPROB:
629                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
630                 break;
631
632         case NDISC_ROUTER_SOLICITATION:
633         case NDISC_ROUTER_ADVERTISEMENT:
634         case NDISC_NEIGHBOUR_SOLICITATION:
635         case NDISC_NEIGHBOUR_ADVERTISEMENT:
636         case NDISC_REDIRECT:
637                 ndisc_rcv(skb);
638                 break;
639
640         case ICMPV6_MGM_QUERY:
641                 igmp6_event_query(skb);
642                 break;
643
644         case ICMPV6_MGM_REPORT:
645                 igmp6_event_report(skb);
646                 break;
647
648         case ICMPV6_MGM_REDUCTION:
649         case ICMPV6_MLD2_REPORT:
650                 break;
651
652         default:
653                 LIMIT_NETDEBUG(
654                         printk(KERN_DEBUG "icmpv6: msg of unknown type\n"));
655
656                 /* informational */
657                 if (type & ICMPV6_INFOMSG_MASK)
658                         break;
659
660                 /* 
661                  * error of unknown type. 
662                  * must pass to upper level 
663                  */
664
665                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
666         };
667         kfree_skb(skb);
668         return 0;
669
670 discard_it:
671         ICMP6_INC_STATS_BH(idev, Icmp6InErrors);
672         kfree_skb(skb);
673         return 0;
674 }
675
676 int __init icmpv6_init(struct net_proto_family *ops)
677 {
678         struct sock *sk;
679         int err, i, j;
680
681         for (i = 0; i < NR_CPUS; i++) {
682                 if (!cpu_possible(i))
683                         continue;
684
685                 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
686                                        &per_cpu(__icmpv6_socket, i));
687                 if (err < 0) {
688                         printk(KERN_ERR
689                                "Failed to initialize the ICMP6 control socket "
690                                "(err %d).\n",
691                                err);
692                         goto fail;
693                 }
694
695                 sk = per_cpu(__icmpv6_socket, i)->sk;
696                 sk->sk_allocation = GFP_ATOMIC;
697
698                 /* Enough space for 2 64K ICMP packets, including
699                  * sk_buff struct overhead.
700                  */
701                 sk->sk_sndbuf =
702                         (2 * ((64 * 1024) + sizeof(struct sk_buff)));
703
704                 sk->sk_prot->unhash(sk);
705         }
706
707
708         if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) {
709                 printk(KERN_ERR "Failed to register ICMP6 protocol\n");
710                 err = -EAGAIN;
711                 goto fail;
712         }
713
714         return 0;
715
716  fail:
717         for (j = 0; j < i; j++) {
718                 if (!cpu_possible(j))
719                         continue;
720                 sock_release(per_cpu(__icmpv6_socket, j));
721         }
722
723         return err;
724 }
725
726 void icmpv6_cleanup(void)
727 {
728         int i;
729
730         for (i = 0; i < NR_CPUS; i++) {
731                 if (!cpu_possible(i))
732                         continue;
733                 sock_release(per_cpu(__icmpv6_socket, i));
734         }
735         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
736 }
737
738 static struct icmp6_err {
739         int err;
740         int fatal;
741 } tab_unreach[] = {
742         {       /* NOROUTE */
743                 .err    = ENETUNREACH,
744                 .fatal  = 0,
745         },
746         {       /* ADM_PROHIBITED */
747                 .err    = EACCES,
748                 .fatal  = 1,
749         },
750         {       /* Was NOT_NEIGHBOUR, now reserved */
751                 .err    = EHOSTUNREACH,
752                 .fatal  = 0,
753         },
754         {       /* ADDR_UNREACH */
755                 .err    = EHOSTUNREACH,
756                 .fatal  = 0,
757         },
758         {       /* PORT_UNREACH */
759                 .err    = ECONNREFUSED,
760                 .fatal  = 1,
761         },
762 };
763
764 int icmpv6_err_convert(int type, int code, int *err)
765 {
766         int fatal = 0;
767
768         *err = EPROTO;
769
770         switch (type) {
771         case ICMPV6_DEST_UNREACH:
772                 fatal = 1;
773                 if (code <= ICMPV6_PORT_UNREACH) {
774                         *err  = tab_unreach[code].err;
775                         fatal = tab_unreach[code].fatal;
776                 }
777                 break;
778
779         case ICMPV6_PKT_TOOBIG:
780                 *err = EMSGSIZE;
781                 break;
782                 
783         case ICMPV6_PARAMPROB:
784                 *err = EPROTO;
785                 fatal = 1;
786                 break;
787
788         case ICMPV6_TIME_EXCEED:
789                 *err = EHOSTUNREACH;
790                 break;
791         };
792
793         return fatal;
794 }
795
796 #ifdef CONFIG_SYSCTL
797 ctl_table ipv6_icmp_table[] = {
798         {
799                 .ctl_name       = NET_IPV6_ICMP_RATELIMIT,
800                 .procname       = "ratelimit",
801                 .data           = &sysctl_icmpv6_time,
802                 .maxlen         = sizeof(int),
803                 .mode           = 0644,
804                 .proc_handler   = &proc_dointvec
805         },
806         { .ctl_name = 0 },
807 };
808 #endif
809