]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
cmd: check for table mismatch first in error reporting
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 8 Jun 2021 11:53:43 +0000 (13:53 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 8 Jun 2021 12:45:24 +0000 (14:45 +0200)
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

index a647130ec8b4ad033f7cff270e5d383a7a52cb86..a69767c551fe5160e3ce38e5358d76ef41773448 100644 (file)
--- 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;