Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'icmp-better-deal-with-ddos'

Eric Dumazet says:

====================
icmp: better deal with DDOS

When dealing with death of big UDP servers, admins might want to
increase net.ipv4.icmp_msgs_per_sec and net.ipv4.icmp_msgs_burst
to big values (2,000,000 or more).

They also might need to tune the per-host ratelimit to 1ms or 0ms
in favor of the global rate limit.

This series fixes bugs showing up in all these needs.
====================

Link: https://patch.msgid.link/20260216142832.3834174-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+31 -19
+4 -3
Documentation/networking/ip-sysctl.rst
··· 3234 3234 =========== 3235 3235 3236 3236 ratelimit - INTEGER 3237 - Limit the maximal rates for sending ICMPv6 messages. 3237 + Limit the maximal rates for sending ICMPv6 messages to a particular 3238 + peer. 3238 3239 3239 3240 0 to disable any limiting, 3240 - otherwise the minimal space between responses in milliseconds. 3241 + otherwise the space between responses in milliseconds. 3241 3242 3242 - Default: 1000 3243 + Default: 100 3243 3244 3244 3245 ratemask - list of comma separated ranges 3245 3246 For ICMPv6 message types matching the ranges in the ratemask, limit
+7 -2
include/net/netns/ipv4.h
··· 88 88 int sysctl_tcp_rcvbuf_low_rtt; 89 89 __cacheline_group_end(netns_ipv4_read_rx); 90 90 91 + /* ICMP rate limiter hot cache line. */ 92 + __cacheline_group_begin_aligned(icmp); 93 + atomic_t icmp_global_credit; 94 + u32 icmp_global_stamp; 95 + __cacheline_group_end_aligned(icmp); 96 + 91 97 struct inet_timewait_death_row tcp_death_row; 92 98 struct udp_table *udp_table; 93 99 ··· 147 141 int sysctl_icmp_ratemask; 148 142 int sysctl_icmp_msgs_per_sec; 149 143 int sysctl_icmp_msgs_burst; 150 - atomic_t icmp_global_credit; 151 - u32 icmp_global_stamp; 144 + 152 145 u32 ip_rt_min_pmtu; 153 146 int ip_rt_mtu_expires; 154 147 int ip_rt_min_advmss;
+12 -5
net/ipv4/icmp.c
··· 250 250 if (delta < HZ / 50) 251 251 return false; 252 252 253 - incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; 253 + incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); 254 + incr = div_u64((u64)incr * delta, HZ); 254 255 if (!incr) 255 256 return false; 256 257 ··· 316 315 struct dst_entry *dst = &rt->dst; 317 316 struct inet_peer *peer; 318 317 struct net_device *dev; 318 + int peer_timeout; 319 319 bool rc = true; 320 320 321 321 if (!apply_ratelimit) 322 322 return true; 323 323 324 + peer_timeout = READ_ONCE(net->ipv4.sysctl_icmp_ratelimit); 325 + if (!peer_timeout) 326 + goto out; 327 + 324 328 /* No rate limit on loopback */ 325 329 rcu_read_lock(); 326 330 dev = dst_dev_rcu(dst); 327 331 if (dev && (dev->flags & IFF_LOOPBACK)) 328 - goto out; 332 + goto out_unlock; 329 333 330 334 peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 331 335 l3mdev_master_ifindex_rcu(dev)); 332 - rc = inet_peer_xrlim_allow(peer, 333 - READ_ONCE(net->ipv4.sysctl_icmp_ratelimit)); 334 - out: 336 + rc = inet_peer_xrlim_allow(peer, peer_timeout); 337 + 338 + out_unlock: 335 339 rcu_read_unlock(); 340 + out: 336 341 if (!rc) 337 342 __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST); 338 343 else
+1 -1
net/ipv6/af_inet6.c
··· 952 952 int err = 0; 953 953 954 954 net->ipv6.sysctl.bindv6only = 0; 955 - net->ipv6.sysctl.icmpv6_time = 1*HZ; 955 + net->ipv6.sysctl.icmpv6_time = HZ / 10; 956 956 net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; 957 957 net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; 958 958 net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
+7 -8
net/ipv6/icmp.c
··· 217 217 } else if (dev && (dev->flags & IFF_LOOPBACK)) { 218 218 res = true; 219 219 } else { 220 - struct rt6_info *rt = dst_rt6_info(dst); 221 - int tmo = net->ipv6.sysctl.icmpv6_time; 220 + int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time); 222 221 struct inet_peer *peer; 223 222 224 - /* Give more bandwidth to wider prefixes. */ 225 - if (rt->rt6i_dst.plen < 128) 226 - tmo >>= ((128 - rt->rt6i_dst.plen)>>5); 227 - 228 - peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); 229 - res = inet_peer_xrlim_allow(peer, tmo); 223 + if (!tmo) { 224 + res = true; 225 + } else { 226 + peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); 227 + res = inet_peer_xrlim_allow(peer, tmo); 228 + } 230 229 } 231 230 rcu_read_unlock(); 232 231 if (!res)