ipv6: Add icmp_echo_ignore_anycast for ICMPv6

In addition to icmp_echo_ignore_multicast, there is a need to also
prevent responding to pings to anycast addresses for security.

Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Stephen Suryaputra 2019-03-20 10:29:27 -04:00 committed by David S. Miller
parent a534ea30e7
commit 0b03a5ca8b
4 changed files with 21 additions and 2 deletions

View File

@ -1923,6 +1923,11 @@ echo_ignore_multicast - BOOLEAN
requests sent to it over the IPv6 protocol via multicast. requests sent to it over the IPv6 protocol via multicast.
Default: 0 Default: 0
echo_ignore_anycast - BOOLEAN
If set non-zero, then the kernel will ignore all ICMP ECHO
requests sent to it over the IPv6 protocol destined to anycast address.
Default: 0
xfrm6_gc_thresh - INTEGER xfrm6_gc_thresh - INTEGER
The threshold at which we will start garbage collecting for IPv6 The threshold at which we will start garbage collecting for IPv6
destination cache entries. At twice this value the system will destination cache entries. At twice this value the system will

View File

@ -34,6 +34,7 @@ struct netns_sysctl_ipv6 {
int icmpv6_time; int icmpv6_time;
int icmpv6_echo_ignore_all; int icmpv6_echo_ignore_all;
int icmpv6_echo_ignore_multicast; int icmpv6_echo_ignore_multicast;
int icmpv6_echo_ignore_anycast;
int anycast_src_echo_reply; int anycast_src_echo_reply;
int ip_nonlocal_bind; int ip_nonlocal_bind;
int fwmark_reflect; int fwmark_reflect;

View File

@ -848,6 +848,7 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_time = 1*HZ; net->ipv6.sysctl.icmpv6_time = 1*HZ;
net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
net->ipv6.sysctl.flowlabel_consistency = 1; net->ipv6.sysctl.flowlabel_consistency = 1;
net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS; net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS;
net->ipv6.sysctl.idgen_retries = 3; net->ipv6.sysctl.idgen_retries = 3;

View File

@ -683,6 +683,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct dst_entry *dst; struct dst_entry *dst;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
u32 mark = IP6_REPLY_MARK(net, skb->mark); u32 mark = IP6_REPLY_MARK(net, skb->mark);
bool acast;
if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) && if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) &&
net->ipv6.sysctl.icmpv6_echo_ignore_multicast) net->ipv6.sysctl.icmpv6_echo_ignore_multicast)
@ -690,9 +691,12 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
saddr = &ipv6_hdr(skb)->daddr; saddr = &ipv6_hdr(skb)->daddr;
acast = ipv6_anycast_destination(skb_dst(skb), saddr);
if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast)
return;
if (!ipv6_unicast_destination(skb) && if (!ipv6_unicast_destination(skb) &&
!(net->ipv6.sysctl.anycast_src_echo_reply && !(net->ipv6.sysctl.anycast_src_echo_reply && acast))
ipv6_anycast_destination(skb_dst(skb), saddr)))
saddr = NULL; saddr = NULL;
memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
@ -1126,6 +1130,13 @@ static struct ctl_table ipv6_icmp_table_template[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec,
}, },
{
.procname = "echo_ignore_anycast",
.data = &init_net.ipv6.sysctl.icmpv6_echo_ignore_anycast,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{ }, { },
}; };
@ -1141,6 +1152,7 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
table[0].data = &net->ipv6.sysctl.icmpv6_time; table[0].data = &net->ipv6.sysctl.icmpv6_time;
table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all; table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all;
table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast; table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
} }
return table; return table;
} }