Fix-for-a-fix: I replaced genmask_cur() with NFT_GENMASK_ANY, but this doesn't work. New entries are unreachable from the active copy, so it makes no difference: current-gen elements are disabled and the new-generation elements cannot be found. Use the genmasks 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. I did not catch this with the tests due to AVX2 being support and the AVX2 version of this algorithm doesn't have the check in the nf tree anymore. But this genmask test is there on -next, where the test fails as well. This also means that this needs another fixup in -next. Fixes: c4eaca2e1052 ("netfilter: nft_set_pipapo: don't check genbit from packetpath lookups") Signed-off-by: Florian Westphal --- Dumb thinko on my end :-( Only noticed it because test case was failing on -next despite "fix" having been merged. net/netfilter/nft_set_pipapo.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 793790d79d13..ac9d989c0a51 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -510,8 +510,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. @@ -520,9 +519,8 @@ static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m, * elements becoming visible. Using nft_genmask_cur() thus creates * 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 @@ -539,7 +537,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(m, (const u8 *)key, NFT_GENMASK_ANY, get_jiffies_64()); + e = pipapo_get(m, (const u8 *)key, 0, get_jiffies_64()); return e ? &e->ext : NULL; } -- 2.49.1