--- /dev/null
+From f175b46d9134f708358b5404730c6dfa200fbf3c Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Wed, 21 Jan 2026 01:08:44 +0100
+Subject: netfilter: nf_tables: add .abort_skip_removal flag for set types
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+commit f175b46d9134f708358b5404730c6dfa200fbf3c upstream.
+
+The pipapo set backend is the only user of the .abort interface so far.
+To speed up pipapo abort path, removals are skipped.
+
+The follow up patch updates the rbtree to use to build an array of
+ordered elements, then use binary search. This needs a new .abort
+interface but, unlike pipapo, it also need to undo/remove elements.
+
+Add a flag and use it from the pipapo set backend.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Cc: "Kris Karas (Bug Reporting)" <bugs-a21@moonlit-rail.com>
+Cc: Genes Lists <lists@sapience.com>
+Cc: Philip Müller <philm@manjaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/netfilter/nf_tables.h | 2 ++
+ net/netfilter/nf_tables_api.c | 3 ++-
+ net/netfilter/nft_set_pipapo.c | 2 ++
+ 3 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -456,6 +456,7 @@ struct nft_set_ext;
+ * @init: initialize private data of new set instance
+ * @destroy: destroy private data of set instance
+ * @gc_init: initialize garbage collection
++ * @abort_skip_removal: skip removal of elements from abort path
+ * @elemsize: element private size
+ *
+ * Operations lookup, update and delete have simpler interfaces, are faster
+@@ -513,6 +514,7 @@ struct nft_set_ops {
+ const struct nft_set *set);
+ void (*gc_init)(const struct nft_set *set);
+
++ bool abort_skip_removal;
+ unsigned int elemsize;
+ };
+
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -7821,7 +7821,8 @@ static bool nft_trans_elems_new_abort(co
+ continue;
+ }
+
+- if (!te->set->ops->abort || nft_setelem_is_catchall(te->set, te->elems[i].priv))
++ if (!te->set->ops->abort_skip_removal ||
++ nft_setelem_is_catchall(te->set, te->elems[i].priv))
+ nft_setelem_remove(ctx->net, te->set, te->elems[i].priv);
+
+ if (!nft_setelem_is_catchall(te->set, te->elems[i].priv))
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -2370,6 +2370,7 @@ const struct nft_set_type nft_set_pipapo
+ .gc_init = nft_pipapo_gc_init,
+ .commit = nft_pipapo_commit,
+ .abort = nft_pipapo_abort,
++ .abort_skip_removal = true,
+ .elemsize = offsetof(struct nft_pipapo_elem, ext),
+ },
+ };
+@@ -2394,6 +2395,7 @@ const struct nft_set_type nft_set_pipapo
+ .gc_init = nft_pipapo_gc_init,
+ .commit = nft_pipapo_commit,
+ .abort = nft_pipapo_abort,
++ .abort_skip_removal = true,
+ .elemsize = offsetof(struct nft_pipapo_elem, ext),
+ },
+ };