Commit f17bf505 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns



Previous patch made ICMP rate limits per netns, it makes sense
to allow each netns to change the associated sysctl.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20240829144641.3880376-4-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b056b4cd
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -797,9 +797,6 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
bool icmp_global_allow(struct net *net);
void icmp_global_consume(struct net *net);

extern int sysctl_icmp_msgs_per_sec;
extern int sysctl_icmp_msgs_burst;

#ifdef CONFIG_PROC_FS
int ip_misc_proc_init(void);
#endif
+2 −0
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ struct netns_ipv4 {
	u8 sysctl_icmp_errors_use_inbound_ifaddr;
	int sysctl_icmp_ratelimit;
	int sysctl_icmp_ratemask;
	int sysctl_icmp_msgs_per_sec;
	int sysctl_icmp_msgs_burst;
	atomic_t icmp_global_credit;
	u32 icmp_global_stamp;
	u32 ip_rt_min_pmtu;
+4 −5
Original line number Diff line number Diff line
@@ -220,9 +220,6 @@ static inline void icmp_xmit_unlock(struct sock *sk)
	spin_unlock(&sk->sk_lock.slock);
}

int sysctl_icmp_msgs_per_sec __read_mostly = 1000;
int sysctl_icmp_msgs_burst __read_mostly = 50;

/**
 * icmp_global_allow - Are we allowed to send one more ICMP message ?
 * @net: network namespace
@@ -249,14 +246,14 @@ bool icmp_global_allow(struct net *net)
	if (delta < HZ / 50)
		return false;

	incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ;
	incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
	if (!incr)
		return false;

	if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) {
		old = atomic_read(&net->ipv4.icmp_global_credit);
		do {
			new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst));
			new = min(old + incr, READ_ONCE(net->ipv4.sysctl_icmp_msgs_burst));
		} while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new));
	}
	return true;
@@ -1492,6 +1489,8 @@ static int __net_init icmp_sk_init(struct net *net)
	net->ipv4.sysctl_icmp_ratelimit = 1 * HZ;
	net->ipv4.sysctl_icmp_ratemask = 0x1818;
	net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;
	net->ipv4.sysctl_icmp_msgs_per_sec = 1000;
	net->ipv4.sysctl_icmp_msgs_burst = 50;

	return 0;
}
+16 −16
Original line number Diff line number Diff line
@@ -600,22 +600,6 @@ static struct ctl_table ipv4_table[] = {
		.mode		= 0444,
		.proc_handler   = proc_tcp_available_ulp,
	},
	{
		.procname	= "icmp_msgs_per_sec",
		.data		= &sysctl_icmp_msgs_per_sec,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ZERO,
	},
	{
		.procname	= "icmp_msgs_burst",
		.data		= &sysctl_icmp_msgs_burst,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ZERO,
	},
	{
		.procname	= "udp_mem",
		.data		= &sysctl_udp_mem,
@@ -701,6 +685,22 @@ static struct ctl_table ipv4_net_table[] = {
		.mode		= 0644,
		.proc_handler	= proc_dointvec
	},
	{
		.procname	= "icmp_msgs_per_sec",
		.data		= &init_net.ipv4.sysctl_icmp_msgs_per_sec,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ZERO,
	},
	{
		.procname	= "icmp_msgs_burst",
		.data		= &init_net.ipv4.sysctl_icmp_msgs_burst,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ZERO,
	},
	{
		.procname	= "ping_group_range",
		.data		= &init_net.ipv4.ping_group_range.range,