.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Internet Control Message Protocol (ICMPv6) |
---|
3 | 4 | * Linux INET6 implementation |
---|
.. | .. |
---|
8 | 9 | * Based on net/ipv4/icmp.c |
---|
9 | 10 | * |
---|
10 | 11 | * 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 | 12 | */ |
---|
17 | 13 | |
---|
18 | 14 | /* |
---|
.. | .. |
---|
79 | 75 | * |
---|
80 | 76 | * On SMP we have one ICMP socket per-cpu. |
---|
81 | 77 | */ |
---|
82 | | -static inline struct sock *icmpv6_sk(struct net *net) |
---|
| 78 | +static struct sock *icmpv6_sk(struct net *net) |
---|
83 | 79 | { |
---|
84 | | - return net->ipv6.icmp_sk[smp_processor_id()]; |
---|
| 80 | + return this_cpu_read(*net->ipv6.icmp_sk); |
---|
85 | 81 | } |
---|
86 | 82 | |
---|
87 | | -static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
---|
| 83 | +static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
---|
88 | 84 | u8 type, u8 code, int offset, __be32 info) |
---|
89 | 85 | { |
---|
90 | 86 | /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ |
---|
.. | .. |
---|
100 | 96 | if (!(type & ICMPV6_INFOMSG_MASK)) |
---|
101 | 97 | if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST) |
---|
102 | 98 | ping_err(skb, offset, ntohl(info)); |
---|
| 99 | + |
---|
| 100 | + return 0; |
---|
103 | 101 | } |
---|
104 | 102 | |
---|
105 | 103 | static int icmpv6_rcv(struct sk_buff *skb); |
---|
.. | .. |
---|
160 | 158 | tp = skb_header_pointer(skb, |
---|
161 | 159 | ptr+offsetof(struct icmp6hdr, icmp6_type), |
---|
162 | 160 | sizeof(_type), &_type); |
---|
163 | | - if (!tp || !(*tp & ICMPV6_INFOMSG_MASK)) |
---|
| 161 | + |
---|
| 162 | + /* Based on RFC 8200, Section 4.5 Fragment Header, return |
---|
| 163 | + * false if this is a fragment packet with no icmp header info. |
---|
| 164 | + */ |
---|
| 165 | + if (!tp && frag_off != 0) |
---|
| 166 | + return false; |
---|
| 167 | + else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK)) |
---|
164 | 168 | return true; |
---|
165 | 169 | } |
---|
166 | 170 | return false; |
---|
167 | 171 | } |
---|
168 | 172 | |
---|
169 | | -static bool icmpv6_mask_allow(int type) |
---|
| 173 | +static bool icmpv6_mask_allow(struct net *net, int type) |
---|
170 | 174 | { |
---|
171 | | - /* Informational messages are not limited. */ |
---|
172 | | - if (type & ICMPV6_INFOMSG_MASK) |
---|
| 175 | + if (type > ICMPV6_MSG_MAX) |
---|
173 | 176 | return true; |
---|
174 | 177 | |
---|
175 | | - /* Do not limit pmtu discovery, it would break it. */ |
---|
176 | | - if (type == ICMPV6_PKT_TOOBIG) |
---|
| 178 | + /* Limit if icmp type is set in ratemask. */ |
---|
| 179 | + if (!test_bit(type, net->ipv6.sysctl.icmpv6_ratemask)) |
---|
177 | 180 | return true; |
---|
178 | 181 | |
---|
179 | 182 | return false; |
---|
180 | 183 | } |
---|
181 | 184 | |
---|
182 | | -static bool icmpv6_global_allow(int type) |
---|
| 185 | +static bool icmpv6_global_allow(struct net *net, int type) |
---|
183 | 186 | { |
---|
184 | | - if (icmpv6_mask_allow(type)) |
---|
| 187 | + if (icmpv6_mask_allow(net, type)) |
---|
185 | 188 | return true; |
---|
186 | 189 | |
---|
187 | 190 | if (icmp_global_allow()) |
---|
.. | .. |
---|
200 | 203 | struct dst_entry *dst; |
---|
201 | 204 | bool res = false; |
---|
202 | 205 | |
---|
203 | | - if (icmpv6_mask_allow(type)) |
---|
| 206 | + if (icmpv6_mask_allow(net, type)) |
---|
204 | 207 | return true; |
---|
205 | 208 | |
---|
206 | 209 | /* |
---|
.. | .. |
---|
227 | 230 | res = inet_peer_xrlim_allow(peer, tmo); |
---|
228 | 231 | if (peer) |
---|
229 | 232 | inet_putpeer(peer); |
---|
| 233 | + } |
---|
| 234 | + dst_release(dst); |
---|
| 235 | + return res; |
---|
| 236 | +} |
---|
| 237 | + |
---|
| 238 | +static bool icmpv6_rt_has_prefsrc(struct sock *sk, u8 type, |
---|
| 239 | + struct flowi6 *fl6) |
---|
| 240 | +{ |
---|
| 241 | + struct net *net = sock_net(sk); |
---|
| 242 | + struct dst_entry *dst; |
---|
| 243 | + bool res = false; |
---|
| 244 | + |
---|
| 245 | + dst = ip6_route_output(net, sk, fl6); |
---|
| 246 | + if (!dst->error) { |
---|
| 247 | + struct rt6_info *rt = (struct rt6_info *)dst; |
---|
| 248 | + struct in6_addr prefsrc; |
---|
| 249 | + |
---|
| 250 | + rt6_get_prefsrc(rt, &prefsrc); |
---|
| 251 | + res = !ipv6_addr_any(&prefsrc); |
---|
230 | 252 | } |
---|
231 | 253 | dst_release(dst); |
---|
232 | 254 | return res; |
---|
.. | .. |
---|
298 | 320 | { |
---|
299 | 321 | struct icmpv6_msg *msg = (struct icmpv6_msg *) from; |
---|
300 | 322 | struct sk_buff *org_skb = msg->skb; |
---|
301 | | - __wsum csum = 0; |
---|
| 323 | + __wsum csum; |
---|
302 | 324 | |
---|
303 | 325 | csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, |
---|
304 | | - to, len, csum); |
---|
| 326 | + to, len); |
---|
305 | 327 | skb->csum = csum_block_add(skb->csum, csum, odd); |
---|
306 | 328 | if (!(msg->type & ICMPV6_INFOMSG_MASK)) |
---|
307 | 329 | nf_ct_attach(skb, org_skb); |
---|
.. | .. |
---|
395 | 417 | return ERR_PTR(err); |
---|
396 | 418 | } |
---|
397 | 419 | |
---|
398 | | -static int icmp6_iif(const struct sk_buff *skb) |
---|
| 420 | +static struct net_device *icmp6_dev(const struct sk_buff *skb) |
---|
399 | 421 | { |
---|
400 | | - int iif = skb->dev->ifindex; |
---|
| 422 | + struct net_device *dev = skb->dev; |
---|
401 | 423 | |
---|
402 | 424 | /* for local traffic to local address, skb dev is the loopback |
---|
403 | 425 | * device. Check if there is a dst attached to the skb and if so |
---|
404 | 426 | * get the real device index. Same is needed for replies to a link |
---|
405 | 427 | * local address on a device enslaved to an L3 master device |
---|
406 | 428 | */ |
---|
407 | | - if (unlikely(iif == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) { |
---|
| 429 | + if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) { |
---|
408 | 430 | const struct rt6_info *rt6 = skb_rt6_info(skb); |
---|
409 | 431 | |
---|
410 | 432 | if (rt6) |
---|
411 | | - iif = rt6->rt6i_idev->dev->ifindex; |
---|
| 433 | + dev = rt6->rt6i_idev->dev; |
---|
412 | 434 | } |
---|
413 | 435 | |
---|
414 | | - return iif; |
---|
| 436 | + return dev; |
---|
| 437 | +} |
---|
| 438 | + |
---|
| 439 | +static int icmp6_iif(const struct sk_buff *skb) |
---|
| 440 | +{ |
---|
| 441 | + return icmp6_dev(skb)->ifindex; |
---|
415 | 442 | } |
---|
416 | 443 | |
---|
417 | 444 | /* |
---|
.. | .. |
---|
480 | 507 | if (__ipv6_addr_needs_scope_id(addr_type)) { |
---|
481 | 508 | iif = icmp6_iif(skb); |
---|
482 | 509 | } else { |
---|
483 | | - dst = skb_dst(skb); |
---|
484 | | - iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev); |
---|
| 510 | + /* |
---|
| 511 | + * The source device is used for looking up which routing table |
---|
| 512 | + * to use for sending an ICMP error. |
---|
| 513 | + */ |
---|
| 514 | + iif = l3mdev_master_ifindex(skb->dev); |
---|
485 | 515 | } |
---|
486 | 516 | |
---|
487 | 517 | /* |
---|
.. | .. |
---|
509 | 539 | local_bh_disable(); |
---|
510 | 540 | |
---|
511 | 541 | /* Check global sysctl_icmp_msgs_per_sec ratelimit */ |
---|
512 | | - if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type)) |
---|
| 542 | + if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type)) |
---|
513 | 543 | goto out_bh_enable; |
---|
514 | 544 | |
---|
515 | 545 | mip6_addr_swap(skb, parm); |
---|
| 546 | + |
---|
| 547 | + sk = icmpv6_xmit_lock(net); |
---|
| 548 | + if (!sk) |
---|
| 549 | + goto out_bh_enable; |
---|
516 | 550 | |
---|
517 | 551 | memset(&fl6, 0, sizeof(fl6)); |
---|
518 | 552 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
---|
519 | 553 | fl6.daddr = hdr->saddr; |
---|
520 | 554 | if (force_saddr) |
---|
521 | 555 | saddr = force_saddr; |
---|
522 | | - if (saddr) |
---|
| 556 | + if (saddr) { |
---|
523 | 557 | fl6.saddr = *saddr; |
---|
| 558 | + } else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) { |
---|
| 559 | + /* select a more meaningful saddr from input if */ |
---|
| 560 | + struct net_device *in_netdev; |
---|
| 561 | + |
---|
| 562 | + in_netdev = dev_get_by_index(net, parm->iif); |
---|
| 563 | + if (in_netdev) { |
---|
| 564 | + ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr, |
---|
| 565 | + inet6_sk(sk)->srcprefs, |
---|
| 566 | + &fl6.saddr); |
---|
| 567 | + dev_put(in_netdev); |
---|
| 568 | + } |
---|
| 569 | + } |
---|
524 | 570 | fl6.flowi6_mark = mark; |
---|
525 | 571 | fl6.flowi6_oif = iif; |
---|
526 | 572 | fl6.fl6_icmp_type = type; |
---|
527 | 573 | fl6.fl6_icmp_code = code; |
---|
528 | 574 | fl6.flowi6_uid = sock_net_uid(net, NULL); |
---|
529 | 575 | fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL); |
---|
530 | | - security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); |
---|
| 576 | + security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6)); |
---|
531 | 577 | |
---|
532 | | - sk = icmpv6_xmit_lock(net); |
---|
533 | | - if (!sk) |
---|
534 | | - goto out_bh_enable; |
---|
535 | | - |
---|
536 | | - sk->sk_mark = mark; |
---|
537 | 578 | np = inet6_sk(sk); |
---|
538 | 579 | |
---|
539 | 580 | if (!icmpv6_xrlim_allow(sk, type, &fl6)) |
---|
.. | .. |
---|
550 | 591 | fl6.flowi6_oif = np->ucast_oif; |
---|
551 | 592 | |
---|
552 | 593 | ipcm6_init_sk(&ipc6, np); |
---|
| 594 | + ipc6.sockc.mark = mark; |
---|
553 | 595 | fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); |
---|
554 | 596 | |
---|
555 | 597 | dst = icmpv6_route_lookup(net, skb, sk, &fl6); |
---|
.. | .. |
---|
682 | 724 | struct dst_entry *dst; |
---|
683 | 725 | struct ipcm6_cookie ipc6; |
---|
684 | 726 | u32 mark = IP6_REPLY_MARK(net, skb->mark); |
---|
| 727 | + bool acast; |
---|
| 728 | + |
---|
| 729 | + if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && |
---|
| 730 | + net->ipv6.sysctl.icmpv6_echo_ignore_multicast) |
---|
| 731 | + return; |
---|
685 | 732 | |
---|
686 | 733 | saddr = &ipv6_hdr(skb)->daddr; |
---|
687 | 734 | |
---|
| 735 | + acast = ipv6_anycast_destination(skb_dst(skb), saddr); |
---|
| 736 | + if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast) |
---|
| 737 | + return; |
---|
| 738 | + |
---|
688 | 739 | if (!ipv6_unicast_destination(skb) && |
---|
689 | | - !(net->ipv6.sysctl.anycast_src_echo_reply && |
---|
690 | | - ipv6_anycast_destination(skb_dst(skb), saddr))) |
---|
| 740 | + !(net->ipv6.sysctl.anycast_src_echo_reply && acast)) |
---|
691 | 741 | saddr = NULL; |
---|
692 | 742 | |
---|
693 | 743 | memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); |
---|
694 | 744 | tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; |
---|
695 | 745 | |
---|
696 | 746 | memset(&fl6, 0, sizeof(fl6)); |
---|
| 747 | + if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES) |
---|
| 748 | + fl6.flowlabel = ip6_flowlabel(ipv6_hdr(skb)); |
---|
| 749 | + |
---|
697 | 750 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
---|
698 | 751 | fl6.daddr = ipv6_hdr(skb)->saddr; |
---|
699 | 752 | if (saddr) |
---|
.. | .. |
---|
702 | 755 | fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY; |
---|
703 | 756 | fl6.flowi6_mark = mark; |
---|
704 | 757 | fl6.flowi6_uid = sock_net_uid(net, NULL); |
---|
705 | | - security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); |
---|
| 758 | + security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6)); |
---|
706 | 759 | |
---|
707 | 760 | local_bh_disable(); |
---|
708 | 761 | sk = icmpv6_xmit_lock(net); |
---|
709 | 762 | if (!sk) |
---|
710 | 763 | goto out_bh_enable; |
---|
711 | | - sk->sk_mark = mark; |
---|
712 | 764 | np = inet6_sk(sk); |
---|
713 | 765 | |
---|
714 | 766 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) |
---|
.. | .. |
---|
722 | 774 | if (IS_ERR(dst)) |
---|
723 | 775 | goto out; |
---|
724 | 776 | |
---|
| 777 | + /* Check the ratelimit */ |
---|
| 778 | + if ((!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, ICMPV6_ECHO_REPLY)) || |
---|
| 779 | + !icmpv6_xrlim_allow(sk, ICMPV6_ECHO_REPLY, &fl6)) |
---|
| 780 | + goto out_dst_release; |
---|
| 781 | + |
---|
725 | 782 | idev = __in6_dev_get(skb->dev); |
---|
726 | 783 | |
---|
727 | 784 | msg.skb = skb; |
---|
.. | .. |
---|
731 | 788 | ipcm6_init_sk(&ipc6, np); |
---|
732 | 789 | ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); |
---|
733 | 790 | ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
---|
| 791 | + ipc6.sockc.mark = mark; |
---|
734 | 792 | |
---|
735 | 793 | if (ip6_append_data(sk, icmpv6_getfrag, &msg, |
---|
736 | 794 | skb->len + sizeof(struct icmp6hdr), |
---|
.. | .. |
---|
742 | 800 | icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, |
---|
743 | 801 | skb->len + sizeof(struct icmp6hdr)); |
---|
744 | 802 | } |
---|
| 803 | +out_dst_release: |
---|
745 | 804 | dst_release(dst); |
---|
746 | 805 | out: |
---|
747 | 806 | icmpv6_xmit_unlock(sk); |
---|
.. | .. |
---|
800 | 859 | static int icmpv6_rcv(struct sk_buff *skb) |
---|
801 | 860 | { |
---|
802 | 861 | struct net *net = dev_net(skb->dev); |
---|
803 | | - struct net_device *dev = skb->dev; |
---|
| 862 | + struct net_device *dev = icmp6_dev(skb); |
---|
804 | 863 | struct inet6_dev *idev = __in6_dev_get(dev); |
---|
805 | 864 | const struct in6_addr *saddr, *daddr; |
---|
806 | 865 | struct icmp6hdr *hdr; |
---|
.. | .. |
---|
868 | 927 | hdr = icmp6_hdr(skb); |
---|
869 | 928 | |
---|
870 | 929 | /* to notify */ |
---|
871 | | - /* fall through */ |
---|
| 930 | + fallthrough; |
---|
872 | 931 | case ICMPV6_DEST_UNREACH: |
---|
873 | 932 | case ICMPV6_TIME_EXCEED: |
---|
874 | 933 | case ICMPV6_PARAMPROB: |
---|
.. | .. |
---|
949 | 1008 | fl6->fl6_icmp_type = type; |
---|
950 | 1009 | fl6->fl6_icmp_code = 0; |
---|
951 | 1010 | fl6->flowi6_oif = oif; |
---|
952 | | - security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); |
---|
| 1011 | + security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6)); |
---|
| 1012 | +} |
---|
| 1013 | + |
---|
| 1014 | +static void __net_exit icmpv6_sk_exit(struct net *net) |
---|
| 1015 | +{ |
---|
| 1016 | + int i; |
---|
| 1017 | + |
---|
| 1018 | + for_each_possible_cpu(i) |
---|
| 1019 | + inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv6.icmp_sk, i)); |
---|
| 1020 | + free_percpu(net->ipv6.icmp_sk); |
---|
953 | 1021 | } |
---|
954 | 1022 | |
---|
955 | 1023 | static int __net_init icmpv6_sk_init(struct net *net) |
---|
956 | 1024 | { |
---|
957 | 1025 | struct sock *sk; |
---|
958 | | - int err, i, j; |
---|
| 1026 | + int err, i; |
---|
959 | 1027 | |
---|
960 | | - net->ipv6.icmp_sk = |
---|
961 | | - kcalloc(nr_cpu_ids, sizeof(struct sock *), GFP_KERNEL); |
---|
| 1028 | + net->ipv6.icmp_sk = alloc_percpu(struct sock *); |
---|
962 | 1029 | if (!net->ipv6.icmp_sk) |
---|
963 | 1030 | return -ENOMEM; |
---|
964 | 1031 | |
---|
.. | .. |
---|
971 | 1038 | goto fail; |
---|
972 | 1039 | } |
---|
973 | 1040 | |
---|
974 | | - net->ipv6.icmp_sk[i] = sk; |
---|
| 1041 | + *per_cpu_ptr(net->ipv6.icmp_sk, i) = sk; |
---|
975 | 1042 | |
---|
976 | 1043 | /* Enough space for 2 64K ICMP packets, including |
---|
977 | 1044 | * sk_buff struct overhead. |
---|
.. | .. |
---|
981 | 1048 | return 0; |
---|
982 | 1049 | |
---|
983 | 1050 | fail: |
---|
984 | | - for (j = 0; j < i; j++) |
---|
985 | | - inet_ctl_sock_destroy(net->ipv6.icmp_sk[j]); |
---|
986 | | - kfree(net->ipv6.icmp_sk); |
---|
| 1051 | + icmpv6_sk_exit(net); |
---|
987 | 1052 | return err; |
---|
988 | | -} |
---|
989 | | - |
---|
990 | | -static void __net_exit icmpv6_sk_exit(struct net *net) |
---|
991 | | -{ |
---|
992 | | - int i; |
---|
993 | | - |
---|
994 | | - for_each_possible_cpu(i) { |
---|
995 | | - inet_ctl_sock_destroy(net->ipv6.icmp_sk[i]); |
---|
996 | | - } |
---|
997 | | - kfree(net->ipv6.icmp_sk); |
---|
998 | 1053 | } |
---|
999 | 1054 | |
---|
1000 | 1055 | static struct pernet_operations icmpv6_sk_ops = { |
---|
.. | .. |
---|
1118 | 1173 | .mode = 0644, |
---|
1119 | 1174 | .proc_handler = proc_dointvec, |
---|
1120 | 1175 | }, |
---|
| 1176 | + { |
---|
| 1177 | + .procname = "echo_ignore_multicast", |
---|
| 1178 | + .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_multicast, |
---|
| 1179 | + .maxlen = sizeof(int), |
---|
| 1180 | + .mode = 0644, |
---|
| 1181 | + .proc_handler = proc_dointvec, |
---|
| 1182 | + }, |
---|
| 1183 | + { |
---|
| 1184 | + .procname = "echo_ignore_anycast", |
---|
| 1185 | + .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_anycast, |
---|
| 1186 | + .maxlen = sizeof(int), |
---|
| 1187 | + .mode = 0644, |
---|
| 1188 | + .proc_handler = proc_dointvec, |
---|
| 1189 | + }, |
---|
| 1190 | + { |
---|
| 1191 | + .procname = "ratemask", |
---|
| 1192 | + .data = &init_net.ipv6.sysctl.icmpv6_ratemask_ptr, |
---|
| 1193 | + .maxlen = ICMPV6_MSG_MAX + 1, |
---|
| 1194 | + .mode = 0644, |
---|
| 1195 | + .proc_handler = proc_do_large_bitmap, |
---|
| 1196 | + }, |
---|
1121 | 1197 | { }, |
---|
1122 | 1198 | }; |
---|
1123 | 1199 | |
---|
.. | .. |
---|
1132 | 1208 | if (table) { |
---|
1133 | 1209 | table[0].data = &net->ipv6.sysctl.icmpv6_time; |
---|
1134 | 1210 | table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all; |
---|
| 1211 | + table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast; |
---|
| 1212 | + table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast; |
---|
| 1213 | + table[4].data = &net->ipv6.sysctl.icmpv6_ratemask_ptr; |
---|
1135 | 1214 | } |
---|
1136 | 1215 | return table; |
---|
1137 | 1216 | } |
---|