]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/ipv6/icmp.c
net/tls: fix slab-out-of-bounds bug in decrypt_internal
[mirror_ubuntu-jammy-kernel.git] / net / ipv6 / icmp.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 * Internet Control Message Protocol (ICMPv6)
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *
1da177e4
LT
9 * Based on net/ipv4/icmp.c
10 *
11 * RFC 1885
1da177e4
LT
12 */
13
14/*
15 * Changes:
16 *
17 * Andi Kleen : exception handling
18 * Andi Kleen add rate limits. never reply to a icmp.
19 * add more length checks and other fixes.
20 * yoshfuji : ensure to sent parameter problem for
21 * fragments.
22 * YOSHIFUJI Hideaki @USAGI: added sysctl for icmp rate limit.
23 * Randy Dunlap and
24 * YOSHIFUJI Hideaki @USAGI: Per-interface statistics support
25 * Kazunori MIYAZAWA @USAGI: change output process to use ip6_append_data
26 */
27
f3213831
JP
28#define pr_fmt(fmt) "IPv6: " fmt
29
1da177e4
LT
30#include <linux/module.h>
31#include <linux/errno.h>
32#include <linux/types.h>
33#include <linux/socket.h>
34#include <linux/in.h>
35#include <linux/kernel.h>
1da177e4
LT
36#include <linux/sockios.h>
37#include <linux/net.h>
38#include <linux/skbuff.h>
39#include <linux/init.h>
763ecff1 40#include <linux/netfilter.h>
5a0e3ad6 41#include <linux/slab.h>
1da177e4
LT
42
43#ifdef CONFIG_SYSCTL
44#include <linux/sysctl.h>
45#endif
46
47#include <linux/inet.h>
48#include <linux/netdevice.h>
49#include <linux/icmpv6.h>
50
51#include <net/ip.h>
52#include <net/sock.h>
53
54#include <net/ipv6.h>
55#include <net/ip6_checksum.h>
6d0bfe22 56#include <net/ping.h>
1da177e4
LT
57#include <net/protocol.h>
58#include <net/raw.h>
59#include <net/rawv6.h>
26c26034 60#include <net/seg6.h>
1da177e4
LT
61#include <net/transp_v6.h>
62#include <net/ip6_route.h>
63#include <net/addrconf.h>
64#include <net/icmp.h>
8b7817f3 65#include <net/xfrm.h>
1ed8516f 66#include <net/inet_common.h>
825edac4 67#include <net/dsfield.h>
ca254490 68#include <net/l3mdev.h>
1da177e4 69
7c0f6ba6 70#include <linux/uaccess.h>
1da177e4 71
1da177e4
LT
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 */
2789c14d 79static struct sock *icmpv6_sk(struct net *net)
98c6d1b2 80{
2789c14d 81 return this_cpu_read(*net->ipv6.icmp_sk);
98c6d1b2 82}
1da177e4 83
32bbd879 84static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
6f809da2
SK
85 u8 type, u8 code, int offset, __be32 info)
86{
6d0bfe22
LC
87 /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
88 struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
6f809da2
SK
89 struct net *net = dev_net(skb->dev);
90
91 if (type == ICMPV6_PKT_TOOBIG)
5f379ef5 92 ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0, sock_net_uid(net, NULL));
6f809da2 93 else if (type == NDISC_REDIRECT)
e2d118a1
LC
94 ip6_redirect(skb, net, skb->dev->ifindex, 0,
95 sock_net_uid(net, NULL));
6d0bfe22
LC
96
97 if (!(type & ICMPV6_INFOMSG_MASK))
98 if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
dcb94b88 99 ping_err(skb, offset, ntohl(info));
32bbd879
SB
100
101 return 0;
6f809da2
SK
102}
103
e5bbef20 104static int icmpv6_rcv(struct sk_buff *skb);
1da177e4 105
41135cc8 106static const struct inet6_protocol icmpv6_protocol = {
1da177e4 107 .handler = icmpv6_rcv,
6f809da2 108 .err_handler = icmpv6_err,
8b7817f3 109 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1da177e4
LT
110};
111
7ba91ecb 112/* Called with BH disabled */
fdc0bde9 113static __inline__ struct sock *icmpv6_xmit_lock(struct net *net)
1da177e4 114{
fdc0bde9
DL
115 struct sock *sk;
116
fdc0bde9 117 sk = icmpv6_sk(net);
405666db 118 if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
1da177e4
LT
119 /* This can happen if the output path (f.e. SIT or
120 * ip6ip6 tunnel) signals dst_link_failure() for an
121 * outgoing ICMP6 packet.
122 */
fdc0bde9 123 return NULL;
1da177e4 124 }
fdc0bde9 125 return sk;
1da177e4
LT
126}
127
405666db 128static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
1da177e4 129{
7ba91ecb 130 spin_unlock(&sk->sk_lock.slock);
1da177e4
LT
131}
132
1da177e4
LT
133/*
134 * Figure out, may we reply to this packet with icmp error.
135 *
136 * We do not reply, if:
137 * - it was icmp error message.
138 * - it is truncated, so that it is known, that protocol is ICMPV6
139 * (i.e. in the middle of some exthdr)
140 *
141 * --ANK (980726)
142 */
143
a50feda5 144static bool is_ineligible(const struct sk_buff *skb)
1da177e4 145{
0660e03f 146 int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
1da177e4 147 int len = skb->len - ptr;
0660e03f 148 __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
75f2811c 149 __be16 frag_off;
1da177e4
LT
150
151 if (len < 0)
a50feda5 152 return true;
1da177e4 153
75f2811c 154 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off);
1da177e4 155 if (ptr < 0)
a50feda5 156 return false;
1da177e4
LT
157 if (nexthdr == IPPROTO_ICMPV6) {
158 u8 _type, *tp;
159 tp = skb_header_pointer(skb,
160 ptr+offsetof(struct icmp6hdr, icmp6_type),
161 sizeof(_type), &_type);
2efdaaaf
HL
162
163 /* Based on RFC 8200, Section 4.5 Fragment Header, return
164 * false if this is a fragment packet with no icmp header info.
165 */
166 if (!tp && frag_off != 0)
167 return false;
168 else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
a50feda5 169 return true;
1da177e4 170 }
a50feda5 171 return false;
1da177e4
LT
172}
173
0bc19985 174static bool icmpv6_mask_allow(struct net *net, int type)
c0303efe 175{
0bc19985 176 if (type > ICMPV6_MSG_MAX)
c0303efe
JDB
177 return true;
178
0bc19985
SS
179 /* Limit if icmp type is set in ratemask. */
180 if (!test_bit(type, net->ipv6.sysctl.icmpv6_ratemask))
c0303efe
JDB
181 return true;
182
183 return false;
184}
185
0bc19985 186static bool icmpv6_global_allow(struct net *net, int type)
c0303efe 187{
0bc19985 188 if (icmpv6_mask_allow(net, type))
c0303efe
JDB
189 return true;
190
191 if (icmp_global_allow())
192 return true;
193
194 return false;
195}
196
1ab1457c
YH
197/*
198 * Check the ICMP output rate limit
1da177e4 199 */
4cdf507d
ED
200static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
201 struct flowi6 *fl6)
1da177e4 202{
3b1e0a65 203 struct net *net = sock_net(sk);
4cdf507d 204 struct dst_entry *dst;
92d86829 205 bool res = false;
1da177e4 206
0bc19985 207 if (icmpv6_mask_allow(net, type))
92d86829 208 return true;
1da177e4 209
1ab1457c 210 /*
1da177e4
LT
211 * Look up the output route.
212 * XXX: perhaps the expire for routing entries cloned by
213 * this lookup should be more aggressive (not longer than timeout).
214 */
4c9483b2 215 dst = ip6_route_output(net, sk, fl6);
1da177e4 216 if (dst->error) {
3bd653c8 217 IP6_INC_STATS(net, ip6_dst_idev(dst),
a11d206d 218 IPSTATS_MIB_OUTNOROUTES);
1da177e4 219 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
92d86829 220 res = true;
1da177e4
LT
221 } else {
222 struct rt6_info *rt = (struct rt6_info *)dst;
9a43b709 223 int tmo = net->ipv6.sysctl.icmpv6_time;
c0303efe 224 struct inet_peer *peer;
1da177e4
LT
225
226 /* Give more bandwidth to wider prefixes. */
227 if (rt->rt6i_dst.plen < 128)
228 tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
229
c0303efe
JDB
230 peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr, 1);
231 res = inet_peer_xrlim_allow(peer, tmo);
232 if (peer)
233 inet_putpeer(peer);
1da177e4
LT
234 }
235 dst_release(dst);
236 return res;
237}
238
b93cfb9c
TS
239static bool icmpv6_rt_has_prefsrc(struct sock *sk, u8 type,
240 struct flowi6 *fl6)
241{
242 struct net *net = sock_net(sk);
243 struct dst_entry *dst;
244 bool res = false;
245
246 dst = ip6_route_output(net, sk, fl6);
247 if (!dst->error) {
248 struct rt6_info *rt = (struct rt6_info *)dst;
249 struct in6_addr prefsrc;
250
251 rt6_get_prefsrc(rt, &prefsrc);
252 res = !ipv6_addr_any(&prefsrc);
253 }
254 dst_release(dst);
255 return res;
256}
257
1da177e4
LT
258/*
259 * an inline helper for the "simple" if statement below
260 * checks if parameter problem report is caused by an
1ab1457c 261 * unrecognized IPv6 option that has the Option Type
1da177e4
LT
262 * highest-order two bits set to 10
263 */
264
a50feda5 265static bool opt_unrec(struct sk_buff *skb, __u32 offset)
1da177e4
LT
266{
267 u8 _optval, *op;
268
bbe735e4 269 offset += skb_network_offset(skb);
1da177e4 270 op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
63159f29 271 if (!op)
a50feda5 272 return true;
1da177e4
LT
273 return (*op & 0xC0) == 0x80;
274}
275
4e64b1ed
JP
276void icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
277 struct icmp6hdr *thdr, int len)
1da177e4
LT
278{
279 struct sk_buff *skb;
280 struct icmp6hdr *icmp6h;
1da177e4 281
e5d08d71 282 skb = skb_peek(&sk->sk_write_queue);
63159f29 283 if (!skb)
4e64b1ed 284 return;
1da177e4 285
cc70ab26 286 icmp6h = icmp6_hdr(skb);
1da177e4
LT
287 memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
288 icmp6h->icmp6_cksum = 0;
289
290 if (skb_queue_len(&sk->sk_write_queue) == 1) {
07f0757a 291 skb->csum = csum_partial(icmp6h,
1da177e4 292 sizeof(struct icmp6hdr), skb->csum);
4c9483b2
DM
293 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
294 &fl6->daddr,
295 len, fl6->flowi6_proto,
1da177e4
LT
296 skb->csum);
297 } else {
868c86bc 298 __wsum tmp_csum = 0;
1da177e4
LT
299
300 skb_queue_walk(&sk->sk_write_queue, skb) {
301 tmp_csum = csum_add(tmp_csum, skb->csum);
302 }
303
07f0757a 304 tmp_csum = csum_partial(icmp6h,
1da177e4 305 sizeof(struct icmp6hdr), tmp_csum);
4c9483b2
DM
306 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
307 &fl6->daddr,
308 len, fl6->flowi6_proto,
868c86bc 309 tmp_csum);
1da177e4 310 }
1da177e4 311 ip6_push_pending_frames(sk);
1da177e4
LT
312}
313
314struct icmpv6_msg {
315 struct sk_buff *skb;
316 int offset;
763ecff1 317 uint8_t type;
1da177e4
LT
318};
319
320static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
321{
322 struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
323 struct sk_buff *org_skb = msg->skb;
8d5930df 324 __wsum csum;
1da177e4
LT
325
326 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
8d5930df 327 to, len);
1da177e4 328 skb->csum = csum_block_add(skb->csum, csum, odd);
763ecff1
YK
329 if (!(msg->type & ICMPV6_INFOMSG_MASK))
330 nf_ct_attach(skb, org_skb);
1da177e4
LT
331 return 0;
332}
333
07a93626 334#if IS_ENABLED(CONFIG_IPV6_MIP6)
ee576c47 335static void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt)
79383236 336{
0660e03f 337 struct ipv6hdr *iph = ipv6_hdr(skb);
79383236
MN
338 struct ipv6_destopt_hao *hao;
339 struct in6_addr tmp;
340 int off;
341
342 if (opt->dsthao) {
343 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
344 if (likely(off >= 0)) {
d56f90a7
ACM
345 hao = (struct ipv6_destopt_hao *)
346 (skb_network_header(skb) + off);
4e3fd7a0
AD
347 tmp = iph->saddr;
348 iph->saddr = hao->addr;
349 hao->addr = tmp;
79383236
MN
350 }
351 }
352}
353#else
ee576c47 354static inline void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt) {}
79383236
MN
355#endif
356
e8243534 357static struct dst_entry *icmpv6_route_lookup(struct net *net,
358 struct sk_buff *skb,
359 struct sock *sk,
360 struct flowi6 *fl6)
b42835db
DM
361{
362 struct dst_entry *dst, *dst2;
4c9483b2 363 struct flowi6 fl2;
b42835db
DM
364 int err;
365
343d60aa 366 err = ip6_dst_lookup(net, sk, &dst, fl6);
b42835db
DM
367 if (err)
368 return ERR_PTR(err);
369
370 /*
371 * We won't send icmp if the destination is known
372 * anycast.
373 */
2647a9b0 374 if (ipv6_anycast_destination(dst, &fl6->daddr)) {
ba7a46f1 375 net_dbg_ratelimited("icmp6_send: acast source\n");
b42835db
DM
376 dst_release(dst);
377 return ERR_PTR(-EINVAL);
378 }
379
380 /* No need to clone since we're just using its address. */
381 dst2 = dst;
382
4c9483b2 383 dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), sk, 0);
452edd59 384 if (!IS_ERR(dst)) {
b42835db
DM
385 if (dst != dst2)
386 return dst;
452edd59
DM
387 } else {
388 if (PTR_ERR(dst) == -EPERM)
389 dst = NULL;
390 else
391 return dst;
b42835db
DM
392 }
393
4c9483b2 394 err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6);
b42835db
DM
395 if (err)
396 goto relookup_failed;
397
343d60aa 398 err = ip6_dst_lookup(net, sk, &dst2, &fl2);
b42835db
DM
399 if (err)
400 goto relookup_failed;
401
4c9483b2 402 dst2 = xfrm_lookup(net, dst2, flowi6_to_flowi(&fl2), sk, XFRM_LOOKUP_ICMP);
452edd59 403 if (!IS_ERR(dst2)) {
b42835db
DM
404 dst_release(dst);
405 dst = dst2;
452edd59
DM
406 } else {
407 err = PTR_ERR(dst2);
408 if (err == -EPERM) {
409 dst_release(dst);
410 return dst2;
411 } else
412 goto relookup_failed;
b42835db
DM
413 }
414
415relookup_failed:
416 if (dst)
417 return dst;
418 return ERR_PTR(err);
419}
420
e1ae5c2e 421static struct net_device *icmp6_dev(const struct sk_buff *skb)
1b70d792 422{
e1ae5c2e 423 struct net_device *dev = skb->dev;
1b70d792
DA
424
425 /* for local traffic to local address, skb dev is the loopback
426 * device. Check if there is a dst attached to the skb and if so
24b711ed
DA
427 * get the real device index. Same is needed for replies to a link
428 * local address on a device enslaved to an L3 master device
1b70d792 429 */
e1ae5c2e 430 if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) {
1b70d792
DA
431 const struct rt6_info *rt6 = skb_rt6_info(skb);
432
433 if (rt6)
e1ae5c2e 434 dev = rt6->rt6i_idev->dev;
1b70d792
DA
435 }
436
e1ae5c2e
SS
437 return dev;
438}
439
440static int icmp6_iif(const struct sk_buff *skb)
441{
442 return icmp6_dev(skb)->ifindex;
1b70d792
DA
443}
444
1da177e4
LT
445/*
446 * Send an ICMP message in response to a packet in error
447 */
cc7a21b6 448void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
ee576c47
JD
449 const struct in6_addr *force_saddr,
450 const struct inet6_skb_parm *parm)
1da177e4
LT
451{
452 struct inet6_dev *idev = NULL;
0660e03f 453 struct ipv6hdr *hdr = ipv6_hdr(skb);
84427d53 454 struct sock *sk;
8d933670 455 struct net *net;
84427d53 456 struct ipv6_pinfo *np;
b71d1d42 457 const struct in6_addr *saddr = NULL;
1da177e4
LT
458 struct dst_entry *dst;
459 struct icmp6hdr tmp_hdr;
4c9483b2 460 struct flowi6 fl6;
1da177e4 461 struct icmpv6_msg msg;
26879da5 462 struct ipcm6_cookie ipc6;
1da177e4
LT
463 int iif = 0;
464 int addr_type = 0;
465 int len;
8d933670 466 u32 mark;
1da177e4 467
27a884dc 468 if ((u8 *)hdr < skb->head ||
29a3cad5 469 (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
1da177e4
LT
470 return;
471
8d933670
ED
472 if (!skb->dev)
473 return;
474 net = dev_net(skb->dev);
475 mark = IP6_REPLY_MARK(net, skb->mark);
1da177e4 476 /*
1ab1457c 477 * Make sure we respect the rules
1da177e4 478 * i.e. RFC 1885 2.4(e)
5f5624cf 479 * Rule (e.1) is enforced by not using icmp6_send
1da177e4
LT
480 * in any code that processes icmp errors.
481 */
482 addr_type = ipv6_addr_type(&hdr->daddr);
483
446fab59 484 if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
d94c1f92 485 ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
1da177e4
LT
486 saddr = &hdr->daddr;
487
488 /*
489 * Dest addr check
490 */
491
9a6b4b39 492 if (addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST) {
1da177e4 493 if (type != ICMPV6_PKT_TOOBIG &&
1ab1457c
YH
494 !(type == ICMPV6_PARAMPROB &&
495 code == ICMPV6_UNK_OPTION &&
1da177e4
LT
496 (opt_unrec(skb, info))))
497 return;
498
499 saddr = NULL;
500 }
501
502 addr_type = ipv6_addr_type(&hdr->saddr);
503
504 /*
505 * Source addr check
506 */
507
4832c30d 508 if (__ipv6_addr_needs_scope_id(addr_type)) {
1b70d792 509 iif = icmp6_iif(skb);
4832c30d 510 } else {
272928d1
MD
511 /*
512 * The source device is used for looking up which routing table
513 * to use for sending an ICMP error.
514 */
515 iif = l3mdev_master_ifindex(skb->dev);
79dc7e3f 516 }
1da177e4
LT
517
518 /*
8de3351e
YH
519 * Must not send error if the source does not uniquely
520 * identify a single node (RFC2463 Section 2.4).
521 * We check unspecified / multicast addresses here,
522 * and anycast addresses will be checked later.
1da177e4
LT
523 */
524 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
4b3418fb
BM
525 net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n",
526 &hdr->saddr, &hdr->daddr);
1da177e4
LT
527 return;
528 }
529
1ab1457c 530 /*
1da177e4
LT
531 * Never answer to a ICMP packet.
532 */
533 if (is_ineligible(skb)) {
4b3418fb
BM
534 net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n",
535 &hdr->saddr, &hdr->daddr);
1da177e4
LT
536 return;
537 }
538
7ba91ecb
JDB
539 /* Needed by both icmp_global_allow and icmpv6_xmit_lock */
540 local_bh_disable();
541
542 /* Check global sysctl_icmp_msgs_per_sec ratelimit */
0bc19985 543 if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
7ba91ecb
JDB
544 goto out_bh_enable;
545
ee576c47 546 mip6_addr_swap(skb, parm);
79383236 547
fac6fce9
FR
548 sk = icmpv6_xmit_lock(net);
549 if (!sk)
550 goto out_bh_enable;
551
4c9483b2
DM
552 memset(&fl6, 0, sizeof(fl6));
553 fl6.flowi6_proto = IPPROTO_ICMPV6;
4e3fd7a0 554 fl6.daddr = hdr->saddr;
b1cadc1a
ED
555 if (force_saddr)
556 saddr = force_saddr;
fac6fce9 557 if (saddr) {
4e3fd7a0 558 fl6.saddr = *saddr;
b93cfb9c 559 } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
fac6fce9
FR
560 /* select a more meaningful saddr from input if */
561 struct net_device *in_netdev;
562
ee576c47 563 in_netdev = dev_get_by_index(net, parm->iif);
fac6fce9
FR
564 if (in_netdev) {
565 ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
566 inet6_sk(sk)->srcprefs,
567 &fl6.saddr);
568 dev_put(in_netdev);
569 }
570 }
e110861f 571 fl6.flowi6_mark = mark;
4c9483b2 572 fl6.flowi6_oif = iif;
1958b856
DM
573 fl6.fl6_icmp_type = type;
574 fl6.fl6_icmp_code = code;
e2d118a1 575 fl6.flowi6_uid = sock_net_uid(net, NULL);
b4bac172 576 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
3df98d79 577 security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6));
1da177e4 578
fdc0bde9 579 np = inet6_sk(sk);
405666db 580
4c9483b2 581 if (!icmpv6_xrlim_allow(sk, type, &fl6))
1da177e4
LT
582 goto out;
583
584 tmp_hdr.icmp6_type = type;
585 tmp_hdr.icmp6_code = code;
586 tmp_hdr.icmp6_cksum = 0;
587 tmp_hdr.icmp6_pointer = htonl(info);
588
4c9483b2
DM
589 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
590 fl6.flowi6_oif = np->mcast_oif;
c4062dfc
EH
591 else if (!fl6.flowi6_oif)
592 fl6.flowi6_oif = np->ucast_oif;
1da177e4 593
b515430a 594 ipcm6_init_sk(&ipc6, np);
0da7536f 595 ipc6.sockc.mark = mark;
38b7097b
HFS
596 fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
597
4c9483b2 598 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
b42835db 599 if (IS_ERR(dst))
1da177e4 600 goto out;
8de3351e 601
26879da5 602 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
1da177e4
LT
603
604 msg.skb = skb;
bbe735e4 605 msg.offset = skb_network_offset(skb);
763ecff1 606 msg.type = type;
1da177e4
LT
607
608 len = skb->len - msg.offset;
67ba4152 609 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr));
1da177e4 610 if (len < 0) {
4b3418fb
BM
611 net_dbg_ratelimited("icmp: len problem [%pI6c > %pI6c]\n",
612 &hdr->saddr, &hdr->daddr);
1da177e4
LT
613 goto out_dst_release;
614 }
615
cfdf7647
ED
616 rcu_read_lock();
617 idev = __in6_dev_get(skb->dev);
1da177e4 618
4e64b1ed
JP
619 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
620 len + sizeof(struct icmp6hdr),
621 sizeof(struct icmp6hdr),
622 &ipc6, &fl6, (struct rt6_info *)dst,
5fdaa88d 623 MSG_DONTWAIT)) {
43a43b60 624 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
1da177e4 625 ip6_flush_pending_frames(sk);
cfdf7647 626 } else {
4e64b1ed
JP
627 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
628 len + sizeof(struct icmp6hdr));
1da177e4 629 }
cfdf7647 630 rcu_read_unlock();
1da177e4
LT
631out_dst_release:
632 dst_release(dst);
633out:
405666db 634 icmpv6_xmit_unlock(sk);
7ba91ecb
JDB
635out_bh_enable:
636 local_bh_enable();
1da177e4 637}
cc7a21b6 638EXPORT_SYMBOL(icmp6_send);
5f5624cf
PS
639
640/* Slightly more convenient version of icmp6_send.
641 */
642void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
643{
ee576c47 644 icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
5f5624cf
PS
645 kfree_skb(skb);
646}
7159039a 647
5fbba8ac
ED
648/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
649 * if sufficient data bytes are available
650 * @nhs is the size of the tunnel header(s) :
651 * Either an IPv4 header for SIT encap
652 * an IPv4 header + GRE header for GRE encap
653 */
20e1954f
ED
654int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
655 unsigned int data_len)
5fbba8ac 656{
2d7a3b27 657 struct in6_addr temp_saddr;
5fbba8ac
ED
658 struct rt6_info *rt;
659 struct sk_buff *skb2;
20e1954f 660 u32 info = 0;
5fbba8ac
ED
661
662 if (!pskb_may_pull(skb, nhs + sizeof(struct ipv6hdr) + 8))
663 return 1;
664
20e1954f
ED
665 /* RFC 4884 (partial) support for ICMP extensions */
666 if (data_len < 128 || (data_len & 7) || skb->len < data_len)
667 data_len = 0;
668
669 skb2 = data_len ? skb_copy(skb, GFP_ATOMIC) : skb_clone(skb, GFP_ATOMIC);
5fbba8ac
ED
670
671 if (!skb2)
672 return 1;
673
674 skb_dst_drop(skb2);
675 skb_pull(skb2, nhs);
676 skb_reset_network_header(skb2);
677
b75cc8f9
DA
678 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0,
679 skb, 0);
5fbba8ac
ED
680
681 if (rt && rt->dst.dev)
682 skb2->dev = rt->dst.dev;
683
2d7a3b27 684 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
20e1954f
ED
685
686 if (data_len) {
687 /* RFC 4884 (partial) support :
688 * insert 0 padding at the end, before the extensions
689 */
690 __skb_push(skb2, nhs);
691 skb_reset_network_header(skb2);
692 memmove(skb2->data, skb2->data + nhs, data_len - nhs);
693 memset(skb2->data + data_len - nhs, 0, nhs);
694 /* RFC 4884 4.5 : Length is measured in 64-bit words,
695 * and stored in reserved[0]
696 */
697 info = (data_len/8) << 24;
698 }
2d7a3b27
ED
699 if (type == ICMP_TIME_EXCEEDED)
700 icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
ee576c47 701 info, &temp_saddr, IP6CB(skb2));
2d7a3b27
ED
702 else
703 icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
ee576c47 704 info, &temp_saddr, IP6CB(skb2));
5fbba8ac
ED
705 if (rt)
706 ip6_rt_put(rt);
707
708 kfree_skb(skb2);
709
710 return 0;
711}
712EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);
713
1da177e4
LT
714static void icmpv6_echo_reply(struct sk_buff *skb)
715{
c346dca1 716 struct net *net = dev_net(skb->dev);
84427d53 717 struct sock *sk;
1da177e4 718 struct inet6_dev *idev;
84427d53 719 struct ipv6_pinfo *np;
b71d1d42 720 const struct in6_addr *saddr = NULL;
cc70ab26 721 struct icmp6hdr *icmph = icmp6_hdr(skb);
1da177e4 722 struct icmp6hdr tmp_hdr;
4c9483b2 723 struct flowi6 fl6;
1da177e4
LT
724 struct icmpv6_msg msg;
725 struct dst_entry *dst;
26879da5 726 struct ipcm6_cookie ipc6;
e110861f 727 u32 mark = IP6_REPLY_MARK(net, skb->mark);
0b03a5ca 728 bool acast;
1fd07f33 729 u8 type;
1da177e4 730
03f1eccc
SS
731 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) &&
732 net->ipv6.sysctl.icmpv6_echo_ignore_multicast)
733 return;
734
0660e03f 735 saddr = &ipv6_hdr(skb)->daddr;
1da177e4 736
0b03a5ca
SS
737 acast = ipv6_anycast_destination(skb_dst(skb), saddr);
738 if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast)
739 return;
740
509aba3b 741 if (!ipv6_unicast_destination(skb) &&
0b03a5ca 742 !(net->ipv6.sysctl.anycast_src_echo_reply && acast))
1da177e4
LT
743 saddr = NULL;
744
1fd07f33
AR
745 if (icmph->icmp6_type == ICMPV6_EXT_ECHO_REQUEST)
746 type = ICMPV6_EXT_ECHO_REPLY;
747 else
748 type = ICMPV6_ECHO_REPLY;
749
1da177e4 750 memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
1fd07f33 751 tmp_hdr.icmp6_type = type;
1da177e4 752
4c9483b2 753 memset(&fl6, 0, sizeof(fl6));
a346abe0
ED
754 if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES)
755 fl6.flowlabel = ip6_flowlabel(ipv6_hdr(skb));
756
4c9483b2 757 fl6.flowi6_proto = IPPROTO_ICMPV6;
4e3fd7a0 758 fl6.daddr = ipv6_hdr(skb)->saddr;
1da177e4 759 if (saddr)
4e3fd7a0 760 fl6.saddr = *saddr;
1b70d792 761 fl6.flowi6_oif = icmp6_iif(skb);
1fd07f33 762 fl6.fl6_icmp_type = type;
e110861f 763 fl6.flowi6_mark = mark;
e2d118a1 764 fl6.flowi6_uid = sock_net_uid(net, NULL);
3df98d79 765 security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6));
1da177e4 766
7ba91ecb 767 local_bh_disable();
fdc0bde9 768 sk = icmpv6_xmit_lock(net);
63159f29 769 if (!sk)
7ba91ecb 770 goto out_bh_enable;
fdc0bde9 771 np = inet6_sk(sk);
405666db 772
4c9483b2
DM
773 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
774 fl6.flowi6_oif = np->mcast_oif;
c4062dfc
EH
775 else if (!fl6.flowi6_oif)
776 fl6.flowi6_oif = np->ucast_oif;
1da177e4 777
4e64b1ed 778 if (ip6_dst_lookup(net, sk, &dst, &fl6))
1da177e4 779 goto out;
4c9483b2 780 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
452edd59 781 if (IS_ERR(dst))
e104411b 782 goto out;
1da177e4 783
0bc19985
SS
784 /* Check the ratelimit */
785 if ((!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, ICMPV6_ECHO_REPLY)) ||
786 !icmpv6_xrlim_allow(sk, ICMPV6_ECHO_REPLY, &fl6))
787 goto out_dst_release;
788
cfdf7647 789 idev = __in6_dev_get(skb->dev);
1da177e4
LT
790
791 msg.skb = skb;
792 msg.offset = 0;
1fd07f33 793 msg.type = type;
1da177e4 794
b515430a 795 ipcm6_init_sk(&ipc6, np);
26879da5
WW
796 ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
797 ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb));
0da7536f 798 ipc6.sockc.mark = mark;
26879da5 799
1fd07f33
AR
800 if (icmph->icmp6_type == ICMPV6_EXT_ECHO_REQUEST)
801 if (!icmp_build_probe(skb, (struct icmphdr *)&tmp_hdr))
802 goto out_dst_release;
803
4e64b1ed
JP
804 if (ip6_append_data(sk, icmpv6_getfrag, &msg,
805 skb->len + sizeof(struct icmp6hdr),
806 sizeof(struct icmp6hdr), &ipc6, &fl6,
5fdaa88d 807 (struct rt6_info *)dst, MSG_DONTWAIT)) {
a16292a0 808 __ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
1da177e4 809 ip6_flush_pending_frames(sk);
cfdf7647 810 } else {
4e64b1ed
JP
811 icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
812 skb->len + sizeof(struct icmp6hdr));
1da177e4 813 }
0bc19985 814out_dst_release:
1da177e4 815 dst_release(dst);
1ab1457c 816out:
405666db 817 icmpv6_xmit_unlock(sk);
7ba91ecb
JDB
818out_bh_enable:
819 local_bh_enable();
1da177e4
LT
820}
821
b94f1c09 822void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
1da177e4 823{
26c26034 824 struct inet6_skb_parm *opt = IP6CB(skb);
41135cc8 825 const struct inet6_protocol *ipprot;
1da177e4 826 int inner_offset;
75f2811c 827 __be16 frag_off;
f9242b6b 828 u8 nexthdr;
7304fe46 829 struct net *net = dev_net(skb->dev);
1da177e4
LT
830
831 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
7304fe46 832 goto out;
1da177e4 833
26c26034
AL
834 seg6_icmp_srh(skb, opt);
835
1da177e4
LT
836 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
837 if (ipv6_ext_hdr(nexthdr)) {
838 /* now skip over extension headers */
75f2811c
JG
839 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
840 &nexthdr, &frag_off);
67ba4152 841 if (inner_offset < 0)
7304fe46 842 goto out;
1da177e4
LT
843 } else {
844 inner_offset = sizeof(struct ipv6hdr);
845 }
846
847 /* Checkin header including 8 bytes of inner protocol header. */
848 if (!pskb_may_pull(skb, inner_offset+8))
7304fe46 849 goto out;
1da177e4 850
1da177e4
LT
851 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
852 Without this we will not able f.e. to make source routed
853 pmtu discovery.
854 Corresponding argument (opt) to notifiers is already added.
855 --ANK (980726)
856 */
857
f9242b6b 858 ipprot = rcu_dereference(inet6_protos[nexthdr]);
1da177e4 859 if (ipprot && ipprot->err_handler)
26c26034 860 ipprot->err_handler(skb, opt, type, code, inner_offset, info);
1da177e4 861
69d6da0b 862 raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
7304fe46
DJ
863 return;
864
865out:
a16292a0 866 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
1da177e4 867}
1ab1457c 868
1da177e4
LT
869/*
870 * Handle icmp messages
871 */
872
e5bbef20 873static int icmpv6_rcv(struct sk_buff *skb)
1da177e4 874{
e6f86b0f 875 struct net *net = dev_net(skb->dev);
e1ae5c2e 876 struct net_device *dev = icmp6_dev(skb);
1da177e4 877 struct inet6_dev *idev = __in6_dev_get(dev);
b71d1d42 878 const struct in6_addr *saddr, *daddr;
1da177e4 879 struct icmp6hdr *hdr;
d5fdd6ba 880 u8 type;
e3e32170 881 bool success = false;
1da177e4 882
aebcf82c 883 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
def8b4fa 884 struct sec_path *sp = skb_sec_path(skb);
8b7817f3
HX
885 int nh;
886
def8b4fa 887 if (!(sp && sp->xvec[sp->len - 1]->props.flags &
aebcf82c
HX
888 XFRM_STATE_ICMP))
889 goto drop_no_count;
890
81aded24 891 if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(struct ipv6hdr)))
8b7817f3
HX
892 goto drop_no_count;
893
894 nh = skb_network_offset(skb);
895 skb_set_network_header(skb, sizeof(*hdr));
896
897 if (!xfrm6_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
898 goto drop_no_count;
899
900 skb_set_network_header(skb, nh);
901 }
902
a16292a0 903 __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INMSGS);
1da177e4 904
0660e03f
ACM
905 saddr = &ipv6_hdr(skb)->saddr;
906 daddr = &ipv6_hdr(skb)->daddr;
1da177e4 907
39471ac8 908 if (skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo)) {
ba7a46f1
JP
909 net_dbg_ratelimited("ICMPv6 checksum failed [%pI6c > %pI6c]\n",
910 saddr, daddr);
39471ac8 911 goto csum_error;
1da177e4
LT
912 }
913
8cf22943
HX
914 if (!pskb_pull(skb, sizeof(*hdr)))
915 goto discard_it;
1da177e4 916
cc70ab26 917 hdr = icmp6_hdr(skb);
1da177e4
LT
918
919 type = hdr->icmp6_type;
920
f3832ed2 921 ICMP6MSGIN_INC_STATS(dev_net(dev), idev, type);
1da177e4
LT
922
923 switch (type) {
924 case ICMPV6_ECHO_REQUEST:
e6f86b0f
VJ
925 if (!net->ipv6.sysctl.icmpv6_echo_ignore_all)
926 icmpv6_echo_reply(skb);
1da177e4 927 break;
1fd07f33
AR
928 case ICMPV6_EXT_ECHO_REQUEST:
929 if (!net->ipv6.sysctl.icmpv6_echo_ignore_all &&
930 net->ipv4.sysctl_icmp_echo_enable_probe)
931 icmpv6_echo_reply(skb);
932 break;
1da177e4
LT
933
934 case ICMPV6_ECHO_REPLY:
e3e32170 935 success = ping_rcv(skb);
1da177e4
LT
936 break;
937
31433202
AR
938 case ICMPV6_EXT_ECHO_REPLY:
939 success = ping_rcv(skb);
940 break;
941
1da177e4
LT
942 case ICMPV6_PKT_TOOBIG:
943 /* BUGGG_FUTURE: if packet contains rthdr, we cannot update
944 standard destination cache. Seems, only "advanced"
945 destination cache will allow to solve this problem
946 --ANK (980726)
947 */
948 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
949 goto discard_it;
cc70ab26 950 hdr = icmp6_hdr(skb);
1da177e4 951
275757e6 952 /* to notify */
a8eceea8 953 fallthrough;
1da177e4
LT
954 case ICMPV6_DEST_UNREACH:
955 case ICMPV6_TIME_EXCEED:
956 case ICMPV6_PARAMPROB:
957 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
958 break;
959
960 case NDISC_ROUTER_SOLICITATION:
961 case NDISC_ROUTER_ADVERTISEMENT:
962 case NDISC_NEIGHBOUR_SOLICITATION:
963 case NDISC_NEIGHBOUR_ADVERTISEMENT:
964 case NDISC_REDIRECT:
965 ndisc_rcv(skb);
966 break;
967
968 case ICMPV6_MGM_QUERY:
969 igmp6_event_query(skb);
f185de28 970 return 0;
1da177e4
LT
971
972 case ICMPV6_MGM_REPORT:
973 igmp6_event_report(skb);
f185de28 974 return 0;
1da177e4
LT
975
976 case ICMPV6_MGM_REDUCTION:
977 case ICMPV6_NI_QUERY:
978 case ICMPV6_NI_REPLY:
979 case ICMPV6_MLD2_REPORT:
980 case ICMPV6_DHAAD_REQUEST:
981 case ICMPV6_DHAAD_REPLY:
982 case ICMPV6_MOBILE_PREFIX_SOL:
983 case ICMPV6_MOBILE_PREFIX_ADV:
984 break;
985
986 default:
1da177e4
LT
987 /* informational */
988 if (type & ICMPV6_INFOMSG_MASK)
989 break;
990
4b3418fb
BM
991 net_dbg_ratelimited("icmpv6: msg of unknown type [%pI6c > %pI6c]\n",
992 saddr, daddr);
ea85a0a2 993
1ab1457c
YH
994 /*
995 * error of unknown type.
996 * must pass to upper level
1da177e4
LT
997 */
998
999 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
3ff50b79
SH
1000 }
1001
e3e32170
RJ
1002 /* until the v6 path can be better sorted assume failure and
1003 * preserve the status quo behaviour for the rest of the paths to here
1004 */
1005 if (success)
1006 consume_skb(skb);
1007 else
1008 kfree_skb(skb);
1009
1da177e4
LT
1010 return 0;
1011
6a5dc9e5 1012csum_error:
a16292a0 1013 __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS);
1da177e4 1014discard_it:
a16292a0 1015 __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INERRORS);
8b7817f3 1016drop_no_count:
1da177e4
LT
1017 kfree_skb(skb);
1018 return 0;
1019}
1020
4c9483b2 1021void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
95e41e93
YH
1022 u8 type,
1023 const struct in6_addr *saddr,
1024 const struct in6_addr *daddr,
1025 int oif)
1026{
4c9483b2 1027 memset(fl6, 0, sizeof(*fl6));
4e3fd7a0
AD
1028 fl6->saddr = *saddr;
1029 fl6->daddr = *daddr;
67ba4152 1030 fl6->flowi6_proto = IPPROTO_ICMPV6;
1958b856
DM
1031 fl6->fl6_icmp_type = type;
1032 fl6->fl6_icmp_code = 0;
4c9483b2 1033 fl6->flowi6_oif = oif;
3df98d79 1034 security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
95e41e93
YH
1035}
1036
3232a1ef
KW
1037static void __net_exit icmpv6_sk_exit(struct net *net)
1038{
1039 int i;
1040
1041 for_each_possible_cpu(i)
75efc250
KW
1042 inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv6.icmp_sk, i));
1043 free_percpu(net->ipv6.icmp_sk);
3232a1ef
KW
1044}
1045
98c6d1b2 1046static int __net_init icmpv6_sk_init(struct net *net)
1da177e4
LT
1047{
1048 struct sock *sk;
3232a1ef 1049 int err, i;
1da177e4 1050
75efc250 1051 net->ipv6.icmp_sk = alloc_percpu(struct sock *);
63159f29 1052 if (!net->ipv6.icmp_sk)
79c91159
DL
1053 return -ENOMEM;
1054
6f912042 1055 for_each_possible_cpu(i) {
1ed8516f
DL
1056 err = inet_ctl_sock_create(&sk, PF_INET6,
1057 SOCK_RAW, IPPROTO_ICMPV6, net);
1da177e4 1058 if (err < 0) {
f3213831 1059 pr_err("Failed to initialize the ICMP6 control socket (err %d)\n",
1da177e4
LT
1060 err);
1061 goto fail;
1062 }
1063
75efc250 1064 *per_cpu_ptr(net->ipv6.icmp_sk, i) = sk;
5c8cafd6 1065
1da177e4
LT
1066 /* Enough space for 2 64K ICMP packets, including
1067 * sk_buff struct overhead.
1068 */
87fb4b7b 1069 sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024);
1da177e4 1070 }
1da177e4
LT
1071 return 0;
1072
1073 fail:
3232a1ef 1074 icmpv6_sk_exit(net);
1da177e4
LT
1075 return err;
1076}
1077
8ed7edce 1078static struct pernet_operations icmpv6_sk_ops = {
67ba4152
IM
1079 .init = icmpv6_sk_init,
1080 .exit = icmpv6_sk_exit,
98c6d1b2
DL
1081};
1082
1083int __init icmpv6_init(void)
1084{
1085 int err;
1086
1087 err = register_pernet_subsys(&icmpv6_sk_ops);
1088 if (err < 0)
1089 return err;
1090
1091 err = -EAGAIN;
1092 if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
1093 goto fail;
5f5624cf
PS
1094
1095 err = inet6_register_icmp_sender(icmp6_send);
1096 if (err)
1097 goto sender_reg_err;
98c6d1b2
DL
1098 return 0;
1099
5f5624cf
PS
1100sender_reg_err:
1101 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
98c6d1b2 1102fail:
f3213831 1103 pr_err("Failed to register ICMP6 protocol\n");
98c6d1b2
DL
1104 unregister_pernet_subsys(&icmpv6_sk_ops);
1105 return err;
1106}
1107
8ed7edce 1108void icmpv6_cleanup(void)
98c6d1b2 1109{
5f5624cf 1110 inet6_unregister_icmp_sender(icmp6_send);
98c6d1b2 1111 unregister_pernet_subsys(&icmpv6_sk_ops);
1da177e4
LT
1112 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
1113}
1114
98c6d1b2 1115
9b5b5cff 1116static const struct icmp6_err {
1da177e4
LT
1117 int err;
1118 int fatal;
1119} tab_unreach[] = {
1120 { /* NOROUTE */
1121 .err = ENETUNREACH,
1122 .fatal = 0,
1123 },
1124 { /* ADM_PROHIBITED */
1125 .err = EACCES,
1126 .fatal = 1,
1127 },
1128 { /* Was NOT_NEIGHBOUR, now reserved */
1129 .err = EHOSTUNREACH,
1130 .fatal = 0,
1131 },
1132 { /* ADDR_UNREACH */
1133 .err = EHOSTUNREACH,
1134 .fatal = 0,
1135 },
1136 { /* PORT_UNREACH */
1137 .err = ECONNREFUSED,
1138 .fatal = 1,
1139 },
61e76b17
JB
1140 { /* POLICY_FAIL */
1141 .err = EACCES,
1142 .fatal = 1,
1143 },
1144 { /* REJECT_ROUTE */
1145 .err = EACCES,
1146 .fatal = 1,
1147 },
1da177e4
LT
1148};
1149
d5fdd6ba 1150int icmpv6_err_convert(u8 type, u8 code, int *err)
1da177e4
LT
1151{
1152 int fatal = 0;
1153
1154 *err = EPROTO;
1155
1156 switch (type) {
1157 case ICMPV6_DEST_UNREACH:
1158 fatal = 1;
61e76b17 1159 if (code < ARRAY_SIZE(tab_unreach)) {
1da177e4
LT
1160 *err = tab_unreach[code].err;
1161 fatal = tab_unreach[code].fatal;
1162 }
1163 break;
1164
1165 case ICMPV6_PKT_TOOBIG:
1166 *err = EMSGSIZE;
1167 break;
1ab1457c 1168
1da177e4
LT
1169 case ICMPV6_PARAMPROB:
1170 *err = EPROTO;
1171 fatal = 1;
1172 break;
1173
1174 case ICMPV6_TIME_EXCEED:
1175 *err = EHOSTUNREACH;
1176 break;
3ff50b79 1177 }
1da177e4
LT
1178
1179 return fatal;
1180}
7159039a
YH
1181EXPORT_SYMBOL(icmpv6_err_convert);
1182
1da177e4 1183#ifdef CONFIG_SYSCTL
e8243534 1184static struct ctl_table ipv6_icmp_table_template[] = {
1da177e4 1185 {
1da177e4 1186 .procname = "ratelimit",
41a76906 1187 .data = &init_net.ipv6.sysctl.icmpv6_time,
1da177e4
LT
1188 .maxlen = sizeof(int),
1189 .mode = 0644,
6d9f239a 1190 .proc_handler = proc_dointvec_ms_jiffies,
1da177e4 1191 },
e6f86b0f
VJ
1192 {
1193 .procname = "echo_ignore_all",
1194 .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_all,
a6175633 1195 .maxlen = sizeof(u8),
e6f86b0f 1196 .mode = 0644,
a6175633 1197 .proc_handler = proc_dou8vec_minmax,
e6f86b0f 1198 },
03f1eccc
SS
1199 {
1200 .procname = "echo_ignore_multicast",
1201 .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_multicast,
a6175633 1202 .maxlen = sizeof(u8),
03f1eccc 1203 .mode = 0644,
a6175633 1204 .proc_handler = proc_dou8vec_minmax,
03f1eccc 1205 },
0b03a5ca
SS
1206 {
1207 .procname = "echo_ignore_anycast",
1208 .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_anycast,
a6175633 1209 .maxlen = sizeof(u8),
0b03a5ca 1210 .mode = 0644,
a6175633 1211 .proc_handler = proc_dou8vec_minmax,
0b03a5ca 1212 },
0bc19985
SS
1213 {
1214 .procname = "ratemask",
1215 .data = &init_net.ipv6.sysctl.icmpv6_ratemask_ptr,
1216 .maxlen = ICMPV6_MSG_MAX + 1,
1217 .mode = 0644,
1218 .proc_handler = proc_do_large_bitmap,
1219 },
f8572d8f 1220 { },
1da177e4 1221};
760f2d01 1222
2c8c1e72 1223struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
760f2d01
DL
1224{
1225 struct ctl_table *table;
1226
1227 table = kmemdup(ipv6_icmp_table_template,
1228 sizeof(ipv6_icmp_table_template),
1229 GFP_KERNEL);
5ee09105 1230
e6f86b0f 1231 if (table) {
5ee09105 1232 table[0].data = &net->ipv6.sysctl.icmpv6_time;
e6f86b0f 1233 table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all;
03f1eccc 1234 table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
0b03a5ca 1235 table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
0bc19985 1236 table[4].data = &net->ipv6.sysctl.icmpv6_ratemask_ptr;
e6f86b0f 1237 }
760f2d01
DL
1238 return table;
1239}
1da177e4 1240#endif