]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: improve error reporting for unsupported chain type
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 10 Mar 2023 18:20:50 +0000 (19:20 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 11 Mar 2023 21:11:34 +0000 (22:11 +0100)
8c75d3a16960 ("Reject invalid chain priority values in user space")
provides error reporting from the evaluation phase. Instead, this patch
infers the error after the kernel reports EOPNOTSUPP.

test.nft:3:28-40: Error: Chains of type "nat" must have a priority value above -200
                type nat hook prerouting priority -300;
                                         ^^^^^^^^^^^^^

This patch also adds another common issue for users compiling their own
kernels if they forget to enable CONFIG_NFT_NAT in their .config file.

Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/cmd.c
src/evaluate.c

index 9e375078b0ac1c472f0f00d6e6da6028d5d3812c..86c5f432c73a75a38c5f9565592c4f21cb443916 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -241,6 +241,33 @@ static void nft_cmd_enoent(struct netlink_ctx *ctx, const struct cmd *cmd,
        netlink_io_error(ctx, loc, "Could not process rule: %s", strerror(err));
 }
 
+static int nft_cmd_chain_error(struct netlink_ctx *ctx, struct cmd *cmd,
+                              struct mnl_err *err)
+{
+       struct chain *chain = cmd->chain;
+       int priority;
+
+       switch (err->err) {
+       case EOPNOTSUPP:
+               if (!(chain->flags & CHAIN_F_BASECHAIN))
+                       break;
+
+               mpz_export_data(&priority, chain->priority.expr->value,
+                               BYTEORDER_HOST_ENDIAN, sizeof(int));
+               if (priority <= -200 && !strcmp(chain->type.str, "nat"))
+                       return netlink_io_error(ctx, &chain->priority.loc,
+                                               "Chains of type \"nat\" must have a priority value above -200");
+
+               return netlink_io_error(ctx, &chain->loc,
+                                       "Chain of type \"%s\" is not supported, perhaps kernel support is missing?",
+                                       chain->type.str);
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
                   struct mnl_err *err)
 {
@@ -263,6 +290,15 @@ void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
                loc = &cmd->location;
        }
 
+       switch (cmd->obj) {
+       case CMD_OBJ_CHAIN:
+               if (nft_cmd_chain_error(ctx, cmd, err) < 0)
+                       return;
+               break;
+       default:
+               break;
+       }
+
        netlink_io_error(ctx, loc, "Could not process rule: %s",
                         strerror(err->err));
 }
index 663ace26f897970f497600860be161eac3d790cd..47caf3b0d7167418e68298f5586cba9a21111bde 100644 (file)
@@ -4885,8 +4885,6 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain)
        }
 
        if (chain->flags & CHAIN_F_BASECHAIN) {
-               int priority;
-
                chain->hook.num = str2hooknum(chain->handle.family,
                                              chain->hook.name);
                if (chain->hook.num == NF_INET_NUMHOOKS)
@@ -4899,13 +4897,6 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain)
                        return __stmt_binary_error(ctx, &chain->priority.loc, NULL,
                                                   "invalid priority expression %s in this context.",
                                                   expr_name(chain->priority.expr));
-
-               mpz_export_data(&priority, chain->priority.expr->value,
-                               BYTEORDER_HOST_ENDIAN, sizeof(int));
-               if (priority <= -200 && !strcmp(chain->type.str, "nat"))
-                       return __stmt_binary_error(ctx, &chain->priority.loc, NULL,
-                                                  "Chains of type \"nat\" must have a priority value above -200.");
-
                if (chain->policy) {
                        expr_set_context(&ctx->ectx, &policy_type,
                                         NFT_NAME_MAXLEN * BITS_PER_BYTE);