[PATCH nft,v3 2/3] src: introduce simple hints on incorrect chain

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 # nft list chain x y
 Error: No such file or directory; did you mean chain ‘y’ in family ‘inet’?
 list chain x y
              ^

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 include/rule.h |  3 +++
 src/evaluate.c | 31 ++++++++++++++++++++++---------
 src/rule.c     | 18 ++++++++++++++++++
 3 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/include/rule.h b/include/rule.h
index a3e0bf117d68..66786bdb2140 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -221,6 +221,9 @@ extern void chain_free(struct chain *chain);
 extern void chain_add_hash(struct chain *chain, struct table *table);
 extern struct chain *chain_lookup(const struct table *table,
 				  const struct handle *h);
+extern struct chain *chain_lookup_fuzzy(const struct handle *h,
+					const struct nft_cache *cache,
+					const struct table **table);
 
 extern const char *family2str(unsigned int family);
 extern const char *hooknum2str(unsigned int family, unsigned int hooknum);
diff --git a/src/evaluate.c b/src/evaluate.c
index 12b6a4cac727..f6c090be57ac 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -181,6 +181,23 @@ static int table_not_found(struct eval_ctx *ctx)
 			 table->handle.table.name);
 }
 
+static int chain_not_found(struct eval_ctx *ctx)
+{
+	const struct table *table;
+	struct chain *chain;
+
+	chain = chain_lookup_fuzzy(&ctx->cmd->handle, &ctx->nft->cache, &table);
+	if (chain == NULL)
+		return cmd_error(ctx, &ctx->cmd->handle.chain.location,
+				 "%s", strerror(ENOENT));
+
+	return cmd_error(ctx, &ctx->cmd->handle.chain.location,
+			 "%s; did you mean chain ‘%s’ in table %s ‘%s’?",
+			 strerror(ENOENT), chain->handle.chain.name,
+			 family2str(chain->handle.family),
+			 table->handle.table.name);
+}
+
 /*
  * Symbol expression: parse symbol and evaluate resulting expression.
  */
@@ -3109,9 +3126,7 @@ static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule)
 
 	chain = chain_lookup(table, &rule->handle);
 	if (!chain)
-		return cmd_error(ctx, &rule->handle.chain.location,
-				"Could not process rule: %s",
-				strerror(ENOENT));
+		return chain_not_found(ctx);
 
 	list_for_each_entry(r, &chain->rules, list) {
 		if (++index < rule->handle.index.id)
@@ -3499,9 +3514,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 			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",
-					 strerror(ENOENT));
+			return chain_not_found(ctx);
+
 		return 0;
 	case CMD_OBJ_QUOTA:
 		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_QUOTA);
@@ -3646,9 +3660,8 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd)
 			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",
-					 strerror(ENOENT));
+			return chain_not_found(ctx);
+
 		break;
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
diff --git a/src/rule.c b/src/rule.c
index 3553b43def06..39f717cabeac 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -762,6 +762,24 @@ struct chain *chain_lookup(const struct table *table, const struct handle *h)
 	return NULL;
 }
 
+struct chain *chain_lookup_fuzzy(const struct handle *h,
+				 const struct nft_cache *cache,
+				 const struct table **t)
+{
+	struct table *table;
+	struct chain *chain;
+
+	list_for_each_entry(table, &cache->list, list) {
+		list_for_each_entry(chain, &table->chains, list) {
+			if (!strcmp(chain->handle.chain.name, h->chain.name)) {
+				*t = table;
+				return chain;
+			}
+		}
+	}
+	return NULL;
+}
+
 const char *family2str(unsigned int family)
 {
 	switch (family) {
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux