All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org,
	pabeni@redhat.com, edumazet@google.com
Subject: [PATCH net-next 19/20] netfilter: nf_tables: support for deleting devices in an existing netdev chain
Date: Sat, 22 Apr 2023 01:02:10 +0200	[thread overview]
Message-ID: <20230421230211.214635-20-pablo@netfilter.org> (raw)
In-Reply-To: <20230421230211.214635-1-pablo@netfilter.org>

This patch allows for deleting devices in an existing netdev chain.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c | 99 +++++++++++++++++++++++++++++++----
 1 file changed, 88 insertions(+), 11 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index f8d8cace0c7d..c55ac3d57c51 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1646,7 +1646,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
 			 NFTA_CHAIN_PAD))
 		goto nla_put_failure;
 
-	if (event == NFT_MSG_DELCHAIN) {
+	if (event == NFT_MSG_DELCHAIN && !hook_list) {
 		nlmsg_end(skb, nlh);
 		return 0;
 	}
@@ -2667,6 +2667,59 @@ static int nf_tables_newchain(struct sk_buff *skb, const struct nfnl_info *info,
 	return nf_tables_addchain(&ctx, family, genmask, policy, flags, extack);
 }
 
+static int nft_delchain_hook(struct nft_ctx *ctx, struct nft_chain *chain,
+			     struct netlink_ext_ack *extack)
+{
+	const struct nlattr * const *nla = ctx->nla;
+	struct nft_chain_hook chain_hook = {};
+	struct nft_base_chain *basechain;
+	struct nft_hook *this, *hook;
+	LIST_HEAD(chain_del_list);
+	struct nft_trans *trans;
+	int err;
+
+	if (!nft_is_base_chain(chain))
+		return -EOPNOTSUPP;
+
+	basechain = nft_base_chain(chain);
+	err = nft_chain_parse_hook(ctx->net, basechain, nla, &chain_hook,
+				   ctx->family, extack);
+	if (err < 0)
+		return err;
+
+	list_for_each_entry(this, &chain_hook.list, list) {
+		hook = nft_hook_list_find(&basechain->hook_list, this);
+		if (!hook) {
+			err = -ENOENT;
+			goto err_chain_del_hook;
+		}
+		list_move(&hook->list, &chain_del_list);
+	}
+
+	trans = nft_trans_alloc(ctx, NFT_MSG_DELCHAIN,
+				sizeof(struct nft_trans_chain));
+	if (!trans) {
+		err = -ENOMEM;
+		goto err_chain_del_hook;
+	}
+
+	nft_trans_basechain(trans) = basechain;
+	nft_trans_chain_update(trans) = true;
+	INIT_LIST_HEAD(&nft_trans_chain_hooks(trans));
+	list_splice(&chain_del_list, &nft_trans_chain_hooks(trans));
+	nft_chain_release_hook(&chain_hook);
+
+	nft_trans_commit_list_add_tail(ctx->net, trans);
+
+	return 0;
+
+err_chain_del_hook:
+	list_splice(&chain_del_list, &basechain->hook_list);
+	nft_chain_release_hook(&chain_hook);
+
+	return err;
+}
+
 static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info,
 			      const struct nlattr * const nla[])
 {
@@ -2707,12 +2760,19 @@ static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info,
 		return PTR_ERR(chain);
 	}
 
+	nft_ctx_init(&ctx, net, skb, info->nlh, family, table, chain, nla);
+
+	if (nla[NFTA_CHAIN_HOOK]) {
+		if (chain->flags & NFT_CHAIN_HW_OFFLOAD)
+			return -EOPNOTSUPP;
+
+		return nft_delchain_hook(&ctx, chain, extack);
+	}
+
 	if (info->nlh->nlmsg_flags & NLM_F_NONREC &&
 	    chain->use > 0)
 		return -EBUSY;
 
-	nft_ctx_init(&ctx, net, skb, info->nlh, family, table, chain, nla);
-
 	use = chain->use;
 	list_for_each_entry(rule, &chain->rules, list) {
 		if (!nft_is_active_next(net, rule))
@@ -8812,7 +8872,10 @@ static void nft_commit_release(struct nft_trans *trans)
 		break;
 	case NFT_MSG_DELCHAIN:
 	case NFT_MSG_DESTROYCHAIN:
-		nf_tables_chain_destroy(&trans->ctx);
+		if (nft_trans_chain_update(trans))
+			nft_hooks_destroy(&nft_trans_chain_hooks(trans));
+		else
+			nf_tables_chain_destroy(&trans->ctx);
 		break;
 	case NFT_MSG_DELRULE:
 	case NFT_MSG_DESTROYRULE:
@@ -9304,11 +9367,20 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 			break;
 		case NFT_MSG_DELCHAIN:
 		case NFT_MSG_DESTROYCHAIN:
-			nft_chain_del(trans->ctx.chain);
-			nf_tables_chain_notify(&trans->ctx, trans->msg_type, NULL);
-			nf_tables_unregister_hook(trans->ctx.net,
-						  trans->ctx.table,
-						  trans->ctx.chain);
+			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);
+			} else {
+				nft_chain_del(trans->ctx.chain);
+				nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN,
+						       NULL);
+				nf_tables_unregister_hook(trans->ctx.net,
+							  trans->ctx.table,
+							  trans->ctx.chain);
+			}
 			break;
 		case NFT_MSG_NEWRULE:
 			nft_clear(trans->ctx.net, nft_trans_rule(trans));
@@ -9558,8 +9630,13 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
 			break;
 		case NFT_MSG_DELCHAIN:
 		case NFT_MSG_DESTROYCHAIN:
-			trans->ctx.table->use++;
-			nft_clear(trans->ctx.net, trans->ctx.chain);
+			if (nft_trans_chain_update(trans)) {
+				list_splice(&nft_trans_chain_hooks(trans),
+					    &nft_trans_basechain(trans)->hook_list);
+			} else {
+				trans->ctx.table->use++;
+				nft_clear(trans->ctx.net, trans->ctx.chain);
+			}
 			nft_trans_destroy(trans);
 			break;
 		case NFT_MSG_NEWRULE:
-- 
2.30.2


  parent reply	other threads:[~2023-04-21 23:03 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-21 23:01 [PATCH net-next 00/20] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 01/20] netfilter: nft_exthdr: add boolean DCCP option matching Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 02/20] netfilter: nf_tables: merge nft_rules_old structure and end of ruleblob marker Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 03/20] netfilter: nf_tables: don't store address of last rule on jump Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 04/20] netfilter: nf_tables: don't store chain address " Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 05/20] netfilter: nf_tables: don't write table validation state without mutex Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 06/20] netfilter: nf_tables: make validation state per table Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 07/20] netfilter: nf_tables: remove unneeded conditional Pablo Neira Ayuso
2023-04-21 23:01 ` [PATCH net-next 08/20] netfilter: nf_tables: do not store pktinfo in traceinfo structure Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 09/20] netfilter: nf_tables: do not store verdict " Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 10/20] netfilter: nf_tables: do not store rule " Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 11/20] ipvs: Update width of source for ip_vs_sync_conn_options Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 12/20] ipvs: Consistently use array_size() in ip_vs_conn_init() Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 13/20] ipvs: Remove {Enter,Leave}Function Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 14/20] ipvs: Correct spelling in comments Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 15/20] netfilter: nf_tables: extended netlink error reporting for netdevice Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 16/20] netfilter: nf_tables: do not send complete notification of deletions Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 17/20] netfilter: nf_tables: rename function to destroy hook list Pablo Neira Ayuso
2023-04-21 23:02 ` [PATCH net-next 18/20] netfilter: nf_tables: support for adding new devices to an existing netdev chain Pablo Neira Ayuso
2023-04-21 23:02 ` Pablo Neira Ayuso [this message]
2023-04-21 23:02 ` [PATCH net-next 20/20] netfilter: nf_tables: allow to create netdev chain without device Pablo Neira Ayuso
2023-04-21 23:40 ` [PATCH net-next 00/20] Netfilter/IPVS updates for net-next Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230421230211.214635-20-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.