]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: introduce simple hints on incorrect set
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 19 Nov 2018 12:02:03 +0000 (13:02 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 19 Nov 2018 12:53:15 +0000 (13:53 +0100)
 # nft rule x y ip saddr @y
 Error: No such file or directory; did you mean set ‘y’ in table inet ‘x’?
 rule x y ip saddr @y
                   ^^

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/rule.h
src/evaluate.c
src/rule.c

index 66786bdb21402b513fc78eae738a1e4b0335f36b..85b9f80d04feb770a3f3f65ef0fbc1451ac7674a 100644 (file)
@@ -308,6 +308,9 @@ extern void set_add_hash(struct set *set, struct table *table);
 extern struct set *set_lookup(const struct table *table, const char *name);
 extern struct set *set_lookup_global(uint32_t family, const char *table,
                                     const char *name, struct nft_cache *cache);
+extern struct set *set_lookup_fuzzy(const char *set_name,
+                                   const struct nft_cache *cache,
+                                   const struct table **table);
 extern const char *set_policy2str(uint32_t policy);
 extern void set_print(const struct set *set, struct output_ctx *octx);
 extern void set_print_plain(const struct set *s, struct output_ctx *octx);
index f1682fa3f6770a795b57421e77a2ae66b2471269..14c76420d524f8006538aacb5438b56d0e3d19a2 100644 (file)
@@ -198,6 +198,23 @@ static int chain_not_found(struct eval_ctx *ctx)
                         table->handle.table.name);
 }
 
+static int set_not_found(struct eval_ctx *ctx, const struct location *loc,
+                        const char *set_name)
+{
+       const struct table *table;
+       struct set *set;
+
+       set = set_lookup_fuzzy(set_name, &ctx->nft->cache, &table);
+       if (set == NULL)
+               return cmd_error(ctx, loc, "%s", strerror(ENOENT));
+
+       return cmd_error(ctx, loc,
+                        "%s; did you mean set ‘%s’ in table %s ‘%s’?",
+                        strerror(ENOENT), set->handle.set.name,
+                                family2str(set->handle.family),
+                                table->handle.table.name);
+}
+
 /*
  * Symbol expression: parse symbol and evaluate resulting expression.
  */
@@ -229,9 +246,8 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
 
                set = set_lookup(table, (*expr)->identifier);
                if (set == NULL)
-                       return expr_error(ctx->msgs, *expr,
-                                         "Set '%s' does not exist",
-                                         (*expr)->identifier);
+                       return set_not_found(ctx, &(*expr)->location,
+                                            (*expr)->identifier);
 
                new = set_ref_expr_alloc(&(*expr)->location, set);
                break;
@@ -2989,9 +3005,8 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr)
 
        set = set_lookup(table, ctx->cmd->handle.set.name);
        if (set == NULL)
-               return cmd_error(ctx, &ctx->cmd->handle.set.location,
-                                "Could not process rule: %s",
-                                strerror(ENOENT));
+               return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                    ctx->cmd->handle.set.name);
 
        ctx->set = set;
        expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
@@ -3426,9 +3441,8 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd)
 
                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,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
 
                return setelem_evaluate(ctx, &cmd->expr);
        default:
@@ -3482,9 +3496,9 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 
                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,
-                                         "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        case CMD_OBJ_METER:
                table = table_lookup(&cmd->handle, &ctx->nft->cache);
@@ -3493,9 +3507,9 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 
                set = set_lookup(table, cmd->handle.set.name);
                if (set == NULL || !(set->flags & NFT_SET_EVAL))
-                       return cmd_error(ctx, &cmd->handle.set.location,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        case CMD_OBJ_MAP:
                table = table_lookup(&cmd->handle, &ctx->nft->cache);
@@ -3504,9 +3518,9 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 
                set = set_lookup(table, cmd->handle.set.name);
                if (set == NULL || !(set->flags & NFT_SET_MAP))
-                       return cmd_error(ctx, &cmd->handle.set.location,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        case CMD_OBJ_CHAIN:
                table = table_lookup(&cmd->handle, &ctx->nft->cache);
@@ -3604,9 +3618,9 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 
                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,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        case CMD_OBJ_MAP:
                ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
@@ -3619,9 +3633,9 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 
                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,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        case CMD_OBJ_METER:
                ret = cache_update(ctx->nft, cmd->op, ctx->msgs);
@@ -3634,9 +3648,9 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 
                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,
-                                        "Could not process rule: %s",
-                                        strerror(ENOENT));
+                       return set_not_found(ctx, &ctx->cmd->handle.set.location,
+                                            ctx->cmd->handle.set.name);
+
                return 0;
        default:
                BUG("invalid command object type %u\n", cmd->obj);
index 39f717cabeacc20c914723f67391b4ba54cf92d9..1fffa39ab243f7d9c1116413d383bb28dde466fd 100644 (file)
@@ -350,6 +350,24 @@ struct set *set_lookup(const struct table *table, const char *name)
        return NULL;
 }
 
+struct set *set_lookup_fuzzy(const char *set_name,
+                            const struct nft_cache *cache,
+                            const struct table **t)
+{
+       struct table *table;
+       struct set *set;
+
+       list_for_each_entry(table, &cache->list, list) {
+               list_for_each_entry(set, &table->sets, list) {
+                       if (!strcmp(set->handle.set.name, set_name)) {
+                               *t = table;
+                               return set;
+                       }
+               }
+       }
+       return NULL;
+}
+
 struct set *set_lookup_global(uint32_t family, const char *table,
                              const char *name, struct nft_cache *cache)
 {