netfilter: nf_tables: skip netdev hook unregistration if table is dormant
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 21 Mar 2024 00:28:07 +0000 (01:28 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 28 Mar 2024 02:54:01 +0000 (03:54 +0100)
Skip hook unregistration when adding or deleting devices from an
existing netdev basechain. Otherwise, commit/abort path try to
unregister hooks which not enabled.

Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
Fixes: 7d937b107108 ("netfilter: nf_tables: support for deleting devices in an existing netdev chain")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c

index 086d85fffeb1529e6b73364bfb49fef58ebb4b88..fd86f2720c9e776b08db64c6f1083a425c289754 100644 (file)
@@ -10212,9 +10212,11 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                        if (nft_trans_chain_update(trans)) {
                                nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN,
                                                       &nft_trans_chain_hooks(trans));
-                               nft_netdev_unregister_hooks(net,
-                                                           &nft_trans_chain_hooks(trans),
-                                                           true);
+                               if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT)) {
+                                       nft_netdev_unregister_hooks(net,
+                                                                   &nft_trans_chain_hooks(trans),
+                                                                   true);
+                               }
                        } else {
                                nft_chain_del(trans->ctx.chain);
                                nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN,
@@ -10490,9 +10492,11 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
                        break;
                case NFT_MSG_NEWCHAIN:
                        if (nft_trans_chain_update(trans)) {
-                               nft_netdev_unregister_hooks(net,
-                                                           &nft_trans_chain_hooks(trans),
-                                                           true);
+                               if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT)) {
+                                       nft_netdev_unregister_hooks(net,
+                                                                   &nft_trans_chain_hooks(trans),
+                                                                   true);
+                               }
                                free_percpu(nft_trans_chain_stats(trans));
                                kfree(nft_trans_chain_name(trans));
                                nft_trans_destroy(trans);