]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nft_set_pipapo: use 0 genmask for packetpath lookups
authorFlorian Westphal <fw@strlen.de>
Tue, 16 Sep 2025 16:34:01 +0000 (18:34 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 24 Sep 2025 09:50:28 +0000 (11:50 +0200)
In commit c4eaca2e1052 ("netfilter: nft_set_pipapo: don't check genbit from
packetpath lookups") I replaced genmask_cur() with NFT_GENMASK_ANY, but
this change has no effect in the pipapo set type.

New entries are unreachable from the active copy, so NFT_GENMASK_ANY has
same result as genmask_cur():

current-gen elements are disabled and the new-generation
elements cannot be found.

Tests did not catch this incomplete fix because the change also dropped
the genmask test from the AVX2 version of the algorithm, so test only
fails if host cpu lacks AVX2 support.

Use genmask test only from the control plane (inserts, deletions, ..).

Packet path has to skip the check, use of 0 is enough for this because
ext->genmask has a the relevant bit set when the element is INACTIVE
in that generation: using a 0 genmask thus makes nft_set_elem_active()
always return true.

Fix the comment and replace NFT_GENMASK_ANY with 0.

Fixes: c4eaca2e1052 ("netfilter: nft_set_pipapo: don't check genbit from packetpath lookups")
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_set_pipapo.c
net/netfilter/nft_set_pipapo_avx2.c

index a7b8fa8cab7c44ac501082f4d11c93b043f51307..112fe46788b6fb5c7e27d95e9c337f6138a70890 100644 (file)
@@ -549,8 +549,7 @@ static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,
  *
  * This function is called from the data path.  It will search for
  * an element matching the given key in the current active copy.
- * Unlike other set types, this uses NFT_GENMASK_ANY instead of
- * nft_genmask_cur().
+ * Unlike other set types, this uses 0 instead of nft_genmask_cur().
  *
  * This is because new (future) elements are not reachable from
  * priv->match, they get added to priv->clone instead.
@@ -560,8 +559,8 @@ static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,
  * inconsistent state: matching old entries get skipped but thew
  * newly matching entries are unreachable.
  *
- * GENMASK will still find the 'now old' entries which ensures consistent
- * priv->match view.
+ * GENMASK_ANY doesn't work for the same reason: old-gen entries get
+ * skipped, new-gen entries are only reachable from priv->clone.
  *
  * nft_pipapo_commit swaps ->clone and ->match shortly after the
  * genbit flip.  As ->clone doesn't contain the old entries in the first
@@ -578,7 +577,7 @@ nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
        const struct nft_pipapo_elem *e;
 
        m = rcu_dereference(priv->match);
-       e = pipapo_get_slow(m, (const u8 *)key, NFT_GENMASK_ANY, get_jiffies_64());
+       e = pipapo_get_slow(m, (const u8 *)key, 0, get_jiffies_64());
 
        return e ? &e->ext : NULL;
 }
index 27dab36675487f571903ab7c8f4f230dbefa4aca..e72fd045d037ed3f49801b140f0960c637e046cc 100644 (file)
@@ -1292,7 +1292,7 @@ nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
 
        m = rcu_dereference(priv->match);
 
-       e = pipapo_get_avx2(m, rp, NFT_GENMASK_ANY, get_jiffies_64());
+       e = pipapo_get_avx2(m, rp, 0, get_jiffies_64());
        local_bh_enable();
 
        return e ? &e->ext : NULL;