Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfdd81ae authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by Greg Kroah-Hartman
Browse files

netfilter: nft_set_rbtree: skip elements in transaction from garbage collection



[ Upstream commit 5d235d6ce75c12a7fdee375eb211e4116f7ab01b ]

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: 8d8540c4 ("netfilter: nft_set_rbtree: add timeout support")
Reviewed-by: default avatarStefano Brivio <sbrivio@redhat.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent ddd49cbb
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -389,23 +389,37 @@ static void nft_rbtree_gc(struct work_struct *work)
	struct nft_rbtree *priv;
	struct rb_node *node;
	struct nft_set *set;
	struct net *net;
	u8 genmask;

	priv = container_of(work, struct nft_rbtree, gc_work.work);
	set  = nft_set_container_of(priv);
	net  = read_pnet(&set->net);
	genmask = nft_genmask_cur(net);

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

		if (!nft_set_elem_active(&rbe->ext, genmask))
			continue;

		/* elements are reversed in the rbtree for historical reasons,
		 * from highest to lowest value, that is why end element is
		 * always visited before the start element.
		 */
		if (nft_rbtree_interval_end(rbe)) {
			rbe_end = rbe;
			continue;
		}
		if (!nft_set_elem_expired(&rbe->ext))
			continue;
		if (nft_set_elem_mark_busy(&rbe->ext))

		if (nft_set_elem_mark_busy(&rbe->ext)) {
			rbe_end = NULL;
			continue;
		}

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