]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ipv6: snmp: do not track per idev ICMP6_MIB_RATELIMITHOST
authorEric Dumazet <edumazet@google.com>
Fri, 5 Sep 2025 16:58:07 +0000 (16:58 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 9 Sep 2025 01:06:20 +0000 (18:06 -0700)
Blamed commit added a critical false sharing on a single
atomic_long_t under DOS, like receiving UDP packets
to closed ports.

Per netns ICMP6_MIB_RATELIMITHOST tracking uses per-cpu
storage and is enough, we do not need per-device and slow tracking.

Fixes: d0941130c9351 ("icmp: Add counters for rate limits")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jamie Bainbridge <jamie.bainbridge@gmail.com>
Cc: Abhishek Rawal <rawal.abhishek92@gmail.com>
Link: https://patch.msgid.link/20250905165813.1470708-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv6/icmp.c
net/ipv6/proc.c

index 95cdd4cacb004fd4f2e569136a313afef3b25c58..56c974cf75d151578ad57a333361c393d5ec403a 100644 (file)
@@ -230,8 +230,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
        }
        rcu_read_unlock();
        if (!res)
-               __ICMP6_INC_STATS(net, ip6_dst_idev(dst),
-                                 ICMP6_MIB_RATELIMITHOST);
+               __ICMP6_INC_STATS(net, NULL, ICMP6_MIB_RATELIMITHOST);
        else
                icmp_global_consume(net);
        dst_release(dst);
index 92ed04729c2f5403a716bca2dc708bc9157bd726..73296f38c25205438ac886583b5a71c6dc38b7d5 100644 (file)
@@ -94,6 +94,7 @@ static const struct snmp_mib snmp6_icmp6_list[] = {
        SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
        SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS),
        SNMP_MIB_ITEM("Icmp6InCsumErrors", ICMP6_MIB_CSUMERRORS),
+/* ICMP6_MIB_RATELIMITHOST needs to be last, see snmp6_dev_seq_show(). */
        SNMP_MIB_ITEM("Icmp6OutRateLimitHost", ICMP6_MIB_RATELIMITHOST),
 };
 
@@ -242,8 +243,11 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
                              snmp6_ipstats_list,
                              ARRAY_SIZE(snmp6_ipstats_list),
                              offsetof(struct ipstats_mib, syncp));
+
+       /* Per idev icmp stats do not have ICMP6_MIB_RATELIMITHOST */
        snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs,
-                           snmp6_icmp6_list, ARRAY_SIZE(snmp6_icmp6_list));
+                           snmp6_icmp6_list, ARRAY_SIZE(snmp6_icmp6_list) - 1);
+
        snmp6_seq_show_icmpv6msg(seq, idev->stats.icmpv6msgdev->mibs);
        return 0;
 }