xref: /openbmc/linux/net/ipv6/icmp.c (revision 1da177e4)
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);
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, *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 = icmpv6_socket->sk;
281 	struct ipv6_pinfo *np = inet6_sk(sk);
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;
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 if we know that source is Anycast also.
332 	 *	for now we don't know that.
333 	 */
334 	if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
335 		LIMIT_NETDEBUG(
336 			printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"));
337 		return;
338 	}
339 
340 	/*
341 	 *	Never answer to a ICMP packet.
342 	 */
343 	if (is_ineligible(skb)) {
344 		LIMIT_NETDEBUG(
345 			printk(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 	if (!icmpv6_xrlim_allow(sk, type, &fl))
362 		goto out;
363 
364 	tmp_hdr.icmp6_type = type;
365 	tmp_hdr.icmp6_code = code;
366 	tmp_hdr.icmp6_cksum = 0;
367 	tmp_hdr.icmp6_pointer = htonl(info);
368 
369 	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
370 		fl.oif = np->mcast_oif;
371 
372 	err = ip6_dst_lookup(sk, &dst, &fl);
373 	if (err)
374 		goto out;
375 	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
376 		goto out_dst_release;
377 
378 	if (ipv6_addr_is_multicast(&fl.fl6_dst))
379 		hlimit = np->mcast_hops;
380 	else
381 		hlimit = np->hop_limit;
382 	if (hlimit < 0)
383 		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
384 	if (hlimit < 0)
385 		hlimit = ipv6_get_hoplimit(dst->dev);
386 
387 	msg.skb = skb;
388 	msg.offset = skb->nh.raw - skb->data;
389 
390 	len = skb->len - msg.offset;
391 	len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
392 	if (len < 0) {
393 		LIMIT_NETDEBUG(
394 			printk(KERN_DEBUG "icmp: len problem\n"));
395 		goto out_dst_release;
396 	}
397 
398 	idev = in6_dev_get(skb->dev);
399 
400 	err = ip6_append_data(sk, icmpv6_getfrag, &msg,
401 			      len + sizeof(struct icmp6hdr),
402 			      sizeof(struct icmp6hdr),
403 			      hlimit, NULL, &fl, (struct rt6_info*)dst,
404 			      MSG_DONTWAIT);
405 	if (err) {
406 		ip6_flush_pending_frames(sk);
407 		goto out_put;
408 	}
409 	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
410 
411 	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
412 		ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
413 	ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
414 
415 out_put:
416 	if (likely(idev != NULL))
417 		in6_dev_put(idev);
418 out_dst_release:
419 	dst_release(dst);
420 out:
421 	icmpv6_xmit_unlock();
422 }
423 
424 static void icmpv6_echo_reply(struct sk_buff *skb)
425 {
426 	struct sock *sk = icmpv6_socket->sk;
427 	struct inet6_dev *idev;
428 	struct ipv6_pinfo *np = inet6_sk(sk);
429 	struct in6_addr *saddr = NULL;
430 	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
431 	struct icmp6hdr tmp_hdr;
432 	struct flowi fl;
433 	struct icmpv6_msg msg;
434 	struct dst_entry *dst;
435 	int err = 0;
436 	int hlimit;
437 
438 	saddr = &skb->nh.ipv6h->daddr;
439 
440 	if (!ipv6_unicast_destination(skb))
441 		saddr = NULL;
442 
443 	memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
444 	tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
445 
446 	memset(&fl, 0, sizeof(fl));
447 	fl.proto = IPPROTO_ICMPV6;
448 	ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
449 	if (saddr)
450 		ipv6_addr_copy(&fl.fl6_src, saddr);
451 	fl.oif = skb->dev->ifindex;
452 	fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
453 
454 	if (icmpv6_xmit_lock())
455 		return;
456 
457 	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
458 		fl.oif = np->mcast_oif;
459 
460 	err = ip6_dst_lookup(sk, &dst, &fl);
461 	if (err)
462 		goto out;
463 	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
464 		goto out_dst_release;
465 
466 	if (ipv6_addr_is_multicast(&fl.fl6_dst))
467 		hlimit = np->mcast_hops;
468 	else
469 		hlimit = np->hop_limit;
470 	if (hlimit < 0)
471 		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
472 	if (hlimit < 0)
473 		hlimit = ipv6_get_hoplimit(dst->dev);
474 
475 	idev = in6_dev_get(skb->dev);
476 
477 	msg.skb = skb;
478 	msg.offset = 0;
479 
480 	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
481 				sizeof(struct icmp6hdr), hlimit, NULL, &fl,
482 				(struct rt6_info*)dst, MSG_DONTWAIT);
483 
484 	if (err) {
485 		ip6_flush_pending_frames(sk);
486 		goto out_put;
487 	}
488 	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
489 
490         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
491         ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
492 
493 out_put:
494 	if (likely(idev != NULL))
495 		in6_dev_put(idev);
496 out_dst_release:
497 	dst_release(dst);
498 out:
499 	icmpv6_xmit_unlock();
500 }
501 
502 static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
503 {
504 	struct in6_addr *saddr, *daddr;
505 	struct inet6_protocol *ipprot;
506 	struct sock *sk;
507 	int inner_offset;
508 	int hash;
509 	u8 nexthdr;
510 
511 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
512 		return;
513 
514 	nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
515 	if (ipv6_ext_hdr(nexthdr)) {
516 		/* now skip over extension headers */
517 		inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, skb->len - sizeof(struct ipv6hdr));
518 		if (inner_offset<0)
519 			return;
520 	} else {
521 		inner_offset = sizeof(struct ipv6hdr);
522 	}
523 
524 	/* Checkin header including 8 bytes of inner protocol header. */
525 	if (!pskb_may_pull(skb, inner_offset+8))
526 		return;
527 
528 	saddr = &skb->nh.ipv6h->saddr;
529 	daddr = &skb->nh.ipv6h->daddr;
530 
531 	/* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
532 	   Without this we will not able f.e. to make source routed
533 	   pmtu discovery.
534 	   Corresponding argument (opt) to notifiers is already added.
535 	   --ANK (980726)
536 	 */
537 
538 	hash = nexthdr & (MAX_INET_PROTOS - 1);
539 
540 	rcu_read_lock();
541 	ipprot = rcu_dereference(inet6_protos[hash]);
542 	if (ipprot && ipprot->err_handler)
543 		ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
544 	rcu_read_unlock();
545 
546 	read_lock(&raw_v6_lock);
547 	if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
548 		while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr))) {
549 			rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
550 			sk = sk_next(sk);
551 		}
552 	}
553 	read_unlock(&raw_v6_lock);
554 }
555 
556 /*
557  *	Handle icmp messages
558  */
559 
560 static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
561 {
562 	struct sk_buff *skb = *pskb;
563 	struct net_device *dev = skb->dev;
564 	struct inet6_dev *idev = __in6_dev_get(dev);
565 	struct in6_addr *saddr, *daddr;
566 	struct ipv6hdr *orig_hdr;
567 	struct icmp6hdr *hdr;
568 	int type;
569 
570 	ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
571 
572 	saddr = &skb->nh.ipv6h->saddr;
573 	daddr = &skb->nh.ipv6h->daddr;
574 
575 	/* Perform checksum. */
576 	if (skb->ip_summed == CHECKSUM_HW) {
577 		skb->ip_summed = CHECKSUM_UNNECESSARY;
578 		if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
579 				    skb->csum)) {
580 			LIMIT_NETDEBUG(
581 				printk(KERN_DEBUG "ICMPv6 hw checksum failed\n"));
582 			skb->ip_summed = CHECKSUM_NONE;
583 		}
584 	}
585 	if (skb->ip_summed == CHECKSUM_NONE) {
586 		if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
587 				    skb_checksum(skb, 0, skb->len, 0))) {
588 			LIMIT_NETDEBUG(
589 				printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
590 				       NIP6(*saddr), NIP6(*daddr)));
591 			goto discard_it;
592 		}
593 	}
594 
595 	if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
596 		goto discard_it;
597 
598 	hdr = (struct icmp6hdr *) skb->h.raw;
599 
600 	type = hdr->icmp6_type;
601 
602 	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
603 		ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
604 	else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
605 		ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST);
606 
607 	switch (type) {
608 	case ICMPV6_ECHO_REQUEST:
609 		icmpv6_echo_reply(skb);
610 		break;
611 
612 	case ICMPV6_ECHO_REPLY:
613 		/* we couldn't care less */
614 		break;
615 
616 	case ICMPV6_PKT_TOOBIG:
617 		/* BUGGG_FUTURE: if packet contains rthdr, we cannot update
618 		   standard destination cache. Seems, only "advanced"
619 		   destination cache will allow to solve this problem
620 		   --ANK (980726)
621 		 */
622 		if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
623 			goto discard_it;
624 		hdr = (struct icmp6hdr *) skb->h.raw;
625 		orig_hdr = (struct ipv6hdr *) (hdr + 1);
626 		rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
627 				   ntohl(hdr->icmp6_mtu));
628 
629 		/*
630 		 *	Drop through to notify
631 		 */
632 
633 	case ICMPV6_DEST_UNREACH:
634 	case ICMPV6_TIME_EXCEED:
635 	case ICMPV6_PARAMPROB:
636 		icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
637 		break;
638 
639 	case NDISC_ROUTER_SOLICITATION:
640 	case NDISC_ROUTER_ADVERTISEMENT:
641 	case NDISC_NEIGHBOUR_SOLICITATION:
642 	case NDISC_NEIGHBOUR_ADVERTISEMENT:
643 	case NDISC_REDIRECT:
644 		ndisc_rcv(skb);
645 		break;
646 
647 	case ICMPV6_MGM_QUERY:
648 		igmp6_event_query(skb);
649 		break;
650 
651 	case ICMPV6_MGM_REPORT:
652 		igmp6_event_report(skb);
653 		break;
654 
655 	case ICMPV6_MGM_REDUCTION:
656 	case ICMPV6_NI_QUERY:
657 	case ICMPV6_NI_REPLY:
658 	case ICMPV6_MLD2_REPORT:
659 	case ICMPV6_DHAAD_REQUEST:
660 	case ICMPV6_DHAAD_REPLY:
661 	case ICMPV6_MOBILE_PREFIX_SOL:
662 	case ICMPV6_MOBILE_PREFIX_ADV:
663 		break;
664 
665 	default:
666 		LIMIT_NETDEBUG(
667 			printk(KERN_DEBUG "icmpv6: msg of unknown type\n"));
668 
669 		/* informational */
670 		if (type & ICMPV6_INFOMSG_MASK)
671 			break;
672 
673 		/*
674 		 * error of unknown type.
675 		 * must pass to upper level
676 		 */
677 
678 		icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
679 	};
680 	kfree_skb(skb);
681 	return 0;
682 
683 discard_it:
684 	ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS);
685 	kfree_skb(skb);
686 	return 0;
687 }
688 
689 int __init icmpv6_init(struct net_proto_family *ops)
690 {
691 	struct sock *sk;
692 	int err, i, j;
693 
694 	for (i = 0; i < NR_CPUS; i++) {
695 		if (!cpu_possible(i))
696 			continue;
697 
698 		err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
699 				       &per_cpu(__icmpv6_socket, i));
700 		if (err < 0) {
701 			printk(KERN_ERR
702 			       "Failed to initialize the ICMP6 control socket "
703 			       "(err %d).\n",
704 			       err);
705 			goto fail;
706 		}
707 
708 		sk = per_cpu(__icmpv6_socket, i)->sk;
709 		sk->sk_allocation = GFP_ATOMIC;
710 
711 		/* Enough space for 2 64K ICMP packets, including
712 		 * sk_buff struct overhead.
713 		 */
714 		sk->sk_sndbuf =
715 			(2 * ((64 * 1024) + sizeof(struct sk_buff)));
716 
717 		sk->sk_prot->unhash(sk);
718 	}
719 
720 
721 	if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) {
722 		printk(KERN_ERR "Failed to register ICMP6 protocol\n");
723 		err = -EAGAIN;
724 		goto fail;
725 	}
726 
727 	return 0;
728 
729  fail:
730 	for (j = 0; j < i; j++) {
731 		if (!cpu_possible(j))
732 			continue;
733 		sock_release(per_cpu(__icmpv6_socket, j));
734 	}
735 
736 	return err;
737 }
738 
739 void icmpv6_cleanup(void)
740 {
741 	int i;
742 
743 	for (i = 0; i < NR_CPUS; i++) {
744 		if (!cpu_possible(i))
745 			continue;
746 		sock_release(per_cpu(__icmpv6_socket, i));
747 	}
748 	inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
749 }
750 
751 static struct icmp6_err {
752 	int err;
753 	int fatal;
754 } tab_unreach[] = {
755 	{	/* NOROUTE */
756 		.err	= ENETUNREACH,
757 		.fatal	= 0,
758 	},
759 	{	/* ADM_PROHIBITED */
760 		.err	= EACCES,
761 		.fatal	= 1,
762 	},
763 	{	/* Was NOT_NEIGHBOUR, now reserved */
764 		.err	= EHOSTUNREACH,
765 		.fatal	= 0,
766 	},
767 	{	/* ADDR_UNREACH	*/
768 		.err	= EHOSTUNREACH,
769 		.fatal	= 0,
770 	},
771 	{	/* PORT_UNREACH	*/
772 		.err	= ECONNREFUSED,
773 		.fatal	= 1,
774 	},
775 };
776 
777 int icmpv6_err_convert(int type, int code, int *err)
778 {
779 	int fatal = 0;
780 
781 	*err = EPROTO;
782 
783 	switch (type) {
784 	case ICMPV6_DEST_UNREACH:
785 		fatal = 1;
786 		if (code <= ICMPV6_PORT_UNREACH) {
787 			*err  = tab_unreach[code].err;
788 			fatal = tab_unreach[code].fatal;
789 		}
790 		break;
791 
792 	case ICMPV6_PKT_TOOBIG:
793 		*err = EMSGSIZE;
794 		break;
795 
796 	case ICMPV6_PARAMPROB:
797 		*err = EPROTO;
798 		fatal = 1;
799 		break;
800 
801 	case ICMPV6_TIME_EXCEED:
802 		*err = EHOSTUNREACH;
803 		break;
804 	};
805 
806 	return fatal;
807 }
808 
809 #ifdef CONFIG_SYSCTL
810 ctl_table ipv6_icmp_table[] = {
811 	{
812 		.ctl_name	= NET_IPV6_ICMP_RATELIMIT,
813 		.procname	= "ratelimit",
814 		.data		= &sysctl_icmpv6_time,
815 		.maxlen		= sizeof(int),
816 		.mode		= 0644,
817 		.proc_handler	= &proc_dointvec
818 	},
819 	{ .ctl_name = 0 },
820 };
821 #endif
822 
823