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

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

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.15 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.73 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.144 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.193 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.193 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.73 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ 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         u32 mark = IP6_REPLY_MARK(net, skb->mark);
404 
405         if ((u8 *)hdr < skb->head ||
406             (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
407                 return;
408 
409         /*
410          *      Make sure we respect the rules
411          *      i.e. RFC 1885 2.4(e)
412          *      Rule (e.1) is enforced by not using icmp6_send
413          *      in any code that processes icmp errors.
414          */
415         addr_type = ipv6_addr_type(&hdr->daddr);
416 
417         if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) ||
418             ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr))
419                 saddr = &hdr->daddr;
420 
421         /*
422          *      Dest addr check
423          */
424 
425         if ((addr_type & IPV6_ADDR_MULTICAST || skb->pkt_type != PACKET_HOST)) {
426                 if (type != ICMPV6_PKT_TOOBIG &&
427                     !(type == ICMPV6_PARAMPROB &&
428                       code == ICMPV6_UNK_OPTION &&
429                       (opt_unrec(skb, info))))
430                         return;
431 
432                 saddr = NULL;
433         }
434 
435         addr_type = ipv6_addr_type(&hdr->saddr);
436 
437         /*
438          *      Source addr check
439          */
440 
441         if (__ipv6_addr_needs_scope_id(addr_type))
442                 iif = skb->dev->ifindex;
443 
444         /*
445          *      Must not send error if the source does not uniquely
446          *      identify a single node (RFC2463 Section 2.4).
447          *      We check unspecified / multicast addresses here,
448          *      and anycast addresses will be checked later.
449          */
450         if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
451                 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: addr_any/mcast source\n");
452                 return;
453         }
454 
455         /*
456          *      Never answer to a ICMP packet.
457          */
458         if (is_ineligible(skb)) {
459                 LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: no reply to icmp error\n");
460                 return;
461         }
462 
463         mip6_addr_swap(skb);
464 
465         memset(&fl6, 0, sizeof(fl6));
466         fl6.flowi6_proto = IPPROTO_ICMPV6;
467         fl6.daddr = hdr->saddr;
468         if (saddr)
469                 fl6.saddr = *saddr;
470         fl6.flowi6_mark = mark;
471         fl6.flowi6_oif = iif;
472         fl6.fl6_icmp_type = type;
473         fl6.fl6_icmp_code = code;
474         security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
475 
476         sk = icmpv6_xmit_lock(net);
477         if (sk == NULL)
478                 return;
479         sk->sk_mark = mark;
480         np = inet6_sk(sk);
481 
482         if (!icmpv6_xrlim_allow(sk, type, &fl6))
483                 goto out;
484 
485         tmp_hdr.icmp6_type = type;
486         tmp_hdr.icmp6_code = code;
487         tmp_hdr.icmp6_cksum = 0;
488         tmp_hdr.icmp6_pointer = htonl(info);
489 
490         if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
491                 fl6.flowi6_oif = np->mcast_oif;
492         else if (!fl6.flowi6_oif)
493                 fl6.flowi6_oif = np->ucast_oif;
494 
495         dst = icmpv6_route_lookup(net, skb, sk, &fl6);
496         if (IS_ERR(dst))
497                 goto out;
498 
499         hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
500 
501         msg.skb = skb;
502         msg.offset = skb_network_offset(skb);
503         msg.type = type;
504 
505         len = skb->len - msg.offset;
506         len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
507         if (len < 0) {
508                 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
509                 goto out_dst_release;
510         }
511 
512         rcu_read_lock();
513         idev = __in6_dev_get(skb->dev);
514 
515         err = ip6_append_data(sk, icmpv6_getfrag, &msg,
516                               len + sizeof(struct icmp6hdr),
517                               sizeof(struct icmp6hdr), hlimit,
518                               np->tclass, NULL, &fl6, (struct rt6_info *)dst,
519                               MSG_DONTWAIT, np->dontfrag);
520         if (err) {
521                 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
522                 ip6_flush_pending_frames(sk);
523         } else {
524                 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
525                                                  len + sizeof(struct icmp6hdr));
526         }
527         rcu_read_unlock();
528 out_dst_release:
529         dst_release(dst);
530 out:
531         icmpv6_xmit_unlock(sk);
532 }
533 
534 /* Slightly more convenient version of icmp6_send.
535  */
536 void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
537 {
538         icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
539         kfree_skb(skb);
540 }
541 
542 static void icmpv6_echo_reply(struct sk_buff *skb)
543 {
544         struct net *net = dev_net(skb->dev);
545         struct sock *sk;
546         struct inet6_dev *idev;
547         struct ipv6_pinfo *np;
548         const struct in6_addr *saddr = NULL;
549         struct icmp6hdr *icmph = icmp6_hdr(skb);
550         struct icmp6hdr tmp_hdr;
551         struct flowi6 fl6;
552         struct icmpv6_msg msg;
553         struct dst_entry *dst;
554         int err = 0;
555         int hlimit;
556         u8 tclass;
557         u32 mark = IP6_REPLY_MARK(net, skb->mark);
558 
559         saddr = &ipv6_hdr(skb)->daddr;
560 
561         if (!ipv6_unicast_destination(skb) &&
562             !(net->ipv6.sysctl.anycast_src_echo_reply &&
563               ipv6_anycast_destination(skb)))
564                 saddr = NULL;
565 
566         memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
567         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
568 
569         memset(&fl6, 0, sizeof(fl6));
570         fl6.flowi6_proto = IPPROTO_ICMPV6;
571         fl6.daddr = ipv6_hdr(skb)->saddr;
572         if (saddr)
573                 fl6.saddr = *saddr;
574         fl6.flowi6_oif = skb->dev->ifindex;
575         fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
576         fl6.flowi6_mark = mark;
577         security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
578 
579         sk = icmpv6_xmit_lock(net);
580         if (sk == NULL)
581                 return;
582         sk->sk_mark = mark;
583         np = inet6_sk(sk);
584 
585         if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
586                 fl6.flowi6_oif = np->mcast_oif;
587         else if (!fl6.flowi6_oif)
588                 fl6.flowi6_oif = np->ucast_oif;
589 
590         err = ip6_dst_lookup(sk, &dst, &fl6);
591         if (err)
592                 goto out;
593         dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
594         if (IS_ERR(dst))
595                 goto out;
596 
597         hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
598 
599         idev = __in6_dev_get(skb->dev);
600 
601         msg.skb = skb;
602         msg.offset = 0;
603         msg.type = ICMPV6_ECHO_REPLY;
604 
605         tclass = ipv6_get_dsfield(ipv6_hdr(skb));
606         err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
607                                 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl6,
608                                 (struct rt6_info *)dst, MSG_DONTWAIT,
609                                 np->dontfrag);
610 
611         if (err) {
612                 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
613                 ip6_flush_pending_frames(sk);
614         } else {
615                 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
616                                                  skb->len + sizeof(struct icmp6hdr));
617         }
618         dst_release(dst);
619 out:
620         icmpv6_xmit_unlock(sk);
621 }
622 
623 void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
624 {
625         const struct inet6_protocol *ipprot;
626         int inner_offset;
627         __be16 frag_off;
628         u8 nexthdr;
629         struct net *net = dev_net(skb->dev);
630 
631         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
632                 goto out;
633 
634         nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
635         if (ipv6_ext_hdr(nexthdr)) {
636                 /* now skip over extension headers */
637                 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
638                                                 &nexthdr, &frag_off);
639                 if (inner_offset<0)
640                         goto out;
641         } else {
642                 inner_offset = sizeof(struct ipv6hdr);
643         }
644 
645         /* Checkin header including 8 bytes of inner protocol header. */
646         if (!pskb_may_pull(skb, inner_offset+8))
647                 goto out;
648 
649         /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
650            Without this we will not able f.e. to make source routed
651            pmtu discovery.
652            Corresponding argument (opt) to notifiers is already added.
653            --ANK (980726)
654          */
655 
656         ipprot = rcu_dereference(inet6_protos[nexthdr]);
657         if (ipprot && ipprot->err_handler)
658                 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
659 
660         raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
661         return;
662 
663 out:
664         ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
665 }
666 
667 /*
668  *      Handle icmp messages
669  */
670 
671 static int icmpv6_rcv(struct sk_buff *skb)
672 {
673         struct net_device *dev = skb->dev;
674         struct inet6_dev *idev = __in6_dev_get(dev);
675         const struct in6_addr *saddr, *daddr;
676         struct icmp6hdr *hdr;
677         u8 type;
678 
679         if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
680                 struct sec_path *sp = skb_sec_path(skb);
681                 int nh;
682 
683                 if (!(sp && sp->xvec[sp->len - 1]->props.flags &
684                                  XFRM_STATE_ICMP))
685                         goto drop_no_count;
686 
687                 if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(struct ipv6hdr)))
688                         goto drop_no_count;
689 
690                 nh = skb_network_offset(skb);
691                 skb_set_network_header(skb, sizeof(*hdr));
692 
693                 if (!xfrm6_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
694                         goto drop_no_count;
695 
696                 skb_set_network_header(skb, nh);
697         }
698 
699         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INMSGS);
700 
701         saddr = &ipv6_hdr(skb)->saddr;
702         daddr = &ipv6_hdr(skb)->daddr;
703 
704         if (skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo)) {
705                 LIMIT_NETDEBUG(KERN_DEBUG
706                                "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
707                                saddr, daddr);
708                 goto csum_error;
709         }
710 
711         if (!pskb_pull(skb, sizeof(*hdr)))
712                 goto discard_it;
713 
714         hdr = icmp6_hdr(skb);
715 
716         type = hdr->icmp6_type;
717 
718         ICMP6MSGIN_INC_STATS_BH(dev_net(dev), idev, type);
719 
720         switch (type) {
721         case ICMPV6_ECHO_REQUEST:
722                 icmpv6_echo_reply(skb);
723                 break;
724 
725         case ICMPV6_ECHO_REPLY:
726                 ping_rcv(skb);
727                 break;
728 
729         case ICMPV6_PKT_TOOBIG:
730                 /* BUGGG_FUTURE: if packet contains rthdr, we cannot update
731                    standard destination cache. Seems, only "advanced"
732                    destination cache will allow to solve this problem
733                    --ANK (980726)
734                  */
735                 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
736                         goto discard_it;
737                 hdr = icmp6_hdr(skb);
738 
739                 /*
740                  *      Drop through to notify
741                  */
742 
743         case ICMPV6_DEST_UNREACH:
744         case ICMPV6_TIME_EXCEED:
745         case ICMPV6_PARAMPROB:
746                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
747                 break;
748 
749         case NDISC_ROUTER_SOLICITATION:
750         case NDISC_ROUTER_ADVERTISEMENT:
751         case NDISC_NEIGHBOUR_SOLICITATION:
752         case NDISC_NEIGHBOUR_ADVERTISEMENT:
753         case NDISC_REDIRECT:
754                 ndisc_rcv(skb);
755                 break;
756 
757         case ICMPV6_MGM_QUERY:
758                 igmp6_event_query(skb);
759                 break;
760 
761         case ICMPV6_MGM_REPORT:
762                 igmp6_event_report(skb);
763                 break;
764 
765         case ICMPV6_MGM_REDUCTION:
766         case ICMPV6_NI_QUERY:
767         case ICMPV6_NI_REPLY:
768         case ICMPV6_MLD2_REPORT:
769         case ICMPV6_DHAAD_REQUEST:
770         case ICMPV6_DHAAD_REPLY:
771         case ICMPV6_MOBILE_PREFIX_SOL:
772         case ICMPV6_MOBILE_PREFIX_ADV:
773                 break;
774 
775         default:
776                 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
777 
778                 /* informational */
779                 if (type & ICMPV6_INFOMSG_MASK)
780                         break;
781 
782                 /*
783                  * error of unknown type.
784                  * must pass to upper level
785                  */
786 
787                 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
788         }
789 
790         kfree_skb(skb);
791         return 0;
792 
793 csum_error:
794         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS);
795 discard_it:
796         ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS);
797 drop_no_count:
798         kfree_skb(skb);
799         return 0;
800 }
801 
802 void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
803                       u8 type,
804                       const struct in6_addr *saddr,
805                       const struct in6_addr *daddr,
806                       int oif)
807 {
808         memset(fl6, 0, sizeof(*fl6));
809         fl6->saddr = *saddr;
810         fl6->daddr = *daddr;
811         fl6->flowi6_proto       = IPPROTO_ICMPV6;
812         fl6->fl6_icmp_type      = type;
813         fl6->fl6_icmp_code      = 0;
814         fl6->flowi6_oif         = oif;
815         security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
816 }
817 
818 /*
819  * Special lock-class for __icmpv6_sk:
820  */
821 static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
822 
823 static int __net_init icmpv6_sk_init(struct net *net)
824 {
825         struct sock *sk;
826         int err, i, j;
827 
828         net->ipv6.icmp_sk =
829                 kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
830         if (net->ipv6.icmp_sk == NULL)
831                 return -ENOMEM;
832 
833         for_each_possible_cpu(i) {
834                 err = inet_ctl_sock_create(&sk, PF_INET6,
835                                            SOCK_RAW, IPPROTO_ICMPV6, net);
836                 if (err < 0) {
837                         pr_err("Failed to initialize the ICMP6 control socket (err %d)\n",
838                                err);
839                         goto fail;
840                 }
841 
842                 net->ipv6.icmp_sk[i] = sk;
843 
844                 /*
845                  * Split off their lock-class, because sk->sk_dst_lock
846                  * gets used from softirqs, which is safe for
847                  * __icmpv6_sk (because those never get directly used
848                  * via userspace syscalls), but unsafe for normal sockets.
849                  */
850                 lockdep_set_class(&sk->sk_dst_lock,
851                                   &icmpv6_socket_sk_dst_lock_key);
852 
853                 /* Enough space for 2 64K ICMP packets, including
854                  * sk_buff struct overhead.
855                  */
856                 sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024);
857         }
858         return 0;
859 
860  fail:
861         for (j = 0; j < i; j++)
862                 inet_ctl_sock_destroy(net->ipv6.icmp_sk[j]);
863         kfree(net->ipv6.icmp_sk);
864         return err;
865 }
866 
867 static void __net_exit icmpv6_sk_exit(struct net *net)
868 {
869         int i;
870 
871         for_each_possible_cpu(i) {
872                 inet_ctl_sock_destroy(net->ipv6.icmp_sk[i]);
873         }
874         kfree(net->ipv6.icmp_sk);
875 }
876 
877 static struct pernet_operations icmpv6_sk_ops = {
878        .init = icmpv6_sk_init,
879        .exit = icmpv6_sk_exit,
880 };
881 
882 int __init icmpv6_init(void)
883 {
884         int err;
885 
886         err = register_pernet_subsys(&icmpv6_sk_ops);
887         if (err < 0)
888                 return err;
889 
890         err = -EAGAIN;
891         if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
892                 goto fail;
893 
894         err = inet6_register_icmp_sender(icmp6_send);
895         if (err)
896                 goto sender_reg_err;
897         return 0;
898 
899 sender_reg_err:
900         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
901 fail:
902         pr_err("Failed to register ICMP6 protocol\n");
903         unregister_pernet_subsys(&icmpv6_sk_ops);
904         return err;
905 }
906 
907 void icmpv6_cleanup(void)
908 {
909         inet6_unregister_icmp_sender(icmp6_send);
910         unregister_pernet_subsys(&icmpv6_sk_ops);
911         inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
912 }
913 
914 
915 static const struct icmp6_err {
916         int err;
917         int fatal;
918 } tab_unreach[] = {
919         {       /* NOROUTE */
920                 .err    = ENETUNREACH,
921                 .fatal  = 0,
922         },
923         {       /* ADM_PROHIBITED */
924                 .err    = EACCES,
925                 .fatal  = 1,
926         },
927         {       /* Was NOT_NEIGHBOUR, now reserved */
928                 .err    = EHOSTUNREACH,
929                 .fatal  = 0,
930         },
931         {       /* ADDR_UNREACH */
932                 .err    = EHOSTUNREACH,
933                 .fatal  = 0,
934         },
935         {       /* PORT_UNREACH */
936                 .err    = ECONNREFUSED,
937                 .fatal  = 1,
938         },
939         {       /* POLICY_FAIL */
940                 .err    = EACCES,
941                 .fatal  = 1,
942         },
943         {       /* REJECT_ROUTE */
944                 .err    = EACCES,
945                 .fatal  = 1,
946         },
947 };
948 
949 int icmpv6_err_convert(u8 type, u8 code, int *err)
950 {
951         int fatal = 0;
952 
953         *err = EPROTO;
954 
955         switch (type) {
956         case ICMPV6_DEST_UNREACH:
957                 fatal = 1;
958                 if (code < ARRAY_SIZE(tab_unreach)) {
959                         *err  = tab_unreach[code].err;
960                         fatal = tab_unreach[code].fatal;
961                 }
962                 break;
963 
964         case ICMPV6_PKT_TOOBIG:
965                 *err = EMSGSIZE;
966                 break;
967 
968         case ICMPV6_PARAMPROB:
969                 *err = EPROTO;
970                 fatal = 1;
971                 break;
972 
973         case ICMPV6_TIME_EXCEED:
974                 *err = EHOSTUNREACH;
975                 break;
976         }
977 
978         return fatal;
979 }
980 EXPORT_SYMBOL(icmpv6_err_convert);
981 
982 #ifdef CONFIG_SYSCTL
983 static struct ctl_table ipv6_icmp_table_template[] = {
984         {
985                 .procname       = "ratelimit",
986                 .data           = &init_net.ipv6.sysctl.icmpv6_time,
987                 .maxlen         = sizeof(int),
988                 .mode           = 0644,
989                 .proc_handler   = proc_dointvec_ms_jiffies,
990         },
991         { },
992 };
993 
994 struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
995 {
996         struct ctl_table *table;
997 
998         table = kmemdup(ipv6_icmp_table_template,
999                         sizeof(ipv6_icmp_table_template),
1000                         GFP_KERNEL);
1001 
1002         if (table)
1003                 table[0].data = &net->ipv6.sysctl.icmpv6_time;
1004 
1005         return table;
1006 }
1007 #endif
1008 
1009 

~ [ 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