]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nf_tables: bogus EBUSY when deleting flowtable after flush
authorPablo Neira Ayuso <pablo@netfilter.org>
Sat, 12 Aug 2023 22:09:02 +0000 (00:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Aug 2023 16:13:01 +0000 (18:13 +0200)
From: Laura Garcia Liebana <nevola@gmail.com>

commit 9b05b6e11d5e93a3a517cadc12b9836e0470c255 upstream.

The deletion of a flowtable after a flush in the same transaction
results in EBUSY. This patch adds an activation and deactivation of
flowtables in order to update the _use_ counter.

Signed-off-by: Laura Garcia Liebana <nevola@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c
net/netfilter/nft_flow_offload.c

index 4719440873723e395aa414782890dd639a7ef521..d3763bbd3a0f2bcf198b62549199496543448228 100644 (file)
@@ -1161,6 +1161,10 @@ struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
                                           const struct nlattr *nla,
                                           u8 genmask);
 
+void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
+                                   struct nft_flowtable *flowtable,
+                                   enum nft_trans_phase phase);
+
 void nft_register_flowtable_type(struct nf_flowtable_type *type);
 void nft_unregister_flowtable_type(struct nf_flowtable_type *type);
 
index 115bc79ec9055320313a6e9fefa9883040549376..c6d285329bcfccd2774a49f14ec39211fe57affa 100644 (file)
@@ -5519,6 +5519,22 @@ struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
 }
 EXPORT_SYMBOL_GPL(nft_flowtable_lookup);
 
+void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
+                                   struct nft_flowtable *flowtable,
+                                   enum nft_trans_phase phase)
+{
+       switch (phase) {
+       case NFT_TRANS_PREPARE:
+       case NFT_TRANS_ABORT:
+       case NFT_TRANS_RELEASE:
+               flowtable->use--;
+               /* fall through */
+       default:
+               return;
+       }
+}
+EXPORT_SYMBOL_GPL(nf_tables_deactivate_flowtable);
+
 static struct nft_flowtable *
 nft_flowtable_lookup_byhandle(const struct nft_table *table,
                              const struct nlattr *nla, u8 genmask)
index 166edea0e45273b91d8a6cd6298c685de285bf86..c78f7bd4c1dbb9910f70502fa6fa8cf294b92254 100644 (file)
@@ -175,6 +175,23 @@ static int nft_flow_offload_init(const struct nft_ctx *ctx,
        return nf_ct_netns_get(ctx->net, ctx->family);
 }
 
+static void nft_flow_offload_deactivate(const struct nft_ctx *ctx,
+                                       const struct nft_expr *expr,
+                                       enum nft_trans_phase phase)
+{
+       struct nft_flow_offload *priv = nft_expr_priv(expr);
+
+       nf_tables_deactivate_flowtable(ctx, priv->flowtable, phase);
+}
+
+static void nft_flow_offload_activate(const struct nft_ctx *ctx,
+                                     const struct nft_expr *expr)
+{
+       struct nft_flow_offload *priv = nft_expr_priv(expr);
+
+       priv->flowtable->use++;
+}
+
 static void nft_flow_offload_destroy(const struct nft_ctx *ctx,
                                     const struct nft_expr *expr)
 {
@@ -203,6 +220,8 @@ static const struct nft_expr_ops nft_flow_offload_ops = {
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_flow_offload)),
        .eval           = nft_flow_offload_eval,
        .init           = nft_flow_offload_init,
+       .activate       = nft_flow_offload_activate,
+       .deactivate     = nft_flow_offload_deactivate,
        .destroy        = nft_flow_offload_destroy,
        .validate       = nft_flow_offload_validate,
        .dump           = nft_flow_offload_dump,