From d7476ddd5f7de35cbc1b5b13d52733f788172ada Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 19 Nov 2018 11:41:07 +0100 Subject: src: introduce simple hints on incorrect table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds simple infrastructure to provide a hints to user on references to incorrect table. While at it, remove "Could not process rule:" which I think it is implicit in the error. # nft rule x y ip saddr @y Error: No such file or directory; did you mean table ā€˜xā€™ in family inet? Signed-off-by: Pablo Neira Ayuso --- include/rule.h | 2 ++ src/evaluate.c | 105 ++++++++++++++++++++++++++------------------------------- src/rule.c | 12 +++++++ 3 files changed, 62 insertions(+), 57 deletions(-) diff --git a/include/rule.h b/include/rule.h index 197efab4..a3e0bf11 100644 --- a/include/rule.h +++ b/include/rule.h @@ -153,6 +153,8 @@ extern void table_free(struct table *table); extern void table_add_hash(struct table *table, struct nft_cache *cache); extern struct table *table_lookup(const struct handle *h, const struct nft_cache *cache); +extern struct table *table_lookup_fuzzy(const struct handle *h, + const struct nft_cache *cache); /** * enum chain_flags - chain flags diff --git a/src/evaluate.c b/src/evaluate.c index d023f47a..d836e18d 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -166,6 +166,21 @@ static struct table *table_lookup_global(struct eval_ctx *ctx) return table; } +static int table_not_found(struct eval_ctx *ctx) +{ + struct table *table; + + table = table_lookup_fuzzy(&ctx->cmd->handle, &ctx->nft->cache); + if (table == NULL) + return cmd_error(ctx, &ctx->cmd->handle.table.location, + "%s", strerror(ENOENT)); + + return cmd_error(ctx, &ctx->cmd->handle.table.location, + "%s; did you mean table ā€˜%sā€™ in family %s?", + strerror(ENOENT), table->handle.table.name, + family2str(table->handle.family)); +} + /* * Symbol expression: parse symbol and evaluate resulting expression. */ @@ -193,15 +208,14 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) table = table_lookup_global(ctx); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); set = set_lookup(table, (*expr)->identifier); if (set == NULL) return expr_error(ctx->msgs, *expr, "Set '%s' does not exist", (*expr)->identifier); + new = set_ref_expr_alloc(&(*expr)->location, set); break; } @@ -2954,9 +2968,7 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr) table = table_lookup_global(ctx); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); set = set_lookup(table, ctx->cmd->handle.set.name); if (set == NULL) @@ -2979,9 +2991,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) table = table_lookup_global(ctx); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); if (!(set->flags & NFT_SET_INTERVAL) && set->automerge) return set_error(ctx, set, "auto-merge only works with interval sets"); @@ -3062,9 +3072,7 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft) table = table_lookup_global(ctx); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); ft->hooknum = str2hooknum(NFPROTO_NETDEV, ft->hookstr); if (ft->hooknum == NF_INET_NUMHOOKS) @@ -3097,9 +3105,7 @@ static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule) table = table_lookup(&rule->handle, &ctx->nft->cache); if (!table) - return cmd_error(ctx, &rule->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); chain = chain_lookup(table, &rule->handle); if (!chain) @@ -3204,9 +3210,7 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain) table = table_lookup_global(ctx); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); if (chain == NULL) { if (chain_lookup(table, &ctx->cmd->handle) == NULL) { @@ -3403,9 +3407,8 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_SETELEM: table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL)) return cmd_error(ctx, &ctx->cmd->handle.set.location, @@ -3428,9 +3431,8 @@ static int cmd_evaluate_list_obj(struct eval_ctx *ctx, const struct cmd *cmd, table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + if (obj_lookup(table, cmd->handle.obj.name, obj_type) == NULL) return cmd_error(ctx, &cmd->handle.obj.location, "Could not process rule: %s", @@ -3455,16 +3457,14 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + return 0; case CMD_OBJ_SET: table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL)) return cmd_error(ctx, &cmd->handle.set.location, @@ -3474,9 +3474,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_METER: table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || !(set->flags & NFT_SET_EVAL)) return cmd_error(ctx, &cmd->handle.set.location, @@ -3486,9 +3485,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_MAP: table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || !(set->flags & NFT_SET_MAP)) return cmd_error(ctx, &cmd->handle.set.location, @@ -3498,9 +3496,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) case CMD_OBJ_CHAIN: table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + if (chain_lookup(table, &cmd->handle) == NULL) return cmd_error(ctx, &cmd->handle.chain.location, "Could not process rule: %s", @@ -3528,9 +3525,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) if (cmd->handle.table.name == NULL) return 0; if (table_lookup(&cmd->handle, &ctx->nft->cache) == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + return 0; case CMD_OBJ_CHAINS: case CMD_OBJ_RULESET: @@ -3558,9 +3554,8 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) if (cmd->handle.table.name == NULL) return 0; if (table_lookup(&cmd->handle, &ctx->nft->cache) == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + return 0; default: BUG("invalid command object type %u\n", cmd->obj); @@ -3591,9 +3586,8 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL)) return cmd_error(ctx, &cmd->handle.set.location, @@ -3607,9 +3601,8 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || !(set->flags & NFT_SET_MAP)) return cmd_error(ctx, &ctx->cmd->handle.set.location, @@ -3623,9 +3616,8 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) table = table_lookup(&cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + set = set_lookup(table, cmd->handle.set.name); if (set == NULL || !(set->flags & NFT_SET_EVAL)) return cmd_error(ctx, &ctx->cmd->handle.set.location, @@ -3651,9 +3643,8 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd) table = table_lookup(&ctx->cmd->handle, &ctx->nft->cache); if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); + return table_not_found(ctx); + if (chain_lookup(table, &ctx->cmd->handle) == NULL) return cmd_error(ctx, &ctx->cmd->handle.chain.location, "Could not process rule: %s", diff --git a/src/rule.c b/src/rule.c index 524db41e..3553b43d 100644 --- a/src/rule.c +++ b/src/rule.c @@ -1103,6 +1103,18 @@ struct table *table_lookup(const struct handle *h, return NULL; } +struct table *table_lookup_fuzzy(const struct handle *h, + const struct nft_cache *cache) +{ + struct table *table; + + list_for_each_entry(table, &cache->list, list) { + if (!strcmp(table->handle.table.name, h->table.name)) + return table; + } + return NULL; +} + const char *table_flags_name[TABLE_FLAGS_MAX] = { "dormant", }; -- cgit v1.2.3