|
|
bacbc8 |
From 0100e69baee2e3a7e4bf5f0fb5c824d5c3e81286 Mon Sep 17 00:00:00 2001
|
|
|
bacbc8 |
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
|
|
bacbc8 |
Date: Fri, 24 May 2019 15:06:50 +0200
|
|
|
bacbc8 |
Subject: [PATCH] src: Allow goto and jump to a variable
|
|
|
bacbc8 |
|
|
|
bacbc8 |
This patch introduces the use of nft input files variables in 'jump' and 'goto'
|
|
|
bacbc8 |
statements, e.g.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
define dest = ber
|
|
|
bacbc8 |
|
|
|
bacbc8 |
add table ip foo
|
|
|
bacbc8 |
add chain ip foo bar {type filter hook input priority 0;}
|
|
|
bacbc8 |
add chain ip foo ber
|
|
|
bacbc8 |
add rule ip foo ber counter
|
|
|
bacbc8 |
add rule ip foo bar jump $dest
|
|
|
bacbc8 |
|
|
|
bacbc8 |
table ip foo {
|
|
|
bacbc8 |
chain bar {
|
|
|
bacbc8 |
type filter hook input priority filter; policy accept;
|
|
|
bacbc8 |
jump ber
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
|
|
|
bacbc8 |
chain ber {
|
|
|
bacbc8 |
counter packets 71 bytes 6664
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
|
|
bacbc8 |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
bacbc8 |
(cherry picked from commit c64457cff9673fbb41f613a67e158b4d62235c09)
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Conflicts:
|
|
|
bacbc8 |
-> Adjust for missing commits 72931553828af
|
|
|
bacbc8 |
("src: expr: add expression etype") and 68e76238749fb
|
|
|
bacbc8 |
("src: expr: add and use expr_name helper").
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
bacbc8 |
---
|
|
|
bacbc8 |
src/datatype.c | 11 ++++++++++
|
|
|
bacbc8 |
src/evaluate.c | 7 +++++++
|
|
|
bacbc8 |
src/parser_bison.y | 3 ++-
|
|
|
bacbc8 |
.../shell/testcases/nft-f/0018jump_variable_0 | 19 ++++++++++++++++++
|
|
|
bacbc8 |
.../shell/testcases/nft-f/0019jump_variable_1 | 20 +++++++++++++++++++
|
|
|
bacbc8 |
.../shell/testcases/nft-f/0020jump_variable_1 | 20 +++++++++++++++++++
|
|
|
bacbc8 |
.../nft-f/dumps/0018jump_variable_0.nft | 8 ++++++++
|
|
|
bacbc8 |
7 files changed, 87 insertions(+), 1 deletion(-)
|
|
|
bacbc8 |
create mode 100755 tests/shell/testcases/nft-f/0018jump_variable_0
|
|
|
bacbc8 |
create mode 100755 tests/shell/testcases/nft-f/0019jump_variable_1
|
|
|
bacbc8 |
create mode 100755 tests/shell/testcases/nft-f/0020jump_variable_1
|
|
|
bacbc8 |
create mode 100644 tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft
|
|
|
bacbc8 |
|
|
|
bacbc8 |
diff --git a/src/datatype.c b/src/datatype.c
|
|
|
bacbc8 |
index f7defa37ff196..5791a6a41599e 100644
|
|
|
bacbc8 |
--- a/src/datatype.c
|
|
|
bacbc8 |
+++ b/src/datatype.c
|
|
|
bacbc8 |
@@ -308,11 +308,22 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
|
|
|
bacbc8 |
+static struct error_record *verdict_type_parse(const struct expr *sym,
|
|
|
bacbc8 |
+ struct expr **res)
|
|
|
bacbc8 |
+{
|
|
|
bacbc8 |
+ *res = constant_expr_alloc(&sym->location, &string_type,
|
|
|
bacbc8 |
+ BYTEORDER_HOST_ENDIAN,
|
|
|
bacbc8 |
+ (strlen(sym->identifier) + 1) * BITS_PER_BYTE,
|
|
|
bacbc8 |
+ sym->identifier);
|
|
|
bacbc8 |
+ return NULL;
|
|
|
bacbc8 |
+}
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
const struct datatype verdict_type = {
|
|
|
bacbc8 |
.type = TYPE_VERDICT,
|
|
|
bacbc8 |
.name = "verdict",
|
|
|
bacbc8 |
.desc = "netfilter verdict",
|
|
|
bacbc8 |
.print = verdict_type_print,
|
|
|
bacbc8 |
+ .parse = verdict_type_parse,
|
|
|
bacbc8 |
};
|
|
|
bacbc8 |
|
|
|
bacbc8 |
static const struct symbol_table nfproto_tbl = {
|
|
|
bacbc8 |
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
|
bacbc8 |
index 5f0f3b36fd99f..8e15e71d8a33b 100644
|
|
|
bacbc8 |
--- a/src/evaluate.c
|
|
|
bacbc8 |
+++ b/src/evaluate.c
|
|
|
bacbc8 |
@@ -1850,6 +1850,13 @@ static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt)
|
|
|
bacbc8 |
if (stmt->expr->chain != NULL) {
|
|
|
bacbc8 |
if (expr_evaluate(ctx, &stmt->expr->chain) < 0)
|
|
|
bacbc8 |
return -1;
|
|
|
bacbc8 |
+ if ((stmt->expr->chain->ops->type != EXPR_SYMBOL &&
|
|
|
bacbc8 |
+ stmt->expr->chain->ops->type != EXPR_VALUE) ||
|
|
|
bacbc8 |
+ stmt->expr->chain->symtype != SYMBOL_VALUE) {
|
|
|
bacbc8 |
+ return stmt_error(ctx, stmt,
|
|
|
bacbc8 |
+ "invalid verdict chain expression %s\n",
|
|
|
bacbc8 |
+ stmt->expr->chain->ops->name);
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
break;
|
|
|
bacbc8 |
case EXPR_MAP:
|
|
|
bacbc8 |
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
|
bacbc8 |
index 08dce52cebd1e..2e8ebde34eee6 100644
|
|
|
bacbc8 |
--- a/src/parser_bison.y
|
|
|
bacbc8 |
+++ b/src/parser_bison.y
|
|
|
bacbc8 |
@@ -3475,7 +3475,8 @@ verdict_expr : ACCEPT
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
;
|
|
|
bacbc8 |
|
|
|
bacbc8 |
-chain_expr : identifier
|
|
|
bacbc8 |
+chain_expr : variable_expr
|
|
|
bacbc8 |
+ | identifier
|
|
|
bacbc8 |
{
|
|
|
bacbc8 |
$$ = constant_expr_alloc(&@$, &string_type,
|
|
|
bacbc8 |
BYTEORDER_HOST_ENDIAN,
|
|
|
bacbc8 |
diff --git a/tests/shell/testcases/nft-f/0018jump_variable_0 b/tests/shell/testcases/nft-f/0018jump_variable_0
|
|
|
bacbc8 |
new file mode 100755
|
|
|
bacbc8 |
index 0000000000000..003a1bdf701f1
|
|
|
bacbc8 |
--- /dev/null
|
|
|
bacbc8 |
+++ b/tests/shell/testcases/nft-f/0018jump_variable_0
|
|
|
bacbc8 |
@@ -0,0 +1,19 @@
|
|
|
bacbc8 |
+#!/bin/bash
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+# Tests use of variables in jump statements
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+set -e
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+RULESET="
|
|
|
bacbc8 |
+define dest = ber
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+table ip foo {
|
|
|
bacbc8 |
+ chain bar {
|
|
|
bacbc8 |
+ jump \$dest
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ chain ber {
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+}"
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+$NFT -f - <<< "$RULESET"
|
|
|
bacbc8 |
diff --git a/tests/shell/testcases/nft-f/0019jump_variable_1 b/tests/shell/testcases/nft-f/0019jump_variable_1
|
|
|
bacbc8 |
new file mode 100755
|
|
|
bacbc8 |
index 0000000000000..bda861c91df31
|
|
|
bacbc8 |
--- /dev/null
|
|
|
bacbc8 |
+++ b/tests/shell/testcases/nft-f/0019jump_variable_1
|
|
|
bacbc8 |
@@ -0,0 +1,20 @@
|
|
|
bacbc8 |
+#!/bin/bash
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+# Tests use of variables in jump statements
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+set -e
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+RULESET="
|
|
|
bacbc8 |
+define dest = { 1024 }
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+table ip foo {
|
|
|
bacbc8 |
+ chain bar {
|
|
|
bacbc8 |
+ jump \$dest
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ chain ber {
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+}"
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+$NFT -f - <<< "$RULESET" && exit 1
|
|
|
bacbc8 |
+exit 0
|
|
|
bacbc8 |
diff --git a/tests/shell/testcases/nft-f/0020jump_variable_1 b/tests/shell/testcases/nft-f/0020jump_variable_1
|
|
|
bacbc8 |
new file mode 100755
|
|
|
bacbc8 |
index 0000000000000..f753058f24f64
|
|
|
bacbc8 |
--- /dev/null
|
|
|
bacbc8 |
+++ b/tests/shell/testcases/nft-f/0020jump_variable_1
|
|
|
bacbc8 |
@@ -0,0 +1,20 @@
|
|
|
bacbc8 |
+#!/bin/bash
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+# Tests use of variables in jump statements
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+set -e
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+RULESET="
|
|
|
bacbc8 |
+define dest = *
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+table ip foo {
|
|
|
bacbc8 |
+ chain bar {
|
|
|
bacbc8 |
+ jump \$dest
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ chain ber {
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+}"
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+$NFT -f - <<< "$RULESET" && exit 1
|
|
|
bacbc8 |
+exit 0
|
|
|
bacbc8 |
diff --git a/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft b/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft
|
|
|
bacbc8 |
new file mode 100644
|
|
|
bacbc8 |
index 0000000000000..0ddaf07f0ea3b
|
|
|
bacbc8 |
--- /dev/null
|
|
|
bacbc8 |
+++ b/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft
|
|
|
bacbc8 |
@@ -0,0 +1,8 @@
|
|
|
bacbc8 |
+table ip foo {
|
|
|
bacbc8 |
+ chain bar {
|
|
|
bacbc8 |
+ jump ber
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ chain ber {
|
|
|
bacbc8 |
+ }
|
|
|
bacbc8 |
+}
|
|
|
bacbc8 |
--
|
|
|
bacbc8 |
2.21.0
|
|
|
bacbc8 |
|