diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-05-19 21:57:41 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-05-20 00:13:35 +0200 |
commit | 5008798157e2114f9fc47bff46e4e6f03c9c7a14 (patch) | |
tree | 5c8385d44a563e4cd87ec9bffa6c6c294d51c3cc | |
parent | 2acf8b2caea19d8abd46d475a908f8d6afb33aa0 (diff) |
libnftables: location-based error reporting for chain type
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@netfilter.org>
-rw-r--r-- | include/rule.h | 7 | ||||
-rw-r--r-- | src/mnl.c | 8 | ||||
-rw-r--r-- | src/netlink.c | 2 | ||||
-rw-r--r-- | src/parser_bison.y | 3 | ||||
-rw-r--r-- | src/parser_json.c | 2 | ||||
-rw-r--r-- | src/rule.c | 6 |
6 files changed, 20 insertions, 8 deletions
diff --git a/include/rule.h b/include/rule.h index fbd2c9a7..f469db55 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; @@ -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 8cdd6d81..6b6fe277 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 957fb528..3a11e697 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -2301,7 +2301,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 9b79497c..fd0d4fd8 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2790,7 +2790,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, @@ -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), |