ipv4: icmp: icmpv4_xrlim_allow() optimization if net.ipv4.icmp_ratelimit is zero
authorEric Dumazet <edumazet@google.com>
Mon, 16 Feb 2026 14:28:31 +0000 (14:28 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 19 Feb 2026 00:46:36 +0000 (16:46 -0800)
If net.ipv4.icmp_ratelimit is zero, we do not have to call
inet_getpeer_v4() and inet_peer_xrlim_allow().

Both can be very expensive under DDOS.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260216142832.3834174-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/icmp.c

index eff8487..a62b4c4 100644 (file)
@@ -316,23 +316,29 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
        struct dst_entry *dst = &rt->dst;
        struct inet_peer *peer;
        struct net_device *dev;
+       int peer_timeout;
        bool rc = true;
 
        if (!apply_ratelimit)
                return true;
 
+       peer_timeout = READ_ONCE(net->ipv4.sysctl_icmp_ratelimit);
+       if (!peer_timeout)
+               goto out;
+
        /* No rate limit on loopback */
        rcu_read_lock();
        dev = dst_dev_rcu(dst);
        if (dev && (dev->flags & IFF_LOOPBACK))
-               goto out;
+               goto out_unlock;
 
        peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr,
                               l3mdev_master_ifindex_rcu(dev));
-       rc = inet_peer_xrlim_allow(peer,
-                                  READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
-out:
+       rc = inet_peer_xrlim_allow(peer, peer_timeout);
+
+out_unlock:
        rcu_read_unlock();
+out:
        if (!rc)
                __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST);
        else