netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft] cmd: check for table mismatch first in error reporting
@ 2021-06-08 13:00 Pablo Neira Ayuso
  2021-06-08 13:00 ` [PATCH nft] netlink: quick sort array of devices Pablo Neira Ayuso
  0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-06-08 13:00 UTC (permalink / raw)
  To: netfilter-devel

If the fuzzy lookup provides a table, check if it is an inexact
matching, in that case, report that the table does not exist and provide
a mispelling suggestion for the non-existing table.

Initialize table to NULL since the fuzzy lookup might return no table
at all.

This patch fixes misleading error reporting:

 # nft delete chain xxx yyy
 Error: No such file or directory; did you mean chain ‘B’ in table ip ‘A’?
 delete chain xxx yyy
              ^^^

This refers to table 'xxx' but the suggestion refers to the chain instead.

Therefore, if the fuzzy lookup provides an exact matching table, then do
the fuzzy lookup for the next non-existing object (either chain, set,
...).

Fixes: 3a0e07106f66 ("src: combine extended netlink error reporting with mispelling support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/cmd.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 14 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c
index a647130ec8b4..a69767c551fe 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -27,16 +27,38 @@ static int nft_cmd_enoent_table(struct netlink_ctx *ctx, const struct cmd *cmd,
 	return 1;
 }
 
+static int table_fuzzy_check(struct netlink_ctx *ctx, const struct cmd *cmd,
+			     const struct table *table,
+			     const struct location *loc)
+{
+	if (strcmp(cmd->handle.table.name, table->handle.table.name) ||
+	    cmd->handle.family != table->handle.family) {
+		netlink_io_error(ctx, loc, "%s; did you mean table ‘%s’ in family %s?",
+				 strerror(ENOENT), table->handle.table.name,
+				 family2str(table->handle.family));
+		return 1;
+	}
+
+	return 0;
+}
+
 static int nft_cmd_enoent_chain(struct netlink_ctx *ctx, const struct cmd *cmd,
 				const struct location *loc)
 {
-	const struct table *table;
+	const struct table *table = NULL;
 	struct chain *chain;
 
 	if (!cmd->handle.chain.name)
 		return 0;
 
 	chain = chain_lookup_fuzzy(&cmd->handle, &ctx->nft->cache, &table);
+	/* check table first. */
+	if (!table)
+		return 0;
+
+	if (table_fuzzy_check(ctx, cmd, table, loc))
+		return 1;
+
 	if (!chain)
 		return 0;
 
@@ -52,24 +74,24 @@ static int nft_cmd_enoent_rule(struct netlink_ctx *ctx, const struct cmd *cmd,
 {
 	unsigned int flags = NFT_CACHE_TABLE |
 			     NFT_CACHE_CHAIN;
-	const struct table *table;
+	const struct table *table = NULL;
 	struct chain *chain;
 
 	if (nft_cache_update(ctx->nft, flags, ctx->msgs) < 0)
 		return 0;
 
-	table = table_lookup_fuzzy(&cmd->handle, &ctx->nft->cache);
-	if (table && strcmp(cmd->handle.table.name, table->handle.table.name)) {
-		netlink_io_error(ctx, loc, "%s; did you mean table ‘%s’ in family %s?",
-				 strerror(ENOENT), table->handle.table.name,
-				 family2str(table->handle.family));
+	chain = chain_lookup_fuzzy(&cmd->handle, &ctx->nft->cache, &table);
+	/* check table first. */
+	if (!table)
+		return 0;
+
+	if (table_fuzzy_check(ctx, cmd, table, loc))
 		return 1;
-	} else if (!table) {
+
+	if (!chain)
 		return 0;
-	}
 
-	chain = chain_lookup_fuzzy(&cmd->handle, &ctx->nft->cache, &table);
-	if (chain && strcmp(cmd->handle.chain.name, chain->handle.chain.name)) {
+	if (strcmp(cmd->handle.chain.name, chain->handle.chain.name)) {
 		netlink_io_error(ctx, loc, "%s; did you mean chain ‘%s’ in table %s ‘%s’?",
 				 strerror(ENOENT),
 				 chain->handle.chain.name,
@@ -84,13 +106,20 @@ static int nft_cmd_enoent_rule(struct netlink_ctx *ctx, const struct cmd *cmd,
 static int nft_cmd_enoent_set(struct netlink_ctx *ctx, const struct cmd *cmd,
 			      const struct location *loc)
 {
-	const struct table *table;
+	const struct table *table = NULL;
 	struct set *set;
 
 	if (!cmd->handle.set.name)
 		return 0;
 
 	set = set_lookup_fuzzy(cmd->handle.set.name, &ctx->nft->cache, &table);
+	/* check table first. */
+	if (!table)
+		return 0;
+
+	if (table_fuzzy_check(ctx, cmd, table, loc))
+		return 1;
+
 	if (!set)
 		return 0;
 
@@ -106,13 +135,20 @@ static int nft_cmd_enoent_set(struct netlink_ctx *ctx, const struct cmd *cmd,
 static int nft_cmd_enoent_obj(struct netlink_ctx *ctx, const struct cmd *cmd,
 			      const struct location *loc)
 {
-	const struct table *table;
+	const struct table *table = NULL;
 	struct obj *obj;
 
 	if (!cmd->handle.obj.name)
 		return 0;
 
 	obj = obj_lookup_fuzzy(cmd->handle.obj.name, &ctx->nft->cache, &table);
+	/* check table first. */
+	if (!table)
+		return 0;
+
+	if (table_fuzzy_check(ctx, cmd, table, loc))
+		return 1;
+
 	if (!obj)
 		return 0;
 
@@ -127,7 +163,7 @@ static int nft_cmd_enoent_flowtable(struct netlink_ctx *ctx,
 				    const struct cmd *cmd,
 				    const struct location *loc)
 {
-	const struct table *table;
+	const struct table *table = NULL;
 	struct flowtable *ft;
 
 	if (!cmd->handle.flowtable.name)
@@ -135,6 +171,13 @@ static int nft_cmd_enoent_flowtable(struct netlink_ctx *ctx,
 
 	ft = flowtable_lookup_fuzzy(cmd->handle.flowtable.name,
 				    &ctx->nft->cache, &table);
+	/* check table first. */
+	if (!table)
+		return 0;
+
+	if (table_fuzzy_check(ctx, cmd, table, loc))
+		return 1;
+
 	if (!ft)
 		return 0;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH nft] netlink: quick sort array of devices
  2021-06-08 13:00 [PATCH nft] cmd: check for table mismatch first in error reporting Pablo Neira Ayuso
@ 2021-06-08 13:00 ` Pablo Neira Ayuso
  0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-06-08 13:00 UTC (permalink / raw)
  To: netfilter-devel

Provide an ordered list of devices for (netdev) chain and flowtable.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1525
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/netlink.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/netlink.c b/src/netlink.c
index 6b6fe27762d5..fef869438c35 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -517,6 +517,11 @@ static int chain_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 	return 0;
 }
 
+static int qsort_device_cmp(const void *a, const void *b)
+{
+	return strcmp(a, b) < 0;
+}
+
 struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
 					const struct nftnl_chain *nlc)
 {
@@ -580,6 +585,11 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
 			chain->dev_array_len = len;
 		}
 		chain->flags        |= CHAIN_F_BASECHAIN;
+
+		if (chain->dev_array_len) {
+			qsort(chain->dev_array, chain->dev_array_len,
+			      sizeof(char *), qsort_device_cmp);
+		}
 	}
 
 	if (nftnl_chain_is_set(nlc, NFTNL_CHAIN_USERDATA)) {
@@ -1582,6 +1592,11 @@ netlink_delinearize_flowtable(struct netlink_ctx *ctx,
 
 	flowtable->dev_array_len = len;
 
+	if (flowtable->dev_array_len) {
+		qsort(flowtable->dev_array, flowtable->dev_array_len,
+		      sizeof(char *), qsort_device_cmp);
+	}
+
 	priority = nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_PRIO);
 	flowtable->priority.expr =
 				constant_expr_alloc(&netlink_location,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-06-08 13:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-06-08 13:00 [PATCH nft] cmd: check for table mismatch first in error reporting Pablo Neira Ayuso
2021-06-08 13:00 ` [PATCH nft] netlink: quick sort array of devices Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).