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