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