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