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 06/20] netfilter: nf_tables: make validation state per table
Date: Sat, 22 Apr 2023 01:01:57 +0200	[thread overview]
Message-ID: <20230421230211.214635-7-pablo@netfilter.org> (raw)
In-Reply-To: <20230421230211.214635-1-pablo@netfilter.org>

From: Florian Westphal <fw@strlen.de>

We only need to validate tables that saw changes in the current
transaction.

The existing code revalidates all tables, but this isn't needed as
cross-table jumps are not allowed (chains have table scope).

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h |  3 ++-
 net/netfilter/nf_tables_api.c     | 38 +++++++++++++++----------------
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f476fd030626..ec347d9cff9e 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1209,6 +1209,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
  *	@genmask: generation mask
  *	@afinfo: address family info
  *	@name: name of the table
+ *	@validate_state: internal, set when transaction adds jumps
  */
 struct nft_table {
 	struct list_head		list;
@@ -1227,6 +1228,7 @@ struct nft_table {
 	char				*name;
 	u16				udlen;
 	u8				*udata;
+	u8				validate_state;
 };
 
 static inline bool nft_table_has_owner(const struct nft_table *table)
@@ -1698,7 +1700,6 @@ struct nftables_pernet {
 	struct mutex		commit_mutex;
 	u64			table_handle;
 	unsigned int		base_seq;
-	u8			validate_state;
 };
 
 extern unsigned int nf_tables_net_id;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 21eb273d2740..44ebc5f9598e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -102,11 +102,9 @@ static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
 	[NFT_MSG_DELFLOWTABLE]	= AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
 };
 
-static void nft_validate_state_update(struct net *net, u8 new_validate_state)
+static void nft_validate_state_update(struct nft_table *table, u8 new_validate_state)
 {
-	struct nftables_pernet *nft_net = nft_pernet(net);
-
-	switch (nft_net->validate_state) {
+	switch (table->validate_state) {
 	case NFT_VALIDATE_SKIP:
 		WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
 		break;
@@ -117,7 +115,7 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state)
 			return;
 	}
 
-	nft_net->validate_state = new_validate_state;
+	table->validate_state = new_validate_state;
 }
 static void nf_tables_trans_destroy_work(struct work_struct *w);
 static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
@@ -1224,6 +1222,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
 	if (table == NULL)
 		goto err_kzalloc;
 
+	table->validate_state = NFT_VALIDATE_SKIP;
 	table->name = nla_strdup(attr, GFP_KERNEL_ACCOUNT);
 	if (table->name == NULL)
 		goto err_strdup;
@@ -3660,7 +3659,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 		}
 
 		if (expr_info[i].ops->validate)
-			nft_validate_state_update(net, NFT_VALIDATE_NEED);
+			nft_validate_state_update(table, NFT_VALIDATE_NEED);
 
 		expr_info[i].ops = NULL;
 		expr = nft_expr_next(expr);
@@ -3710,7 +3709,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 	if (flow)
 		nft_trans_flow_rule(trans) = flow;
 
-	if (nft_net->validate_state == NFT_VALIDATE_DO)
+	if (table->validate_state == NFT_VALIDATE_DO)
 		return nft_table_validate(net, table);
 
 	return 0;
@@ -6312,7 +6311,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 			if (desc.type == NFT_DATA_VERDICT &&
 			    (elem.data.val.verdict.code == NFT_GOTO ||
 			     elem.data.val.verdict.code == NFT_JUMP))
-				nft_validate_state_update(ctx->net,
+				nft_validate_state_update(ctx->table,
 							  NFT_VALIDATE_NEED);
 		}
 
@@ -6437,7 +6436,6 @@ static int nf_tables_newsetelem(struct sk_buff *skb,
 				const struct nfnl_info *info,
 				const struct nlattr * const nla[])
 {
-	struct nftables_pernet *nft_net = nft_pernet(info->net);
 	struct netlink_ext_ack *extack = info->extack;
 	u8 genmask = nft_genmask_next(info->net);
 	u8 family = info->nfmsg->nfgen_family;
@@ -6476,7 +6474,7 @@ static int nf_tables_newsetelem(struct sk_buff *skb,
 		}
 	}
 
-	if (nft_net->validate_state == NFT_VALIDATE_DO)
+	if (table->validate_state == NFT_VALIDATE_DO)
 		return nft_table_validate(net, table);
 
 	return 0;
@@ -8628,19 +8626,20 @@ static int nf_tables_validate(struct net *net)
 	struct nftables_pernet *nft_net = nft_pernet(net);
 	struct nft_table *table;
 
-	switch (nft_net->validate_state) {
-	case NFT_VALIDATE_SKIP:
-		break;
-	case NFT_VALIDATE_NEED:
-		nft_validate_state_update(net, NFT_VALIDATE_DO);
-		fallthrough;
-	case NFT_VALIDATE_DO:
-		list_for_each_entry(table, &nft_net->tables, list) {
+	list_for_each_entry(table, &nft_net->tables, list) {
+		switch (table->validate_state) {
+		case NFT_VALIDATE_SKIP:
+			continue;
+		case NFT_VALIDATE_NEED:
+			nft_validate_state_update(table, NFT_VALIDATE_DO);
+			fallthrough;
+		case NFT_VALIDATE_DO:
 			if (nft_table_validate(net, table) < 0)
 				return -EAGAIN;
+
+			nft_validate_state_update(table, NFT_VALIDATE_SKIP);
 		}
 
-		nft_validate_state_update(net, NFT_VALIDATE_SKIP);
 		break;
 	}
 
@@ -10355,7 +10354,6 @@ static int __net_init nf_tables_init_net(struct net *net)
 	INIT_LIST_HEAD(&nft_net->notify_list);
 	mutex_init(&nft_net->commit_mutex);
 	nft_net->base_seq = 1;
-	nft_net->validate_state = NFT_VALIDATE_SKIP;
 
 	return 0;
 }
-- 
2.30.2


  parent reply	other threads:[~2023-04-21 23:02 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 ` Pablo Neira Ayuso [this message]
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 ` [PATCH net-next 19/20] netfilter: nf_tables: support for deleting devices in " Pablo Neira Ayuso
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-7-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.