]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Allow goto and jump to a variable
authorFernando Fernandez Mancera <ffmancera@riseup.net>
Fri, 24 May 2019 13:06:50 +0000 (15:06 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 May 2019 19:56:23 +0000 (21:56 +0200)
This patch introduces the use of nft input files variables in 'jump' and 'goto'
statements, e.g.

define dest = ber

add table ip foo
add chain ip foo bar {type filter hook input priority 0;}
add chain ip foo ber
add rule ip foo ber counter
add rule ip foo bar jump $dest

table ip foo {
        chain bar {
                type filter hook input priority filter; policy accept;
                jump ber
        }

        chain ber {
                counter packets 71 bytes 6664
        }
}

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/datatype.c
src/evaluate.c
src/parser_bison.y
tests/shell/testcases/nft-f/0018jump_variable_0 [new file with mode: 0755]
tests/shell/testcases/nft-f/0019jump_variable_1 [new file with mode: 0755]
tests/shell/testcases/nft-f/0020jump_variable_1 [new file with mode: 0755]
tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft [new file with mode: 0644]

index 10f185bc462c1d45b22af68e8b1740fcd1c1be20..1d5ed6f798de150484ba3f896f71b83bb7a70c2d 100644 (file)
@@ -309,11 +309,22 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
        }
 }
 
+static struct error_record *verdict_type_parse(const struct expr *sym,
+                                              struct expr **res)
+{
+       *res = constant_expr_alloc(&sym->location, &string_type,
+                                  BYTEORDER_HOST_ENDIAN,
+                                  (strlen(sym->identifier) + 1) * BITS_PER_BYTE,
+                                  sym->identifier);
+       return NULL;
+}
+
 const struct datatype verdict_type = {
        .type           = TYPE_VERDICT,
        .name           = "verdict",
        .desc           = "netfilter verdict",
        .print          = verdict_type_print,
+       .parse          = verdict_type_parse,
 };
 
 static const struct symbol_table nfproto_tbl = {
index 83940378562c64d00a41de8e21cd7babfdbc64f8..55fb3b6131e0444871647ac6fe38880413edc9d0 100644 (file)
@@ -1950,6 +1950,13 @@ static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt)
                if (stmt->expr->chain != NULL) {
                        if (expr_evaluate(ctx, &stmt->expr->chain) < 0)
                                return -1;
+                       if ((stmt->expr->chain->etype != EXPR_SYMBOL &&
+                           stmt->expr->chain->etype != EXPR_VALUE) ||
+                           stmt->expr->chain->symtype != SYMBOL_VALUE) {
+                               return stmt_error(ctx, stmt,
+                                                 "invalid verdict chain expression %s\n",
+                                                 expr_name(stmt->expr->chain));
+                       }
                }
                break;
        case EXPR_MAP:
index f2583ade47f594d4c7d328262926dce484154daa..62e76fe617c8bda01e41873790a3273ac9dea0b6 100644 (file)
@@ -3841,7 +3841,8 @@ verdict_expr              :       ACCEPT
                        }
                        ;
 
-chain_expr             :       identifier
+chain_expr             :       variable_expr
+                       |       identifier
                        {
                                $$ = constant_expr_alloc(&@$, &string_type,
                                                         BYTEORDER_HOST_ENDIAN,
diff --git a/tests/shell/testcases/nft-f/0018jump_variable_0 b/tests/shell/testcases/nft-f/0018jump_variable_0
new file mode 100755 (executable)
index 0000000..003a1bd
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Tests use of variables in jump statements
+
+set -e
+
+RULESET="
+define dest = ber
+
+table ip foo {
+       chain bar {
+               jump \$dest
+       }
+
+       chain ber {
+       }
+}"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/nft-f/0019jump_variable_1 b/tests/shell/testcases/nft-f/0019jump_variable_1
new file mode 100755 (executable)
index 0000000..bda861c
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Tests use of variables in jump statements
+
+set -e
+
+RULESET="
+define dest = { 1024 }
+
+table ip foo {
+       chain bar {
+               jump \$dest
+       }
+
+       chain ber {
+       }
+}"
+
+$NFT -f - <<< "$RULESET" && exit 1
+exit 0
diff --git a/tests/shell/testcases/nft-f/0020jump_variable_1 b/tests/shell/testcases/nft-f/0020jump_variable_1
new file mode 100755 (executable)
index 0000000..f753058
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Tests use of variables in jump statements
+
+set -e
+
+RULESET="
+define dest = *
+
+table ip foo {
+       chain bar {
+               jump \$dest
+       }
+
+       chain ber {
+       }
+}"
+
+$NFT -f - <<< "$RULESET" && exit 1
+exit 0
diff --git a/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft b/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft
new file mode 100644 (file)
index 0000000..0ddaf07
--- /dev/null
@@ -0,0 +1,8 @@
+table ip foo {
+       chain bar {
+               jump ber
+       }
+
+       chain ber {
+       }
+}