[PATCH] libnftables: location-based error reporting for chain type

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

 



Store the location of the chain type for better error reporting.

Several users that compile custom kernels reported that error
reporting is misleading when accidentally selecting
CONFIG_NFT_NAT=n.

After this patch, a better hint is provided:

 # nft 'add chain x y { type nat hook prerouting priority dstnat; }'
 Error: Could not process rule: No such file or directory
 add chain x y { type nat hook prerouting priority dstnat; }
                      ^^^

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 include/rule.h     | 7 ++++++-
 src/mnl.c          | 8 +++++++-
 src/netlink.c      | 2 +-
 src/parser_bison.y | 3 ++-
 src/parser_json.c  | 2 +-
 src/rule.c         | 6 +++---
 6 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/rule.h b/include/rule.h
index fbd2c9a79b47..f469db55bf60 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -213,6 +213,11 @@ struct hook_spec {
 	unsigned int	num;
 };
 
+struct chain_type_spec {
+	struct location	loc;
+	const char	*str;
+};
+
 /**
  * struct chain - nftables chain
  *
@@ -242,7 +247,7 @@ struct chain {
 		struct prio_spec	priority;
 		struct hook_spec	hook;
 		struct expr		*policy;
-		const char		*type;
+		struct chain_type_spec	type;
 		const char		**dev_array;
 		struct expr		*dev_expr;
 		int			dev_array_len;
diff --git a/src/mnl.c b/src/mnl.c
index 1a8e8105707b..ef45cbd193f9 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -698,7 +698,7 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
 					BYTEORDER_HOST_ENDIAN, sizeof(int));
 			nftnl_chain_set_s32(nlc, NFTNL_CHAIN_PRIO, priority);
 			nftnl_chain_set_str(nlc, NFTNL_CHAIN_TYPE,
-					    cmd->chain->type);
+					    cmd->chain->type.str);
 		}
 		if (cmd->chain->dev_expr) {
 			dev_array = xmalloc(sizeof(char *) * 8);
@@ -764,6 +764,12 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
 			nftnl_chain_set_u32(nlc, NFTNL_CHAIN_FLAGS, cmd->chain->flags);
 	}
 
+	if (cmd->chain && cmd->chain->flags & CHAIN_F_BASECHAIN) {
+		nftnl_chain_unset(nlc, NFTNL_CHAIN_TYPE);
+		cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->chain->type.loc);
+		mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, cmd->chain->type.str);
+	}
+
 	if (cmd->chain && cmd->chain->policy) {
 		mpz_export_data(&policy, cmd->chain->policy->value,
 				BYTEORDER_HOST_ENDIAN, sizeof(int));
diff --git a/src/netlink.c b/src/netlink.c
index 8cdd6d818221..6b6fe27762d5 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -552,7 +552,7 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
 						    BYTEORDER_HOST_ENDIAN,
 						    sizeof(int) * BITS_PER_BYTE,
 						    &priority);
-		chain->type          =
+		chain->type.str =
 			xstrdup(nftnl_chain_get_str(nlc, NFTNL_CHAIN_TYPE));
 		policy = nftnl_chain_get_u32(nlc, NFTNL_CHAIN_POLICY);
 		chain->policy = constant_expr_alloc(&netlink_location,
diff --git a/src/parser_bison.y b/src/parser_bison.y
index cdb04fa8d19b..4e6c2ba75099 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2261,7 +2261,8 @@ hook_spec		:	TYPE		STRING		HOOK		STRING		dev_spec	prio_spec
 					xfree($2);
 					YYERROR;
 				}
-				$<chain>0->type		= xstrdup(chain_type);
+				$<chain>0->type.loc = @2;
+				$<chain>0->type.str = xstrdup(chain_type);
 				xfree($2);
 
 				$<chain>0->loc = @$;
diff --git a/src/parser_json.c b/src/parser_json.c
index 17bb10c34cbc..9d8cef726ad3 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -2741,7 +2741,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
 
 	chain = chain_alloc(NULL);
 	chain->flags |= CHAIN_F_BASECHAIN;
-	chain->type = xstrdup(type);
+	chain->type.str = xstrdup(type);
 	chain->priority.expr = constant_expr_alloc(int_loc, &integer_type,
 						   BYTEORDER_HOST_ENDIAN,
 						   sizeof(int) * BITS_PER_BYTE,
diff --git a/src/rule.c b/src/rule.c
index 07a541a20bb9..dda1718d69ef 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -730,7 +730,7 @@ void chain_free(struct chain *chain)
 		rule_free(rule);
 	handle_free(&chain->handle);
 	scope_release(&chain->scope);
-	xfree(chain->type);
+	xfree(chain->type.str);
 	expr_free(chain->dev_expr);
 	for (i = 0; i < chain->dev_array_len; i++)
 		xfree(chain->dev_array[i]);
@@ -1024,7 +1024,7 @@ static void chain_print_declaration(const struct chain *chain,
 		nft_print(octx, "\n\t\tcomment \"%s\"", chain->comment);
 	nft_print(octx, "\n");
 	if (chain->flags & CHAIN_F_BASECHAIN) {
-		nft_print(octx, "\t\ttype %s hook %s", chain->type,
+		nft_print(octx, "\t\ttype %s hook %s", chain->type.str,
 			  hooknum2str(chain->handle.family, chain->hook.num));
 		if (chain->dev_array_len == 1) {
 			nft_print(octx, " device \"%s\"", chain->dev_array[0]);
@@ -1085,7 +1085,7 @@ void chain_print_plain(const struct chain *chain, struct output_ctx *octx)
 		mpz_export_data(&policy, chain->policy->value,
 				BYTEORDER_HOST_ENDIAN, sizeof(int));
 		nft_print(octx, " { type %s hook %s priority %s; policy %s; }",
-			  chain->type, chain->hook.name,
+			  chain->type.str, chain->hook.name,
 			  prio2str(octx, priobuf, sizeof(priobuf),
 				   chain->handle.family, chain->hook.num,
 				   chain->priority.expr),
-- 
2.30.2




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux