~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv6/icmp.c

Version: ~ [ linux-5.15-rc5 ] ~ [ linux-5.14.11 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.72 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.152 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.210 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.250 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.286 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.288 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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         return net->ipv6.icmp_sk[smp_processor_id()];
 84 }
 85 
 86 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         struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
 91         struct net *net = dev_net(skb->dev);
 92 
 93         if (type == ICMPV6_PKT_TOOBIG)
 94                 ip6_update_pmtu(skb, net, info, 0, 0);
 95         else if (type == NDISC_REDIRECT)
 96                 ip6_redirect(skb, net, skb->dev->ifindex, 0);
 97 
 98         if (!(type & ICMPV6_INFOMSG_MASK))
 99                 if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
100                         ping_err(skb, offset, info);
101 }
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 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         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 static bool is_ineligible(const struct sk_buff *skb)
146 {
147         int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
148         int len = skb->len - ptr;
149         __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
150         __be16 frag_off;
151 
152         if (len < 0)
153                 return true;
154 
155         ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off);
156         if (ptr < 0)
157                 return false;
158         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                 if (tp == NULL ||
164                     !(*tp & ICMPV6_INFOMSG_MASK))
165                         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         if (type & ICMPV6_INFOMSG_MASK)
182                 return true;
183 
184         /* Do not limit pmtu discovery, it would break it. */
185         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         dst = ip6_route_output(net, sk, fl6);
194         if (dst->error) {
195                 IP6_INC_STATS(net, ip6_dst_idev(dst),
196                               IPSTATS_MIB_OUTNOROUTES);
197         } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
198                 res = true;
199         } else {
200                 struct rt6_info *rt = (struct rt6_info *)dst;
201                 int tmo = net->ipv6.sysctl.icmpv6_time;
202                 struct inet_peer *peer;
203 
204                 /* Give more bandwidth to wider prefixes. */
205                 if (rt->rt6i_dst.plen < 128)
206                         tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
207 
208                 peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
209                 res = inet_peer_xrlim_allow(peer, tmo);
210                 if (peer)
211                         inet_putpeer(peer);
212         }
213         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 static bool opt_unrec(struct sk_buff *skb, __u32 offset)
225 {
226         u8 _optval, *op;
227 
228         offset += skb_network_offset(skb);
229         op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
230         if (op == NULL)
231                 return true;
232         return (*op & 0xC0) == 0x80;
233 }
234 
235 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         if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
243                 goto out;
244 
245         icmp6h = icmp6_hdr(skb);
246         memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
247         icmp6h->icmp6_cksum = 0;
248 
249         if (skb_queue_len(&sk->sk_write_queue) == 1) {
250                 skb->csum = csum_partial(icmp6h,
251                                         sizeof(struct icmp6hdr), skb->csum);
252                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
253                                                       &fl6->daddr,
254                                                       len, fl6->flowi6_proto,
255                                                       skb->csum);
256         } else {
257                 __wsum tmp_csum = 0;
258 
259                 skb_queue_walk(&sk->sk_write_queue, skb) {
260                         tmp_csum = csum_add(tmp_csum, skb->csum);
261                 }
262 
263                 tmp_csum = csum_partial(icmp6h,
264                                         sizeof(struct icmp6hdr), tmp_csum);
265                 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
266                                                       &fl6->daddr,
267                                                       len, fl6->flowi6_proto,
268                                                       tmp_csum);
269         }
270         ip6_push_pending_frames(sk);
271 out:
272         return err;
273 }
274 
275 struct icmpv6_msg {
276         struct sk_buff  *skb;
277         int             offset;
278         uint8_t         type;
279 };
280 
281 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         struct sk_buff *org_skb = msg->skb;
285         __wsum csum = 0;
286 
287         csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
288                                       to, len, csum);
289         skb->csum = csum_block_add(skb->csum, csum, odd);
290         if (!(msg->type & ICMPV6_INFOMSG_MASK))
291                 nf_ct_attach(skb, org_skb);
292         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 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         err = ip6_dst_lookup(sk, &dst, fl6);
329         if (err)
330                 return ERR_PTR(err);
331 
332         /*
333          * We won't send icmp if the destination is known
334          * anycast.
335          */
336         if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) {
337                 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: acast source\n");
338                 dst_release(dst);
339                 return ERR_PTR(-EINVAL);
340         }
341 
342         /* No need to clone since we're just using its address. */
343         dst2 = dst;
344 
345         dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), sk, 0);
346         if (!IS_ERR(dst)) {
347                 if (dst != dst2)
348                         return dst;
349         } else {
350                 if (PTR_ERR(dst) == -EPERM)
351                         dst = NULL;
352                 else
353                         return dst;
354         }
355 
356         err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6);
357         if (err)
358                 goto relookup_failed;
359 
360         err = ip6_dst_lookup(sk, &dst2, &fl2);
361         if (err)
362                 goto relookup_failed;
363 
364         dst2 = xfrm_lookup(net, dst2, flowi6_to_flowi(&fl2), sk, XFRM_LOOKUP_ICMP);
365         if (!IS_ERR(dst2)) {
366                 dst_release(dst);
367                 dst = dst2;
368         } else {
369                 err = PTR_ERR(dst2);
370                 if (err == -EPERM) {
371                         dst_release(dst);
372                         return dst2;
373                 } else
374                         goto relookup_failed;
375         }
376 
377 relookup_failed:
378         if (dst)
379                 return dst;
380         return ERR_PTR(err);
381 }
382 
383 /*
384  *      Send an ICMP message in response to a packet in error
385  */
386 static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
387 {
388         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         if ((u8 *)hdr < skb->head ||
405             (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
406                 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         addr_type = ipv6_addr_type(&hdr->daddr);
415 
416         if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
417             ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
418                 saddr = &hdr->daddr;
419 
420         /*
421          *      Dest addr check
422          */
423 
424         if ((addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST)) {
425                 if (type != ICMPV6_PKT_TOOBIG &&
426                     !(type == ICMPV6_PARAMPROB &&
427                       code == ICMPV6_UNK_OPTION &&
428                       (opt_unrec(skb, info))))
429                         return;
430 
431                 saddr = NULL;
432         }
433 
434         addr_type = ipv6_addr_type(&hdr->saddr);
435 
436         /*
437          *      Source addr check
438          */
439 
440         if (__ipv6_addr_needs_scope_id(addr_type))
441                 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         if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
450                 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         if (is_ineligible(skb)) {
458                 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: no reply to icmp error\n");
459                 return;
460         }
461 
462         mip6_addr_swap(skb);
463 
464         memset(&fl6, 0, sizeof(fl6));
465         fl6.flowi6_proto = IPPROTO_ICMPV6;
466         fl6.daddr = hdr->saddr;
467         if (saddr)
468                 fl6.saddr = *saddr;
469         fl6.flowi6_oif = iif;
470         fl6.fl6_icmp_type = type;
471         fl6.fl6_icmp_code = code;
472         security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
473 
474         sk = icmpv6_xmit_lock(net);
475         if (sk == NULL)
476                 return;
477         np = inet6_sk(sk);
478 
479         if (!icmpv6_xrlim_allow(sk, type, &fl6))
480                 goto out;
481 
482         tmp_hdr.icmp6_type = type;
483         tmp_hdr.icmp6_code = code;
484         tmp_hdr.icmp6_cksum = 0;
485         tmp_hdr.icmp6_pointer = htonl(info);
486 
487         if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
488                 fl6.flowi6_oif = np->mcast_oif;
489         else if (!fl6.flowi6_oif)
490                 fl6.flowi6_oif = np->ucast_oif;
491 
492         dst = icmpv6_route_lookup(net, skb, sk, &fl6);
493         if (IS_ERR(dst))
494                 goto out;
495 
496         if (ipv6_addr_is_multicast(&fl6.daddr))
497                 hlimit = np->mcast_hops;
498         else
499                 hlimit = np->hop_limit;
500         if (hlimit < 0)
501                 hlimit = ip6_dst_hoplimit(dst);
502 
503         msg.skb = skb;
504         msg.offset = skb_network_offset(skb);
505         msg.type = type;
506 
507         len = skb->len - msg.offset;
508         len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
509         if (len < 0) {
510                 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
511                 goto out_dst_release;
512         }
513 
514         rcu_read_lock();
515         idev = __in6_dev_get(skb->dev);
516 
517         err = ip6_append_data(sk, icmpv6_getfrag, &msg,
518                               len + sizeof(struct icmp6hdr),
519                               sizeof(struct icmp6hdr), hlimit,
520                               np->tclass, NULL, &fl6, (struct rt6_info *)dst,
521                               MSG_DONTWAIT, np->dontfrag);
522         if (err) {
523                 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
524                 ip6_flush_pending_frames(sk);
525         } else {
526                 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
527                                                  len + sizeof(struct icmp6hdr));
528         }
529         rcu_read_unlock();
530 out_dst_release:
531         dst_release(dst);
532 out:
533         icmpv6_xmit_unlock(sk);
534 }
535 
536 /* Slightly more convenient version of icmp6_send.
537  */
538 void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
539 {
540         icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
541         kfree_skb(skb);
542 }
543 
544 static void icmpv6_echo_reply(struct sk_buff *skb)
545 {
546         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         saddr = &ipv6_hdr(skb)->daddr;
561 
562         if (!ipv6_unicast_destination(skb) &&
563             !(net->ipv6.sysctl.anycast_src_echo_reply &&
564               ipv6_anycast_destination(skb)))
565                 saddr = NULL;
566 
567         memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
568         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
569 
570         memset(&fl6, 0, sizeof(fl6));
571         fl6.flowi6_proto = IPPROTO_ICMPV6;
572         fl6.daddr = ipv6_hdr(skb)->saddr;
573         if (saddr)
574                 fl6.saddr = *saddr;
575         fl6.flowi6_oif = skb->dev->ifindex;
576         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         if (sk == NULL)
581                 return;
582         np = inet6_sk(sk);
583 
584         if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
585                 fl6.flowi6_oif = np->mcast_oif;
586         else if (!fl6.flowi6_oif)
587                 fl6.flowi6_oif = np->ucast_oif;
588 
589         err = ip6_dst_lookup(sk, &dst, &fl6);
590         if (err)
591                 goto out;
592         dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
593         if (IS_ERR(dst))
594                 goto out;
595 
596         if (ipv6_addr_is_multicast(&fl6.daddr))
597                 hlimit = np->mcast_hops;
598         else
599                 hlimit = np->hop_limit;
600         if (hlimit < 0)
601                 hlimit = ip6_dst_hoplimit(dst);
602 
603         idev = __in6_dev_get(skb->dev);
604 
605         msg.skb = skb;
606         msg.offset = 0;
607         msg.type = ICMPV6_ECHO_REPLY;
608 
609         tclass = ipv6_get_dsfield(ipv6_hdr(skb));
610         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                                 np->dontfrag);
614 
615         if (err) {
616                 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
617                 ip6_flush_pending_frames(sk);
618         } else {
619                 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
620                                                  skb->len + sizeof(struct icmp6hdr));
621         }
622         dst_release(dst);
623 out:
624         icmpv6_xmit_unlock(sk);
625 }
626 
627 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         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
635                 return;
636 
637         nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
638         if (ipv6_ext_hdr(nexthdr)) {
639                 /* now skip over extension headers */
640                 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
641                                                 &nexthdr, &frag_off);
642                 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         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         ipprot = rcu_dereference(inet6_protos[nexthdr]);
661         if (ipprot && ipprot->err_handler)
662                 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
663         rcu_read_unlock();
664 
665         raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
666 }
667 
668 /*
669  *      Handle icmp messages
670  */
671 
672 static int icmpv6_rcv(struct sk_buff *skb)
673 {
674         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         if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
681                 struct sec_path *sp = skb_sec_path(skb);
682                 int nh;
683 
684                 if (!(sp && sp->xvec[sp->len - 1]->props.flags &
685                                  XFRM_STATE_ICMP))
686                         goto drop_no_count;
687 
688                 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                 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         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INMSGS);
701 
702         saddr = &ipv6_hdr(skb)->saddr;
703         daddr = &ipv6_hdr(skb)->daddr;
704 
705         /* Perform checksum. */
706         switch (skb->ip_summed) {
707         case CHECKSUM_COMPLETE:
708                 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
709                                      skb->csum))
710                         break;
711                 /* fall through */
712         case CHECKSUM_NONE:
713                 skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
714                                              IPPROTO_ICMPV6, 0));
715                 if (__skb_checksum_complete(skb)) {
716                         LIMIT_NETDEBUG(KERN_DEBUG
717                                        "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
718                                        saddr, daddr);
719                         goto csum_error;
720                 }
721         }
722 
723         if (!pskb_pull(skb, sizeof(*hdr)))
724                 goto discard_it;
725 
726         hdr = icmp6_hdr(skb);
727 
728         type = hdr->icmp6_type;
729 
730         ICMP6MSGIN_INC_STATS_BH(dev_net(dev), idev, type);
731 
732         switch (type) {
733         case ICMPV6_ECHO_REQUEST:
734                 icmpv6_echo_reply(skb);
735                 break;
736 
737         case ICMPV6_ECHO_REPLY:
738                 ping_rcv(skb);
739                 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                 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                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
759                 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                 ndisc_rcv(skb);
767                 break;
768 
769         case ICMPV6_MGM_QUERY:
770                 igmp6_event_query(skb);
771                 break;
772 
773         case ICMPV6_MGM_REPORT:
774                 igmp6_event_report(skb);
775                 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                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
789 
790                 /* informational */
791                 if (type & ICMPV6_INFOMSG_MASK)
792                         break;
793 
794                 /*
795                  * error of unknown type.
796                  * must pass to upper level
797                  */
798 
799                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
800         }
801 
802         kfree_skb(skb);
803         return 0;
804 
805 csum_error:
806         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS);
807 discard_it:
808         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS);
809 drop_no_count:
810         kfree_skb(skb);
811         return 0;
812 }
813 
814 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         memset(fl6, 0, sizeof(*fl6));
821         fl6->saddr = *saddr;
822         fl6->daddr = *daddr;
823         fl6->flowi6_proto       = IPPROTO_ICMPV6;
824         fl6->fl6_icmp_type      = type;
825         fl6->fl6_icmp_code      = 0;
826         fl6->flowi6_oif         = oif;
827         security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
828 }
829 
830 /*
831  * Special lock-class for __icmpv6_sk:
832  */
833 static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
834 
835 static int __net_init icmpv6_sk_init(struct net *net)
836 {
837         struct sock *sk;
838         int err, i, j;
839 
840         net->ipv6.icmp_sk =
841                 kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
842         if (net->ipv6.icmp_sk == NULL)
843                 return -ENOMEM;
844 
845         for_each_possible_cpu(i) {
846                 err = inet_ctl_sock_create(&sk, PF_INET6,
847                                            SOCK_RAW, IPPROTO_ICMPV6, net);
848                 if (err < 0) {
849                         pr_err("Failed to initialize the ICMP6 control socket (err %d)\n",
850                                err);
851                         goto fail;
852                 }
853 
854                 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                 sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024);
869         }
870         return 0;
871 
872  fail:
873         for (j = 0; j < i; j++)
874                 inet_ctl_sock_destroy(net->ipv6.icmp_sk[j]);
875         kfree(net->ipv6.icmp_sk);
876         return err;
877 }
878 
879 static void __net_exit icmpv6_sk_exit(struct net *net)
880 {
881         int i;
882 
883         for_each_possible_cpu(i) {
884                 inet_ctl_sock_destroy(net->ipv6.icmp_sk[i]);
885         }
886         kfree(net->ipv6.icmp_sk);
887 }
888 
889 static struct pernet_operations icmpv6_sk_ops = {
890        .init = icmpv6_sk_init,
891        .exit = icmpv6_sk_exit,
892 };
893 
894 int __init icmpv6_init(void)
895 {
896         int err;
897 
898         err = register_pernet_subsys(&icmpv6_sk_ops);
899         if (err < 0)
900                 return err;
901 
902         err = -EAGAIN;
903         if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
904                 goto fail;
905 
906         err = inet6_register_icmp_sender(icmp6_send);
907         if (err)
908                 goto sender_reg_err;
909         return 0;
910 
911 sender_reg_err:
912         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
913 fail:
914         pr_err("Failed to register ICMP6 protocol\n");
915         unregister_pernet_subsys(&icmpv6_sk_ops);
916         return err;
917 }
918 
919 void icmpv6_cleanup(void)
920 {
921         inet6_unregister_icmp_sender(icmp6_send);
922         unregister_pernet_subsys(&icmpv6_sk_ops);
923         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
924 }
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 int icmpv6_err_convert(u8 type, u8 code, int *err)
962 {
963         int fatal = 0;
964 
965         *err = EPROTO;
966 
967         switch (type) {
968         case ICMPV6_DEST_UNREACH:
969                 fatal = 1;
970                 if (code < ARRAY_SIZE(tab_unreach)) {
971                         *err  = tab_unreach[code].err;
972                         fatal = tab_unreach[code].fatal;
973                 }
974                 break;
975 
976         case ICMPV6_PKT_TOOBIG:
977                 *err = EMSGSIZE;
978                 break;
979 
980         case ICMPV6_PARAMPROB:
981                 *err = EPROTO;
982                 fatal = 1;
983                 break;
984 
985         case ICMPV6_TIME_EXCEED:
986                 *err = EHOSTUNREACH;
987                 break;
988         }
989 
990         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 struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
1007 {
1008         struct ctl_table *table;
1009 
1010         table = kmemdup(ipv6_icmp_table_template,
1011                         sizeof(ipv6_icmp_table_template),
1012                         GFP_KERNEL);
1013 
1014         if (table)
1015                 table[0].data = &net->ipv6.sysctl.icmpv6_time;
1016 
1017         return table;
1018 }
1019 #endif
1020 
1021 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp