Skip to content

Commit aebf798

Browse files
committed
netfilter: nft_set_rbtree: skip elements in transaction from garbage collection
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2189550 Upstream Status: commit 5d235d6 commit 5d235d6 Author: Pablo Neira Ayuso <[email protected]> Date: Sat Jan 14 23:49:46 2023 +0100 netfilter: nft_set_rbtree: skip elements in transaction from garbage collection Skip interference with an ongoing transaction, do not perform garbage collection on inactive elements. Reset annotated previous end interval if the expired element is marked as busy (control plane removed the element right before expiration). Fixes: 8d8540c ("netfilter: nft_set_rbtree: add timeout support") Reviewed-by: Stefano Brivio <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Florian Westphal <[email protected]>
1 parent 97220e3 commit aebf798

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

net/netfilter/nft_set_rbtree.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,23 +563,37 @@ static void nft_rbtree_gc(struct work_struct *work)
563563
struct nft_rbtree *priv;
564564
struct rb_node *node;
565565
struct nft_set *set;
566+
struct net *net;
567+
u8 genmask;
566568

567569
priv = container_of(work, struct nft_rbtree, gc_work.work);
568570
set = nft_set_container_of(priv);
571+
net = read_pnet(&set->net);
572+
genmask = nft_genmask_cur(net);
569573

570574
write_lock_bh(&priv->lock);
571575
write_seqcount_begin(&priv->count);
572576
for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
573577
rbe = rb_entry(node, struct nft_rbtree_elem, node);
574578

579+
if (!nft_set_elem_active(&rbe->ext, genmask))
580+
continue;
581+
582+
/* elements are reversed in the rbtree for historical reasons,
583+
* from highest to lowest value, that is why end element is
584+
* always visited before the start element.
585+
*/
575586
if (nft_rbtree_interval_end(rbe)) {
576587
rbe_end = rbe;
577588
continue;
578589
}
579590
if (!nft_set_elem_expired(&rbe->ext))
580591
continue;
581-
if (nft_set_elem_mark_busy(&rbe->ext))
592+
593+
if (nft_set_elem_mark_busy(&rbe->ext)) {
594+
rbe_end = NULL;
582595
continue;
596+
}
583597

584598
if (rbe_prev) {
585599
rb_erase(&rbe_prev->node, &priv->root);

0 commit comments

Comments
 (0)