aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt5
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/icmp.c16
4 files changed, 21 insertions, 2 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 55ea7def46be..bd029fc55ccb 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1923,6 +1923,11 @@ echo_ignore_multicast - BOOLEAN
1923 requests sent to it over the IPv6 protocol via multicast. 1923 requests sent to it over the IPv6 protocol via multicast.
1924 Default: 0 1924 Default: 0
1925 1925
1926echo_ignore_anycast - BOOLEAN
1927 If set non-zero, then the kernel will ignore all ICMP ECHO
1928 requests sent to it over the IPv6 protocol destined to anycast address.
1929 Default: 0
1930
1926xfrm6_gc_thresh - INTEGER 1931xfrm6_gc_thresh - INTEGER
1927 The threshold at which we will start garbage collecting for IPv6 1932 The threshold at which we will start garbage collecting for IPv6
1928 destination cache entries. At twice this value the system will 1933 destination cache entries. At twice this value the system will
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index e29aff15acc9..64e29b58bb5e 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -34,6 +34,7 @@ struct netns_sysctl_ipv6 {
34 int icmpv6_time; 34 int icmpv6_time;
35 int icmpv6_echo_ignore_all; 35 int icmpv6_echo_ignore_all;
36 int icmpv6_echo_ignore_multicast; 36 int icmpv6_echo_ignore_multicast;
37 int icmpv6_echo_ignore_anycast;
37 int anycast_src_echo_reply; 38 int anycast_src_echo_reply;
38 int ip_nonlocal_bind; 39 int ip_nonlocal_bind;
39 int fwmark_reflect; 40 int fwmark_reflect;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index fdc117de849c..fa6b404cbd10 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -848,6 +848,7 @@ static int __net_init inet6_net_init(struct net *net)
848 net->ipv6.sysctl.icmpv6_time = 1*HZ; 848 net->ipv6.sysctl.icmpv6_time = 1*HZ;
849 net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; 849 net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
850 net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; 850 net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
851 net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
851 net->ipv6.sysctl.flowlabel_consistency = 1; 852 net->ipv6.sysctl.flowlabel_consistency = 1;
852 net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS; 853 net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS;
853 net->ipv6.sysctl.idgen_retries = 3; 854 net->ipv6.sysctl.idgen_retries = 3;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 0907bcede5e5..cc14b9998941 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -683,6 +683,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
683 struct dst_entry *dst; 683 struct dst_entry *dst;
684 struct ipcm6_cookie ipc6; 684 struct ipcm6_cookie ipc6;
685 u32 mark = IP6_REPLY_MARK(net, skb->mark); 685 u32 mark = IP6_REPLY_MARK(net, skb->mark);
686 bool acast;
686 687
687 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && 688 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) &&
688 net->ipv6.sysctl.icmpv6_echo_ignore_multicast) 689 net->ipv6.sysctl.icmpv6_echo_ignore_multicast)
@@ -690,9 +691,12 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
690 691
691 saddr = &ipv6_hdr(skb)->daddr; 692 saddr = &ipv6_hdr(skb)->daddr;
692 693
694 acast = ipv6_anycast_destination(skb_dst(skb), saddr);
695 if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast)
696 return;
697
693 if (!ipv6_unicast_destination(skb) && 698 if (!ipv6_unicast_destination(skb) &&
694 !(net->ipv6.sysctl.anycast_src_echo_reply && 699 !(net->ipv6.sysctl.anycast_src_echo_reply && acast))
695 ipv6_anycast_destination(skb_dst(skb), saddr)))
696 saddr = NULL; 700 saddr = NULL;
697 701
698 memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); 702 memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
@@ -1126,6 +1130,13 @@ static struct ctl_table ipv6_icmp_table_template[] = {
1126 .mode = 0644, 1130 .mode = 0644,
1127 .proc_handler = proc_dointvec, 1131 .proc_handler = proc_dointvec,
1128 }, 1132 },
1133 {
1134 .procname = "echo_ignore_anycast",
1135 .data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_anycast,
1136 .maxlen = sizeof(int),
1137 .mode = 0644,
1138 .proc_handler = proc_dointvec,
1139 },
1129 { }, 1140 { },
1130}; 1141};
1131 1142
@@ -1141,6 +1152,7 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
1141 table[0].data = &net->ipv6.sysctl.icmpv6_time; 1152 table[0].data = &net->ipv6.sysctl.icmpv6_time;
1142 table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all; 1153 table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all;
1143 table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast; 1154 table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
1155 table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
1144 } 1156 }
1145 return table; 1157 return table;
1146} 1158}