netfilter: nft_quota: use atomic64_xchg for reset
authorBrian Witte <brianwitte@mailfence.com>
Wed, 4 Feb 2026 20:26:38 +0000 (14:26 -0600)
committerFlorian Westphal <fw@strlen.de>
Tue, 17 Feb 2026 14:04:20 +0000 (15:04 +0100)
Use atomic64_xchg() to atomically read and zero the consumed value
on reset, which is simpler than the previous read+sub pattern and
doesn't require lock serialization.

Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Brian Witte <brianwitte@mailfence.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_quota.c

index df0798d..cb6c0e0 100644 (file)
@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
        u64 consumed, consumed_cap, quota;
        u32 flags = priv->flags;
 
-       /* Since we inconditionally increment consumed quota for each packet
+       /* Since we unconditionally increment consumed quota for each packet
         * that we see, don't go over the quota boundary in what we send to
         * userspace.
         */
-       consumed = atomic64_read(priv->consumed);
+       if (reset) {
+               consumed = atomic64_xchg(priv->consumed, 0);
+               clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+       } else {
+               consumed = atomic64_read(priv->consumed);
+       }
        quota = atomic64_read(&priv->quota);
        if (consumed >= quota) {
                consumed_cap = quota;
@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
            nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
                goto nla_put_failure;
 
-       if (reset) {
-               atomic64_sub(consumed, priv->consumed);
-               clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
-       }
        return 0;
 
 nla_put_failure: