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>
unsigned int num;
};
+struct chain_type_spec {
+ struct location loc;
+ const char *str;
+};
+
/**
* struct chain - nftables 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;
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);
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));
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,
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 = @$;
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,
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]);
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]);
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),