]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some netfilter patches that did not build
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Aug 2023 17:32:35 +0000 (19:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Aug 2023 17:32:35 +0000 (19:32 +0200)
queue-5.10/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch [deleted file]
queue-5.10/series
queue-5.15/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch [deleted file]
queue-5.15/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch [deleted file]
queue-5.15/series
queue-5.4/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch [deleted file]
queue-5.4/series
queue-6.1/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch [deleted file]
queue-6.1/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch [deleted file]
queue-6.1/series

diff --git a/queue-5.10/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch b/queue-5.10/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
deleted file mode 100644 (file)
index 028c765..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From c92db3030492b8ad1d0faace7a93bbcf53850d0c Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 15:00:06 +0200
-Subject: netfilter: nft_set_hash: mark set element as dead when deleting from packet path
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit c92db3030492b8ad1d0faace7a93bbcf53850d0c upstream.
-
-Set on the NFT_SET_ELEM_DEAD_BIT flag on this element, instead of
-performing element removal which might race with an ongoing transaction.
-Enable gc when dynamic flag is set on since dynset deletion requires
-garbage collection after this patch.
-
-Fixes: d0a8d877da97 ("netfilter: nft_dynset: support for element deletion")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nft_set_hash.c |    6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -251,7 +251,9 @@ static bool nft_rhash_delete(const struc
-       if (he == NULL)
-               return false;
--      return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
-+      nft_set_elem_dead(&he->ext);
-+
-+      return true;
- }
- static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
-@@ -372,7 +374,7 @@ static int nft_rhash_init(const struct n
-               return err;
-       INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
--      if (set->flags & NFT_SET_TIMEOUT)
-+      if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
-               nft_rhash_gc_init(set);
-       return 0;
index 2e1c101bd1c3356335d1f9bf55f1234e44359697..401825e80be0b21f6bc4fdbd779dcfa11293313a 100644 (file)
@@ -29,4 +29,3 @@ x86-speculation-add-cpu_show_gds-prototype.patch
 x86-move-gds_ucode_mitigated-declaration-to-header.patch
 drm-nouveau-disp-revert-a-null-check-inside-nouveau_connector_get_modes.patch
 netfilter-nf_tables-don-t-skip-expired-elements-during-walk.patch
-netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
diff --git a/queue-5.15/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch b/queue-5.15/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch
deleted file mode 100644 (file)
index 90aff74..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-From f6c383b8c31a93752a52697f8430a71dcbc46adf Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 14:54:23 +0200
-Subject: netfilter: nf_tables: adapt set backend to use GC transaction API
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit f6c383b8c31a93752a52697f8430a71dcbc46adf upstream.
-
-Use the GC transaction API to replace the old and buggy gc API and the
-busy mark approach.
-
-No set elements are removed from async garbage collection anymore,
-instead the _DEAD bit is set on so the set element is not visible from
-lookup path anymore. Async GC enqueues transaction work that might be
-aborted and retried later.
-
-rbtree and pipapo set backends does not set on the _DEAD bit from the
-sync GC path since this runs in control plane path where mutex is held.
-In this case, set elements are deactivated, removed and then released
-via RCU callback, sync GC never fails.
-
-Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges")
-Fixes: 8d8540c4f5e0 ("netfilter: nft_set_rbtree: add timeout support")
-Fixes: 9d0982927e79 ("netfilter: nft_hash: add support for timeouts")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nf_tables_api.c  |    7 -
- net/netfilter/nft_set_hash.c   |   77 +++++++++++++--------
- net/netfilter/nft_set_pipapo.c |   48 ++++++++++---
- net/netfilter/nft_set_rbtree.c |  146 ++++++++++++++++++++++++-----------------
- 4 files changed, 174 insertions(+), 104 deletions(-)
-
---- a/net/netfilter/nf_tables_api.c
-+++ b/net/netfilter/nf_tables_api.c
-@@ -5983,7 +5983,6 @@ static void nft_setelem_activate(struct
-       if (nft_setelem_is_catchall(set, elem)) {
-               nft_set_elem_change_active(net, set, ext);
--              nft_set_elem_clear_busy(ext);
-       } else {
-               set->ops->activate(net, set, elem);
-       }
-@@ -5998,8 +5997,7 @@ static int nft_setelem_catchall_deactiva
-       list_for_each_entry(catchall, &set->catchall_list, list) {
-               ext = nft_set_elem_ext(set, catchall->elem);
--              if (!nft_is_active(net, ext) ||
--                  nft_set_elem_mark_busy(ext))
-+              if (!nft_is_active(net, ext))
-                       continue;
-               kfree(elem->priv);
-@@ -6693,8 +6691,7 @@ static int nft_set_catchall_flush(const
-       list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
-               ext = nft_set_elem_ext(set, catchall->elem);
--              if (!nft_set_elem_active(ext, genmask) ||
--                  nft_set_elem_mark_busy(ext))
-+              if (!nft_set_elem_active(ext, genmask))
-                       continue;
-               elem.priv = catchall->elem;
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -59,6 +59,8 @@ static inline int nft_rhash_cmp(struct r
-       if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
-               return 1;
-+      if (nft_set_elem_is_dead(&he->ext))
-+              return 1;
-       if (nft_set_elem_expired(&he->ext))
-               return 1;
-       if (!nft_set_elem_active(&he->ext, x->genmask))
-@@ -188,7 +190,6 @@ static void nft_rhash_activate(const str
-       struct nft_rhash_elem *he = elem->priv;
-       nft_set_elem_change_active(net, set, &he->ext);
--      nft_set_elem_clear_busy(&he->ext);
- }
- static bool nft_rhash_flush(const struct net *net,
-@@ -196,12 +197,9 @@ static bool nft_rhash_flush(const struct
- {
-       struct nft_rhash_elem *he = priv;
--      if (!nft_set_elem_mark_busy(&he->ext) ||
--          !nft_is_active(net, &he->ext)) {
--              nft_set_elem_change_active(net, set, &he->ext);
--              return true;
--      }
--      return false;
-+      nft_set_elem_change_active(net, set, &he->ext);
-+
-+      return true;
- }
- static void *nft_rhash_deactivate(const struct net *net,
-@@ -218,9 +216,8 @@ static void *nft_rhash_deactivate(const
-       rcu_read_lock();
-       he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
--      if (he != NULL &&
--          !nft_rhash_flush(net, set, he))
--              he = NULL;
-+      if (he)
-+              nft_set_elem_change_active(net, set, &he->ext);
-       rcu_read_unlock();
-@@ -312,25 +309,48 @@ static bool nft_rhash_expr_needs_gc_run(
- static void nft_rhash_gc(struct work_struct *work)
- {
-+      struct nftables_pernet *nft_net;
-       struct nft_set *set;
-       struct nft_rhash_elem *he;
-       struct nft_rhash *priv;
--      struct nft_set_gc_batch *gcb = NULL;
-       struct rhashtable_iter hti;
-+      struct nft_trans_gc *gc;
-+      struct net *net;
-+      u32 gc_seq;
-       priv = container_of(work, struct nft_rhash, gc_work.work);
-       set  = nft_set_container_of(priv);
-+      net  = read_pnet(&set->net);
-+      nft_net = nft_pernet(net);
-+      gc_seq = READ_ONCE(nft_net->gc_seq);
-+
-+      gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
-+      if (!gc)
-+              goto done;
-       rhashtable_walk_enter(&priv->ht, &hti);
-       rhashtable_walk_start(&hti);
-       while ((he = rhashtable_walk_next(&hti))) {
-               if (IS_ERR(he)) {
--                      if (PTR_ERR(he) != -EAGAIN)
--                              break;
-+                      if (PTR_ERR(he) != -EAGAIN) {
-+                              nft_trans_gc_destroy(gc);
-+                              gc = NULL;
-+                              goto try_later;
-+                      }
-                       continue;
-               }
-+              /* Ruleset has been updated, try later. */
-+              if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
-+                      nft_trans_gc_destroy(gc);
-+                      gc = NULL;
-+                      goto try_later;
-+              }
-+
-+              if (nft_set_elem_is_dead(&he->ext))
-+                      goto dead_elem;
-+
-               if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) &&
-                   nft_rhash_expr_needs_gc_run(set, &he->ext))
-                       goto needs_gc_run;
-@@ -338,26 +358,26 @@ static void nft_rhash_gc(struct work_str
-               if (!nft_set_elem_expired(&he->ext))
-                       continue;
- needs_gc_run:
--              if (nft_set_elem_mark_busy(&he->ext))
--                      continue;
-+              nft_set_elem_dead(&he->ext);
-+dead_elem:
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb == NULL)
--                      break;
--              rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, he);
-+              nft_trans_gc_elem_add(gc, he);
-       }
-+
-+      gc = nft_trans_gc_catchall(gc, gc_seq);
-+
-+try_later:
-+      /* catchall list iteration requires rcu read side lock. */
-       rhashtable_walk_stop(&hti);
-       rhashtable_walk_exit(&hti);
--      he = nft_set_catchall_gc(set);
--      if (he) {
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb)
--                      nft_set_gc_batch_add(gcb, he);
--      }
--      nft_set_gc_batch_complete(gcb);
-+      if (gc)
-+              nft_trans_gc_queue_async_done(gc);
-+
-+done:
-       queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
-                          nft_set_gc_interval(set));
- }
-@@ -420,7 +440,6 @@ static void nft_rhash_destroy(const stru
-       };
-       cancel_delayed_work_sync(&priv->gc_work);
--      rcu_barrier();
-       rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
-                                   (void *)&rhash_ctx);
- }
---- a/net/netfilter/nft_set_pipapo.c
-+++ b/net/netfilter/nft_set_pipapo.c
-@@ -1537,16 +1537,34 @@ static void pipapo_drop(struct nft_pipap
-       }
- }
-+static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set,
-+                                   struct nft_pipapo_elem *e)
-+
-+{
-+      struct nft_set_elem elem = {
-+              .priv   = e,
-+      };
-+
-+      nft_setelem_data_deactivate(net, set, &elem);
-+}
-+
- /**
-  * pipapo_gc() - Drop expired entries from set, destroy start and end elements
-  * @set:      nftables API set representation
-  * @m:                Matching data
-  */
--static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
-+static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m)
- {
-+      struct nft_set *set = (struct nft_set *) _set;
-       struct nft_pipapo *priv = nft_set_priv(set);
-+      struct net *net = read_pnet(&set->net);
-       int rules_f0, first_rule = 0;
-       struct nft_pipapo_elem *e;
-+      struct nft_trans_gc *gc;
-+
-+      gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL);
-+      if (!gc)
-+              return;
-       while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
-               union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
-@@ -1570,13 +1588,20 @@ static void pipapo_gc(const struct nft_s
-               f--;
-               i--;
-               e = f->mt[rulemap[i].to].e;
--              if (nft_set_elem_expired(&e->ext) &&
--                  !nft_set_elem_mark_busy(&e->ext)) {
-+
-+              /* synchronous gc never fails, there is no need to set on
-+               * NFT_SET_ELEM_DEAD_BIT.
-+               */
-+              if (nft_set_elem_expired(&e->ext)) {
-                       priv->dirty = true;
--                      pipapo_drop(m, rulemap);
--                      rcu_barrier();
--                      nft_set_elem_destroy(set, e, true);
-+                      gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+                      if (!gc)
-+                              break;
-+
-+                      nft_pipapo_gc_deactivate(net, set, e);
-+                      pipapo_drop(m, rulemap);
-+                      nft_trans_gc_elem_add(gc, e);
-                       /* And check again current first rule, which is now the
-                        * first we haven't checked.
-@@ -1586,11 +1611,11 @@ static void pipapo_gc(const struct nft_s
-               }
-       }
--      e = nft_set_catchall_gc(set);
--      if (e)
--              nft_set_elem_destroy(set, e, true);
--
--      priv->last_gc = jiffies;
-+      gc = nft_trans_gc_catchall(gc, 0);
-+      if (gc) {
-+              nft_trans_gc_queue_sync_done(gc);
-+              priv->last_gc = jiffies;
-+      }
- }
- /**
-@@ -1715,7 +1740,6 @@ static void nft_pipapo_activate(const st
-               return;
-       nft_set_elem_change_active(net, set, &e->ext);
--      nft_set_elem_clear_busy(&e->ext);
- }
- /**
---- a/net/netfilter/nft_set_rbtree.c
-+++ b/net/netfilter/nft_set_rbtree.c
-@@ -46,6 +46,12 @@ static int nft_rbtree_cmp(const struct n
-                     set->klen);
- }
-+static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe)
-+{
-+      return nft_set_elem_expired(&rbe->ext) ||
-+             nft_set_elem_is_dead(&rbe->ext);
-+}
-+
- static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
-                               const u32 *key, const struct nft_set_ext **ext,
-                               unsigned int seq)
-@@ -80,7 +86,7 @@ static bool __nft_rbtree_lookup(const st
-                               continue;
-                       }
--                      if (nft_set_elem_expired(&rbe->ext))
-+                      if (nft_rbtree_elem_expired(rbe))
-                               return false;
-                       if (nft_rbtree_interval_end(rbe)) {
-@@ -98,7 +104,7 @@ static bool __nft_rbtree_lookup(const st
-       if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
-           nft_set_elem_active(&interval->ext, genmask) &&
--          !nft_set_elem_expired(&interval->ext) &&
-+          !nft_rbtree_elem_expired(interval) &&
-           nft_rbtree_interval_start(interval)) {
-               *ext = &interval->ext;
-               return true;
-@@ -215,6 +221,18 @@ static void *nft_rbtree_get(const struct
-       return rbe;
- }
-+static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
-+                               struct nft_rbtree *priv,
-+                               struct nft_rbtree_elem *rbe)
-+{
-+      struct nft_set_elem elem = {
-+              .priv   = rbe,
-+      };
-+
-+      nft_setelem_data_deactivate(net, set, &elem);
-+      rb_erase(&rbe->node, &priv->root);
-+}
-+
- static int nft_rbtree_gc_elem(const struct nft_set *__set,
-                             struct nft_rbtree *priv,
-                             struct nft_rbtree_elem *rbe,
-@@ -222,11 +240,12 @@ static int nft_rbtree_gc_elem(const stru
- {
-       struct nft_set *set = (struct nft_set *)__set;
-       struct rb_node *prev = rb_prev(&rbe->node);
-+      struct net *net = read_pnet(&set->net);
-       struct nft_rbtree_elem *rbe_prev;
--      struct nft_set_gc_batch *gcb;
-+      struct nft_trans_gc *gc;
--      gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC);
--      if (!gcb)
-+      gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
-+      if (!gc)
-               return -ENOMEM;
-       /* search for end interval coming before this element.
-@@ -244,17 +263,28 @@ static int nft_rbtree_gc_elem(const stru
-       if (prev) {
-               rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
-+              nft_rbtree_gc_remove(net, set, priv, rbe_prev);
--              rb_erase(&rbe_prev->node, &priv->root);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, rbe_prev);
-+              /* There is always room in this trans gc for this element,
-+               * memory allocation never actually happens, hence, the warning
-+               * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT,
-+               * this is synchronous gc which never fails.
-+               */
-+              gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+              if (WARN_ON_ONCE(!gc))
-+                      return -ENOMEM;
-+
-+              nft_trans_gc_elem_add(gc, rbe_prev);
-       }
--      rb_erase(&rbe->node, &priv->root);
--      atomic_dec(&set->nelems);
-+      nft_rbtree_gc_remove(net, set, priv, rbe);
-+      gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+      if (WARN_ON_ONCE(!gc))
-+              return -ENOMEM;
--      nft_set_gc_batch_add(gcb, rbe);
--      nft_set_gc_batch_complete(gcb);
-+      nft_trans_gc_elem_add(gc, rbe);
-+
-+      nft_trans_gc_queue_sync_done(gc);
-       return 0;
- }
-@@ -482,7 +512,6 @@ static void nft_rbtree_activate(const st
-       struct nft_rbtree_elem *rbe = elem->priv;
-       nft_set_elem_change_active(net, set, &rbe->ext);
--      nft_set_elem_clear_busy(&rbe->ext);
- }
- static bool nft_rbtree_flush(const struct net *net,
-@@ -490,12 +519,9 @@ static bool nft_rbtree_flush(const struc
- {
-       struct nft_rbtree_elem *rbe = priv;
--      if (!nft_set_elem_mark_busy(&rbe->ext) ||
--          !nft_is_active(net, &rbe->ext)) {
--              nft_set_elem_change_active(net, set, &rbe->ext);
--              return true;
--      }
--      return false;
-+      nft_set_elem_change_active(net, set, &rbe->ext);
-+
-+      return true;
- }
- static void *nft_rbtree_deactivate(const struct net *net,
-@@ -570,26 +596,40 @@ cont:
- static void nft_rbtree_gc(struct work_struct *work)
- {
--      struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL;
--      struct nft_set_gc_batch *gcb = NULL;
-+      struct nft_rbtree_elem *rbe, *rbe_end = NULL;
-+      struct nftables_pernet *nft_net;
-       struct nft_rbtree *priv;
-+      struct nft_trans_gc *gc;
-       struct rb_node *node;
-       struct nft_set *set;
-+      unsigned int gc_seq;
-       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);
-+      nft_net = nft_pernet(net);
-+      gc_seq  = READ_ONCE(nft_net->gc_seq);
-+
-+      gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
-+      if (!gc)
-+              goto done;
-       write_lock_bh(&priv->lock);
-       write_seqcount_begin(&priv->count);
-       for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
-+
-+              /* Ruleset has been updated, try later. */
-+              if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
-+                      nft_trans_gc_destroy(gc);
-+                      gc = NULL;
-+                      goto try_later;
-+              }
-+
-               rbe = rb_entry(node, struct nft_rbtree_elem, node);
--              if (!nft_set_elem_active(&rbe->ext, genmask))
--                      continue;
-+              if (nft_set_elem_is_dead(&rbe->ext))
-+                      goto dead_elem;
-               /* elements are reversed in the rbtree for historical reasons,
-                * from highest to lowest value, that is why end element is
-@@ -602,46 +642,36 @@ static void nft_rbtree_gc(struct work_st
-               if (!nft_set_elem_expired(&rbe->ext))
-                       continue;
--              if (nft_set_elem_mark_busy(&rbe->ext)) {
--                      rbe_end = NULL;
-+              nft_set_elem_dead(&rbe->ext);
-+
-+              if (!rbe_end)
-                       continue;
--              }
--              if (rbe_prev) {
--                      rb_erase(&rbe_prev->node, &priv->root);
--                      rbe_prev = NULL;
--              }
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (!gcb)
--                      break;
-+              nft_set_elem_dead(&rbe_end->ext);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, rbe);
--              rbe_prev = rbe;
--
--              if (rbe_end) {
--                      atomic_dec(&set->nelems);
--                      nft_set_gc_batch_add(gcb, rbe_end);
--                      rb_erase(&rbe_end->node, &priv->root);
--                      rbe_end = NULL;
--              }
--              node = rb_next(node);
--              if (!node)
--                      break;
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
-+
-+              nft_trans_gc_elem_add(gc, rbe_end);
-+              rbe_end = NULL;
-+dead_elem:
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
-+
-+              nft_trans_gc_elem_add(gc, rbe);
-       }
--      if (rbe_prev)
--              rb_erase(&rbe_prev->node, &priv->root);
-+
-+      gc = nft_trans_gc_catchall(gc, gc_seq);
-+
-+try_later:
-       write_seqcount_end(&priv->count);
-       write_unlock_bh(&priv->lock);
--      rbe = nft_set_catchall_gc(set);
--      if (rbe) {
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb)
--                      nft_set_gc_batch_add(gcb, rbe);
--      }
--      nft_set_gc_batch_complete(gcb);
--
-+      if (gc)
-+              nft_trans_gc_queue_async_done(gc);
-+done:
-       queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
-                          nft_set_gc_interval(set));
- }
diff --git a/queue-5.15/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch b/queue-5.15/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
deleted file mode 100644 (file)
index acb5302..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From c92db3030492b8ad1d0faace7a93bbcf53850d0c Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 15:00:06 +0200
-Subject: netfilter: nft_set_hash: mark set element as dead when deleting from packet path
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit c92db3030492b8ad1d0faace7a93bbcf53850d0c upstream.
-
-Set on the NFT_SET_ELEM_DEAD_BIT flag on this element, instead of
-performing element removal which might race with an ongoing transaction.
-Enable gc when dynamic flag is set on since dynset deletion requires
-garbage collection after this patch.
-
-Fixes: d0a8d877da97 ("netfilter: nft_dynset: support for element deletion")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nft_set_hash.c |    6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -249,7 +249,9 @@ static bool nft_rhash_delete(const struc
-       if (he == NULL)
-               return false;
--      return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
-+      nft_set_elem_dead(&he->ext);
-+
-+      return true;
- }
- static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
-@@ -412,7 +414,7 @@ static int nft_rhash_init(const struct n
-               return err;
-       INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
--      if (set->flags & NFT_SET_TIMEOUT)
-+      if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
-               nft_rhash_gc_init(set);
-       return 0;
index c3c0b406aacabc8b9d2ce6e6d213504c0c70f0ef..4022f5e96d6cf1fee6822594c06feee1dba77470 100644 (file)
@@ -33,5 +33,3 @@ x86-speculation-add-cpu_show_gds-prototype.patch
 x86-move-gds_ucode_mitigated-declaration-to-header.patch
 drm-nouveau-disp-revert-a-null-check-inside-nouveau_connector_get_modes.patch
 netfilter-nf_tables-don-t-skip-expired-elements-during-walk.patch
-netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch
-netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
diff --git a/queue-5.4/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch b/queue-5.4/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
deleted file mode 100644 (file)
index 2845172..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From c92db3030492b8ad1d0faace7a93bbcf53850d0c Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 15:00:06 +0200
-Subject: netfilter: nft_set_hash: mark set element as dead when deleting from packet path
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit c92db3030492b8ad1d0faace7a93bbcf53850d0c upstream.
-
-Set on the NFT_SET_ELEM_DEAD_BIT flag on this element, instead of
-performing element removal which might race with an ongoing transaction.
-Enable gc when dynamic flag is set on since dynset deletion requires
-garbage collection after this patch.
-
-Fixes: d0a8d877da97 ("netfilter: nft_dynset: support for element deletion")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nft_set_hash.c |    6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -251,7 +251,9 @@ static bool nft_rhash_delete(const struc
-       if (he == NULL)
-               return false;
--      return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
-+      nft_set_elem_dead(&he->ext);
-+
-+      return true;
- }
- static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
-@@ -374,7 +376,7 @@ static int nft_rhash_init(const struct n
-               return err;
-       INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
--      if (set->flags & NFT_SET_TIMEOUT)
-+      if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
-               nft_rhash_gc_init(set);
-       return 0;
index 1ba7a75210fae6e573d13dbc2338be9401312564..62d1bd8f77b6339ca97a86f98724bfd7398bc29e 100644 (file)
@@ -14,4 +14,3 @@ x86-cpu-amd-enable-zenbleed-fix-for-amd-custom-apu-0405.patch
 x86-mm-fix-vdso-and-vvar-placement-on-5-level-paging-machines.patch
 x86-move-gds_ucode_mitigated-declaration-to-header.patch
 drm-nouveau-disp-revert-a-null-check-inside-nouveau_connector_get_modes.patch
-netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
diff --git a/queue-6.1/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch b/queue-6.1/netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch
deleted file mode 100644 (file)
index e5dfdab..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-From f6c383b8c31a93752a52697f8430a71dcbc46adf Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 14:54:23 +0200
-Subject: netfilter: nf_tables: adapt set backend to use GC transaction API
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit f6c383b8c31a93752a52697f8430a71dcbc46adf upstream.
-
-Use the GC transaction API to replace the old and buggy gc API and the
-busy mark approach.
-
-No set elements are removed from async garbage collection anymore,
-instead the _DEAD bit is set on so the set element is not visible from
-lookup path anymore. Async GC enqueues transaction work that might be
-aborted and retried later.
-
-rbtree and pipapo set backends does not set on the _DEAD bit from the
-sync GC path since this runs in control plane path where mutex is held.
-In this case, set elements are deactivated, removed and then released
-via RCU callback, sync GC never fails.
-
-Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges")
-Fixes: 8d8540c4f5e0 ("netfilter: nft_set_rbtree: add timeout support")
-Fixes: 9d0982927e79 ("netfilter: nft_hash: add support for timeouts")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nf_tables_api.c  |    7 -
- net/netfilter/nft_set_hash.c   |   77 +++++++++++++--------
- net/netfilter/nft_set_pipapo.c |   48 ++++++++++---
- net/netfilter/nft_set_rbtree.c |  146 ++++++++++++++++++++++++-----------------
- 4 files changed, 174 insertions(+), 104 deletions(-)
-
---- a/net/netfilter/nf_tables_api.c
-+++ b/net/netfilter/nf_tables_api.c
-@@ -6128,7 +6128,6 @@ static void nft_setelem_activate(struct
-       if (nft_setelem_is_catchall(set, elem)) {
-               nft_set_elem_change_active(net, set, ext);
--              nft_set_elem_clear_busy(ext);
-       } else {
-               set->ops->activate(net, set, elem);
-       }
-@@ -6143,8 +6142,7 @@ static int nft_setelem_catchall_deactiva
-       list_for_each_entry(catchall, &set->catchall_list, list) {
-               ext = nft_set_elem_ext(set, catchall->elem);
--              if (!nft_is_active(net, ext) ||
--                  nft_set_elem_mark_busy(ext))
-+              if (!nft_is_active(net, ext))
-                       continue;
-               kfree(elem->priv);
-@@ -6847,8 +6845,7 @@ static int nft_set_catchall_flush(const
-       list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
-               ext = nft_set_elem_ext(set, catchall->elem);
--              if (!nft_set_elem_active(ext, genmask) ||
--                  nft_set_elem_mark_busy(ext))
-+              if (!nft_set_elem_active(ext, genmask))
-                       continue;
-               elem.priv = catchall->elem;
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -59,6 +59,8 @@ static inline int nft_rhash_cmp(struct r
-       if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
-               return 1;
-+      if (nft_set_elem_is_dead(&he->ext))
-+              return 1;
-       if (nft_set_elem_expired(&he->ext))
-               return 1;
-       if (!nft_set_elem_active(&he->ext, x->genmask))
-@@ -188,7 +190,6 @@ static void nft_rhash_activate(const str
-       struct nft_rhash_elem *he = elem->priv;
-       nft_set_elem_change_active(net, set, &he->ext);
--      nft_set_elem_clear_busy(&he->ext);
- }
- static bool nft_rhash_flush(const struct net *net,
-@@ -196,12 +197,9 @@ static bool nft_rhash_flush(const struct
- {
-       struct nft_rhash_elem *he = priv;
--      if (!nft_set_elem_mark_busy(&he->ext) ||
--          !nft_is_active(net, &he->ext)) {
--              nft_set_elem_change_active(net, set, &he->ext);
--              return true;
--      }
--      return false;
-+      nft_set_elem_change_active(net, set, &he->ext);
-+
-+      return true;
- }
- static void *nft_rhash_deactivate(const struct net *net,
-@@ -218,9 +216,8 @@ static void *nft_rhash_deactivate(const
-       rcu_read_lock();
-       he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
--      if (he != NULL &&
--          !nft_rhash_flush(net, set, he))
--              he = NULL;
-+      if (he)
-+              nft_set_elem_change_active(net, set, &he->ext);
-       rcu_read_unlock();
-@@ -312,25 +309,48 @@ static bool nft_rhash_expr_needs_gc_run(
- static void nft_rhash_gc(struct work_struct *work)
- {
-+      struct nftables_pernet *nft_net;
-       struct nft_set *set;
-       struct nft_rhash_elem *he;
-       struct nft_rhash *priv;
--      struct nft_set_gc_batch *gcb = NULL;
-       struct rhashtable_iter hti;
-+      struct nft_trans_gc *gc;
-+      struct net *net;
-+      u32 gc_seq;
-       priv = container_of(work, struct nft_rhash, gc_work.work);
-       set  = nft_set_container_of(priv);
-+      net  = read_pnet(&set->net);
-+      nft_net = nft_pernet(net);
-+      gc_seq = READ_ONCE(nft_net->gc_seq);
-+
-+      gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
-+      if (!gc)
-+              goto done;
-       rhashtable_walk_enter(&priv->ht, &hti);
-       rhashtable_walk_start(&hti);
-       while ((he = rhashtable_walk_next(&hti))) {
-               if (IS_ERR(he)) {
--                      if (PTR_ERR(he) != -EAGAIN)
--                              break;
-+                      if (PTR_ERR(he) != -EAGAIN) {
-+                              nft_trans_gc_destroy(gc);
-+                              gc = NULL;
-+                              goto try_later;
-+                      }
-                       continue;
-               }
-+              /* Ruleset has been updated, try later. */
-+              if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
-+                      nft_trans_gc_destroy(gc);
-+                      gc = NULL;
-+                      goto try_later;
-+              }
-+
-+              if (nft_set_elem_is_dead(&he->ext))
-+                      goto dead_elem;
-+
-               if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) &&
-                   nft_rhash_expr_needs_gc_run(set, &he->ext))
-                       goto needs_gc_run;
-@@ -338,26 +358,26 @@ static void nft_rhash_gc(struct work_str
-               if (!nft_set_elem_expired(&he->ext))
-                       continue;
- needs_gc_run:
--              if (nft_set_elem_mark_busy(&he->ext))
--                      continue;
-+              nft_set_elem_dead(&he->ext);
-+dead_elem:
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb == NULL)
--                      break;
--              rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, he);
-+              nft_trans_gc_elem_add(gc, he);
-       }
-+
-+      gc = nft_trans_gc_catchall(gc, gc_seq);
-+
-+try_later:
-+      /* catchall list iteration requires rcu read side lock. */
-       rhashtable_walk_stop(&hti);
-       rhashtable_walk_exit(&hti);
--      he = nft_set_catchall_gc(set);
--      if (he) {
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb)
--                      nft_set_gc_batch_add(gcb, he);
--      }
--      nft_set_gc_batch_complete(gcb);
-+      if (gc)
-+              nft_trans_gc_queue_async_done(gc);
-+
-+done:
-       queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
-                          nft_set_gc_interval(set));
- }
-@@ -420,7 +440,6 @@ static void nft_rhash_destroy(const stru
-       };
-       cancel_delayed_work_sync(&priv->gc_work);
--      rcu_barrier();
-       rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
-                                   (void *)&rhash_ctx);
- }
---- a/net/netfilter/nft_set_pipapo.c
-+++ b/net/netfilter/nft_set_pipapo.c
-@@ -1537,16 +1537,34 @@ static void pipapo_drop(struct nft_pipap
-       }
- }
-+static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set,
-+                                   struct nft_pipapo_elem *e)
-+
-+{
-+      struct nft_set_elem elem = {
-+              .priv   = e,
-+      };
-+
-+      nft_setelem_data_deactivate(net, set, &elem);
-+}
-+
- /**
-  * pipapo_gc() - Drop expired entries from set, destroy start and end elements
-  * @set:      nftables API set representation
-  * @m:                Matching data
-  */
--static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
-+static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m)
- {
-+      struct nft_set *set = (struct nft_set *) _set;
-       struct nft_pipapo *priv = nft_set_priv(set);
-+      struct net *net = read_pnet(&set->net);
-       int rules_f0, first_rule = 0;
-       struct nft_pipapo_elem *e;
-+      struct nft_trans_gc *gc;
-+
-+      gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL);
-+      if (!gc)
-+              return;
-       while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
-               union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
-@@ -1570,13 +1588,20 @@ static void pipapo_gc(const struct nft_s
-               f--;
-               i--;
-               e = f->mt[rulemap[i].to].e;
--              if (nft_set_elem_expired(&e->ext) &&
--                  !nft_set_elem_mark_busy(&e->ext)) {
-+
-+              /* synchronous gc never fails, there is no need to set on
-+               * NFT_SET_ELEM_DEAD_BIT.
-+               */
-+              if (nft_set_elem_expired(&e->ext)) {
-                       priv->dirty = true;
--                      pipapo_drop(m, rulemap);
--                      rcu_barrier();
--                      nft_set_elem_destroy(set, e, true);
-+                      gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+                      if (!gc)
-+                              break;
-+
-+                      nft_pipapo_gc_deactivate(net, set, e);
-+                      pipapo_drop(m, rulemap);
-+                      nft_trans_gc_elem_add(gc, e);
-                       /* And check again current first rule, which is now the
-                        * first we haven't checked.
-@@ -1586,11 +1611,11 @@ static void pipapo_gc(const struct nft_s
-               }
-       }
--      e = nft_set_catchall_gc(set);
--      if (e)
--              nft_set_elem_destroy(set, e, true);
--
--      priv->last_gc = jiffies;
-+      gc = nft_trans_gc_catchall(gc, 0);
-+      if (gc) {
-+              nft_trans_gc_queue_sync_done(gc);
-+              priv->last_gc = jiffies;
-+      }
- }
- /**
-@@ -1715,7 +1740,6 @@ static void nft_pipapo_activate(const st
-               return;
-       nft_set_elem_change_active(net, set, &e->ext);
--      nft_set_elem_clear_busy(&e->ext);
- }
- /**
---- a/net/netfilter/nft_set_rbtree.c
-+++ b/net/netfilter/nft_set_rbtree.c
-@@ -46,6 +46,12 @@ static int nft_rbtree_cmp(const struct n
-                     set->klen);
- }
-+static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe)
-+{
-+      return nft_set_elem_expired(&rbe->ext) ||
-+             nft_set_elem_is_dead(&rbe->ext);
-+}
-+
- static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
-                               const u32 *key, const struct nft_set_ext **ext,
-                               unsigned int seq)
-@@ -80,7 +86,7 @@ static bool __nft_rbtree_lookup(const st
-                               continue;
-                       }
--                      if (nft_set_elem_expired(&rbe->ext))
-+                      if (nft_rbtree_elem_expired(rbe))
-                               return false;
-                       if (nft_rbtree_interval_end(rbe)) {
-@@ -98,7 +104,7 @@ static bool __nft_rbtree_lookup(const st
-       if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
-           nft_set_elem_active(&interval->ext, genmask) &&
--          !nft_set_elem_expired(&interval->ext) &&
-+          !nft_rbtree_elem_expired(interval) &&
-           nft_rbtree_interval_start(interval)) {
-               *ext = &interval->ext;
-               return true;
-@@ -215,6 +221,18 @@ static void *nft_rbtree_get(const struct
-       return rbe;
- }
-+static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
-+                               struct nft_rbtree *priv,
-+                               struct nft_rbtree_elem *rbe)
-+{
-+      struct nft_set_elem elem = {
-+              .priv   = rbe,
-+      };
-+
-+      nft_setelem_data_deactivate(net, set, &elem);
-+      rb_erase(&rbe->node, &priv->root);
-+}
-+
- static int nft_rbtree_gc_elem(const struct nft_set *__set,
-                             struct nft_rbtree *priv,
-                             struct nft_rbtree_elem *rbe,
-@@ -222,11 +240,12 @@ static int nft_rbtree_gc_elem(const stru
- {
-       struct nft_set *set = (struct nft_set *)__set;
-       struct rb_node *prev = rb_prev(&rbe->node);
-+      struct net *net = read_pnet(&set->net);
-       struct nft_rbtree_elem *rbe_prev;
--      struct nft_set_gc_batch *gcb;
-+      struct nft_trans_gc *gc;
--      gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC);
--      if (!gcb)
-+      gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
-+      if (!gc)
-               return -ENOMEM;
-       /* search for end interval coming before this element.
-@@ -244,17 +263,28 @@ static int nft_rbtree_gc_elem(const stru
-       if (prev) {
-               rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
-+              nft_rbtree_gc_remove(net, set, priv, rbe_prev);
--              rb_erase(&rbe_prev->node, &priv->root);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, rbe_prev);
-+              /* There is always room in this trans gc for this element,
-+               * memory allocation never actually happens, hence, the warning
-+               * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT,
-+               * this is synchronous gc which never fails.
-+               */
-+              gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+              if (WARN_ON_ONCE(!gc))
-+                      return -ENOMEM;
-+
-+              nft_trans_gc_elem_add(gc, rbe_prev);
-       }
--      rb_erase(&rbe->node, &priv->root);
--      atomic_dec(&set->nelems);
-+      nft_rbtree_gc_remove(net, set, priv, rbe);
-+      gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
-+      if (WARN_ON_ONCE(!gc))
-+              return -ENOMEM;
--      nft_set_gc_batch_add(gcb, rbe);
--      nft_set_gc_batch_complete(gcb);
-+      nft_trans_gc_elem_add(gc, rbe);
-+
-+      nft_trans_gc_queue_sync_done(gc);
-       return 0;
- }
-@@ -482,7 +512,6 @@ static void nft_rbtree_activate(const st
-       struct nft_rbtree_elem *rbe = elem->priv;
-       nft_set_elem_change_active(net, set, &rbe->ext);
--      nft_set_elem_clear_busy(&rbe->ext);
- }
- static bool nft_rbtree_flush(const struct net *net,
-@@ -490,12 +519,9 @@ static bool nft_rbtree_flush(const struc
- {
-       struct nft_rbtree_elem *rbe = priv;
--      if (!nft_set_elem_mark_busy(&rbe->ext) ||
--          !nft_is_active(net, &rbe->ext)) {
--              nft_set_elem_change_active(net, set, &rbe->ext);
--              return true;
--      }
--      return false;
-+      nft_set_elem_change_active(net, set, &rbe->ext);
-+
-+      return true;
- }
- static void *nft_rbtree_deactivate(const struct net *net,
-@@ -570,26 +596,40 @@ cont:
- static void nft_rbtree_gc(struct work_struct *work)
- {
--      struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL;
--      struct nft_set_gc_batch *gcb = NULL;
-+      struct nft_rbtree_elem *rbe, *rbe_end = NULL;
-+      struct nftables_pernet *nft_net;
-       struct nft_rbtree *priv;
-+      struct nft_trans_gc *gc;
-       struct rb_node *node;
-       struct nft_set *set;
-+      unsigned int gc_seq;
-       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);
-+      nft_net = nft_pernet(net);
-+      gc_seq  = READ_ONCE(nft_net->gc_seq);
-+
-+      gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
-+      if (!gc)
-+              goto done;
-       write_lock_bh(&priv->lock);
-       write_seqcount_begin(&priv->count);
-       for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
-+
-+              /* Ruleset has been updated, try later. */
-+              if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
-+                      nft_trans_gc_destroy(gc);
-+                      gc = NULL;
-+                      goto try_later;
-+              }
-+
-               rbe = rb_entry(node, struct nft_rbtree_elem, node);
--              if (!nft_set_elem_active(&rbe->ext, genmask))
--                      continue;
-+              if (nft_set_elem_is_dead(&rbe->ext))
-+                      goto dead_elem;
-               /* elements are reversed in the rbtree for historical reasons,
-                * from highest to lowest value, that is why end element is
-@@ -602,46 +642,36 @@ static void nft_rbtree_gc(struct work_st
-               if (!nft_set_elem_expired(&rbe->ext))
-                       continue;
--              if (nft_set_elem_mark_busy(&rbe->ext)) {
--                      rbe_end = NULL;
-+              nft_set_elem_dead(&rbe->ext);
-+
-+              if (!rbe_end)
-                       continue;
--              }
--              if (rbe_prev) {
--                      rb_erase(&rbe_prev->node, &priv->root);
--                      rbe_prev = NULL;
--              }
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (!gcb)
--                      break;
-+              nft_set_elem_dead(&rbe_end->ext);
--              atomic_dec(&set->nelems);
--              nft_set_gc_batch_add(gcb, rbe);
--              rbe_prev = rbe;
--
--              if (rbe_end) {
--                      atomic_dec(&set->nelems);
--                      nft_set_gc_batch_add(gcb, rbe_end);
--                      rb_erase(&rbe_end->node, &priv->root);
--                      rbe_end = NULL;
--              }
--              node = rb_next(node);
--              if (!node)
--                      break;
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
-+
-+              nft_trans_gc_elem_add(gc, rbe_end);
-+              rbe_end = NULL;
-+dead_elem:
-+              gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
-+              if (!gc)
-+                      goto try_later;
-+
-+              nft_trans_gc_elem_add(gc, rbe);
-       }
--      if (rbe_prev)
--              rb_erase(&rbe_prev->node, &priv->root);
-+
-+      gc = nft_trans_gc_catchall(gc, gc_seq);
-+
-+try_later:
-       write_seqcount_end(&priv->count);
-       write_unlock_bh(&priv->lock);
--      rbe = nft_set_catchall_gc(set);
--      if (rbe) {
--              gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
--              if (gcb)
--                      nft_set_gc_batch_add(gcb, rbe);
--      }
--      nft_set_gc_batch_complete(gcb);
--
-+      if (gc)
-+              nft_trans_gc_queue_async_done(gc);
-+done:
-       queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
-                          nft_set_gc_interval(set));
- }
diff --git a/queue-6.1/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch b/queue-6.1/netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
deleted file mode 100644 (file)
index acb5302..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-From c92db3030492b8ad1d0faace7a93bbcf53850d0c Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Wed, 9 Aug 2023 15:00:06 +0200
-Subject: netfilter: nft_set_hash: mark set element as dead when deleting from packet path
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-commit c92db3030492b8ad1d0faace7a93bbcf53850d0c upstream.
-
-Set on the NFT_SET_ELEM_DEAD_BIT flag on this element, instead of
-performing element removal which might race with an ongoing transaction.
-Enable gc when dynamic flag is set on since dynset deletion requires
-garbage collection after this patch.
-
-Fixes: d0a8d877da97 ("netfilter: nft_dynset: support for element deletion")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/netfilter/nft_set_hash.c |    6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/net/netfilter/nft_set_hash.c
-+++ b/net/netfilter/nft_set_hash.c
-@@ -249,7 +249,9 @@ static bool nft_rhash_delete(const struc
-       if (he == NULL)
-               return false;
--      return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
-+      nft_set_elem_dead(&he->ext);
-+
-+      return true;
- }
- static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
-@@ -412,7 +414,7 @@ static int nft_rhash_init(const struct n
-               return err;
-       INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
--      if (set->flags & NFT_SET_TIMEOUT)
-+      if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
-               nft_rhash_gc_init(set);
-       return 0;
index 621f4c67e03da8189504a38fadb322e0511ad3a2..05c283b393f6cdf72b5c6a32cbc88576850dc09e 100644 (file)
@@ -69,6 +69,4 @@ x86-speculation-add-cpu_show_gds-prototype.patch
 x86-move-gds_ucode_mitigated-declaration-to-header.patch
 drm-nouveau-disp-revert-a-null-check-inside-nouveau_connector_get_modes.patch
 netfilter-nf_tables-don-t-skip-expired-elements-during-walk.patch
-netfilter-nf_tables-adapt-set-backend-to-use-gc-transaction-api.patch
-netfilter-nft_set_hash-mark-set-element-as-dead-when-deleting-from-packet-path.patch
 iio-core-prevent-invalid-memory-access-when-there-is-no-parent.patch