Commit 0b03a5ca authored by Stephen Suryaputra's avatar Stephen Suryaputra Committed by David S. Miller
Browse files

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: default avatarStephen Suryaputra <ssuryaextr@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a534ea30
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1923,6 +1923,11 @@ echo_ignore_multicast - BOOLEAN
	requests sent to it over the IPv6 protocol via multicast.
	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
	The threshold at which we will start garbage collecting for IPv6
	destination cache entries.  At twice this value the system will
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ struct netns_sysctl_ipv6 {
	int icmpv6_time;
	int icmpv6_echo_ignore_all;
	int icmpv6_echo_ignore_multicast;
	int icmpv6_echo_ignore_anycast;
	int anycast_src_echo_reply;
	int ip_nonlocal_bind;
	int fwmark_reflect;
+1 −0
Original line number Diff line number Diff line
@@ -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_echo_ignore_all = 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.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS;
	net->ipv6.sysctl.idgen_retries = 3;
+14 −2
Original line number Diff line number Diff line
@@ -683,6 +683,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
	struct dst_entry *dst;
	struct ipcm6_cookie ipc6;
	u32 mark = IP6_REPLY_MARK(net, skb->mark);
	bool acast;

	if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) &&
	    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;

	acast = ipv6_anycast_destination(skb_dst(skb), saddr);
	if (acast && net->ipv6.sysctl.icmpv6_echo_ignore_anycast)
		return;

	if (!ipv6_unicast_destination(skb) &&
	    !(net->ipv6.sysctl.anycast_src_echo_reply &&
	      ipv6_anycast_destination(skb_dst(skb), saddr)))
	    !(net->ipv6.sysctl.anycast_src_echo_reply && acast))
		saddr = NULL;

	memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
@@ -1126,6 +1130,13 @@ static struct ctl_table ipv6_icmp_table_template[] = {
		.mode		= 0644,
		.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[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all;
		table[2].data = &net->ipv6.sysctl.icmpv6_echo_ignore_multicast;
		table[3].data = &net->ipv6.sysctl.icmpv6_echo_ignore_anycast;
	}
	return table;
}