Compare commits
No commits in common. "c9s-stable" and "c8" have entirely different histories.
c9s-stable
...
c8
@ -1 +0,0 @@
|
|||||||
1
|
|
||||||
25
.gitignore
vendored
25
.gitignore
vendored
@ -1,24 +1 @@
|
|||||||
/nftables-20140326.tar.bz2
|
SOURCES/nftables-1.0.4.tar.bz2
|
||||||
/nftables-20140330.tar.bz2
|
|
||||||
/nftables-20140426.tar.bz2
|
|
||||||
/nftables-20140704.tar.bz2
|
|
||||||
/nftables-20140903.tar.bz2
|
|
||||||
/nftables-0.4.tar.bz2
|
|
||||||
/nftables-0.5.tar.bz2
|
|
||||||
/nftables-0.6.tar.bz2
|
|
||||||
/nftables-0.7.tar.bz2
|
|
||||||
/nftables-0.8.tar.bz2
|
|
||||||
/nftables-0.8.1.tar.bz2
|
|
||||||
/nftables-0.8.2.tar.bz2
|
|
||||||
/nftables-0.8.3.tar.bz2
|
|
||||||
/nftables-0.8.4.tar.bz2
|
|
||||||
/nftables-0.8.5.tar.bz2
|
|
||||||
/nftables-0.9.0.tar.bz2
|
|
||||||
/nftables-0.9.1.tar.bz2
|
|
||||||
/nftables-0.9.2.tar.bz2
|
|
||||||
/nftables-0.9.3.tar.bz2
|
|
||||||
/nftables-0.9.6.tar.bz2
|
|
||||||
/nftables-0.9.7.tar.bz2
|
|
||||||
/nftables-0.9.8.tar.bz2
|
|
||||||
/nftables-1.0.4.tar.bz2
|
|
||||||
/nftables-1.0.9.tar.xz
|
|
||||||
|
|||||||
1
.nftables.metadata
Normal file
1
.nftables.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
e2e8b324cece1409a311284ff4fe26c3a5554809 SOURCES/nftables-1.0.4.tar.bz2
|
||||||
@ -1,337 +0,0 @@
|
|||||||
From 450520649ac5ac6f983b40e15e54863aab9d5bd7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Fri, 14 Jun 2024 18:30:55 +0200
|
|
||||||
Subject: [PATCH] Add support for table's persist flag
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-32122
|
|
||||||
Upstream Status: nftables commit 4955ae1a81b73f9a61b7fbf1a73e11544513548e
|
|
||||||
Conflicts:
|
|
||||||
- Adjusted to missing commit ffd6b4790a728
|
|
||||||
("src: add free_const() and use it instead of xfree()")
|
|
||||||
|
|
||||||
commit 4955ae1a81b73f9a61b7fbf1a73e11544513548e
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Dec 15 01:10:39 2023 +0100
|
|
||||||
|
|
||||||
Add support for table's persist flag
|
|
||||||
|
|
||||||
Bison parser lacked support for passing multiple flags, JSON parser
|
|
||||||
did not support table flags at all.
|
|
||||||
|
|
||||||
Document also 'owner' flag (and describe their relationship in nft.8.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/libnftables-json.adoc | 11 ++++-
|
|
||||||
doc/nft.txt | 9 ++++
|
|
||||||
include/rule.h | 4 +-
|
|
||||||
src/parser_bison.y | 35 +++++++++------
|
|
||||||
src/parser_json.c | 49 ++++++++++++++++++++-
|
|
||||||
src/rule.c | 12 +++++
|
|
||||||
tests/shell/features/table_flag_persist.nft | 3 ++
|
|
||||||
tests/shell/testcases/owner/0002-persist | 36 +++++++++++++++
|
|
||||||
8 files changed, 142 insertions(+), 17 deletions(-)
|
|
||||||
create mode 100644 tests/shell/features/table_flag_persist.nft
|
|
||||||
create mode 100755 tests/shell/testcases/owner/0002-persist
|
|
||||||
|
|
||||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
|
||||||
index 3e6e1db..0e424c2 100644
|
|
||||||
--- a/doc/libnftables-json.adoc
|
|
||||||
+++ b/doc/libnftables-json.adoc
|
|
||||||
@@ -202,12 +202,19 @@ Rename a chain. The new name is expected in a dedicated property named
|
|
||||||
|
|
||||||
=== TABLE
|
|
||||||
[verse]
|
|
||||||
+____
|
|
||||||
*{ "table": {
|
|
||||||
"family":* 'STRING'*,
|
|
||||||
"name":* 'STRING'*,
|
|
||||||
- "handle":* 'NUMBER'
|
|
||||||
+ "handle":* 'NUMBER'*,
|
|
||||||
+ "flags":* 'TABLE_FLAGS'
|
|
||||||
*}}*
|
|
||||||
|
|
||||||
+'TABLE_FLAGS' := 'TABLE_FLAG' | *[* 'TABLE_FLAG_LIST' *]*
|
|
||||||
+'TABLE_FLAG_LIST' := 'TABLE_FLAG' [*,* 'TABLE_FLAG_LIST' ]
|
|
||||||
+'TABLE_FLAG' := *"dormant"* | *"owner"* | *"persist"*
|
|
||||||
+____
|
|
||||||
+
|
|
||||||
This object describes a table.
|
|
||||||
|
|
||||||
*family*::
|
|
||||||
@@ -217,6 +224,8 @@ This object describes a table.
|
|
||||||
*handle*::
|
|
||||||
The table's handle. In input, it is used only in *delete* command as
|
|
||||||
alternative to *name*.
|
|
||||||
+*flags*::
|
|
||||||
+ The table's flags.
|
|
||||||
|
|
||||||
=== CHAIN
|
|
||||||
[verse]
|
|
||||||
diff --git a/doc/nft.txt b/doc/nft.txt
|
|
||||||
index b08e32f..dba1b60 100644
|
|
||||||
--- a/doc/nft.txt
|
|
||||||
+++ b/doc/nft.txt
|
|
||||||
@@ -343,8 +343,17 @@ return an error.
|
|
||||||
|Flag | Description
|
|
||||||
|dormant |
|
|
||||||
table is not evaluated any more (base chains are unregistered).
|
|
||||||
+|owner |
|
|
||||||
+table is owned by the creating process.
|
|
||||||
+|persist |
|
|
||||||
+table shall outlive the owning process.
|
|
||||||
|=================
|
|
||||||
|
|
||||||
+Creating a table with flag *owner* excludes other processes from manipulating
|
|
||||||
+it or its contents. By default, it will be removed when the process exits.
|
|
||||||
+Setting flag *persist* will prevent this and the resulting orphaned table will
|
|
||||||
+accept a new owner, e.g. a restarting daemon maintaining the table.
|
|
||||||
+
|
|
||||||
.*Add, change, delete a table*
|
|
||||||
---------------------------------------
|
|
||||||
# start nft in interactive mode
|
|
||||||
diff --git a/include/rule.h b/include/rule.h
|
|
||||||
index 6236d29..a8bb11f 100644
|
|
||||||
--- a/include/rule.h
|
|
||||||
+++ b/include/rule.h
|
|
||||||
@@ -130,10 +130,12 @@ struct symbol *symbol_get(const struct scope *scope, const char *identifier);
|
|
||||||
enum table_flags {
|
|
||||||
TABLE_F_DORMANT = (1 << 0),
|
|
||||||
TABLE_F_OWNER = (1 << 1),
|
|
||||||
+ TABLE_F_PERSIST = (1 << 2),
|
|
||||||
};
|
|
||||||
-#define TABLE_FLAGS_MAX 2
|
|
||||||
+#define TABLE_FLAGS_MAX 3
|
|
||||||
|
|
||||||
const char *table_flag_name(uint32_t flag);
|
|
||||||
+unsigned int parse_table_flag(const char *name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct table - nftables table
|
|
||||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
||||||
index c517dc3..5ced6e1 100644
|
|
||||||
--- a/src/parser_bison.y
|
|
||||||
+++ b/src/parser_bison.y
|
|
||||||
@@ -720,6 +720,8 @@ int nft_lex(void *, void *, void *);
|
|
||||||
%type <rule> rule rule_alloc
|
|
||||||
%destructor { rule_free($$); } rule
|
|
||||||
|
|
||||||
+%type <val> table_flags table_flag
|
|
||||||
+
|
|
||||||
%type <val> set_flag_list set_flag
|
|
||||||
|
|
||||||
%type <val> set_policy_spec
|
|
||||||
@@ -1874,20 +1876,9 @@ table_block_alloc : /* empty */
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
-table_options : FLAGS STRING
|
|
||||||
+table_options : FLAGS table_flags
|
|
||||||
{
|
|
||||||
- if (strcmp($2, "dormant") == 0) {
|
|
||||||
- $<table>0->flags |= TABLE_F_DORMANT;
|
|
||||||
- xfree($2);
|
|
||||||
- } else if (strcmp($2, "owner") == 0) {
|
|
||||||
- $<table>0->flags |= TABLE_F_OWNER;
|
|
||||||
- xfree($2);
|
|
||||||
- } else {
|
|
||||||
- erec_queue(error(&@2, "unknown table option %s", $2),
|
|
||||||
- state->msgs);
|
|
||||||
- xfree($2);
|
|
||||||
- YYERROR;
|
|
||||||
- }
|
|
||||||
+ $<table>0->flags |= $2;
|
|
||||||
}
|
|
||||||
| comment_spec
|
|
||||||
{
|
|
||||||
@@ -1899,6 +1890,24 @@ table_options : FLAGS STRING
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
+table_flags : table_flag
|
|
||||||
+ | table_flags COMMA table_flag
|
|
||||||
+ {
|
|
||||||
+ $$ = $1 | $3;
|
|
||||||
+ }
|
|
||||||
+ ;
|
|
||||||
+table_flag : STRING
|
|
||||||
+ {
|
|
||||||
+ $$ = parse_table_flag($1);
|
|
||||||
+ xfree($1);
|
|
||||||
+ if ($$ == 0) {
|
|
||||||
+ erec_queue(error(&@1, "unknown table option %s", $1),
|
|
||||||
+ state->msgs);
|
|
||||||
+ YYERROR;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ;
|
|
||||||
+
|
|
||||||
table_block : /* empty */ { $$ = $<table>-1; }
|
|
||||||
| table_block common_block
|
|
||||||
| table_block stmt_separator
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 199241a..9e5b656 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -2941,6 +2941,45 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int json_parse_table_flags(struct json_ctx *ctx, json_t *root,
|
|
||||||
+ enum table_flags *flags)
|
|
||||||
+{
|
|
||||||
+ json_t *tmp, *tmp2;
|
|
||||||
+ size_t index;
|
|
||||||
+ int flag;
|
|
||||||
+
|
|
||||||
+ if (json_unpack(root, "{s:o}", "flags", &tmp))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (json_is_string(tmp)) {
|
|
||||||
+ flag = parse_table_flag(json_string_value(tmp));
|
|
||||||
+ if (flag) {
|
|
||||||
+ *flags = flag;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ json_error(ctx, "Invalid table flag '%s'.",
|
|
||||||
+ json_string_value(tmp));
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ if (!json_is_array(tmp)) {
|
|
||||||
+ json_error(ctx, "Unexpected table flags value.");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ json_array_foreach(tmp, index, tmp2) {
|
|
||||||
+ if (json_is_string(tmp2)) {
|
|
||||||
+ flag = parse_table_flag(json_string_value(tmp2));
|
|
||||||
+
|
|
||||||
+ if (flag) {
|
|
||||||
+ *flags |= flag;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ json_error(ctx, "Invalid table flag at index %zu.", index);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
enum cmd_ops op, enum cmd_obj obj)
|
|
||||||
{
|
|
||||||
@@ -2949,6 +2988,7 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
.table.location = *int_loc,
|
|
||||||
};
|
|
||||||
struct table *table = NULL;
|
|
||||||
+ enum table_flags flags = 0;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s}",
|
|
||||||
"family", &family))
|
|
||||||
@@ -2959,6 +2999,9 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
json_unpack(root, "{s:s}", "comment", &comment);
|
|
||||||
+ if (json_parse_table_flags(ctx, root, &flags))
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
} else if (op == CMD_DELETE &&
|
|
||||||
json_unpack(root, "{s:s}", "name", &h.table.name) &&
|
|
||||||
json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
|
|
||||||
@@ -2972,10 +3015,12 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
if (h.table.name)
|
|
||||||
h.table.name = xstrdup(h.table.name);
|
|
||||||
|
|
||||||
- if (comment) {
|
|
||||||
+ if (comment || flags) {
|
|
||||||
table = table_alloc();
|
|
||||||
handle_merge(&table->handle, &h);
|
|
||||||
- table->comment = xstrdup(comment);
|
|
||||||
+ if (comment)
|
|
||||||
+ table->comment = xstrdup(comment);
|
|
||||||
+ table->flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == CMD_ADD)
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index 739b7a5..a0e151d 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -1208,6 +1208,7 @@ struct table *table_lookup_fuzzy(const struct handle *h,
|
|
||||||
static const char *table_flags_name[TABLE_FLAGS_MAX] = {
|
|
||||||
"dormant",
|
|
||||||
"owner",
|
|
||||||
+ "persist",
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *table_flag_name(uint32_t flag)
|
|
||||||
@@ -1218,6 +1219,17 @@ const char *table_flag_name(uint32_t flag)
|
|
||||||
return table_flags_name[flag];
|
|
||||||
}
|
|
||||||
|
|
||||||
+unsigned int parse_table_flag(const char *name)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < TABLE_FLAGS_MAX; i++) {
|
|
||||||
+ if (!strcmp(name, table_flags_name[i]))
|
|
||||||
+ return 1 << i;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void table_print_flags(const struct table *table, const char **delim,
|
|
||||||
struct output_ctx *octx)
|
|
||||||
{
|
|
||||||
diff --git a/tests/shell/features/table_flag_persist.nft b/tests/shell/features/table_flag_persist.nft
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0da3e6d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/features/table_flag_persist.nft
|
|
||||||
@@ -0,0 +1,3 @@
|
|
||||||
+table t {
|
|
||||||
+ flags persist;
|
|
||||||
+}
|
|
||||||
diff --git a/tests/shell/testcases/owner/0002-persist b/tests/shell/testcases/owner/0002-persist
|
|
||||||
new file mode 100755
|
|
||||||
index 0000000..cf4b8f1
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/owner/0002-persist
|
|
||||||
@@ -0,0 +1,36 @@
|
|
||||||
+#!/bin/bash
|
|
||||||
+
|
|
||||||
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_table_flag_owner)
|
|
||||||
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_table_flag_persist)
|
|
||||||
+
|
|
||||||
+die() {
|
|
||||||
+ echo "$@"
|
|
||||||
+ exit 1
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+$NFT -f - <<EOF
|
|
||||||
+table ip t {
|
|
||||||
+ flags owner, persist
|
|
||||||
+}
|
|
||||||
+EOF
|
|
||||||
+[[ $? -eq 0 ]] || {
|
|
||||||
+ die "table add failed"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+$NFT list ruleset | grep -q 'table ip t' || {
|
|
||||||
+ die "table does not persist"
|
|
||||||
+}
|
|
||||||
+$NFT list ruleset | grep -q 'flags persist$' || {
|
|
||||||
+ die "unexpected flags in orphaned table"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+$NFT -f - <<EOF
|
|
||||||
+table ip t {
|
|
||||||
+ flags owner, persist
|
|
||||||
+}
|
|
||||||
+EOF
|
|
||||||
+[[ $? -eq 0 ]] || {
|
|
||||||
+ die "retake ownership failed"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+exit 0
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
From 2ef49849b901184c3d97c98c05ffa6418b50af1e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 2 Jul 2024 16:41:22 +0200
|
|
||||||
Subject: [PATCH] cache: Always set NFT_CACHE_TERSE for list cmd with --terse
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-45633
|
|
||||||
Upstream Status: nftables commit cd4e947032a57a585b1a457ce03f546afc7ba033
|
|
||||||
|
|
||||||
commit cd4e947032a57a585b1a457ce03f546afc7ba033
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Feb 8 02:10:48 2024 +0100
|
|
||||||
|
|
||||||
cache: Always set NFT_CACHE_TERSE for list cmd with --terse
|
|
||||||
|
|
||||||
This fixes at least 'nft -t list table ...' and 'nft -t list set ...'.
|
|
||||||
|
|
||||||
Note how --terse handling for 'list sets/maps' remains in place since
|
|
||||||
setting NFT_CACHE_TERSE does not fully undo NFT_CACHE_SETELEM: setting
|
|
||||||
both enables fetching of anonymous sets which is pointless for that
|
|
||||||
command.
|
|
||||||
|
|
||||||
Reported-by: anton.khazan@gmail.com
|
|
||||||
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1735
|
|
||||||
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 10 +++-------
|
|
||||||
1 file changed, 3 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index 4e89fe1..0ac0f7c 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -230,8 +230,6 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
}
|
|
||||||
if (filter->list.table && filter->list.set)
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_SET | NFT_CACHE_SETELEM;
|
|
||||||
- else if (nft_output_terse(&nft->output))
|
|
||||||
- flags |= NFT_CACHE_FULL | NFT_CACHE_TERSE;
|
|
||||||
else
|
|
||||||
flags |= NFT_CACHE_FULL;
|
|
||||||
break;
|
|
||||||
@@ -257,17 +255,15 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_FLOWTABLE;
|
|
||||||
break;
|
|
||||||
case CMD_OBJ_RULESET:
|
|
||||||
- if (nft_output_terse(&nft->output))
|
|
||||||
- flags |= NFT_CACHE_FULL | NFT_CACHE_TERSE;
|
|
||||||
- else
|
|
||||||
- flags |= NFT_CACHE_FULL;
|
|
||||||
- break;
|
|
||||||
default:
|
|
||||||
flags |= NFT_CACHE_FULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
flags |= NFT_CACHE_REFRESH;
|
|
||||||
|
|
||||||
+ if (nft_output_terse(&nft->output))
|
|
||||||
+ flags |= NFT_CACHE_TERSE;
|
|
||||||
+
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,213 +0,0 @@
|
|||||||
From f85059245c5c5da7c0db98c3f35ab28a73e7cf4c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 23 Apr 2025 14:25:43 +0200
|
|
||||||
Subject: [PATCH] json: deal appropriately with multidevice in chain
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-88181
|
|
||||||
Upstream Status: nftables commit 4dfb5b2010917da3f9f11c83931069931a7d6fb3
|
|
||||||
Conflicts: Dropped changes to shell testsuite stored dumps, downstream
|
|
||||||
misses commit 3d24b16b9ac13 ("tests/shell: add JSON dump
|
|
||||||
files").
|
|
||||||
|
|
||||||
commit 4dfb5b2010917da3f9f11c83931069931a7d6fb3
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Thu Nov 23 10:36:50 2023 +0100
|
|
||||||
|
|
||||||
json: deal appropriately with multidevice in chain
|
|
||||||
|
|
||||||
Chain device support is broken in JSON: listing does not include devices
|
|
||||||
and parser only deals with one single device.
|
|
||||||
|
|
||||||
Use existing json_parse_flowtable_devs() function, rename it to
|
|
||||||
json_parse_devs() to parse the device array.
|
|
||||||
|
|
||||||
Use the dev_array that contains the device names (as string) for the
|
|
||||||
listing.
|
|
||||||
|
|
||||||
Update incorrect .json-nft files in tests/shell.
|
|
||||||
|
|
||||||
Fixes: 3fdc7541fba0 ("src: add multidevice support for netdev chain")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 25 ++++++-------
|
|
||||||
src/parser_json.c | 91 +++++++++++++++++++++++------------------------
|
|
||||||
2 files changed, 58 insertions(+), 58 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 068c423..dad93e5 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -257,9 +257,8 @@ static json_t *rule_print_json(struct output_ctx *octx,
|
|
||||||
|
|
||||||
static json_t *chain_print_json(const struct chain *chain)
|
|
||||||
{
|
|
||||||
- int priority, policy, n = 0;
|
|
||||||
- struct expr *dev, *expr;
|
|
||||||
- json_t *root, *tmp;
|
|
||||||
+ json_t *root, *tmp, *devs = NULL;
|
|
||||||
+ int priority, policy, i;
|
|
||||||
|
|
||||||
root = json_pack("{s:s, s:s, s:s, s:I}",
|
|
||||||
"family", family2str(chain->handle.family),
|
|
||||||
@@ -281,17 +280,19 @@ static json_t *chain_print_json(const struct chain *chain)
|
|
||||||
chain->hook.num),
|
|
||||||
"prio", priority,
|
|
||||||
"policy", chain_policy2str(policy));
|
|
||||||
- if (chain->dev_expr) {
|
|
||||||
- list_for_each_entry(expr, &chain->dev_expr->expressions, list) {
|
|
||||||
- dev = expr;
|
|
||||||
- n++;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
|
|
||||||
- if (n == 1) {
|
|
||||||
- json_object_set_new(tmp, "dev",
|
|
||||||
- json_string(dev->identifier));
|
|
||||||
+ for (i = 0; i < chain->dev_array_len; i++) {
|
|
||||||
+ const char *dev = chain->dev_array[i];
|
|
||||||
+ if (!devs)
|
|
||||||
+ devs = json_string(dev);
|
|
||||||
+ else if (json_is_string(devs))
|
|
||||||
+ devs = json_pack("[o, s]", devs, dev);
|
|
||||||
+ else
|
|
||||||
+ json_array_append_new(devs, json_string(dev));
|
|
||||||
}
|
|
||||||
+ if (devs)
|
|
||||||
+ json_object_set_new(root, "dev", devs);
|
|
||||||
+
|
|
||||||
json_object_update(root, tmp);
|
|
||||||
json_decref(tmp);
|
|
||||||
}
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 9e5b656..d57aa6b 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -3045,14 +3045,49 @@ static struct expr *parse_policy(const char *policy)
|
|
||||||
sizeof(int) * BITS_PER_BYTE, &policy_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root)
|
|
||||||
+{
|
|
||||||
+ struct expr *tmp, *expr = compound_expr_alloc(int_loc, EXPR_LIST);
|
|
||||||
+ const char *dev;
|
|
||||||
+ json_t *value;
|
|
||||||
+ size_t index;
|
|
||||||
+
|
|
||||||
+ if (!json_unpack(root, "s", &dev)) {
|
|
||||||
+ tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
+ BYTEORDER_HOST_ENDIAN,
|
|
||||||
+ strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
+ compound_expr_add(expr, tmp);
|
|
||||||
+ return expr;
|
|
||||||
+ }
|
|
||||||
+ if (!json_is_array(root)) {
|
|
||||||
+ expr_free(expr);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ json_array_foreach(root, index, value) {
|
|
||||||
+ if (json_unpack(value, "s", &dev)) {
|
|
||||||
+ json_error(ctx, "Invalid device at index %zu.",
|
|
||||||
+ index);
|
|
||||||
+ expr_free(expr);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
+ BYTEORDER_HOST_ENDIAN,
|
|
||||||
+ strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
+ compound_expr_add(expr, tmp);
|
|
||||||
+ }
|
|
||||||
+ return expr;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
enum cmd_ops op, enum cmd_obj obj)
|
|
||||||
{
|
|
||||||
struct handle h = {
|
|
||||||
.table.location = *int_loc,
|
|
||||||
};
|
|
||||||
- const char *family = "", *policy = "", *type, *hookstr, *name, *comment = NULL;
|
|
||||||
+ const char *family = "", *policy = "", *type, *hookstr, *comment = NULL;
|
|
||||||
struct chain *chain = NULL;
|
|
||||||
+ json_t *devs = NULL;
|
|
||||||
int prio;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s, s:s}",
|
|
||||||
@@ -3107,16 +3142,15 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!json_unpack(root, "{s:s}", "dev", &name)) {
|
|
||||||
- struct expr *dev_expr, *expr;
|
|
||||||
+ json_unpack(root, "{s:o}", "dev", &devs);
|
|
||||||
|
|
||||||
- dev_expr = compound_expr_alloc(int_loc, EXPR_LIST);
|
|
||||||
- expr = constant_expr_alloc(int_loc, &integer_type,
|
|
||||||
- BYTEORDER_HOST_ENDIAN,
|
|
||||||
- strlen(name) * BITS_PER_BYTE,
|
|
||||||
- name);
|
|
||||||
- compound_expr_add(dev_expr, expr);
|
|
||||||
- chain->dev_expr = dev_expr;
|
|
||||||
+ if (devs) {
|
|
||||||
+ chain->dev_expr = json_parse_devs(ctx, devs);
|
|
||||||
+ if (!chain->dev_expr) {
|
|
||||||
+ json_error(ctx, "Invalid chain dev.");
|
|
||||||
+ chain_free(chain);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!json_unpack(root, "{s:s}", "policy", &policy)) {
|
|
||||||
@@ -3411,41 +3445,6 @@ static struct cmd *json_parse_cmd_add_element(struct json_ctx *ctx,
|
|
||||||
return cmd_alloc(op, cmd_obj, &h, int_loc, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct expr *json_parse_flowtable_devs(struct json_ctx *ctx,
|
|
||||||
- json_t *root)
|
|
||||||
-{
|
|
||||||
- struct expr *tmp, *expr = compound_expr_alloc(int_loc, EXPR_LIST);
|
|
||||||
- const char *dev;
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
-
|
|
||||||
- if (!json_unpack(root, "s", &dev)) {
|
|
||||||
- tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
- BYTEORDER_HOST_ENDIAN,
|
|
||||||
- strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
- compound_expr_add(expr, tmp);
|
|
||||||
- return expr;
|
|
||||||
- }
|
|
||||||
- if (!json_is_array(root)) {
|
|
||||||
- expr_free(expr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- json_array_foreach(root, index, value) {
|
|
||||||
- if (json_unpack(value, "s", &dev)) {
|
|
||||||
- json_error(ctx, "Invalid flowtable dev at index %zu.",
|
|
||||||
- index);
|
|
||||||
- expr_free(expr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
- BYTEORDER_HOST_ENDIAN,
|
|
||||||
- strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
- compound_expr_add(expr, tmp);
|
|
||||||
- }
|
|
||||||
- return expr;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
|
|
||||||
json_t *root, enum cmd_ops op,
|
|
||||||
enum cmd_obj cmd_obj)
|
|
||||||
@@ -3506,7 +3505,7 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
|
|
||||||
sizeof(int) * BITS_PER_BYTE, &prio);
|
|
||||||
|
|
||||||
if (devs) {
|
|
||||||
- flowtable->dev_expr = json_parse_flowtable_devs(ctx, devs);
|
|
||||||
+ flowtable->dev_expr = json_parse_devs(ctx, devs);
|
|
||||||
if (!flowtable->dev_expr) {
|
|
||||||
json_error(ctx, "Invalid flowtable dev.");
|
|
||||||
flowtable_free(flowtable);
|
|
||||||
@ -1,280 +0,0 @@
|
|||||||
From c7225a21a31131edd16f018a4e4947944db88f01 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 23 Apr 2025 14:26:47 +0200
|
|
||||||
Subject: [PATCH] parser_json: fix handle memleak from error path
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-88181
|
|
||||||
Upstream Status: nftables commit 47e18c0eba51a538e1110322d1a9248b0501d7c8
|
|
||||||
|
|
||||||
commit 47e18c0eba51a538e1110322d1a9248b0501d7c8
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Mon Aug 19 21:34:49 2024 +0200
|
|
||||||
|
|
||||||
parser_json: fix handle memleak from error path
|
|
||||||
|
|
||||||
Based on patch from Sebastian Walz.
|
|
||||||
|
|
||||||
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_json.c | 93 ++++++++++++++++++++++++-----------------------
|
|
||||||
1 file changed, 47 insertions(+), 46 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index d57aa6b..2acc248 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -3138,8 +3138,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
chain->hook.name = chain_hookname_lookup(hookstr);
|
|
||||||
if (!chain->hook.name) {
|
|
||||||
json_error(ctx, "Invalid chain hook '%s'.", hookstr);
|
|
||||||
- chain_free(chain);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_unpack(root, "{s:o}", "dev", &devs);
|
|
||||||
@@ -3148,8 +3147,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
chain->dev_expr = json_parse_devs(ctx, devs);
|
|
||||||
if (!chain->dev_expr) {
|
|
||||||
json_error(ctx, "Invalid chain dev.");
|
|
||||||
- chain_free(chain);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_chain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -3157,8 +3155,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
chain->policy = parse_policy(policy);
|
|
||||||
if (!chain->policy) {
|
|
||||||
json_error(ctx, "Unknown policy '%s'.", policy);
|
|
||||||
- chain_free(chain);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_chain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -3167,6 +3164,11 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
|
|
||||||
|
|
||||||
handle_merge(&chain->handle, &h);
|
|
||||||
return cmd_alloc(op, obj, &h, int_loc, chain);
|
|
||||||
+
|
|
||||||
+err_free_chain:
|
|
||||||
+ chain_free(chain);
|
|
||||||
+ handle_free(&h);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
|
|
||||||
@@ -3206,6 +3208,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
|
|
||||||
|
|
||||||
if (!json_is_array(tmp)) {
|
|
||||||
json_error(ctx, "Value of property \"expr\" must be an array.");
|
|
||||||
+ handle_free(&h);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -3225,16 +3228,14 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
|
|
||||||
if (!json_is_object(value)) {
|
|
||||||
json_error(ctx, "Unexpected expr array element of type %s, expected object.",
|
|
||||||
json_typename(value));
|
|
||||||
- rule_free(rule);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt = json_parse_stmt(ctx, value);
|
|
||||||
|
|
||||||
if (!stmt) {
|
|
||||||
json_error(ctx, "Parsing expr array at index %zd failed.", index);
|
|
||||||
- rule_free(rule);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
rule_stmt_append(rule, stmt);
|
|
||||||
@@ -3244,6 +3245,11 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
|
|
||||||
json_object_del(root, "handle");
|
|
||||||
|
|
||||||
return cmd_alloc(op, obj, &h, int_loc, rule);
|
|
||||||
+
|
|
||||||
+err_free_rule:
|
|
||||||
+ rule_free(rule);
|
|
||||||
+ handle_free(&h);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int string_to_nft_object(const char *str)
|
|
||||||
@@ -3617,8 +3623,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
if (ret < 0 || ret >= (int)sizeof(obj->secmark.ctx)) {
|
|
||||||
json_error(ctx, "Invalid secmark context '%s', max length is %zu.",
|
|
||||||
tmp, sizeof(obj->secmark.ctx));
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
@@ -3634,8 +3639,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
ret >= (int)sizeof(obj->ct_helper.name)) {
|
|
||||||
json_error(ctx, "Invalid CT helper type '%s', max length is %zu.",
|
|
||||||
tmp, sizeof(obj->ct_helper.name));
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
|
|
||||||
@@ -3645,15 +3649,13 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
obj->ct_helper.l4proto = IPPROTO_UDP;
|
|
||||||
} else {
|
|
||||||
json_error(ctx, "Invalid ct helper protocol '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
|
|
||||||
parse_family(tmp, &l3proto)) {
|
|
||||||
json_error(ctx, "Invalid ct helper l3proto '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
obj->ct_helper.l3proto = l3proto;
|
|
||||||
break;
|
|
||||||
@@ -3667,23 +3669,19 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
obj->ct_timeout.l4proto = IPPROTO_UDP;
|
|
||||||
} else {
|
|
||||||
json_error(ctx, "Invalid ct timeout protocol '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
|
|
||||||
parse_family(tmp, &l3proto)) {
|
|
||||||
json_error(ctx, "Invalid ct timeout l3proto '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
obj->ct_timeout.l3proto = l3proto;
|
|
||||||
|
|
||||||
init_list_head(&obj->ct_timeout.timeout_list);
|
|
||||||
- if (json_parse_ct_timeout_policy(ctx, root, obj)) {
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ if (json_parse_ct_timeout_policy(ctx, root, obj))
|
|
||||||
+ goto err_free_obj;
|
|
||||||
break;
|
|
||||||
case NFT_OBJECT_CT_EXPECT:
|
|
||||||
cmd_obj = CMD_OBJ_CT_EXPECT;
|
|
||||||
@@ -3691,8 +3689,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
|
|
||||||
parse_family(tmp, &l3proto)) {
|
|
||||||
json_error(ctx, "Invalid ct expectation l3proto '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
obj->ct_expect.l3proto = l3proto;
|
|
||||||
if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
|
|
||||||
@@ -3702,8 +3699,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
obj->ct_expect.l4proto = IPPROTO_UDP;
|
|
||||||
} else {
|
|
||||||
json_error(ctx, "Invalid ct expectation protocol '%s'.", tmp);
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!json_unpack(root, "{s:i}", "dport", &i))
|
|
||||||
@@ -3717,10 +3713,9 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
obj->type = NFT_OBJECT_LIMIT;
|
|
||||||
if (json_unpack_err(ctx, root, "{s:I, s:s}",
|
|
||||||
"rate", &obj->limit.rate,
|
|
||||||
- "per", &tmp)) {
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ "per", &tmp))
|
|
||||||
+ goto err_free_obj;
|
|
||||||
+
|
|
||||||
json_unpack(root, "{s:s}", "rate_unit", &rate_unit);
|
|
||||||
json_unpack(root, "{s:b}", "inv", &inv);
|
|
||||||
json_unpack(root, "{s:i}", "burst", &obj->limit.burst);
|
|
||||||
@@ -3741,20 +3736,18 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
case CMD_OBJ_SYNPROXY:
|
|
||||||
obj->type = NFT_OBJECT_SYNPROXY;
|
|
||||||
if (json_unpack_err(ctx, root, "{s:i, s:i}",
|
|
||||||
- "mss", &i, "wscale", &j)) {
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ "mss", &i, "wscale", &j))
|
|
||||||
+ goto err_free_obj;
|
|
||||||
+
|
|
||||||
obj->synproxy.mss = i;
|
|
||||||
obj->synproxy.wscale = j;
|
|
||||||
obj->synproxy.flags |= NF_SYNPROXY_OPT_MSS;
|
|
||||||
obj->synproxy.flags |= NF_SYNPROXY_OPT_WSCALE;
|
|
||||||
if (!json_unpack(root, "{s:o}", "flags", &jflags)) {
|
|
||||||
flags = json_parse_synproxy_flags(ctx, jflags);
|
|
||||||
- if (flags < 0) {
|
|
||||||
- obj_free(obj);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
+ if (flags < 0)
|
|
||||||
+ goto err_free_obj;
|
|
||||||
+
|
|
||||||
obj->synproxy.flags |= flags;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
@@ -3766,6 +3759,11 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
json_object_del(root, "handle");
|
|
||||||
|
|
||||||
return cmd_alloc(op, cmd_obj, &h, int_loc, obj);
|
|
||||||
+
|
|
||||||
+err_free_obj:
|
|
||||||
+ obj_free(obj);
|
|
||||||
+ handle_free(&h);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cmd *json_parse_cmd_add(struct json_ctx *ctx,
|
|
||||||
@@ -3879,8 +3877,7 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
|
|
||||||
if (!json_is_object(value)) {
|
|
||||||
json_error(ctx, "Unexpected expr array element of type %s, expected object.",
|
|
||||||
json_typename(value));
|
|
||||||
- rule_free(rule);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt = json_parse_stmt(ctx, value);
|
|
||||||
@@ -3888,8 +3885,7 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
|
|
||||||
if (!stmt) {
|
|
||||||
json_error(ctx, "Parsing expr array at index %zd failed.",
|
|
||||||
index);
|
|
||||||
- rule_free(rule);
|
|
||||||
- return NULL;
|
|
||||||
+ goto err_free_replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
rule_stmt_append(rule, stmt);
|
|
||||||
@@ -3899,6 +3895,11 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
|
|
||||||
json_object_del(root, "handle");
|
|
||||||
|
|
||||||
return cmd_alloc(op, CMD_OBJ_RULE, &h, int_loc, rule);
|
|
||||||
+
|
|
||||||
+err_free_replace:
|
|
||||||
+ rule_free(rule);
|
|
||||||
+ handle_free(&h);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cmd *json_parse_cmd_list_multiple(struct json_ctx *ctx,
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
From 1172955315cf4d14f0ddc53f26ff82447f0dadda Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:09 +0200
|
|
||||||
Subject: [PATCH] tests: shell: Fix sets/reset_command_0 for current kernels
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit 7a6089a400a573b9a4fd92f29c00a6be7b8ef269
|
|
||||||
|
|
||||||
commit 7a6089a400a573b9a4fd92f29c00a6be7b8ef269
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Nov 2 16:02:14 2023 +0100
|
|
||||||
|
|
||||||
tests: shell: Fix sets/reset_command_0 for current kernels
|
|
||||||
|
|
||||||
Since kernel commit 4c90bba60c26 ("netfilter: nf_tables: do not refresh
|
|
||||||
timeout when resetting element"), element reset won't touch expiry
|
|
||||||
anymore. Invert the one check to make sure it remains unaltered, drop
|
|
||||||
the other testing behaviour for per-element timeouts.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/shell/testcases/sets/reset_command_0 | 10 ++--------
|
|
||||||
1 file changed, 2 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/sets/reset_command_0 b/tests/shell/testcases/sets/reset_command_0
|
|
||||||
index e663dac..d38ddb3 100755
|
|
||||||
--- a/tests/shell/testcases/sets/reset_command_0
|
|
||||||
+++ b/tests/shell/testcases/sets/reset_command_0
|
|
||||||
@@ -44,10 +44,10 @@ elem='element t s { 1.0.0.1 . udp . 53 }'
|
|
||||||
grep 'elements = ' | drop_seconds | uniq | wc -l) == 1 ]]
|
|
||||||
echo OK
|
|
||||||
|
|
||||||
-echo -n "counters and expiry are reset: "
|
|
||||||
+echo -n "counters are reset, expiry left alone: "
|
|
||||||
NEW=$($NFT "get $elem")
|
|
||||||
grep -q 'counter packets 0 bytes 0' <<< "$NEW"
|
|
||||||
-[[ $(expires_minutes <<< "$NEW") -gt 20 ]]
|
|
||||||
+[[ $(expires_minutes <<< "$NEW") -lt 20 ]]
|
|
||||||
echo OK
|
|
||||||
|
|
||||||
echo -n "get map elem matches reset map elem: "
|
|
||||||
@@ -80,12 +80,6 @@ OUT=$($NFT reset map t m)
|
|
||||||
$DIFF -u <(echo "$EXP") <(echo "$OUT")
|
|
||||||
echo OK
|
|
||||||
|
|
||||||
-echo -n "reset command respects per-element timeout: "
|
|
||||||
-VAL=$($NFT get element t s '{ 2.0.0.2 . tcp . 22 }' | expires_minutes)
|
|
||||||
-[[ $VAL -lt 15 ]] # custom timeout applies
|
|
||||||
-[[ $VAL -gt 10 ]] # expires was reset
|
|
||||||
-echo OK
|
|
||||||
-
|
|
||||||
echo -n "remaining elements are reset: "
|
|
||||||
OUT=$($NFT list ruleset)
|
|
||||||
grep -q '2.0.0.2 . tcp . 22 counter packets 0 bytes 0' <<< "$OUT"
|
|
||||||
@ -1,165 +0,0 @@
|
|||||||
From 52f4e05d55ef0215dd7df050ff93270f185c07b0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:09 +0200
|
|
||||||
Subject: [PATCH] tests: shell: connect chains to hook point
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit 1fc78397e9a1fb5e41841b8b4e92a9eb9536c6f1
|
|
||||||
Conflicts: Dropped changes to .json-nft files missing downstream
|
|
||||||
|
|
||||||
commit 1fc78397e9a1fb5e41841b8b4e92a9eb9536c6f1
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Wed Jul 10 02:33:37 2024 +0200
|
|
||||||
|
|
||||||
tests: shell: connect chains to hook point
|
|
||||||
|
|
||||||
These tests should fail because they contain a loop or exceed the jump stack.
|
|
||||||
|
|
||||||
But this depends on the kernel validating chains that are not bound to any
|
|
||||||
basechain/hook point.
|
|
||||||
|
|
||||||
Wire up the initial chain to filter type.
|
|
||||||
|
|
||||||
Without this tests will start to fail when kernel stops validating
|
|
||||||
chains that are not reachable by any base chain.
|
|
||||||
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/shell/testcases/chains/0003jump_loop_1 | 3 ++-
|
|
||||||
tests/shell/testcases/chains/0010endless_jump_loop_1 | 2 +-
|
|
||||||
tests/shell/testcases/chains/0011endless_jump_loop_1 | 2 +-
|
|
||||||
tests/shell/testcases/chains/0018check_jump_loop_1 | 2 +-
|
|
||||||
tests/shell/testcases/chains/dumps/0003jump_loop_1.nft | 1 +
|
|
||||||
tests/shell/testcases/chains/dumps/0010endless_jump_loop_1.nft | 1 +
|
|
||||||
tests/shell/testcases/chains/dumps/0011endless_jump_loop_1.nft | 1 +
|
|
||||||
tests/shell/testcases/chains/dumps/0018check_jump_loop_1.nft | 1 +
|
|
||||||
tests/shell/testcases/transactions/0023rule_1 | 2 +-
|
|
||||||
tests/shell/testcases/transactions/anon_chain_loop | 2 +-
|
|
||||||
10 files changed, 11 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/chains/0003jump_loop_1 b/tests/shell/testcases/chains/0003jump_loop_1
|
|
||||||
index 80e243f..1a8eaf6 100755
|
|
||||||
--- a/tests/shell/testcases/chains/0003jump_loop_1
|
|
||||||
+++ b/tests/shell/testcases/chains/0003jump_loop_1
|
|
||||||
@@ -5,8 +5,9 @@ set -e
|
|
||||||
MAX_JUMPS=16
|
|
||||||
|
|
||||||
$NFT add table t
|
|
||||||
+$NFT "add chain t c1 { type filter hook prerouting priority 0; }"
|
|
||||||
|
|
||||||
-for i in $(seq 1 $MAX_JUMPS)
|
|
||||||
+for i in $(seq 2 $MAX_JUMPS)
|
|
||||||
do
|
|
||||||
$NFT add chain t c${i}
|
|
||||||
done
|
|
||||||
diff --git a/tests/shell/testcases/chains/0010endless_jump_loop_1 b/tests/shell/testcases/chains/0010endless_jump_loop_1
|
|
||||||
index 5d3ef23..6000e5d 100755
|
|
||||||
--- a/tests/shell/testcases/chains/0010endless_jump_loop_1
|
|
||||||
+++ b/tests/shell/testcases/chains/0010endless_jump_loop_1
|
|
||||||
@@ -3,7 +3,7 @@
|
|
||||||
set -e
|
|
||||||
|
|
||||||
$NFT add table t
|
|
||||||
-$NFT add chain t c
|
|
||||||
+$NFT add chain "t c { type filter hook input priority 0; }"
|
|
||||||
|
|
||||||
# kernel should return ELOOP
|
|
||||||
$NFT add rule t c tcp dport vmap {1 : jump c} 2>/dev/null || exit 0
|
|
||||||
diff --git a/tests/shell/testcases/chains/0011endless_jump_loop_1 b/tests/shell/testcases/chains/0011endless_jump_loop_1
|
|
||||||
index d75932d..66abf8d 100755
|
|
||||||
--- a/tests/shell/testcases/chains/0011endless_jump_loop_1
|
|
||||||
+++ b/tests/shell/testcases/chains/0011endless_jump_loop_1
|
|
||||||
@@ -3,7 +3,7 @@
|
|
||||||
set -e
|
|
||||||
|
|
||||||
$NFT add table t
|
|
||||||
-$NFT add chain t c1
|
|
||||||
+$NFT add chain "t c1 { type filter hook forward priority 0; }"
|
|
||||||
$NFT add chain t c2
|
|
||||||
$NFT add map t m {type inet_service : verdict \;}
|
|
||||||
$NFT add element t m {2 : jump c2}
|
|
||||||
diff --git a/tests/shell/testcases/chains/0018check_jump_loop_1 b/tests/shell/testcases/chains/0018check_jump_loop_1
|
|
||||||
index b87520f..1e674d3 100755
|
|
||||||
--- a/tests/shell/testcases/chains/0018check_jump_loop_1
|
|
||||||
+++ b/tests/shell/testcases/chains/0018check_jump_loop_1
|
|
||||||
@@ -3,7 +3,7 @@
|
|
||||||
set -e
|
|
||||||
|
|
||||||
$NFT add table ip filter
|
|
||||||
-$NFT add chain ip filter ap1
|
|
||||||
+$NFT add chain ip filter ap1 "{ type filter hook input priority 0; }"
|
|
||||||
$NFT add chain ip filter ap2
|
|
||||||
$NFT add rule ip filter ap1 jump ap2
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0003jump_loop_1.nft b/tests/shell/testcases/chains/dumps/0003jump_loop_1.nft
|
|
||||||
index 7054cde..8d89bc4 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0003jump_loop_1.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0003jump_loop_1.nft
|
|
||||||
@@ -1,5 +1,6 @@
|
|
||||||
table ip t {
|
|
||||||
chain c1 {
|
|
||||||
+ type filter hook prerouting priority filter; policy accept;
|
|
||||||
jump c2
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0010endless_jump_loop_1.nft b/tests/shell/testcases/chains/dumps/0010endless_jump_loop_1.nft
|
|
||||||
index 1e0d1d6..62fefaf 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0010endless_jump_loop_1.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0010endless_jump_loop_1.nft
|
|
||||||
@@ -1,4 +1,5 @@
|
|
||||||
table ip t {
|
|
||||||
chain c {
|
|
||||||
+ type filter hook input priority filter; policy accept;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0011endless_jump_loop_1.nft b/tests/shell/testcases/chains/dumps/0011endless_jump_loop_1.nft
|
|
||||||
index ca0a737..d35736e 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0011endless_jump_loop_1.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0011endless_jump_loop_1.nft
|
|
||||||
@@ -5,6 +5,7 @@ table ip t {
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c1 {
|
|
||||||
+ type filter hook forward priority filter; policy accept;
|
|
||||||
tcp dport vmap @m
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0018check_jump_loop_1.nft b/tests/shell/testcases/chains/dumps/0018check_jump_loop_1.nft
|
|
||||||
index 437900b..bdd0ead 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0018check_jump_loop_1.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0018check_jump_loop_1.nft
|
|
||||||
@@ -1,5 +1,6 @@
|
|
||||||
table ip filter {
|
|
||||||
chain ap1 {
|
|
||||||
+ type filter hook input priority filter; policy accept;
|
|
||||||
jump ap2
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/transactions/0023rule_1 b/tests/shell/testcases/transactions/0023rule_1
|
|
||||||
index e58c088..863bcde 100755
|
|
||||||
--- a/tests/shell/testcases/transactions/0023rule_1
|
|
||||||
+++ b/tests/shell/testcases/transactions/0023rule_1
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
RULESET="add table x
|
|
||||||
-add chain x y
|
|
||||||
+add chain x y { type filter hook input priority 0; }
|
|
||||||
add rule x y jump y"
|
|
||||||
|
|
||||||
# kernel must return ELOOP
|
|
||||||
diff --git a/tests/shell/testcases/transactions/anon_chain_loop b/tests/shell/testcases/transactions/anon_chain_loop
|
|
||||||
index 2fd6181..3053d16 100755
|
|
||||||
--- a/tests/shell/testcases/transactions/anon_chain_loop
|
|
||||||
+++ b/tests/shell/testcases/transactions/anon_chain_loop
|
|
||||||
@@ -3,7 +3,7 @@
|
|
||||||
# anon chains with c1 -> c2 recursive jump, expect failure
|
|
||||||
$NFT -f - <<EOF
|
|
||||||
table ip t {
|
|
||||||
- chain c2 { }
|
|
||||||
+ chain c2 { type filter hook input priority 0; }
|
|
||||||
chain c1 { }
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
From 5cf419d1ee6579ca404c4e0778713a65fd473a50 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:50 +0200
|
|
||||||
Subject: [PATCH] datatype: rt_symbol_table_init() to search for iproute2
|
|
||||||
configs
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit d0f70a1739b8e512986fb460a7fa7ff8a9300b68
|
|
||||||
|
|
||||||
commit d0f70a1739b8e512986fb460a7fa7ff8a9300b68
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Dec 15 21:59:44 2023 +0100
|
|
||||||
|
|
||||||
datatype: rt_symbol_table_init() to search for iproute2 configs
|
|
||||||
|
|
||||||
There is an ongoing effort among various distributions to tidy up in
|
|
||||||
/etc. The idea is to reduce contents to just what the admin manually
|
|
||||||
inserted to customize the system, anything else shall move out to /usr
|
|
||||||
(or so). The various files in /etc/iproute2 fall in that category as
|
|
||||||
they are seldomly modified.
|
|
||||||
|
|
||||||
The crux is though that iproute2 project seems not quite sure yet where
|
|
||||||
the files should go. While v6.6.0 installs them into /usr/lib/iproute2,
|
|
||||||
current mast^Wmain branch uses /usr/share/iproute2. Assume this is going
|
|
||||||
to stay as /(usr/)lib does not seem right for such files.
|
|
||||||
|
|
||||||
Note that rt_symbol_table_init() is not just used for
|
|
||||||
iproute2-maintained configs but also for connlabel.conf - so retain the
|
|
||||||
old behaviour when passed an absolute path.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/datatype.c | 38 ++++++++++++++++++++++++++++++++++----
|
|
||||||
src/meta.c | 2 +-
|
|
||||||
src/rt.c | 2 +-
|
|
||||||
3 files changed, 36 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/datatype.c b/src/datatype.c
|
|
||||||
index 64e4647..9530ae7 100644
|
|
||||||
--- a/src/datatype.c
|
|
||||||
+++ b/src/datatype.c
|
|
||||||
@@ -855,19 +855,47 @@ const struct datatype inet_service_type = {
|
|
||||||
|
|
||||||
#define RT_SYM_TAB_INITIAL_SIZE 16
|
|
||||||
|
|
||||||
+static FILE *open_iproute2_db(const char *filename, char **path)
|
|
||||||
+{
|
|
||||||
+ FILE *ret;
|
|
||||||
+
|
|
||||||
+ if (filename[0] == '/')
|
|
||||||
+ return fopen(filename, "r");
|
|
||||||
+
|
|
||||||
+ if (asprintf(path, "/etc/iproute2/%s", filename) == -1)
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
+ ret = fopen(*path, "r");
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ free(*path);
|
|
||||||
+ if (asprintf(path, "/usr/share/iproute2/%s", filename) == -1)
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
+ ret = fopen(*path, "r");
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ free(*path);
|
|
||||||
+fail:
|
|
||||||
+ *path = NULL;
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
struct symbol_table *rt_symbol_table_init(const char *filename)
|
|
||||||
{
|
|
||||||
+ char buf[512], namebuf[512], *p, *path = NULL;
|
|
||||||
struct symbolic_constant s;
|
|
||||||
struct symbol_table *tbl;
|
|
||||||
unsigned int size, nelems, val;
|
|
||||||
- char buf[512], namebuf[512], *p;
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
size = RT_SYM_TAB_INITIAL_SIZE;
|
|
||||||
tbl = xmalloc(sizeof(*tbl) + size * sizeof(s));
|
|
||||||
nelems = 0;
|
|
||||||
|
|
||||||
- f = fopen(filename, "r");
|
|
||||||
+ f = open_iproute2_db(filename, &path);
|
|
||||||
if (f == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
@@ -882,7 +910,7 @@ struct symbol_table *rt_symbol_table_init(const char *filename)
|
|
||||||
sscanf(p, "%u %511s\n", &val, namebuf) != 2 &&
|
|
||||||
sscanf(p, "%u %511s #", &val, namebuf) != 2) {
|
|
||||||
fprintf(stderr, "iproute database '%s' corrupted\n",
|
|
||||||
- filename);
|
|
||||||
+ path ?: filename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -899,6 +927,8 @@ struct symbol_table *rt_symbol_table_init(const char *filename)
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
out:
|
|
||||||
+ if (path)
|
|
||||||
+ free(path);
|
|
||||||
tbl->symbols[nelems] = SYMBOL_LIST_END;
|
|
||||||
return tbl;
|
|
||||||
}
|
|
||||||
@@ -914,7 +944,7 @@ void rt_symbol_table_free(const struct symbol_table *tbl)
|
|
||||||
|
|
||||||
void mark_table_init(struct nft_ctx *ctx)
|
|
||||||
{
|
|
||||||
- ctx->output.tbl.mark = rt_symbol_table_init("/etc/iproute2/rt_marks");
|
|
||||||
+ ctx->output.tbl.mark = rt_symbol_table_init("rt_marks");
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark_table_exit(struct nft_ctx *ctx)
|
|
||||||
diff --git a/src/meta.c b/src/meta.c
|
|
||||||
index b578d5e..b69dca2 100644
|
|
||||||
--- a/src/meta.c
|
|
||||||
+++ b/src/meta.c
|
|
||||||
@@ -336,7 +336,7 @@ const struct datatype pkttype_type = {
|
|
||||||
|
|
||||||
void devgroup_table_init(struct nft_ctx *ctx)
|
|
||||||
{
|
|
||||||
- ctx->output.tbl.devgroup = rt_symbol_table_init("/etc/iproute2/group");
|
|
||||||
+ ctx->output.tbl.devgroup = rt_symbol_table_init("group");
|
|
||||||
}
|
|
||||||
|
|
||||||
void devgroup_table_exit(struct nft_ctx *ctx)
|
|
||||||
diff --git a/src/rt.c b/src/rt.c
|
|
||||||
index f5c8055..3ee710d 100644
|
|
||||||
--- a/src/rt.c
|
|
||||||
+++ b/src/rt.c
|
|
||||||
@@ -25,7 +25,7 @@
|
|
||||||
|
|
||||||
void realm_table_rt_init(struct nft_ctx *ctx)
|
|
||||||
{
|
|
||||||
- ctx->output.tbl.realm = rt_symbol_table_init("/etc/iproute2/rt_realms");
|
|
||||||
+ ctx->output.tbl.realm = rt_symbol_table_init("rt_realms");
|
|
||||||
}
|
|
||||||
|
|
||||||
void realm_table_rt_exit(struct nft_ctx *ctx)
|
|
||||||
@ -1,226 +0,0 @@
|
|||||||
From a902fc33ebf202de6e8a7fa7cbd8ba840d80605c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:50 +0200
|
|
||||||
Subject: [PATCH] tests: py: remove huge-limit test cases
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit 1ee84db0360db0da336d5b1ee92807d29fcfbbe1
|
|
||||||
|
|
||||||
commit 1ee84db0360db0da336d5b1ee92807d29fcfbbe1
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu Jan 18 13:24:04 2024 +0100
|
|
||||||
|
|
||||||
tests: py: remove huge-limit test cases
|
|
||||||
|
|
||||||
These tests will fail once the kernel checks for overflow
|
|
||||||
in the internal token bucken counter, so drop them.
|
|
||||||
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/any/limit.t | 4 ---
|
|
||||||
tests/py/any/limit.t.json | 51 --------------------------------
|
|
||||||
tests/py/any/limit.t.json.output | 28 ------------------
|
|
||||||
tests/py/any/limit.t.payload | 17 -----------
|
|
||||||
4 files changed, 100 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/any/limit.t b/tests/py/any/limit.t
|
|
||||||
index a04ef42..2a84e3f 100644
|
|
||||||
--- a/tests/py/any/limit.t
|
|
||||||
+++ b/tests/py/any/limit.t
|
|
||||||
@@ -22,7 +22,6 @@ limit rate 2 kbytes/second;ok
|
|
||||||
limit rate 1025 kbytes/second;ok
|
|
||||||
limit rate 1023 mbytes/second;ok
|
|
||||||
limit rate 10230 mbytes/second;ok
|
|
||||||
-limit rate 1023000 mbytes/second;ok
|
|
||||||
limit rate 512 kbytes/second burst 5 packets;fail
|
|
||||||
|
|
||||||
limit rate 1 bytes / second;ok;limit rate 1 bytes/second
|
|
||||||
@@ -33,7 +32,6 @@ limit rate 1 gbytes / second;fail
|
|
||||||
limit rate 1025 bytes/second burst 512 bytes;ok
|
|
||||||
limit rate 1025 kbytes/second burst 1023 kbytes;ok
|
|
||||||
limit rate 1025 mbytes/second burst 1025 kbytes;ok
|
|
||||||
-limit rate 1025000 mbytes/second burst 1023 mbytes;ok
|
|
||||||
|
|
||||||
limit rate over 400/minute;ok;limit rate over 400/minute burst 5 packets
|
|
||||||
limit rate over 20/second;ok;limit rate over 20/second burst 5 packets
|
|
||||||
@@ -47,9 +45,7 @@ limit rate over 2 kbytes/second;ok
|
|
||||||
limit rate over 1025 kbytes/second;ok
|
|
||||||
limit rate over 1023 mbytes/second;ok
|
|
||||||
limit rate over 10230 mbytes/second;ok
|
|
||||||
-limit rate over 1023000 mbytes/second;ok
|
|
||||||
|
|
||||||
limit rate over 1025 bytes/second burst 512 bytes;ok
|
|
||||||
limit rate over 1025 kbytes/second burst 1023 kbytes;ok
|
|
||||||
limit rate over 1025 mbytes/second burst 1025 kbytes;ok
|
|
||||||
-limit rate over 1025000 mbytes/second burst 1023 mbytes;ok
|
|
||||||
diff --git a/tests/py/any/limit.t.json b/tests/py/any/limit.t.json
|
|
||||||
index e001ba0..73160b2 100644
|
|
||||||
--- a/tests/py/any/limit.t.json
|
|
||||||
+++ b/tests/py/any/limit.t.json
|
|
||||||
@@ -114,17 +114,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# limit rate 1023000 mbytes/second
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1023000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# limit rate 1 bytes / second
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -203,19 +192,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# limit rate 1025000 mbytes/second burst 1023 mbytes
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "burst": 1023,
|
|
||||||
- "burst_unit": "mbytes",
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1025000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# limit rate over 400/minute
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -343,18 +319,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# limit rate over 1023000 mbytes/second
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "inv": true,
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1023000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# limit rate over 1025 bytes/second burst 512 bytes
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -396,18 +360,3 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
-
|
|
||||||
-# limit rate over 1025000 mbytes/second burst 1023 mbytes
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "burst": 1023,
|
|
||||||
- "burst_unit": "mbytes",
|
|
||||||
- "inv": true,
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1025000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
diff --git a/tests/py/any/limit.t.json.output b/tests/py/any/limit.t.json.output
|
|
||||||
index 5a95f5e..2c94d2d 100644
|
|
||||||
--- a/tests/py/any/limit.t.json.output
|
|
||||||
+++ b/tests/py/any/limit.t.json.output
|
|
||||||
@@ -118,19 +118,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# limit rate 1023000 mbytes/second
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "burst": 0,
|
|
||||||
- "burst_unit": "bytes",
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1023000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# limit rate over 400/minute
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -260,18 +247,3 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
-
|
|
||||||
-# limit rate over 1023000 mbytes/second
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "limit": {
|
|
||||||
- "burst": 0,
|
|
||||||
- "burst_unit": "bytes",
|
|
||||||
- "inv": true,
|
|
||||||
- "per": "second",
|
|
||||||
- "rate": 1023000,
|
|
||||||
- "rate_unit": "mbytes"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
diff --git a/tests/py/any/limit.t.payload b/tests/py/any/limit.t.payload
|
|
||||||
index 0c7ee94..dc6701b 100644
|
|
||||||
--- a/tests/py/any/limit.t.payload
|
|
||||||
+++ b/tests/py/any/limit.t.payload
|
|
||||||
@@ -42,10 +42,6 @@ ip test-ip4 output
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 10726932480/second burst 0 type bytes flags 0x0 ]
|
|
||||||
|
|
||||||
-# limit rate 1023000 mbytes/second
|
|
||||||
-ip test-ip4 output
|
|
||||||
- [ limit rate 1072693248000/second burst 0 type bytes flags 0x0 ]
|
|
||||||
-
|
|
||||||
# limit rate 1 bytes / second
|
|
||||||
ip
|
|
||||||
[ limit rate 1/second burst 0 type bytes flags 0x0 ]
|
|
||||||
@@ -71,10 +67,6 @@ ip test-ip4 output
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 1074790400/second burst 1049600 type bytes flags 0x0 ]
|
|
||||||
|
|
||||||
-# limit rate 1025000 mbytes/second burst 1023 mbytes
|
|
||||||
-ip test-ip4 output
|
|
||||||
- [ limit rate 1074790400000/second burst 1072693248 type bytes flags 0x0 ]
|
|
||||||
-
|
|
||||||
# limit rate over 400/minute
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 400/minute burst 5 type packets flags 0x1 ]
|
|
||||||
@@ -119,10 +111,6 @@ ip test-ip4 output
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 10726932480/second burst 0 type bytes flags 0x1 ]
|
|
||||||
|
|
||||||
-# limit rate over 1023000 mbytes/second
|
|
||||||
-ip test-ip4 output
|
|
||||||
- [ limit rate 1072693248000/second burst 0 type bytes flags 0x1 ]
|
|
||||||
-
|
|
||||||
# limit rate over 1025 bytes/second burst 512 bytes
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 1025/second burst 512 type bytes flags 0x1 ]
|
|
||||||
@@ -134,8 +122,3 @@ ip test-ip4 output
|
|
||||||
# limit rate over 1025 mbytes/second burst 1025 kbytes
|
|
||||||
ip test-ip4 output
|
|
||||||
[ limit rate 1074790400/second burst 1049600 type bytes flags 0x1 ]
|
|
||||||
-
|
|
||||||
-# limit rate over 1025000 mbytes/second burst 1023 mbytes
|
|
||||||
-ip test-ip4 output
|
|
||||||
- [ limit rate 1074790400000/second burst 1072693248 type bytes flags 0x1 ]
|
|
||||||
-
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
From 757dee30af84a3443c6eeb9a3cddf8a5e4f8928a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:50 +0200
|
|
||||||
Subject: [PATCH] tests: py: add missing json.output data
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit f58e72a2f5aa134653e7ee8b5432b23eb0674c3c
|
|
||||||
|
|
||||||
commit f58e72a2f5aa134653e7ee8b5432b23eb0674c3c
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Mon Feb 26 09:45:43 2024 +0100
|
|
||||||
|
|
||||||
tests: py: add missing json.output data
|
|
||||||
|
|
||||||
Fixes: bridge/vlan.t: WARNING: line 56: ...
|
|
||||||
|
|
||||||
Fixes: 8b9ae77598b4 ("tests: never merge across non-expression statements redux 2")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/bridge/vlan.t.json.output | 31 ++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 31 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/tests/py/bridge/vlan.t.json.output b/tests/py/bridge/vlan.t.json.output
|
|
||||||
index 2f90c8f..eea2d41 100644
|
|
||||||
--- a/tests/py/bridge/vlan.t.json.output
|
|
||||||
+++ b/tests/py/bridge/vlan.t.json.output
|
|
||||||
@@ -202,3 +202,34 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
+
|
|
||||||
+# ether saddr 00:11:22:33:44:55 counter ether type 8021q
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "saddr",
|
|
||||||
+ "protocol": "ether"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "00:11:22:33:44:55"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "counter": null
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "type",
|
|
||||||
+ "protocol": "ether"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "8021q"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
From c970cef4925493bc7ef0064896d4b2486bb2fa6a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Thu, 16 Oct 2025 16:12:50 +0200
|
|
||||||
Subject: [PATCH] tests: py: missing json output in never merge across
|
|
||||||
non-expression statements
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-114095
|
|
||||||
Upstream Status: nftables commit 94fd162ea4d25fe6b0b4d58dcb7ff66dc55f3247
|
|
||||||
|
|
||||||
commit 94fd162ea4d25fe6b0b4d58dcb7ff66dc55f3247
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Wed Dec 6 19:30:44 2023 +0100
|
|
||||||
|
|
||||||
tests: py: missing json output in never merge across non-expression statements
|
|
||||||
|
|
||||||
Add missing json output.
|
|
||||||
|
|
||||||
Fixes: 99ab1b8feb16 ("rule: never merge across non-expression statements")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/ip/ip.t.json.output | 31 +++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 31 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/tests/py/ip/ip.t.json.output b/tests/py/ip/ip.t.json.output
|
|
||||||
index b201cda..351ae93 100644
|
|
||||||
--- a/tests/py/ip/ip.t.json.output
|
|
||||||
+++ b/tests/py/ip/ip.t.json.output
|
|
||||||
@@ -230,3 +230,34 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# ip saddr 1.2.3.4 counter ip daddr 3.4.5.6
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "saddr",
|
|
||||||
+ "protocol": "ip"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "1.2.3.4"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "counter": null
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "daddr",
|
|
||||||
+ "protocol": "ip"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "3.4.5.6"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
From 8dc1e0b04b316e0e860e39a61d012fd9772bf32c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 26 Nov 2025 18:35:24 +0100
|
|
||||||
Subject: [PATCH] Revert doc/ part of "src: add tcp option reset support"
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-126817
|
|
||||||
Upstream Status: RHEL-only
|
|
||||||
|
|
||||||
Revert documentation added by commit
|
|
||||||
5d837d270d5a8b3a4d3fdca12d0f0800b8287cdd.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/statements.txt | 7 -------
|
|
||||||
1 file changed, 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/statements.txt b/doc/statements.txt
|
|
||||||
index 1967280..abe9e6d 100644
|
|
||||||
--- a/doc/statements.txt
|
|
||||||
+++ b/doc/statements.txt
|
|
||||||
@@ -80,13 +80,6 @@ tcp flags syn tcp option maxseg size set 1360
|
|
||||||
tcp flags syn tcp option maxseg size set rt mtu
|
|
||||||
---------------
|
|
||||||
|
|
||||||
-You can also remove tcp options via reset keyword.
|
|
||||||
-
|
|
||||||
-.remove tcp option
|
|
||||||
----------------
|
|
||||||
-tcp flags syn reset tcp option sack-perm
|
|
||||||
----------------
|
|
||||||
-
|
|
||||||
LOG STATEMENT
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
[verse]
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From f9387056d058e33ffa48288fcdf5c3468d9ab53c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 26 Nov 2025 18:35:53 +0100
|
|
||||||
Subject: [PATCH] Revert doc/ part of "meta: introduce meta broute support"
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-126817
|
|
||||||
Upstream Status: RHEL-only
|
|
||||||
|
|
||||||
Revert documentation added by commit
|
|
||||||
97672e54518b28923951c96191edb5b7b5f5f294.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/statements.txt | 5 +----
|
|
||||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/statements.txt b/doc/statements.txt
|
|
||||||
index abe9e6d..c29a2ff 100644
|
|
||||||
--- a/doc/statements.txt
|
|
||||||
+++ b/doc/statements.txt
|
|
||||||
@@ -289,7 +289,7 @@ A meta statement sets the value of a meta expression. The existing meta fields
|
|
||||||
are: priority, mark, pkttype, nftrace. +
|
|
||||||
|
|
||||||
[verse]
|
|
||||||
-*meta* {*mark* | *priority* | *pkttype* | *nftrace* | *broute*} *set* 'value'
|
|
||||||
+*meta* {*mark* | *priority* | *pkttype* | *nftrace*} *set* 'value'
|
|
||||||
|
|
||||||
A meta statement sets meta data associated with a packet. +
|
|
||||||
|
|
||||||
@@ -309,9 +309,6 @@ pkt_type
|
|
||||||
|nftrace |
|
|
||||||
ruleset packet tracing on/off. Use *monitor trace* command to watch traces|
|
|
||||||
0, 1
|
|
||||||
-|broute |
|
|
||||||
-broute on/off. packets are routed instead of being bridged|
|
|
||||||
-0, 1
|
|
||||||
|==========================
|
|
||||||
|
|
||||||
LIMIT STATEMENT
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
From dc0320014e2b147479705c5e2f7df7080d27bc66 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 26 Nov 2025 18:36:13 +0100
|
|
||||||
Subject: [PATCH] Revert doc/ part of "exthdr: add boolean DCCP option
|
|
||||||
matching"
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-126817
|
|
||||||
Upstream Status: RHEL-only
|
|
||||||
|
|
||||||
Revert documentation added by commit
|
|
||||||
6ab0fd6c67dbccedb49209b94eb7f740dd32fd2a.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/libnftables-json.adoc | 11 -----------
|
|
||||||
doc/payload-expression.txt | 6 ------
|
|
||||||
2 files changed, 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
|
||||||
index 0e424c2..c5e5f23 100644
|
|
||||||
--- a/doc/libnftables-json.adoc
|
|
||||||
+++ b/doc/libnftables-json.adoc
|
|
||||||
@@ -1235,17 +1235,6 @@ If the *field* property is not given, the expression is to be used as an SCTP
|
|
||||||
chunk existence check in a *match* statement with a boolean on the right hand
|
|
||||||
side.
|
|
||||||
|
|
||||||
-=== DCCP OPTION
|
|
||||||
-[verse]
|
|
||||||
-*{ "dccp option": {
|
|
||||||
- "type":* 'NUMBER'*
|
|
||||||
-*}}*
|
|
||||||
-
|
|
||||||
-Create a reference to a DCCP option (*type*).
|
|
||||||
-
|
|
||||||
-The expression is to be used as a DCCP option existence check in a *match*
|
|
||||||
-statement with a boolean on the right hand side.
|
|
||||||
-
|
|
||||||
=== META
|
|
||||||
[verse]
|
|
||||||
____
|
|
||||||
diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
|
|
||||||
index c7c267d..8afeb71 100644
|
|
||||||
--- a/doc/payload-expression.txt
|
|
||||||
+++ b/doc/payload-expression.txt
|
|
||||||
@@ -775,7 +775,6 @@ The following syntaxes are valid only in a relational expression with boolean ty
|
|
||||||
*exthdr* {*hbh* | *frag* | *rt* | *dst* | *mh*}
|
|
||||||
*tcp option* {*eol* | *nop* | *maxseg* | *window* | *sack-perm* | *sack* | *sack0* | *sack1* | *sack2* | *sack3* | *timestamp*}
|
|
||||||
*ip option* { lsrr | ra | rr | ssrr }
|
|
||||||
-*dccp option* 'dccp_option_type'
|
|
||||||
|
|
||||||
.IPv6 extension headers
|
|
||||||
[options="header"]
|
|
||||||
@@ -878,11 +877,6 @@ ip6 filter input frag more-fragments 1 counter
|
|
||||||
filter input ip option lsrr exists counter
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
-.finding DCCP option
|
|
||||||
-------------------
|
|
||||||
-filter input dccp option 40 exists counter
|
|
||||||
----------------------------------------
|
|
||||||
-
|
|
||||||
CONNTRACK EXPRESSIONS
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Conntrack expressions refer to meta data of the connection tracking entry associated with a packet. +
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From 98fb87d77b87476d5a3847e6482c0ab24d48ca44 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 18 Mar 2026 16:27:12 +0100
|
|
||||||
Subject: [PATCH] src: netlink: fix crash when ops doesn't support udata
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/https://redhat.atlassian.net/browse/RHEL-153461
|
|
||||||
Upstream Status: nftables commit be737a1986bfee0ddea4bee7863dca0123a2bcbc
|
|
||||||
|
|
||||||
commit be737a1986bfee0ddea4bee7863dca0123a2bcbc
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu May 8 16:29:04 2025 +0200
|
|
||||||
|
|
||||||
src: netlink: fix crash when ops doesn't support udata
|
|
||||||
|
|
||||||
Whenever a new version adds udata support to an expression, then old
|
|
||||||
versions of nft will crash when trying to list such a ruleset generated
|
|
||||||
by a more recent version of nftables.
|
|
||||||
|
|
||||||
Fix this by falling back to 'type' format.
|
|
||||||
|
|
||||||
Fixes: 6e48df5329ea ('src: add "typeof" build/parse/print support')
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index 120a8ba..04bba59 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -895,7 +895,7 @@ static struct expr *set_make_key(const struct nftnl_udata *attr)
|
|
||||||
|
|
||||||
etype = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_TYPEOF_EXPR]);
|
|
||||||
ops = expr_ops_by_type_u32(etype);
|
|
||||||
- if (!ops)
|
|
||||||
+ if (!ops || !ops->parse_udata)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
expr = ops->parse_udata(ud[NFTNL_UDATA_SET_TYPEOF_DATA]);
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
From 0a38b9fcf1841e68088f2db39e3c96b3ad3b0369 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Wed, 18 Mar 2026 22:17:46 +0100
|
|
||||||
Subject: [PATCH] src: fix reset element support for interval set type
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/https://redhat.atlassian.net/browse/RHEL-153461
|
|
||||||
Upstream Status: nftables commit 2b164aec4295d5f4f6d45aa098279494ab44289b
|
|
||||||
|
|
||||||
commit 2b164aec4295d5f4f6d45aa098279494ab44289b
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu Mar 6 14:23:30 2025 +0100
|
|
||||||
|
|
||||||
src: fix reset element support for interval set type
|
|
||||||
|
|
||||||
Running reset command yields on an interval (rbtree) set yields:
|
|
||||||
nft reset element inet filter rbtreeset {1.2.3.4}
|
|
||||||
BUG: unhandled op 8
|
|
||||||
|
|
||||||
This is easy to fix, CMD_RESET doesn't add or remove so it should be
|
|
||||||
treated like CMD_GET.
|
|
||||||
|
|
||||||
Unfortunately, this still doesn't work properly:
|
|
||||||
|
|
||||||
nft get element inet filter rbset {1.2.3.4}
|
|
||||||
returns:
|
|
||||||
... elements = { 1.2.3.4 }
|
|
||||||
|
|
||||||
but its expected that "get" and "reset" also return stateful objects
|
|
||||||
associated with the element. This works for other set types, but for
|
|
||||||
rbtree, the list of statements gets lost during segtree processing.
|
|
||||||
|
|
||||||
After fix, get/reset returns:
|
|
||||||
elements = { 1.2.3.4 counter packets 10 ...
|
|
||||||
|
|
||||||
A follow up patch will add a test case.
|
|
||||||
|
|
||||||
Fixes: 83e0f4402fb7 ("Implement 'reset {set,map,element}' commands")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/evaluate.c | 1 +
|
|
||||||
src/segtree.c | 36 ++++++++++++++++++++++++++++++------
|
|
||||||
2 files changed, 31 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
||||||
index 2196e92..711990a 100644
|
|
||||||
--- a/src/evaluate.c
|
|
||||||
+++ b/src/evaluate.c
|
|
||||||
@@ -1729,6 +1729,7 @@ static int interval_set_eval(struct eval_ctx *ctx, struct set *set,
|
|
||||||
ctx->nft->debug_mask);
|
|
||||||
break;
|
|
||||||
case CMD_GET:
|
|
||||||
+ case CMD_RESET:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG("unhandled op %d\n", ctx->cmd->op);
|
|
||||||
diff --git a/src/segtree.c b/src/segtree.c
|
|
||||||
index 28172b3..c4029f9 100644
|
|
||||||
--- a/src/segtree.c
|
|
||||||
+++ b/src/segtree.c
|
|
||||||
@@ -206,6 +206,27 @@ static struct expr *expr_to_set_elem(struct expr *e)
|
|
||||||
return __expr_to_set_elem(e, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void set_compound_expr_add(struct expr *compound, struct expr *expr, struct expr *orig)
|
|
||||||
+{
|
|
||||||
+ struct expr *elem;
|
|
||||||
+
|
|
||||||
+ switch (expr->etype) {
|
|
||||||
+ case EXPR_SET_ELEM:
|
|
||||||
+ list_splice_init(&orig->stmt_list, &expr->stmt_list);
|
|
||||||
+ compound_expr_add(compound, expr);
|
|
||||||
+ break;
|
|
||||||
+ case EXPR_MAPPING:
|
|
||||||
+ list_splice_init(&orig->left->stmt_list, &expr->left->stmt_list);
|
|
||||||
+ compound_expr_add(compound, expr);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ elem = set_elem_expr_alloc(&orig->location, expr);
|
|
||||||
+ list_splice_init(&orig->stmt_list, &elem->stmt_list);
|
|
||||||
+ compound_expr_add(compound, elem);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int get_set_decompose(struct set *cache_set, struct set *set)
|
|
||||||
{
|
|
||||||
struct expr *i, *next, *range;
|
|
||||||
@@ -227,20 +248,23 @@ int get_set_decompose(struct set *cache_set, struct set *set)
|
|
||||||
errno = ENOENT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ set_compound_expr_add(new_init, range, left);
|
|
||||||
+
|
|
||||||
expr_free(left);
|
|
||||||
expr_free(i);
|
|
||||||
|
|
||||||
- compound_expr_add(new_init, range);
|
|
||||||
left = NULL;
|
|
||||||
} else {
|
|
||||||
if (left) {
|
|
||||||
range = get_set_interval_find(cache_set,
|
|
||||||
left, NULL);
|
|
||||||
+
|
|
||||||
if (range)
|
|
||||||
- compound_expr_add(new_init, range);
|
|
||||||
+ set_compound_expr_add(new_init, range, left);
|
|
||||||
else
|
|
||||||
- compound_expr_add(new_init,
|
|
||||||
- expr_to_set_elem(left));
|
|
||||||
+ set_compound_expr_add(new_init,
|
|
||||||
+ expr_to_set_elem(left), left);
|
|
||||||
}
|
|
||||||
left = i;
|
|
||||||
}
|
|
||||||
@@ -248,9 +272,9 @@ int get_set_decompose(struct set *cache_set, struct set *set)
|
|
||||||
if (left) {
|
|
||||||
range = get_set_interval_find(cache_set, left, NULL);
|
|
||||||
if (range)
|
|
||||||
- compound_expr_add(new_init, range);
|
|
||||||
+ set_compound_expr_add(new_init, range, left);
|
|
||||||
else
|
|
||||||
- compound_expr_add(new_init, expr_to_set_elem(left));
|
|
||||||
+ set_compound_expr_add(new_init, expr_to_set_elem(left), left);
|
|
||||||
}
|
|
||||||
|
|
||||||
expr_free(set->init);
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
From 5bd9f93cc070364eae782196112fe81953d8f872 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:23:48 +0200
|
|
||||||
Subject: [PATCH] doc: Fix typo in nat statement 'prefix' description
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 1b3c33a7931967fb7afe4efdf68deb7781786489
|
|
||||||
|
|
||||||
commit 1b3c33a7931967fb7afe4efdf68deb7781786489
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu May 8 16:35:47 2025 +0200
|
|
||||||
|
|
||||||
doc: Fix typo in nat statement 'prefix' description
|
|
||||||
|
|
||||||
No point in repeating 'to map' here.
|
|
||||||
|
|
||||||
Fixes: 19d73ccdd39fa ("doc: add nat examples")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/statements.txt | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/doc/statements.txt b/doc/statements.txt
|
|
||||||
index c29a2ff..c7529ee 100644
|
|
||||||
--- a/doc/statements.txt
|
|
||||||
+++ b/doc/statements.txt
|
|
||||||
@@ -388,7 +388,7 @@ Before kernel 4.18 nat statements require both prerouting and postrouting base c
|
|
||||||
to be present since otherwise packets on the return path won't be seen by
|
|
||||||
netfilter and therefore no reverse translation will take place.
|
|
||||||
|
|
||||||
-The optional *prefix* keyword allows to map to map *n* source addresses to *n*
|
|
||||||
+The optional *prefix* keyword allows to map *n* source addresses to *n*
|
|
||||||
destination addresses. See 'Advanced NAT examples' below.
|
|
||||||
|
|
||||||
.NAT statement values
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 8e7d599a1d42add21949ff5c05ede51db9dc4db9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:23:49 +0200
|
|
||||||
Subject: [PATCH] json: Print single set flag as non-array
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 6bedb12af1658562f277ca68d74cf1e9e7433a08
|
|
||||||
Conflicts: Dropped changes to non-existent dump files
|
|
||||||
|
|
||||||
commit 6bedb12af1658562f277ca68d74cf1e9e7433a08
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu May 8 16:39:24 2025 +0200
|
|
||||||
|
|
||||||
json: Print single set flag as non-array
|
|
||||||
|
|
||||||
The code obviously intended to do this already but got the array length
|
|
||||||
check wrong.
|
|
||||||
|
|
||||||
Fixes: e70354f53e9f6 ("libnftables: Implement JSON output support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index dad93e5..0e6e39d 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -178,7 +178,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
|
||||||
if (set->flags & NFT_SET_EVAL)
|
|
||||||
json_array_append_new(tmp, json_pack("s", "dynamic"));
|
|
||||||
|
|
||||||
- if (json_array_size(tmp) > 0) {
|
|
||||||
+ if (json_array_size(tmp) > 1) {
|
|
||||||
json_object_set_new(root, "flags", tmp);
|
|
||||||
} else {
|
|
||||||
if (json_array_size(tmp))
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From 8e81e7293c38e19b4d9e2953b51adaab93a38c90 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] netlink: Avoid potential NULL-ptr deref parsing set elem
|
|
||||||
expressions
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 89645d04106d45d5e23b6d5206777dad1fb3e6bf
|
|
||||||
|
|
||||||
commit 89645d04106d45d5e23b6d5206777dad1fb3e6bf
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri May 16 20:08:05 2025 +0200
|
|
||||||
|
|
||||||
netlink: Avoid potential NULL-ptr deref parsing set elem expressions
|
|
||||||
|
|
||||||
Since netlink_parse_set_expr() may return NULL, the following deref must
|
|
||||||
be guarded.
|
|
||||||
|
|
||||||
Fixes: e6d1d0d611958 ("src: add set element multi-statement support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index 04bba59..9fa95ea 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -927,7 +927,8 @@ static int set_elem_parse_expressions(struct nftnl_expr *e, void *data)
|
|
||||||
struct stmt *stmt;
|
|
||||||
|
|
||||||
stmt = netlink_parse_set_expr(set, cache, e);
|
|
||||||
- list_add_tail(&stmt->list, &setelem_parse_ctx->stmt_list);
|
|
||||||
+ if (stmt)
|
|
||||||
+ list_add_tail(&stmt->list, &setelem_parse_ctx->stmt_list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From 548a3e9dbc1b111e9bdd0be5df0056d12b77836f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] netlink: Catch unknown types when deserializing objects
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 690f19eadde5cb607ec3d8d471c86d558c7229bd
|
|
||||||
|
|
||||||
commit 690f19eadde5cb607ec3d8d471c86d558c7229bd
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri May 16 19:41:19 2025 +0200
|
|
||||||
|
|
||||||
netlink: Catch unknown types when deserializing objects
|
|
||||||
|
|
||||||
Print an error message and discard the object instead of returning it to
|
|
||||||
the caller. At least when trying to print it, we would hit an assert()
|
|
||||||
in obj_type_name() anyway.
|
|
||||||
|
|
||||||
Fixes: 4756d92e517ae ("src: listing of stateful objects")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index 9fa95ea..6130e56 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -1733,6 +1733,10 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
|
|
||||||
obj->synproxy.flags =
|
|
||||||
nftnl_obj_get_u32(nlo, NFTNL_OBJ_SYNPROXY_FLAGS);
|
|
||||||
break;
|
|
||||||
+ default:
|
|
||||||
+ netlink_io_error(ctx, NULL, "Unknown object type %u", type);
|
|
||||||
+ obj_free(obj);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
obj->type = type;
|
|
||||||
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
From 7fe078fda20ce68b53147afcab2ed126ecf739c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] json: prevent null deref if chain->policy is not set
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 69b90023c7220fe283ee38686c758e3494e853d9
|
|
||||||
|
|
||||||
commit 69b90023c7220fe283ee38686c758e3494e853d9
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Mon Jun 2 14:22:33 2025 +0200
|
|
||||||
|
|
||||||
json: prevent null deref if chain->policy is not set
|
|
||||||
|
|
||||||
The two commits mentioned below resolved null dererence crashes when the
|
|
||||||
policy resp. priority keyword was missing in the chain/flowtable
|
|
||||||
specification.
|
|
||||||
|
|
||||||
Same issue exists in the json output path, so apply similar fix there
|
|
||||||
and extend the existing test cases.
|
|
||||||
|
|
||||||
Fixes: 5b37479b42b3 ("nftables: don't crash in 'list ruleset' if policy is not set")
|
|
||||||
Fixes: b40bebbcee36 ("rule: do not crash if to-be-printed flowtable lacks priority")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Acked-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 19 ++++++++++++++-----
|
|
||||||
.../nft-j-f/flowtable-no-priority-crash | 6 ++++++
|
|
||||||
.../shell/testcases/nft-f/0021list_ruleset_0 | 7 ++++++-
|
|
||||||
3 files changed, 26 insertions(+), 6 deletions(-)
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-j-f/flowtable-no-priority-crash
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 0e6e39d..4836e6b 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -272,8 +272,14 @@ static json_t *chain_print_json(const struct chain *chain)
|
|
||||||
if (chain->flags & CHAIN_F_BASECHAIN) {
|
|
||||||
mpz_export_data(&priority, chain->priority.expr->value,
|
|
||||||
BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
- mpz_export_data(&policy, chain->policy->value,
|
|
||||||
- BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
+
|
|
||||||
+ if (chain->policy) {
|
|
||||||
+ mpz_export_data(&policy, chain->policy->value,
|
|
||||||
+ BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
+ } else {
|
|
||||||
+ policy = NF_ACCEPT;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
tmp = json_pack("{s:s, s:s, s:i, s:s}",
|
|
||||||
"type", chain->type.str,
|
|
||||||
"hook", hooknum2str(chain->handle.family,
|
|
||||||
@@ -451,10 +457,13 @@ static json_t *obj_print_json(const struct obj *obj)
|
|
||||||
static json_t *flowtable_print_json(const struct flowtable *ftable)
|
|
||||||
{
|
|
||||||
json_t *root, *devs = NULL;
|
|
||||||
- int i, priority;
|
|
||||||
+ int i, priority = 0;
|
|
||||||
+
|
|
||||||
+ if (ftable->priority.expr) {
|
|
||||||
+ mpz_export_data(&priority, ftable->priority.expr->value,
|
|
||||||
+ BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- mpz_export_data(&priority, ftable->priority.expr->value,
|
|
||||||
- BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
root = json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
|
|
||||||
"family", family2str(ftable->handle.family),
|
|
||||||
"name", ftable->handle.flowtable.name,
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-j-f/flowtable-no-priority-crash b/tests/shell/testcases/bogons/nft-j-f/flowtable-no-priority-crash
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..f348da9
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-j-f/flowtable-no-priority-crash
|
|
||||||
@@ -0,0 +1,6 @@
|
|
||||||
+table ip filter {
|
|
||||||
+ flowtable ft1 {
|
|
||||||
+ devices = { lo }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+list ruleset
|
|
||||||
diff --git a/tests/shell/testcases/nft-f/0021list_ruleset_0 b/tests/shell/testcases/nft-f/0021list_ruleset_0
|
|
||||||
index 37729b4..f3c3749 100755
|
|
||||||
--- a/tests/shell/testcases/nft-f/0021list_ruleset_0
|
|
||||||
+++ b/tests/shell/testcases/nft-f/0021list_ruleset_0
|
|
||||||
@@ -12,4 +12,9 @@ RULESET="table filter {
|
|
||||||
list ruleset
|
|
||||||
"
|
|
||||||
|
|
||||||
-exec $NFT -f - <<< "$RULESET"
|
|
||||||
+$NFT -f - <<< "$RULESET"
|
|
||||||
+
|
|
||||||
+if [ "$NFT_TEST_HAVE_json" != n ]; then
|
|
||||||
+ $NFT flush ruleset
|
|
||||||
+ $NFT -j -f - <<< "$RULESET"
|
|
||||||
+fi
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From 8fe856057e51298ebaadbfa59b56923b5d169b22 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] netlink: Fix for potential crash parsing a flowtable
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit d5ef04441eb1de3efc27aa70193fe3d7f0b5c408
|
|
||||||
|
|
||||||
commit d5ef04441eb1de3efc27aa70193fe3d7f0b5c408
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Jun 11 13:12:56 2025 +0200
|
|
||||||
|
|
||||||
netlink: Fix for potential crash parsing a flowtable
|
|
||||||
|
|
||||||
Kernel's flowtable message might not contain the
|
|
||||||
NFTA_FLOWTABLE_HOOK_DEVS attribute. In that case, nftnl_flowtable_get()
|
|
||||||
will return NULL for the respective nftnl attribute.
|
|
||||||
|
|
||||||
Fixes: db0697ce7f602 ("src: support for flowtable listing")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index 6130e56..9a01d8a 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -1853,7 +1853,7 @@ netlink_delinearize_flowtable(struct netlink_ctx *ctx,
|
|
||||||
if (nftnl_flowtable_is_set(nlo, NFTNL_FLOWTABLE_FLAGS))
|
|
||||||
flowtable->flags = nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_FLAGS);
|
|
||||||
dev_array = nftnl_flowtable_get(nlo, NFTNL_FLOWTABLE_DEVICES);
|
|
||||||
- while (dev_array[len])
|
|
||||||
+ while (dev_array && dev_array[len])
|
|
||||||
len++;
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
From 3130995d533b2c8155001ca592c4d6fd3e0fc6c7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] netlink: Do not allocate a bogus flowtable priority expr
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 10b9a85b3278e0933bf47226588fede8c9fcbcc8
|
|
||||||
|
|
||||||
commit 10b9a85b3278e0933bf47226588fede8c9fcbcc8
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Jun 11 14:15:38 2025 +0200
|
|
||||||
|
|
||||||
netlink: Do not allocate a bogus flowtable priority expr
|
|
||||||
|
|
||||||
Code accidentally treats missing NFTNL_FLOWTABLE_PRIO attribute as zero
|
|
||||||
prio value which may not be correct.
|
|
||||||
|
|
||||||
Fixes: db0697ce7f602 ("src: support for flowtable listing")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 6 ++++--
|
|
||||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index 9a01d8a..b1dd31d 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -1868,14 +1868,16 @@ netlink_delinearize_flowtable(struct netlink_ctx *ctx,
|
|
||||||
sizeof(char *), qsort_device_cmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
- priority = nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_PRIO);
|
|
||||||
- flowtable->priority.expr =
|
|
||||||
+ if (nftnl_flowtable_is_set(nlo, NFTNL_FLOWTABLE_PRIO)) {
|
|
||||||
+ priority = nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_PRIO);
|
|
||||||
+ flowtable->priority.expr =
|
|
||||||
constant_expr_alloc(&netlink_location,
|
|
||||||
&integer_type,
|
|
||||||
BYTEORDER_HOST_ENDIAN,
|
|
||||||
sizeof(int) *
|
|
||||||
BITS_PER_BYTE,
|
|
||||||
&priority);
|
|
||||||
+ }
|
|
||||||
flowtable->hook.num =
|
|
||||||
nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_HOOKNUM);
|
|
||||||
flowtable->flags =
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
From ae0e0face33e74339f4f8082d3e6119b2ad57dcb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:19 +0200
|
|
||||||
Subject: [PATCH] json: Support typeof in set and map types
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit bb6312484af93a83a9ec8716f3887a43566a775a
|
|
||||||
Conflicts: Dropped changes to non-existent test and dump files
|
|
||||||
|
|
||||||
commit bb6312484af93a83a9ec8716f3887a43566a775a
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Sat Sep 28 00:55:34 2024 +0200
|
|
||||||
|
|
||||||
json: Support typeof in set and map types
|
|
||||||
|
|
||||||
Implement this as a special "type" property value which is an object
|
|
||||||
with sole property "typeof". The latter's value is the JSON
|
|
||||||
representation of the expression in set->key, so for concatenated
|
|
||||||
typeofs it is a concat expression.
|
|
||||||
|
|
||||||
All this is a bit clumsy right now but it works and it should be
|
|
||||||
possible to tear it down a bit for more user-friendliness in a
|
|
||||||
compatible way by either replacing the concat expression by the array it
|
|
||||||
contains or even the whole "typeof" object - the parser would just
|
|
||||||
assume any object (or objects in an array) in the "type" property value
|
|
||||||
are expressions to extract a type from.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/libnftables-json.adoc | 7 ++++---
|
|
||||||
src/json.c | 13 ++++++++++++-
|
|
||||||
src/parser_json.c | 9 +++++++++
|
|
||||||
tests/monitor/testcases/map-expr.t | 2 +-
|
|
||||||
4 files changed, 26 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
|
||||||
index c5e5f23..c3e3bcc 100644
|
|
||||||
--- a/doc/libnftables-json.adoc
|
|
||||||
+++ b/doc/libnftables-json.adoc
|
|
||||||
@@ -339,7 +339,7 @@ ____
|
|
||||||
"size":* 'NUMBER'
|
|
||||||
*}}*
|
|
||||||
|
|
||||||
-'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]*
|
|
||||||
+'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]* | *{ "typeof":* 'EXPRESSION' *}*
|
|
||||||
'SET_TYPE_LIST' := 'STRING' [*,* 'SET_TYPE_LIST' ]
|
|
||||||
'SET_POLICY' := *"performance"* | *"memory"*
|
|
||||||
'SET_FLAG_LIST' := 'SET_FLAG' [*,* 'SET_FLAG_LIST' ]
|
|
||||||
@@ -377,8 +377,9 @@ that they translate a unique key to a value.
|
|
||||||
Maximum number of elements supported.
|
|
||||||
|
|
||||||
==== TYPE
|
|
||||||
-The set type might be a string, such as *"ipv4_addr"* or an array
|
|
||||||
-consisting of strings (for concatenated types).
|
|
||||||
+The set type might be a string, such as *"ipv4_addr"*, an array
|
|
||||||
+consisting of strings (for concatenated types) or a *typeof* object containing
|
|
||||||
+an expression to extract the type from.
|
|
||||||
|
|
||||||
==== ELEM
|
|
||||||
A single set element might be given as string, integer or boolean value for
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 4836e6b..39b1ada 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -87,6 +87,17 @@ static json_t *set_dtype_json(const struct expr *key)
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static json_t *set_key_dtype_json(const struct set *set,
|
|
||||||
+ struct output_ctx *octx)
|
|
||||||
+{
|
|
||||||
+ bool use_typeof = set->key_typeof_valid;
|
|
||||||
+
|
|
||||||
+ if (!use_typeof)
|
|
||||||
+ return set_dtype_json(set->key);
|
|
||||||
+
|
|
||||||
+ return json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
@@ -149,7 +160,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
|
||||||
"family", family2str(set->handle.family),
|
|
||||||
"name", set->handle.set.name,
|
|
||||||
"table", set->handle.table.name,
|
|
||||||
- "type", set_dtype_json(set->key),
|
|
||||||
+ "type", set_key_dtype_json(set, octx),
|
|
||||||
"handle", set->handle.handle.id);
|
|
||||||
|
|
||||||
if (set->comment)
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 2acc248..936c5aa 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -1700,7 +1700,16 @@ static struct expr *json_parse_dtype_expr(struct json_ctx *ctx, json_t *root)
|
|
||||||
compound_expr_add(expr, i);
|
|
||||||
}
|
|
||||||
return expr;
|
|
||||||
+ } else if (json_is_object(root)) {
|
|
||||||
+ const char *key;
|
|
||||||
+ json_t *val;
|
|
||||||
+
|
|
||||||
+ if (!json_unpack_stmt(ctx, root, &key, &val) &&
|
|
||||||
+ !strcmp(key, "typeof")) {
|
|
||||||
+ return json_parse_expr(ctx, val);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
+
|
|
||||||
json_error(ctx, "Invalid set datatype.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
diff --git a/tests/monitor/testcases/map-expr.t b/tests/monitor/testcases/map-expr.t
|
|
||||||
index 8729c0b..d11ad0e 100644
|
|
||||||
--- a/tests/monitor/testcases/map-expr.t
|
|
||||||
+++ b/tests/monitor/testcases/map-expr.t
|
|
||||||
@@ -3,4 +3,4 @@ I add table ip t
|
|
||||||
I add map ip t m { typeof meta day . meta hour : verdict; flags interval; counter; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": ["day", "hour"], "handle": 0, "map": "verdict", "flags": ["interval"], "stmt": [{"counter": null}]}}}
|
|
||||||
+J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": {"typeof": {"concat": [{"meta": {"key": "day"}}, {"meta": {"key": "hour"}}]}}, "handle": 0, "map": "verdict", "flags": ["interval"], "stmt": [{"counter": null}]}}}
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
From d5c438d2a4d502460ad83ec2f3224c7faf83ed8f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:24:52 +0200
|
|
||||||
Subject: [PATCH] tests: monitor: Fix for single flag array avoidance
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b5f43dfc8b28989290a16818f00ca73c6cd8ff65
|
|
||||||
Conflicts: Dropped changes to non-existent test case
|
|
||||||
|
|
||||||
commit b5f43dfc8b28989290a16818f00ca73c6cd8ff65
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Jun 11 17:15:22 2025 +0200
|
|
||||||
|
|
||||||
tests: monitor: Fix for single flag array avoidance
|
|
||||||
|
|
||||||
Missed to update the JSON monitor expected output.
|
|
||||||
|
|
||||||
Fixes: 6bedb12af1658 ("json: Print single set flag as non-array")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/monitor/testcases/map-expr.t | 2 +-
|
|
||||||
tests/monitor/testcases/set-interval.t | 2 +-
|
|
||||||
tests/monitor/testcases/set-maps.t | 2 +-
|
|
||||||
tests/monitor/testcases/set-mixed.t | 2 +-
|
|
||||||
tests/monitor/testcases/set-multiple.t | 4 ++--
|
|
||||||
tests/monitor/testcases/set-simple.t | 2 +-
|
|
||||||
6 files changed, 7 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/monitor/testcases/map-expr.t b/tests/monitor/testcases/map-expr.t
|
|
||||||
index d11ad0e..9042004 100644
|
|
||||||
--- a/tests/monitor/testcases/map-expr.t
|
|
||||||
+++ b/tests/monitor/testcases/map-expr.t
|
|
||||||
@@ -3,4 +3,4 @@ I add table ip t
|
|
||||||
I add map ip t m { typeof meta day . meta hour : verdict; flags interval; counter; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": {"typeof": {"concat": [{"meta": {"key": "day"}}, {"meta": {"key": "hour"}}]}}, "handle": 0, "map": "verdict", "flags": ["interval"], "stmt": [{"counter": null}]}}}
|
|
||||||
+J {"add": {"map": {"family": "ip", "name": "m", "table": "t", "type": {"typeof": {"concat": [{"meta": {"key": "day"}}, {"meta": {"key": "hour"}}]}}, "handle": 0, "map": "verdict", "flags": "interval", "stmt": [{"counter": null}]}}}
|
|
||||||
diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t
|
|
||||||
index 5053c59..84cf98c 100644
|
|
||||||
--- a/tests/monitor/testcases/set-interval.t
|
|
||||||
+++ b/tests/monitor/testcases/set-interval.t
|
|
||||||
@@ -10,7 +10,7 @@ I add set ip t s { type inet_service; flags interval; elements = { 20, 30-40 };
|
|
||||||
O add set ip t s { type inet_service; flags interval; }
|
|
||||||
O add element ip t s { 20 }
|
|
||||||
O add element ip t s { 30-40 }
|
|
||||||
-J {"add": {"set": {"family": "ip", "name": "s", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}}
|
|
||||||
+J {"add": {"set": {"family": "ip", "name": "s", "table": "t", "type": "inet_service", "handle": 0, "flags": "interval"}}}
|
|
||||||
J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [20]}}}}
|
|
||||||
J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [{"range": [30, 40]}]}}}}
|
|
||||||
|
|
||||||
diff --git a/tests/monitor/testcases/set-maps.t b/tests/monitor/testcases/set-maps.t
|
|
||||||
index acda480..aaf332f 100644
|
|
||||||
--- a/tests/monitor/testcases/set-maps.t
|
|
||||||
+++ b/tests/monitor/testcases/set-maps.t
|
|
||||||
@@ -3,7 +3,7 @@ I add table ip t
|
|
||||||
I add map ip t portip { type inet_service: ipv4_addr; flags interval; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"map": {"family": "ip", "name": "portip", "table": "t", "type": "inet_service", "handle": 0, "map": "ipv4_addr", "flags": ["interval"]}}}
|
|
||||||
+J {"add": {"map": {"family": "ip", "name": "portip", "table": "t", "type": "inet_service", "handle": 0, "map": "ipv4_addr", "flags": "interval"}}}
|
|
||||||
|
|
||||||
I add element ip t portip { 80-100: 10.0.0.1 }
|
|
||||||
O -
|
|
||||||
diff --git a/tests/monitor/testcases/set-mixed.t b/tests/monitor/testcases/set-mixed.t
|
|
||||||
index 08c2011..1cf3d38 100644
|
|
||||||
--- a/tests/monitor/testcases/set-mixed.t
|
|
||||||
+++ b/tests/monitor/testcases/set-mixed.t
|
|
||||||
@@ -4,7 +4,7 @@ I add set ip t portrange { type inet_service; flags interval; }
|
|
||||||
I add set ip t ports { type inet_service; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}}
|
|
||||||
+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": "interval"}}}
|
|
||||||
J {"add": {"set": {"family": "ip", "name": "ports", "table": "t", "type": "inet_service", "handle": 0}}}
|
|
||||||
|
|
||||||
# make sure concurrent adds work
|
|
||||||
diff --git a/tests/monitor/testcases/set-multiple.t b/tests/monitor/testcases/set-multiple.t
|
|
||||||
index bd7a624..84de98e 100644
|
|
||||||
--- a/tests/monitor/testcases/set-multiple.t
|
|
||||||
+++ b/tests/monitor/testcases/set-multiple.t
|
|
||||||
@@ -4,8 +4,8 @@ I add set ip t portrange { type inet_service; flags interval; }
|
|
||||||
I add set ip t portrange2 { type inet_service; flags interval; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}}
|
|
||||||
-J {"add": {"set": {"family": "ip", "name": "portrange2", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}}
|
|
||||||
+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": "interval"}}}
|
|
||||||
+J {"add": {"set": {"family": "ip", "name": "portrange2", "table": "t", "type": "inet_service", "handle": 0, "flags": "interval"}}}
|
|
||||||
|
|
||||||
# make sure concurrent adds work
|
|
||||||
I add element ip t portrange { 1024-65535 }
|
|
||||||
diff --git a/tests/monitor/testcases/set-simple.t b/tests/monitor/testcases/set-simple.t
|
|
||||||
index 8ca4f32..6bac08a 100644
|
|
||||||
--- a/tests/monitor/testcases/set-simple.t
|
|
||||||
+++ b/tests/monitor/testcases/set-simple.t
|
|
||||||
@@ -3,7 +3,7 @@ I add table ip t
|
|
||||||
I add set ip t portrange { type inet_service; flags interval; }
|
|
||||||
O -
|
|
||||||
J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
|
||||||
-J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}}
|
|
||||||
+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": "interval"}}}
|
|
||||||
|
|
||||||
# adding some ranges
|
|
||||||
I add element ip t portrange { 1-10 }
|
|
||||||
@ -1,232 +0,0 @@
|
|||||||
From 1bbd3a42f69d0eaaab66fede7d781013183ef064 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] tests: py: Properly fix JSON equivalents for netdev/reject.t
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b7a11c691d459d06a801a28ae9a52bc564584a1a
|
|
||||||
|
|
||||||
commit b7a11c691d459d06a801a28ae9a52bc564584a1a
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Jun 12 12:59:29 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Properly fix JSON equivalents for netdev/reject.t
|
|
||||||
|
|
||||||
Revert commit d1a7b9e19fe65 ("tests: py: update netdev reject test
|
|
||||||
file"), the stored JSON equivalents were correct in that they matched
|
|
||||||
the standard syntax input.
|
|
||||||
|
|
||||||
In fact, we missed a .json.output file recording the expected deviation
|
|
||||||
in JSON output.
|
|
||||||
|
|
||||||
Fixes: d1a7b9e19fe65 ("tests: py: update netdev reject test file")
|
|
||||||
Fixes: 7ca3368cd7575 ("reject: Unify inet, netdev and bridge delinearization")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/netdev/reject.t.json | 66 +++++++++++++++--------
|
|
||||||
tests/py/netdev/reject.t.json.output | 81 ++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 126 insertions(+), 21 deletions(-)
|
|
||||||
create mode 100644 tests/py/netdev/reject.t.json.output
|
|
||||||
|
|
||||||
diff --git a/tests/py/netdev/reject.t.json b/tests/py/netdev/reject.t.json
|
|
||||||
index 9968aaf..b80db03 100644
|
|
||||||
--- a/tests/py/netdev/reject.t.json
|
|
||||||
+++ b/tests/py/netdev/reject.t.json
|
|
||||||
@@ -130,17 +130,6 @@
|
|
||||||
|
|
||||||
# mark 12345 reject with tcp reset
|
|
||||||
[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": {
|
|
||||||
- "key": "l4proto"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 6
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
{
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
@@ -162,30 +151,43 @@
|
|
||||||
# reject
|
|
||||||
[
|
|
||||||
{
|
|
||||||
- "reject": {
|
|
||||||
- "expr": "port-unreachable",
|
|
||||||
- "type": "icmpx"
|
|
||||||
- }
|
|
||||||
+ "reject": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
# meta protocol ip reject
|
|
||||||
[
|
|
||||||
{
|
|
||||||
- "reject": {
|
|
||||||
- "expr": "port-unreachable",
|
|
||||||
- "type": "icmp"
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "protocol"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "ip"
|
|
||||||
}
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "reject": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
# meta protocol ip6 reject
|
|
||||||
[
|
|
||||||
{
|
|
||||||
- "reject": {
|
|
||||||
- "expr": "port-unreachable",
|
|
||||||
- "type": "icmpv6"
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "protocol"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "ip6"
|
|
||||||
}
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "reject": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
@@ -231,6 +233,17 @@
|
|
||||||
|
|
||||||
# meta protocol ip reject with icmp host-unreachable
|
|
||||||
[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "protocol"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "ip"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
"reject": {
|
|
||||||
"expr": "host-unreachable",
|
|
||||||
@@ -241,6 +254,17 @@
|
|
||||||
|
|
||||||
# meta protocol ip6 reject with icmpv6 no-route
|
|
||||||
[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "protocol"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "ip6"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
"reject": {
|
|
||||||
"expr": "no-route",
|
|
||||||
diff --git a/tests/py/netdev/reject.t.json.output b/tests/py/netdev/reject.t.json.output
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..cbd7310
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/py/netdev/reject.t.json.output
|
|
||||||
@@ -0,0 +1,81 @@
|
|
||||||
+# mark 12345 reject with tcp reset
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "l4proto"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 6
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 12345
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "type": "tcp reset"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# reject
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "expr": "port-unreachable",
|
|
||||||
+ "type": "icmpx"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# meta protocol ip reject
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "expr": "port-unreachable",
|
|
||||||
+ "type": "icmp"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# meta protocol ip6 reject
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "expr": "port-unreachable",
|
|
||||||
+ "type": "icmpv6"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# meta protocol ip reject with icmp host-unreachable
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "expr": "host-unreachable",
|
|
||||||
+ "type": "icmp"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# meta protocol ip6 reject with icmpv6 no-route
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "reject": {
|
|
||||||
+ "expr": "no-route",
|
|
||||||
+ "type": "icmpv6"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From 0f092c2cb0cc45ea48e8d8714ad2b5bf47a0f9ee Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] netlink: Avoid crash upon missing NFTNL_OBJ_CT_TIMEOUT_ARRAY
|
|
||||||
attribute
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 2a38f458f12bc032dac1b3ba63f95ca5a3c03fbd
|
|
||||||
|
|
||||||
commit 2a38f458f12bc032dac1b3ba63f95ca5a3c03fbd
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Jun 12 20:17:22 2025 +0200
|
|
||||||
|
|
||||||
netlink: Avoid crash upon missing NFTNL_OBJ_CT_TIMEOUT_ARRAY attribute
|
|
||||||
|
|
||||||
If missing, the memcpy call ends up reading from address zero.
|
|
||||||
|
|
||||||
Fixes: c7c94802679cd ("src: add ct timeout support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/netlink.c | 7 ++++---
|
|
||||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index b1dd31d..aafc583 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -1697,9 +1697,10 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
|
|
||||||
init_list_head(&obj->ct_timeout.timeout_list);
|
|
||||||
obj->ct_timeout.l3proto = nftnl_obj_get_u16(nlo, NFTNL_OBJ_CT_TIMEOUT_L3PROTO);
|
|
||||||
obj->ct_timeout.l4proto = nftnl_obj_get_u8(nlo, NFTNL_OBJ_CT_TIMEOUT_L4PROTO);
|
|
||||||
- memcpy(obj->ct_timeout.timeout,
|
|
||||||
- nftnl_obj_get(nlo, NFTNL_OBJ_CT_TIMEOUT_ARRAY),
|
|
||||||
- NFTNL_CTTIMEOUT_ARRAY_MAX * sizeof(uint32_t));
|
|
||||||
+ if (nftnl_obj_is_set(nlo, NFTNL_OBJ_CT_TIMEOUT_ARRAY))
|
|
||||||
+ memcpy(obj->ct_timeout.timeout,
|
|
||||||
+ nftnl_obj_get(nlo, NFTNL_OBJ_CT_TIMEOUT_ARRAY),
|
|
||||||
+ NFTNL_CTTIMEOUT_ARRAY_MAX * sizeof(uint32_t));
|
|
||||||
break;
|
|
||||||
case NFT_OBJECT_LIMIT:
|
|
||||||
obj->limit.rate =
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
From 708d27f80214211252181333ef680b15e3be8dd7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] src: BASECHAIN flag no longer implies presence of priority
|
|
||||||
expression
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 44ea1936463728475768861073ca4ba34a5c2f75
|
|
||||||
|
|
||||||
commit 44ea1936463728475768861073ca4ba34a5c2f75
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu Jun 12 20:17:15 2025 +0200
|
|
||||||
|
|
||||||
src: BASECHAIN flag no longer implies presence of priority expression
|
|
||||||
|
|
||||||
The included bogon will crash nft because print side assumes that BASECHAIN
|
|
||||||
flag presence also means that priority expression is available.
|
|
||||||
|
|
||||||
Make the print side conditional.
|
|
||||||
|
|
||||||
Fixes: a66b5ad9540d ("src: allow for updating devices on existing netdev chain")
|
|
||||||
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/rule.c | 16 ++++++++++------
|
|
||||||
.../bogons/nft-f/null_ingress_type_crash | 6 ++++++
|
|
||||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-f/null_ingress_type_crash
|
|
||||||
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index a0e151d..36d590a 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -1029,8 +1029,10 @@ 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.str,
|
|
||||||
- hooknum2str(chain->handle.family, chain->hook.num));
|
|
||||||
+ if (chain->type.str)
|
|
||||||
+ 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]);
|
|
||||||
} else if (chain->dev_array_len > 1) {
|
|
||||||
@@ -1042,10 +1044,12 @@ static void chain_print_declaration(const struct chain *chain,
|
|
||||||
}
|
|
||||||
nft_print(octx, " }");
|
|
||||||
}
|
|
||||||
- nft_print(octx, " priority %s;",
|
|
||||||
- prio2str(octx, priobuf, sizeof(priobuf),
|
|
||||||
- chain->handle.family, chain->hook.num,
|
|
||||||
- chain->priority.expr));
|
|
||||||
+
|
|
||||||
+ if (chain->priority.expr)
|
|
||||||
+ nft_print(octx, " priority %s;",
|
|
||||||
+ prio2str(octx, priobuf, sizeof(priobuf),
|
|
||||||
+ chain->handle.family, chain->hook.num,
|
|
||||||
+ chain->priority.expr));
|
|
||||||
if (chain->policy) {
|
|
||||||
mpz_export_data(&policy, chain->policy->value,
|
|
||||||
BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-f/null_ingress_type_crash b/tests/shell/testcases/bogons/nft-f/null_ingress_type_crash
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..2ed88af
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-f/null_ingress_type_crash
|
|
||||||
@@ -0,0 +1,6 @@
|
|
||||||
+table netdev filter1 {
|
|
||||||
+ chain c {
|
|
||||||
+ devices = { lo }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+list ruleset
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
From 41f3f87fff4e57993aaefde497c572fd15af2f82 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] rule: skip fuzzy lookup if object name is not available
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit de8396358f869d6d7640eae6d6287c2f7fb0d3dc
|
|
||||||
|
|
||||||
commit de8396358f869d6d7640eae6d6287c2f7fb0d3dc
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Sun Jun 15 11:33:42 2025 +0200
|
|
||||||
|
|
||||||
rule: skip fuzzy lookup if object name is not available
|
|
||||||
|
|
||||||
Skip fuzzy lookup for suggestions when handles are used.
|
|
||||||
|
|
||||||
Note that 4cf97abfee61 ("rule: Avoid segfault with anonymous chains")
|
|
||||||
already skips it for chain.
|
|
||||||
|
|
||||||
Fixes: 285bb67a11ad ("src: introduce simple hints on incorrect set")
|
|
||||||
Fixes: 9f7817a4e022 ("src: introduce simple hints on incorrect chain")
|
|
||||||
Fixes: d7476ddd5f7d ("src: introduce simple hints on incorrect table")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/rule.c | 12 ++++++++++++
|
|
||||||
1 file changed, 12 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index 36d590a..6f97f77 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -211,6 +211,9 @@ struct set *set_lookup_fuzzy(const char *set_name,
|
|
||||||
struct table *table;
|
|
||||||
struct set *set;
|
|
||||||
|
|
||||||
+ if (!set_name)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
string_misspell_init(&st);
|
|
||||||
|
|
||||||
list_for_each_entry(table, &cache->table_cache.list, cache.list) {
|
|
||||||
@@ -1200,6 +1203,9 @@ struct table *table_lookup_fuzzy(const struct handle *h,
|
|
||||||
struct string_misspell_state st;
|
|
||||||
struct table *table;
|
|
||||||
|
|
||||||
+ if (!h->table.name)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
string_misspell_init(&st);
|
|
||||||
|
|
||||||
list_for_each_entry(table, &cache->table_cache.list, cache.list) {
|
|
||||||
@@ -1680,6 +1686,9 @@ struct obj *obj_lookup_fuzzy(const char *obj_name,
|
|
||||||
struct table *table;
|
|
||||||
struct obj *obj;
|
|
||||||
|
|
||||||
+ if (!obj_name)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
string_misspell_init(&st);
|
|
||||||
|
|
||||||
list_for_each_entry(table, &cache->table_cache.list, cache.list) {
|
|
||||||
@@ -2157,6 +2166,9 @@ struct flowtable *flowtable_lookup_fuzzy(const char *ft_name,
|
|
||||||
struct table *table;
|
|
||||||
struct flowtable *ft;
|
|
||||||
|
|
||||||
+ if (!ft_name)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
string_misspell_init(&st);
|
|
||||||
|
|
||||||
list_for_each_entry(table, &cache->table_cache.list, cache.list) {
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
From b6f184c87e7ddf8262426f17ec3bb02295d422bd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] cache: assert name is non-nul when looking up
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit f15bc7d368b7c1d897fd830f91e7db6929175b27
|
|
||||||
|
|
||||||
commit f15bc7d368b7c1d897fd830f91e7db6929175b27
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Sun Jun 15 11:33:49 2025 +0200
|
|
||||||
|
|
||||||
cache: assert name is non-nul when looking up
|
|
||||||
|
|
||||||
{table,chain,set,obj,flowtable}_cache_find() should not be called when
|
|
||||||
handles are used
|
|
||||||
|
|
||||||
Fixes: 5ec5c706d993 ("cache: add hashtable cache for table")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 11 +++++++++--
|
|
||||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index 0ac0f7c..2330112 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -487,8 +487,7 @@ struct table *table_cache_find(const struct cache *cache,
|
|
||||||
struct table *table;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
- if (!name)
|
|
||||||
- return NULL;
|
|
||||||
+ assert(name);
|
|
||||||
|
|
||||||
hash = djb_hash(name) % NFT_CACHE_HSIZE;
|
|
||||||
list_for_each_entry(table, &cache->ht[hash], cache.hlist) {
|
|
||||||
@@ -608,6 +607,8 @@ struct chain *chain_cache_find(const struct table *table, const char *name)
|
|
||||||
struct chain *chain;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
+ assert(name);
|
|
||||||
+
|
|
||||||
hash = djb_hash(name) % NFT_CACHE_HSIZE;
|
|
||||||
list_for_each_entry(chain, &table->chain_cache.ht[hash], cache.hlist) {
|
|
||||||
if (!strcmp(chain->handle.chain.name, name))
|
|
||||||
@@ -765,6 +766,8 @@ struct set *set_cache_find(const struct table *table, const char *name)
|
|
||||||
struct set *set;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
+ assert(name);
|
|
||||||
+
|
|
||||||
hash = djb_hash(name) % NFT_CACHE_HSIZE;
|
|
||||||
list_for_each_entry(set, &table->set_cache.ht[hash], cache.hlist) {
|
|
||||||
if (!strcmp(set->handle.set.name, name))
|
|
||||||
@@ -851,6 +854,8 @@ struct obj *obj_cache_find(const struct table *table, const char *name,
|
|
||||||
struct obj *obj;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
+ assert(name);
|
|
||||||
+
|
|
||||||
hash = djb_hash(name) % NFT_CACHE_HSIZE;
|
|
||||||
list_for_each_entry(obj, &table->obj_cache.ht[hash], cache.hlist) {
|
|
||||||
if (!strcmp(obj->handle.obj.name, name) &&
|
|
||||||
@@ -955,6 +960,8 @@ struct flowtable *ft_cache_find(const struct table *table, const char *name)
|
|
||||||
struct flowtable *ft;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
+ assert(name);
|
|
||||||
+
|
|
||||||
hash = djb_hash(name) % NFT_CACHE_HSIZE;
|
|
||||||
list_for_each_entry(ft, &table->ft_cache.ht[hash], cache.hlist) {
|
|
||||||
if (!strcmp(ft->handle.flowtable.name, name))
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
From 9f153e8f0425b02169617aefa65eab6e6f594b9f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] parser_bison: only reset by name is supported by now
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit e8c7ba0aac7ce321e61008fe9b4b8f11c3ba7e1d
|
|
||||||
|
|
||||||
commit e8c7ba0aac7ce321e61008fe9b4b8f11c3ba7e1d
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Sun Jun 15 11:34:11 2025 +0200
|
|
||||||
|
|
||||||
parser_bison: only reset by name is supported by now
|
|
||||||
|
|
||||||
NFT_MSG_GETSET does not support for handle lookup yet, restrict this to
|
|
||||||
reset by name by now.
|
|
||||||
|
|
||||||
Add a bogon test reported by Florian Westphal.
|
|
||||||
|
|
||||||
Fixes: 83e0f4402fb7 ("Implement 'reset {set,map,element}' commands")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_bison.y | 4 ++--
|
|
||||||
tests/shell/testcases/bogons/nft-f/null_set_name_crash | 2 ++
|
|
||||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-f/null_set_name_crash
|
|
||||||
|
|
||||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
||||||
index 5ced6e1..ff6660c 100644
|
|
||||||
--- a/src/parser_bison.y
|
|
||||||
+++ b/src/parser_bison.y
|
|
||||||
@@ -1750,11 +1750,11 @@ reset_cmd : COUNTERS ruleset_spec
|
|
||||||
{
|
|
||||||
$$ = cmd_alloc(CMD_RESET, CMD_OBJ_ELEMENTS, &$2, &@$, $3);
|
|
||||||
}
|
|
||||||
- | SET set_or_id_spec
|
|
||||||
+ | SET set_spec
|
|
||||||
{
|
|
||||||
$$ = cmd_alloc(CMD_RESET, CMD_OBJ_SET, &$2, &@$, NULL);
|
|
||||||
}
|
|
||||||
- | MAP set_or_id_spec
|
|
||||||
+ | MAP set_spec
|
|
||||||
{
|
|
||||||
$$ = cmd_alloc(CMD_RESET, CMD_OBJ_MAP, &$2, &@$, NULL);
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-f/null_set_name_crash b/tests/shell/testcases/bogons/nft-f/null_set_name_crash
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..e5d85b2
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-f/null_set_name_crash
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+table y { }
|
|
||||||
+reset set y handle 6
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
From 7e5c81ad7028802c7e61f304ccba8a932cc3fac8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] parser_bison: allow delete command with map via handle
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 640312b1529c548790117635c91886a6c83e83f2
|
|
||||||
|
|
||||||
commit 640312b1529c548790117635c91886a6c83e83f2
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Sun Jun 15 11:36:28 2025 +0200
|
|
||||||
|
|
||||||
parser_bison: allow delete command with map via handle
|
|
||||||
|
|
||||||
For consistency with sets, allow delete via handle for maps too.
|
|
||||||
|
|
||||||
Fixes: f4a34d25f6d5 ("src: list set handle and delete set via set handle")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_bison.y | 2 +-
|
|
||||||
tests/shell/testcases/cache/0008_delete_by_handle_0 | 4 ++++
|
|
||||||
tests/shell/testcases/cache/0009_delete_by_handle_incorrect_0 | 1 +
|
|
||||||
3 files changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
||||||
index ff6660c..e252113 100644
|
|
||||||
--- a/src/parser_bison.y
|
|
||||||
+++ b/src/parser_bison.y
|
|
||||||
@@ -1403,7 +1403,7 @@ delete_cmd : TABLE table_or_id_spec
|
|
||||||
{
|
|
||||||
$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
|
|
||||||
}
|
|
||||||
- | MAP set_spec
|
|
||||||
+ | MAP set_or_id_spec
|
|
||||||
{
|
|
||||||
$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/cache/0008_delete_by_handle_0 b/tests/shell/testcases/cache/0008_delete_by_handle_0
|
|
||||||
index 0db4c69..9eb75e6 100755
|
|
||||||
--- a/tests/shell/testcases/cache/0008_delete_by_handle_0
|
|
||||||
+++ b/tests/shell/testcases/cache/0008_delete_by_handle_0
|
|
||||||
@@ -16,6 +16,10 @@ $NFT add set t s { type ipv4_addr\; }
|
|
||||||
HANDLE=`$NFT -a list ruleset | grep "set.*handle" | cut -d' ' -f6`
|
|
||||||
$NFT delete set t handle $HANDLE
|
|
||||||
|
|
||||||
+$NFT add map t m { type ipv4_addr : ipv4_addr\; }
|
|
||||||
+HANDLE=`$NFT -a list ruleset | grep "map.*handle" | cut -d' ' -f6`
|
|
||||||
+$NFT delete map t handle $HANDLE
|
|
||||||
+
|
|
||||||
$NFT add flowtable t f { hook ingress priority 0\; devices = { lo } \; }
|
|
||||||
HANDLE=`$NFT -a list ruleset | grep "flowtable.*handle" | cut -d' ' -f6`
|
|
||||||
$NFT delete flowtable t handle $HANDLE
|
|
||||||
diff --git a/tests/shell/testcases/cache/0009_delete_by_handle_incorrect_0 b/tests/shell/testcases/cache/0009_delete_by_handle_incorrect_0
|
|
||||||
index f0bb02a..dd390e7 100755
|
|
||||||
--- a/tests/shell/testcases/cache/0009_delete_by_handle_incorrect_0
|
|
||||||
+++ b/tests/shell/testcases/cache/0009_delete_by_handle_incorrect_0
|
|
||||||
@@ -3,6 +3,7 @@
|
|
||||||
$NFT delete table handle 4000 && exit 1
|
|
||||||
$NFT delete chain t handle 4000 && exit 1
|
|
||||||
$NFT delete set t handle 4000 && exit 1
|
|
||||||
+$NFT delete map t handle 4000 && exit 1
|
|
||||||
$NFT delete flowtable t handle 4000 && exit 1
|
|
||||||
$NFT delete counter t handle 4000 && exit 1
|
|
||||||
exit 0
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
From 0a64846a869aab6c9bc5cb1adb268a16f53bb9f8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] json: reject too long interface names
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit bed99830c4c63eae205c28a7ff914737bedb199d
|
|
||||||
|
|
||||||
commit bed99830c4c63eae205c28a7ff914737bedb199d
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Tue Jun 24 23:46:59 2025 +0200
|
|
||||||
|
|
||||||
json: reject too long interface names
|
|
||||||
|
|
||||||
Blamed commit added a length check on ifnames to the bison parser.
|
|
||||||
Unfortunately that wasn't enough, json parser has the same issue.
|
|
||||||
|
|
||||||
Bogon results in:
|
|
||||||
BUG: Interface length 44 exceeds limit
|
|
||||||
nft: src/mnl.c:742: nft_dev_add: Assertion `0' failed.
|
|
||||||
|
|
||||||
After patch, included bogon results in:
|
|
||||||
Error: Invalid device at index 0. name d2345678999999999999999999999999999999012345 too long
|
|
||||||
|
|
||||||
I intentionally did not extend evaluate.c to catch this, past sentiment
|
|
||||||
was that frontends should not send garbage.
|
|
||||||
|
|
||||||
I'll send a followup patch to also catch this from eval stage in case there
|
|
||||||
are further reports for frontends passing in such long names.
|
|
||||||
|
|
||||||
Fixes: fa52bc225806 ("parser: reject zero-length interface names")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_json.c | 17 +++-
|
|
||||||
.../nft-j-f/dev_name_parser_overflow_crash | 90 +++++++++++++++++++
|
|
||||||
2 files changed, 105 insertions(+), 2 deletions(-)
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-j-f/dev_name_parser_overflow_crash
|
|
||||||
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 936c5aa..eefb8af 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -3062,7 +3062,13 @@ static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root)
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
if (!json_unpack(root, "s", &dev)) {
|
|
||||||
- tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
+ if (strlen(dev) >= IFNAMSIZ) {
|
|
||||||
+ json_error(ctx, "Device name %s too long", dev);
|
|
||||||
+ expr_free(expr);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ tmp = constant_expr_alloc(int_loc, &ifname_type,
|
|
||||||
BYTEORDER_HOST_ENDIAN,
|
|
||||||
strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
compound_expr_add(expr, tmp);
|
|
||||||
@@ -3080,7 +3086,14 @@ static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root)
|
|
||||||
expr_free(expr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
- tmp = constant_expr_alloc(int_loc, &string_type,
|
|
||||||
+
|
|
||||||
+ if (strlen(dev) >= IFNAMSIZ) {
|
|
||||||
+ json_error(ctx, "Device name %s too long at index %zu", dev, index);
|
|
||||||
+ expr_free(expr);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ tmp = constant_expr_alloc(int_loc, &ifname_type,
|
|
||||||
BYTEORDER_HOST_ENDIAN,
|
|
||||||
strlen(dev) * BITS_PER_BYTE, dev);
|
|
||||||
compound_expr_add(expr, tmp);
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-j-f/dev_name_parser_overflow_crash b/tests/shell/testcases/bogons/nft-j-f/dev_name_parser_overflow_crash
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..8303c5c
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-j-f/dev_name_parser_overflow_crash
|
|
||||||
@@ -0,0 +1,90 @@
|
|
||||||
+{
|
|
||||||
+ "nftables": [
|
|
||||||
+ {
|
|
||||||
+ "metainfo": {
|
|
||||||
+ "version": "VERSION",
|
|
||||||
+ "release_name": "RELEASE_NAME",
|
|
||||||
+ "json_schema_version": 1
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "table": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "name": "filter1",
|
|
||||||
+ "handle": 0
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "chain": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "table": "filter1",
|
|
||||||
+ "name": "Main_Ingress1",
|
|
||||||
+ "handle": 0,
|
|
||||||
+ "dev": "lo",
|
|
||||||
+ "type": "filter",
|
|
||||||
+ "hook": "ingress",
|
|
||||||
+ "prio": -500,
|
|
||||||
+ "policy": "accept"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "table": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "name": "filter2",
|
|
||||||
+ "handle": 0
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "chain": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "table": "filter2",
|
|
||||||
+ "name": "Main_Ingress2",
|
|
||||||
+ "handle": 0,
|
|
||||||
+ "dev": [
|
|
||||||
+ "d2345678999999999999999999999999999999012345",
|
|
||||||
+ "lo"
|
|
||||||
+ ],
|
|
||||||
+ "type": "filter",
|
|
||||||
+ "hook": "ingress",
|
|
||||||
+ "prio": -500,
|
|
||||||
+ "policy": "accept"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "table": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "name": "filter3",
|
|
||||||
+ "handle": 0
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "chain": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "table": "filter3",
|
|
||||||
+ "name": "Main_Ingress3",
|
|
||||||
+ "handle": 0,
|
|
||||||
+ "dev": [
|
|
||||||
+ "d23456789012345",
|
|
||||||
+ "lo"
|
|
||||||
+ ],
|
|
||||||
+ "type": "filter",
|
|
||||||
+ "hook": "ingress",
|
|
||||||
+ "prio": -500,
|
|
||||||
+ "policy": "accept"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "chain": {
|
|
||||||
+ "family": "netdev",
|
|
||||||
+ "table": "filter3",
|
|
||||||
+ "name": "Main_Egress3",
|
|
||||||
+ "handle": 0,
|
|
||||||
+ "dev": "lo",
|
|
||||||
+ "type": "filter",
|
|
||||||
+ "hook": "egress",
|
|
||||||
+ "prio": -500,
|
|
||||||
+ "policy": "accept"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
From 34c6ee9bfa7992d449be6436cf0e550ab68e3dd1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] doc: extend description of fib expression
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit be4b61c05a2491aad596aa9243b17b13c937b347
|
|
||||||
|
|
||||||
commit be4b61c05a2491aad596aa9243b17b13c937b347
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu Oct 10 15:37:42 2024 +0200
|
|
||||||
|
|
||||||
doc: extend description of fib expression
|
|
||||||
|
|
||||||
Describe the input keys and the result types.
|
|
||||||
Mention which input keys are mandatory and which keys are mutually
|
|
||||||
exclusive.
|
|
||||||
|
|
||||||
Describe which hooks can be used with the various lookup modifiers
|
|
||||||
and extend the examples with more information on fib expression
|
|
||||||
capabilities.
|
|
||||||
|
|
||||||
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1663
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/primary-expression.txt | 77 +++++++++++++++++++++++++++++++-------
|
|
||||||
1 file changed, 63 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
|
|
||||||
index e13970c..e85fa58 100644
|
|
||||||
--- a/doc/primary-expression.txt
|
|
||||||
+++ b/doc/primary-expression.txt
|
|
||||||
@@ -304,17 +304,48 @@ table inet x {
|
|
||||||
FIB EXPRESSIONS
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
[verse]
|
|
||||||
-*fib* {*saddr* | *daddr* | *mark* | *iif* | *oif*} [*.* ...] {*oif* | *oifname* | *type*}
|
|
||||||
+*fib* 'FIB_TUPLE' 'FIB_RESULT'
|
|
||||||
+'FIB_TUPLE' := { *saddr* | *daddr*} [ *.* { *iif* | *oif* } *.* *mark* ]
|
|
||||||
+'FIB_RESULT' := { *oif* | *oifname* | *type* }
|
|
||||||
|
|
||||||
-A fib expression queries the fib (forwarding information base) to obtain
|
|
||||||
-information such as the output interface index a particular address would use.
|
|
||||||
-The input is a tuple of elements that is used as input to the fib lookup
|
|
||||||
-functions.
|
|
||||||
|
|
||||||
-.fib expression specific types
|
|
||||||
+A fib expression queries the fib (forwarding information base) to obtain information
|
|
||||||
+such as the output interface index.
|
|
||||||
+
|
|
||||||
+The first arguments to the *fib* expression are the input keys to be passed to the fib lookup function.
|
|
||||||
+One of *saddr* or *daddr* is mandatory, they are also mutually exclusive.
|
|
||||||
+
|
|
||||||
+*mark*, *iif* and *oif* keywords are optional modifiers to influence the search result, see
|
|
||||||
+the *FIB_TUPLE* keyword table below for a description.
|
|
||||||
+The *iif* and *oif* tuple keywords are also mutually exclusive.
|
|
||||||
+
|
|
||||||
+The last argument to the *fib* expression is the desired result type.
|
|
||||||
+
|
|
||||||
+*oif* asks to obtain the interface index that would be used to send packets to the packets source
|
|
||||||
+(*saddr* key) or destination (*daddr* key). If no routing entry is found, the returned interface
|
|
||||||
+index is 0.
|
|
||||||
+
|
|
||||||
+*oifname* is like *oif*, but it fills the interface name instead. This is useful to check dynamic
|
|
||||||
+interfaces such as ppp devices. If no entry is found, an empty interface name is returned.
|
|
||||||
+
|
|
||||||
+*type* returns the address type such as unicast or multicast. A complete list of supported
|
|
||||||
+address types can be shown with *nft* *describe* *fib_addrtype*.
|
|
||||||
+
|
|
||||||
+.FIB_TUPLE keywords
|
|
||||||
[options="header"]
|
|
||||||
|==================
|
|
||||||
-|Keyword| Description| Type
|
|
||||||
+|flag| Description
|
|
||||||
+|daddr| Perform a normal route lookup: search fib for route to the *destination address* of the packet.
|
|
||||||
+|saddr| Perform a reverse route lookup: search the fib for route to the *source address* of the packet.
|
|
||||||
+|mark | consider the packet mark (nfmark) when querying the fib.
|
|
||||||
+|iif | if fib lookups provides a route then check its output interface is identical to the packets *input* interface.
|
|
||||||
+|oif | if fib lookups provides a route then check its output interface is identical to the packets *output* interface. This flag can only be used with the *type* result.
|
|
||||||
+|=======================
|
|
||||||
+
|
|
||||||
+.FIB_RESULT keywords
|
|
||||||
+[options="header"]
|
|
||||||
+|==================
|
|
||||||
+|Keyword| Description| Result Type
|
|
||||||
|oif|
|
|
||||||
Output interface index|
|
|
||||||
integer (32 bit)
|
|
||||||
@@ -323,25 +354,43 @@ Output interface name|
|
|
||||||
string
|
|
||||||
|type|
|
|
||||||
Address type |
|
|
||||||
-fib_addrtype
|
|
||||||
+fib_addrtype (see *nft* *describe* *fib_addrtype* for a list)
|
|
||||||
|=======================
|
|
||||||
|
|
||||||
-Use *nft* *describe* *fib_addrtype* to get a list of all address types.
|
|
||||||
+The *oif* and *oifname* result is only valid in the *prerouting*, *input* and *forward* hooks.
|
|
||||||
+The *type* can be queried from any one of *prerouting*, *input*, *forward* *output* and *postrouting*.
|
|
||||||
+
|
|
||||||
+For *type*, the presence of the *iif* keyword in the 'FIB_TUPLE' modifiers restrict the available
|
|
||||||
+hooks to those where the packet is associated with an incoming interface, i.e. *prerouting*, *input* and *forward*.
|
|
||||||
+Likewise, the *oif* keyword in the 'FIB_TUPLE' modifier list will limit the available hooks to
|
|
||||||
+*forward*, *output* and *postrouting*.
|
|
||||||
|
|
||||||
.Using fib expressions
|
|
||||||
----------------------
|
|
||||||
# drop packets without a reverse path
|
|
||||||
filter prerouting fib saddr . iif oif missing drop
|
|
||||||
|
|
||||||
-In this example, 'saddr . iif' looks up routing information based on the source address and the input interface.
|
|
||||||
-oif picks the output interface index from the routing information.
|
|
||||||
+In this example, 'saddr . iif' looks up a route to the *source address* of the packet and restricts matching
|
|
||||||
+results to the interface that the packet arrived on, then stores the output interface index from the obtained
|
|
||||||
+fib route result.
|
|
||||||
+
|
|
||||||
If no route was found for the source address/input interface combination, the output interface index is zero.
|
|
||||||
-In case the input interface is specified as part of the input key, the output interface index is always the same as the input interface index or zero.
|
|
||||||
-If only 'saddr oif' is given, then oif can be any interface index or zero.
|
|
||||||
+Hence, this rule will drop all packets that do not have a strict reverse path (hypothetical reply packet
|
|
||||||
+would be sent via the interface the tested packet arrived on).
|
|
||||||
+
|
|
||||||
+If only 'saddr oif' is used as the input key, then this rule would only drop packets where the fib cannot
|
|
||||||
+find a route. In most setups this will never drop packets because the default route is returned.
|
|
||||||
|
|
||||||
-# drop packets to address not configured on incoming interface
|
|
||||||
+# drop packets if the destination ip address is not configured on the incoming interface
|
|
||||||
filter prerouting fib daddr . iif type != { local, broadcast, multicast } drop
|
|
||||||
|
|
||||||
+This queries the fib based on the current packets' destination address and the incoming interface.
|
|
||||||
+
|
|
||||||
+If the packet is sent to a unicast address that is configured on a different interface, then the packet
|
|
||||||
+will be dropped as such an address would be classified as 'unicast' type.
|
|
||||||
+Without the 'iif' modifier, any address configured on the local machine is 'local', and unicast addresses
|
|
||||||
+not configured on any interface would return the type 'unicast'.
|
|
||||||
+
|
|
||||||
# perform lookup in a specific 'blackhole' table (0xdead, needs ip appropriate ip rule)
|
|
||||||
filter prerouting meta mark set 0xdead fib daddr . mark type vmap { blackhole : drop, prohibit : jump prohibited, unreachable : drop }
|
|
||||||
----------------------
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
From e3bdd843cd1b342082c7b01a888c33d05a91117b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] json: fix use after free in table_flags_json()
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b04512cf30de1ba6657facba5ebe2321e17c2727
|
|
||||||
|
|
||||||
commit b04512cf30de1ba6657facba5ebe2321e17c2727
|
|
||||||
Author: Thomas Haller <thaller@redhat.com>
|
|
||||||
Date: Tue Nov 14 16:29:25 2023 +0100
|
|
||||||
|
|
||||||
json: fix use after free in table_flags_json()
|
|
||||||
|
|
||||||
Add `$NFT -j list ruleset` to the end of "tests/shell/testcases/transactions/table_onoff".
|
|
||||||
Then valgrind will find this issue:
|
|
||||||
|
|
||||||
$ make -j && ./tests/shell/run-tests.sh tests/shell/testcases/transactions/table_onoff -V
|
|
||||||
|
|
||||||
Gives:
|
|
||||||
|
|
||||||
==286== Invalid read of size 4
|
|
||||||
==286== at 0x49B0261: do_dump (dump.c:211)
|
|
||||||
==286== by 0x49B08B8: do_dump (dump.c:378)
|
|
||||||
==286== by 0x49B08B8: do_dump (dump.c:378)
|
|
||||||
==286== by 0x49B04F7: do_dump (dump.c:273)
|
|
||||||
==286== by 0x49B08B8: do_dump (dump.c:378)
|
|
||||||
==286== by 0x49B0E84: json_dump_callback (dump.c:465)
|
|
||||||
==286== by 0x48AF22A: do_command_list_json (json.c:2016)
|
|
||||||
==286== by 0x48732F1: do_command_list (rule.c:2335)
|
|
||||||
==286== by 0x48737F5: do_command (rule.c:2605)
|
|
||||||
==286== by 0x48A867D: nft_netlink (libnftables.c:42)
|
|
||||||
==286== by 0x48A92B1: nft_run_cmd_from_buffer (libnftables.c:597)
|
|
||||||
==286== by 0x402CBA: main (main.c:533)
|
|
||||||
|
|
||||||
Fixes: e70354f53e9f ("libnftables: Implement JSON output support")
|
|
||||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 39b1ada..e5bec4f 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -517,7 +517,7 @@ static json_t *table_flags_json(const struct table *table)
|
|
||||||
json_decref(root);
|
|
||||||
return NULL;
|
|
||||||
case 1:
|
|
||||||
- json_unpack(root, "[o]", &tmp);
|
|
||||||
+ json_unpack(root, "[O]", &tmp);
|
|
||||||
json_decref(root);
|
|
||||||
root = tmp;
|
|
||||||
break;
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From 1c481d182bca10f9384f00545a4e2b85acffb76c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] json: Print single fib flag as non-array
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit dbe5c44f2b891c1d305cc94a7ea9dd963a7b6100
|
|
||||||
|
|
||||||
commit dbe5c44f2b891c1d305cc94a7ea9dd963a7b6100
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu May 8 16:40:41 2025 +0200
|
|
||||||
|
|
||||||
json: Print single fib flag as non-array
|
|
||||||
|
|
||||||
Check array size and reduce the array if possible.
|
|
||||||
|
|
||||||
The zero array length check is dead code here due to the surrounding 'if
|
|
||||||
(flags)' block, but it's a common idiom one could replace by a shared
|
|
||||||
routine later.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 10 +++++++++-
|
|
||||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index e5bec4f..9320336 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -935,7 +935,15 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
|
|
||||||
}
|
|
||||||
if (flags)
|
|
||||||
json_array_append_new(tmp, json_integer(flags));
|
|
||||||
- json_object_set_new(root, "flags", tmp);
|
|
||||||
+
|
|
||||||
+ if (json_array_size(tmp) > 1) {
|
|
||||||
+ json_object_set_new(root, "flags", tmp);
|
|
||||||
+ } else {
|
|
||||||
+ if (json_array_size(tmp))
|
|
||||||
+ json_object_set(root, "flags",
|
|
||||||
+ json_array_get(tmp, 0));
|
|
||||||
+ json_decref(tmp);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
return json_pack("{s:o}", "fib", root);
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From 399c60ed7706c110123aa28f282f45899a2cd56f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:19 +0200
|
|
||||||
Subject: [PATCH] json: Print single synproxy flags as non-array
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 38f99ee84fe6bd029fbc3d1389f42ab82fa9789c
|
|
||||||
|
|
||||||
commit 38f99ee84fe6bd029fbc3d1389f42ab82fa9789c
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu May 8 16:44:39 2025 +0200
|
|
||||||
|
|
||||||
json: Print single synproxy flags as non-array
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 8 ++++++--
|
|
||||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 9320336..9b3a639 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -1685,10 +1685,14 @@ json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
if (stmt->synproxy.flags & NF_SYNPROXY_OPT_SACK_PERM)
|
|
||||||
json_array_append_new(flags, json_string("sack-perm"));
|
|
||||||
|
|
||||||
- if (json_array_size(flags) > 0)
|
|
||||||
+ if (json_array_size(flags) > 1) {
|
|
||||||
json_object_set_new(root, "flags", flags);
|
|
||||||
- else
|
|
||||||
+ } else {
|
|
||||||
+ if (json_array_size(flags))
|
|
||||||
+ json_object_set(root, "flags",
|
|
||||||
+ json_array_get(flags, 0));
|
|
||||||
json_decref(flags);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (!json_object_size(root)) {
|
|
||||||
json_decref(root);
|
|
||||||
@ -1,221 +0,0 @@
|
|||||||
From a3f57e683bbf70bbba05bd495a2f5d8c32eb6aa4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:25:20 +0200
|
|
||||||
Subject: [PATCH] json: Introduce json_add_array_new()
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit a740f2036ad0d50b4a91e110611563809dac420a
|
|
||||||
Conflicts: Context change due to missing commit a0a15e4dd0576
|
|
||||||
("json: Fix for memleak in __binop_expr_json")
|
|
||||||
|
|
||||||
commit a740f2036ad0d50b4a91e110611563809dac420a
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu May 8 17:28:02 2025 +0200
|
|
||||||
|
|
||||||
json: Introduce json_add_array_new()
|
|
||||||
|
|
||||||
Propagate nat_stmt_add_array() to a generic helper for use in all spots
|
|
||||||
adding an array property which may reduce to a single item or even not
|
|
||||||
exist at all.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 99 +++++++++++++-----------------------------------------
|
|
||||||
1 file changed, 24 insertions(+), 75 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 9b3a639..c8abc56 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -42,6 +42,18 @@
|
|
||||||
})
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+static void json_add_array_new(json_t *obj, const char *name, json_t *array)
|
|
||||||
+{
|
|
||||||
+ if (json_array_size(array) > 1) {
|
|
||||||
+ json_object_set_new(obj, name, array);
|
|
||||||
+ } else {
|
|
||||||
+ if (json_array_size(array))
|
|
||||||
+ json_object_set(obj, name,
|
|
||||||
+ json_array_get(array, 0));
|
|
||||||
+ json_decref(array);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static json_t *expr_print_json(const struct expr *expr, struct output_ctx *octx)
|
|
||||||
{
|
|
||||||
const struct expr_ops *ops;
|
|
||||||
@@ -188,14 +200,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
|
||||||
json_array_append_new(tmp, json_pack("s", "timeout"));
|
|
||||||
if (set->flags & NFT_SET_EVAL)
|
|
||||||
json_array_append_new(tmp, json_pack("s", "dynamic"));
|
|
||||||
-
|
|
||||||
- if (json_array_size(tmp) > 1) {
|
|
||||||
- json_object_set_new(root, "flags", tmp);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(tmp))
|
|
||||||
- json_object_set(root, "flags", json_array_get(tmp, 0));
|
|
||||||
- json_decref(tmp);
|
|
||||||
- }
|
|
||||||
+ json_add_array_new(root, "flags", tmp);
|
|
||||||
|
|
||||||
if (set->timeout) {
|
|
||||||
tmp = json_integer(set->timeout / 1000);
|
|
||||||
@@ -443,19 +448,16 @@ static json_t *obj_print_json(const struct obj *obj)
|
|
||||||
json_decref(tmp);
|
|
||||||
break;
|
|
||||||
case NFT_OBJECT_SYNPROXY:
|
|
||||||
- flags = json_array();
|
|
||||||
tmp = json_pack("{s:i, s:i}",
|
|
||||||
"mss", obj->synproxy.mss,
|
|
||||||
"wscale", obj->synproxy.wscale);
|
|
||||||
+
|
|
||||||
+ flags = json_array();
|
|
||||||
if (obj->synproxy.flags & NF_SYNPROXY_OPT_TIMESTAMP)
|
|
||||||
json_array_append_new(flags, json_string("timestamp"));
|
|
||||||
if (obj->synproxy.flags & NF_SYNPROXY_OPT_SACK_PERM)
|
|
||||||
json_array_append_new(flags, json_string("sack-perm"));
|
|
||||||
-
|
|
||||||
- if (json_array_size(flags) > 0)
|
|
||||||
- json_object_set_new(tmp, "flags", flags);
|
|
||||||
- else
|
|
||||||
- json_decref(flags);
|
|
||||||
+ json_add_array_new(tmp, "flags", flags);
|
|
||||||
|
|
||||||
json_object_update(root, tmp);
|
|
||||||
json_decref(tmp);
|
|
||||||
@@ -512,31 +514,18 @@ static json_t *table_flags_json(const struct table *table)
|
|
||||||
flags >>= 1;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
- switch (json_array_size(root)) {
|
|
||||||
- case 0:
|
|
||||||
- json_decref(root);
|
|
||||||
- return NULL;
|
|
||||||
- case 1:
|
|
||||||
- json_unpack(root, "[O]", &tmp);
|
|
||||||
- json_decref(root);
|
|
||||||
- root = tmp;
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
static json_t *table_print_json(const struct table *table)
|
|
||||||
{
|
|
||||||
- json_t *root, *tmp;
|
|
||||||
+ json_t *root;
|
|
||||||
|
|
||||||
root = json_pack("{s:s, s:s, s:I}",
|
|
||||||
"family", family2str(table->handle.family),
|
|
||||||
"name", table->handle.table.name,
|
|
||||||
"handle", table->handle.handle.id);
|
|
||||||
-
|
|
||||||
- tmp = table_flags_json(table);
|
|
||||||
- if (tmp)
|
|
||||||
- json_object_set_new(root, "flags", tmp);
|
|
||||||
+ json_add_array_new(root, "flags", table_flags_json(table));
|
|
||||||
|
|
||||||
if (table->comment)
|
|
||||||
json_object_set_new(root, "comment", json_string(table->comment));
|
|
||||||
@@ -936,14 +925,7 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
|
|
||||||
if (flags)
|
|
||||||
json_array_append_new(tmp, json_integer(flags));
|
|
||||||
|
|
||||||
- if (json_array_size(tmp) > 1) {
|
|
||||||
- json_object_set_new(root, "flags", tmp);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(tmp))
|
|
||||||
- json_object_set(root, "flags",
|
|
||||||
- json_array_get(tmp, 0));
|
|
||||||
- json_decref(tmp);
|
|
||||||
- }
|
|
||||||
+ json_add_array_new(root, "flags", tmp);
|
|
||||||
}
|
|
||||||
return json_pack("{s:o}", "fib", root);
|
|
||||||
}
|
|
||||||
@@ -1383,14 +1365,7 @@ json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
if (stmt->log.logflags & NF_LOG_MACDECODE)
|
|
||||||
json_array_append_new(flags, json_string("ether"));
|
|
||||||
}
|
|
||||||
- if (json_array_size(flags) > 1) {
|
|
||||||
- json_object_set_new(root, "flags", flags);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(flags))
|
|
||||||
- json_object_set(root, "flags",
|
|
||||||
- json_array_get(flags, 0));
|
|
||||||
- json_decref(flags);
|
|
||||||
- }
|
|
||||||
+ json_add_array_new(root, "flags", flags);
|
|
||||||
|
|
||||||
if (!json_object_size(root)) {
|
|
||||||
json_decref(root);
|
|
||||||
@@ -1425,18 +1400,6 @@ static json_t *nat_type_flags_json(uint32_t type_flags)
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void nat_stmt_add_array(json_t *root, const char *name, json_t *array)
|
|
||||||
-{
|
|
||||||
- if (json_array_size(array) > 1) {
|
|
||||||
- json_object_set_new(root, name, array);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(array))
|
|
||||||
- json_object_set(root, name,
|
|
||||||
- json_array_get(array, 0));
|
|
||||||
- json_decref(array);
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
{
|
|
||||||
json_t *root = json_object();
|
|
||||||
@@ -1458,12 +1421,12 @@ json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
json_object_set_new(root, "port",
|
|
||||||
expr_print_json(stmt->nat.proto, octx));
|
|
||||||
|
|
||||||
- nat_stmt_add_array(root, "flags", array);
|
|
||||||
+ json_add_array_new(root, "flags", array);
|
|
||||||
|
|
||||||
if (stmt->nat.type_flags) {
|
|
||||||
array = nat_type_flags_json(stmt->nat.type_flags);
|
|
||||||
|
|
||||||
- nat_stmt_add_array(root, "type_flags", array);
|
|
||||||
+ json_add_array_new(root, "type_flags", array);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!json_object_size(root)) {
|
|
||||||
@@ -1615,14 +1578,7 @@ json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
json_array_append_new(flags, json_string("bypass"));
|
|
||||||
if (stmt->queue.flags & NFT_QUEUE_FLAG_CPU_FANOUT)
|
|
||||||
json_array_append_new(flags, json_string("fanout"));
|
|
||||||
- if (json_array_size(flags) > 1) {
|
|
||||||
- json_object_set_new(root, "flags", flags);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(flags))
|
|
||||||
- json_object_set(root, "flags",
|
|
||||||
- json_array_get(flags, 0));
|
|
||||||
- json_decref(flags);
|
|
||||||
- }
|
|
||||||
+ json_add_array_new(root, "flags", flags);
|
|
||||||
|
|
||||||
if (!json_object_size(root)) {
|
|
||||||
json_decref(root);
|
|
||||||
@@ -1685,14 +1641,7 @@ json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
|
||||||
if (stmt->synproxy.flags & NF_SYNPROXY_OPT_SACK_PERM)
|
|
||||||
json_array_append_new(flags, json_string("sack-perm"));
|
|
||||||
|
|
||||||
- if (json_array_size(flags) > 1) {
|
|
||||||
- json_object_set_new(root, "flags", flags);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(flags))
|
|
||||||
- json_object_set(root, "flags",
|
|
||||||
- json_array_get(flags, 0));
|
|
||||||
- json_decref(flags);
|
|
||||||
- }
|
|
||||||
+ json_add_array_new(root, "flags", flags);
|
|
||||||
|
|
||||||
if (!json_object_size(root)) {
|
|
||||||
json_decref(root);
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,769 +0,0 @@
|
|||||||
From df090a258ef0753e76112b58ba3165a452fc24be Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:30:19 +0200
|
|
||||||
Subject: [PATCH] parser_json: Introduce parse_flags_array()
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 3550dd69632f3a883ab6593daeffb514c67dfb8c
|
|
||||||
|
|
||||||
commit 3550dd69632f3a883ab6593daeffb514c67dfb8c
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Apr 10 16:42:42 2025 +0200
|
|
||||||
|
|
||||||
parser_json: Introduce parse_flags_array()
|
|
||||||
|
|
||||||
Various objects support a 'flags' property with value usually being an
|
|
||||||
array of strings. There is a special case, when merely a single flag is
|
|
||||||
set: The value may be a string representing this flag.
|
|
||||||
|
|
||||||
Introduce a function assisting in parsing this polymorphic value. Have
|
|
||||||
callers pass a parser callback translating a single flag name into a
|
|
||||||
corresponding value. Luckily, these single flag parsers are very common
|
|
||||||
already.
|
|
||||||
|
|
||||||
As a side-effect, enable the single flag spec for set flags as well and
|
|
||||||
update the documentation accordingly.
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/libnftables-json.adoc | 5 +-
|
|
||||||
src/parser_json.c | 466 +++++++++++---------------------------
|
|
||||||
2 files changed, 136 insertions(+), 335 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
|
||||||
index c3e3bcc..27c96c3 100644
|
|
||||||
--- a/doc/libnftables-json.adoc
|
|
||||||
+++ b/doc/libnftables-json.adoc
|
|
||||||
@@ -317,7 +317,7 @@ ____
|
|
||||||
"handle":* 'NUMBER'*,
|
|
||||||
"type":* 'SET_TYPE'*,
|
|
||||||
"policy":* 'SET_POLICY'*,
|
|
||||||
- "flags": [* 'SET_FLAG_LIST' *],
|
|
||||||
+ "flags":* 'SET_FLAGS'*,
|
|
||||||
"elem":* 'SET_ELEMENTS'*,
|
|
||||||
"timeout":* 'NUMBER'*,
|
|
||||||
"gc-interval":* 'NUMBER'*,
|
|
||||||
@@ -332,7 +332,7 @@ ____
|
|
||||||
"type":* 'SET_TYPE'*,
|
|
||||||
"map":* 'STRING'*,
|
|
||||||
"policy":* 'SET_POLICY'*,
|
|
||||||
- "flags": [* 'SET_FLAG_LIST' *],
|
|
||||||
+ "flags":* 'SET_FLAGS'*,
|
|
||||||
"elem":* 'SET_ELEMENTS'*,
|
|
||||||
"timeout":* 'NUMBER'*,
|
|
||||||
"gc-interval":* 'NUMBER'*,
|
|
||||||
@@ -342,6 +342,7 @@ ____
|
|
||||||
'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]* | *{ "typeof":* 'EXPRESSION' *}*
|
|
||||||
'SET_TYPE_LIST' := 'STRING' [*,* 'SET_TYPE_LIST' ]
|
|
||||||
'SET_POLICY' := *"performance"* | *"memory"*
|
|
||||||
+'SET_FLAGS' := 'SET_FLAG' | *[* 'SET_FLAG_LIST' *]*
|
|
||||||
'SET_FLAG_LIST' := 'SET_FLAG' [*,* 'SET_FLAG_LIST' ]
|
|
||||||
'SET_FLAG' := *"constant"* | *"interval"* | *"timeout"*
|
|
||||||
'SET_ELEMENTS' := 'EXPRESSION' | *[* 'EXPRESSION_LIST' *]*
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index eefb8af..0bf81d1 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -193,6 +193,60 @@ static int json_unpack_stmt(struct json_ctx *ctx, json_t *root,
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * parse_flags_array - parse JSON property as an array of flags
|
|
||||||
+ *
|
|
||||||
+ * @ctx: JSON parser context
|
|
||||||
+ * @obj: JSON object to extract property from
|
|
||||||
+ * @key: name of property containing the flags array
|
|
||||||
+ * @flag_parser: Callback parsing a single flag, returns 0 on error
|
|
||||||
+ *
|
|
||||||
+ * The property value may be a string representing a single flag or an array of
|
|
||||||
+ * strings representing a number of flags whose values are ORed together.
|
|
||||||
+ *
|
|
||||||
+ * @return: Combined flag value, 0 if no such property found or -1 if data is
|
|
||||||
+ * malformed or flag parsing failed.
|
|
||||||
+ */
|
|
||||||
+static int parse_flags_array(struct json_ctx *ctx, json_t *obj, const char *key,
|
|
||||||
+ unsigned int (*flag_parser)(const char *flag))
|
|
||||||
+{
|
|
||||||
+ json_t *value = json_object_get(obj, key), *tmp;
|
|
||||||
+ size_t index;
|
|
||||||
+ int ret = 0;
|
|
||||||
+
|
|
||||||
+ if (!value)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (json_is_string(value)) {
|
|
||||||
+ ret = flag_parser(json_string_value(value));
|
|
||||||
+ return ret ?: -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!json_is_array(value)) {
|
|
||||||
+ json_error(ctx,
|
|
||||||
+ "Expecting string or array in '%s' property.", key);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ json_array_foreach(value, index, tmp) {
|
|
||||||
+ int flag = 0;
|
|
||||||
+
|
|
||||||
+ if (json_is_string(tmp))
|
|
||||||
+ flag = flag_parser(json_string_value(tmp));
|
|
||||||
+
|
|
||||||
+ if (!flag) {
|
|
||||||
+ json_error(ctx,
|
|
||||||
+ "Invalid flag in '%s' property array at index %zu.",
|
|
||||||
+ key, index);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret |= flag;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int parse_family(const char *name, uint32_t *family)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
@@ -1060,7 +1114,7 @@ static struct expr *json_parse_hash_expr(struct json_ctx *ctx,
|
|
||||||
return hash_expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int fib_flag_parse(const char *name, int *flags)
|
|
||||||
+static unsigned int fib_flag_parse(const char *name)
|
|
||||||
{
|
|
||||||
const char *fib_flags[] = {
|
|
||||||
"saddr",
|
|
||||||
@@ -1072,12 +1126,10 @@ static int fib_flag_parse(const char *name, int *flags)
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < array_size(fib_flags); i++) {
|
|
||||||
- if (!strcmp(name, fib_flags[i])) {
|
|
||||||
- *flags |= (1 << i);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
+ if (!strcmp(name, fib_flags[i]))
|
|
||||||
+ return 1 << i;
|
|
||||||
}
|
|
||||||
- return 1;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct expr *json_parse_fib_expr(struct json_ctx *ctx,
|
|
||||||
@@ -1090,11 +1142,9 @@ static struct expr *json_parse_fib_expr(struct json_ctx *ctx,
|
|
||||||
[NFT_FIB_RESULT_ADDRTYPE] = "type",
|
|
||||||
};
|
|
||||||
enum nft_fib_result resultval = NFT_FIB_RESULT_UNSPEC;
|
|
||||||
- json_t *flags, *value;
|
|
||||||
const char *result;
|
|
||||||
- unsigned int i;
|
|
||||||
- size_t index;
|
|
||||||
int flagval = 0;
|
|
||||||
+ unsigned int i;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s}", "result", &result))
|
|
||||||
return NULL;
|
|
||||||
@@ -1110,34 +1160,9 @@ static struct expr *json_parse_fib_expr(struct json_ctx *ctx,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!json_unpack(root, "{s:o}", "flags", &flags)) {
|
|
||||||
- const char *flag;
|
|
||||||
-
|
|
||||||
- if (json_is_string(flags)) {
|
|
||||||
- flag = json_string_value(flags);
|
|
||||||
-
|
|
||||||
- if (fib_flag_parse(flag, &flagval)) {
|
|
||||||
- json_error(ctx, "Invalid fib flag '%s'.", flag);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- } else if (!json_is_array(flags)) {
|
|
||||||
- json_error(ctx, "Unexpected object type in fib tuple.");
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- json_array_foreach(flags, index, value) {
|
|
||||||
- if (!json_is_string(value)) {
|
|
||||||
- json_error(ctx, "Unexpected object type in fib flags array at index %zd.", index);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(value);
|
|
||||||
-
|
|
||||||
- if (fib_flag_parse(flag, &flagval)) {
|
|
||||||
- json_error(ctx, "Invalid fib flag '%s'.", flag);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ flagval = parse_flags_array(ctx, root, "flags", fib_flag_parse);
|
|
||||||
+ if (flagval < 0)
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
/* sanity checks from fib_expr in parser_bison.y */
|
|
||||||
|
|
||||||
@@ -2090,8 +2115,7 @@ static struct stmt *json_parse_secmark_stmt(struct json_ctx *ctx,
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int json_parse_nat_flag(struct json_ctx *ctx,
|
|
||||||
- json_t *root, int *flags)
|
|
||||||
+static unsigned int json_parse_nat_flag(const char *flag)
|
|
||||||
{
|
|
||||||
const struct {
|
|
||||||
const char *flag;
|
|
||||||
@@ -2102,51 +2126,16 @@ static int json_parse_nat_flag(struct json_ctx *ctx,
|
|
||||||
{ "persistent", NF_NAT_RANGE_PERSISTENT },
|
|
||||||
{ "netmap", NF_NAT_RANGE_NETMAP },
|
|
||||||
};
|
|
||||||
- const char *flag;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
- assert(flags);
|
|
||||||
-
|
|
||||||
- if (!json_is_string(root)) {
|
|
||||||
- json_error(ctx, "Invalid nat flag type %s, expected string.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(root);
|
|
||||||
for (i = 0; i < array_size(flag_tbl); i++) {
|
|
||||||
- if (!strcmp(flag, flag_tbl[i].flag)) {
|
|
||||||
- *flags |= flag_tbl[i].val;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Unknown nat flag '%s'.", flag);
|
|
||||||
- return 1;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int json_parse_nat_flags(struct json_ctx *ctx, json_t *root)
|
|
||||||
-{
|
|
||||||
- int flags = 0;
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
-
|
|
||||||
- if (json_is_string(root)) {
|
|
||||||
- json_parse_nat_flag(ctx, root, &flags);
|
|
||||||
- return flags;
|
|
||||||
- } else if (!json_is_array(root)) {
|
|
||||||
- json_error(ctx, "Invalid nat flags type %s.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
- json_array_foreach(root, index, value) {
|
|
||||||
- if (json_parse_nat_flag(ctx, value, &flags))
|
|
||||||
- json_error(ctx, "Parsing nat flag at index %zu failed.",
|
|
||||||
- index);
|
|
||||||
+ if (!strcmp(flag, flag_tbl[i].flag))
|
|
||||||
+ return flag_tbl[i].val;
|
|
||||||
}
|
|
||||||
- return flags;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int json_parse_nat_type_flag(struct json_ctx *ctx,
|
|
||||||
- json_t *root, int *flags)
|
|
||||||
+static unsigned int json_parse_nat_type_flag(const char *flag)
|
|
||||||
{
|
|
||||||
const struct {
|
|
||||||
const char *flag;
|
|
||||||
@@ -2156,47 +2145,13 @@ static int json_parse_nat_type_flag(struct json_ctx *ctx,
|
|
||||||
{ "prefix", STMT_NAT_F_PREFIX },
|
|
||||||
{ "concat", STMT_NAT_F_CONCAT },
|
|
||||||
};
|
|
||||||
- const char *flag;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
- assert(flags);
|
|
||||||
-
|
|
||||||
- if (!json_is_string(root)) {
|
|
||||||
- json_error(ctx, "Invalid nat type flag type %s, expected string.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(root);
|
|
||||||
for (i = 0; i < array_size(flag_tbl); i++) {
|
|
||||||
- if (!strcmp(flag, flag_tbl[i].flag)) {
|
|
||||||
- *flags |= flag_tbl[i].val;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Unknown nat type flag '%s'.", flag);
|
|
||||||
- return 1;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int json_parse_nat_type_flags(struct json_ctx *ctx, json_t *root)
|
|
||||||
-{
|
|
||||||
- int flags = 0;
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
-
|
|
||||||
- if (json_is_string(root)) {
|
|
||||||
- json_parse_nat_type_flag(ctx, root, &flags);
|
|
||||||
- return flags;
|
|
||||||
- } else if (!json_is_array(root)) {
|
|
||||||
- json_error(ctx, "Invalid nat flags type %s.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
- json_array_foreach(root, index, value) {
|
|
||||||
- if (json_parse_nat_type_flag(ctx, value, &flags))
|
|
||||||
- json_error(ctx, "Parsing nat type flag at index %zu failed.",
|
|
||||||
- index);
|
|
||||||
+ if (!strcmp(flag, flag_tbl[i].flag))
|
|
||||||
+ return flag_tbl[i].val;
|
|
||||||
}
|
|
||||||
- return flags;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nat_type_parse(const char *type)
|
|
||||||
@@ -2219,7 +2174,7 @@ static int nat_type_parse(const char *type)
|
|
||||||
static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx,
|
|
||||||
const char *key, json_t *value)
|
|
||||||
{
|
|
||||||
- int type, familyval;
|
|
||||||
+ int type, familyval, flags;
|
|
||||||
struct stmt *stmt;
|
|
||||||
json_t *tmp;
|
|
||||||
|
|
||||||
@@ -2252,24 +2207,20 @@ static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (!json_unpack(value, "{s:o}", "flags", &tmp)) {
|
|
||||||
- int flags = json_parse_nat_flags(ctx, tmp);
|
|
||||||
-
|
|
||||||
- if (flags < 0) {
|
|
||||||
- stmt_free(stmt);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- stmt->nat.flags = flags;
|
|
||||||
+ flags = parse_flags_array(ctx, value, "flags", json_parse_nat_flag);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ stmt_free(stmt);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
- if (!json_unpack(value, "{s:o}", "type_flags", &tmp)) {
|
|
||||||
- int flags = json_parse_nat_type_flags(ctx, tmp);
|
|
||||||
+ stmt->nat.flags = flags;
|
|
||||||
|
|
||||||
- if (flags < 0) {
|
|
||||||
- stmt_free(stmt);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- stmt->nat.type_flags = flags;
|
|
||||||
+ flags = parse_flags_array(ctx, value, "type_flags",
|
|
||||||
+ json_parse_nat_type_flag);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ stmt_free(stmt);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
+ stmt->nat.type_flags = flags;
|
|
||||||
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
@@ -2481,8 +2432,7 @@ static struct stmt *json_parse_map_stmt(struct json_ctx *ctx,
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int json_parse_log_flag(struct json_ctx *ctx,
|
|
||||||
- json_t *root, int *flags)
|
|
||||||
+static unsigned int json_parse_log_flag(const char *flag)
|
|
||||||
{
|
|
||||||
const struct {
|
|
||||||
const char *flag;
|
|
||||||
@@ -2495,47 +2445,13 @@ static int json_parse_log_flag(struct json_ctx *ctx,
|
|
||||||
{ "ether", NF_LOG_MACDECODE },
|
|
||||||
{ "all", NF_LOG_MASK },
|
|
||||||
};
|
|
||||||
- const char *flag;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
- assert(flags);
|
|
||||||
-
|
|
||||||
- if (!json_is_string(root)) {
|
|
||||||
- json_error(ctx, "Invalid log flag type %s, expected string.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(root);
|
|
||||||
for (i = 0; i < array_size(flag_tbl); i++) {
|
|
||||||
- if (!strcmp(flag, flag_tbl[i].flag)) {
|
|
||||||
- *flags |= flag_tbl[i].val;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Unknown log flag '%s'.", flag);
|
|
||||||
- return 1;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int json_parse_log_flags(struct json_ctx *ctx, json_t *root)
|
|
||||||
-{
|
|
||||||
- int flags = 0;
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
-
|
|
||||||
- if (json_is_string(root)) {
|
|
||||||
- json_parse_log_flag(ctx, root, &flags);
|
|
||||||
- return flags;
|
|
||||||
- } else if (!json_is_array(root)) {
|
|
||||||
- json_error(ctx, "Invalid log flags type %s.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
- json_array_foreach(root, index, value) {
|
|
||||||
- if (json_parse_log_flag(ctx, value, &flags))
|
|
||||||
- json_error(ctx, "Parsing log flag at index %zu failed.",
|
|
||||||
- index);
|
|
||||||
+ if (!strcmp(flag, flag_tbl[i].flag))
|
|
||||||
+ return flag_tbl[i].val;
|
|
||||||
}
|
|
||||||
- return flags;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct stmt *json_parse_log_stmt(struct json_ctx *ctx,
|
|
||||||
@@ -2543,8 +2459,7 @@ static struct stmt *json_parse_log_stmt(struct json_ctx *ctx,
|
|
||||||
{
|
|
||||||
const char *tmpstr;
|
|
||||||
struct stmt *stmt;
|
|
||||||
- json_t *jflags;
|
|
||||||
- int tmp;
|
|
||||||
+ int tmp, flags;
|
|
||||||
|
|
||||||
stmt = log_stmt_alloc(int_loc);
|
|
||||||
|
|
||||||
@@ -2577,20 +2492,17 @@ static struct stmt *json_parse_log_stmt(struct json_ctx *ctx,
|
|
||||||
stmt->log.level = level;
|
|
||||||
stmt->log.flags |= STMT_LOG_LEVEL;
|
|
||||||
}
|
|
||||||
- if (!json_unpack(value, "{s:o}", "flags", &jflags)) {
|
|
||||||
- int flags = json_parse_log_flags(ctx, jflags);
|
|
||||||
-
|
|
||||||
- if (flags < 0) {
|
|
||||||
- stmt_free(stmt);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- stmt->log.logflags = flags;
|
|
||||||
+ flags = parse_flags_array(ctx, value, "flags", json_parse_log_flag);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ stmt_free(stmt);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
+ stmt->log.logflags = flags;
|
|
||||||
+
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int json_parse_synproxy_flag(struct json_ctx *ctx,
|
|
||||||
- json_t *root, int *flags)
|
|
||||||
+static unsigned int json_parse_synproxy_flag(const char *flag)
|
|
||||||
{
|
|
||||||
const struct {
|
|
||||||
const char *flag;
|
|
||||||
@@ -2599,54 +2511,19 @@ static int json_parse_synproxy_flag(struct json_ctx *ctx,
|
|
||||||
{ "timestamp", NF_SYNPROXY_OPT_TIMESTAMP },
|
|
||||||
{ "sack-perm", NF_SYNPROXY_OPT_SACK_PERM },
|
|
||||||
};
|
|
||||||
- const char *flag;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
- assert(flags);
|
|
||||||
-
|
|
||||||
- if (!json_is_string(root)) {
|
|
||||||
- json_error(ctx, "Invalid synproxy flag type %s, expected string.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(root);
|
|
||||||
for (i = 0; i < array_size(flag_tbl); i++) {
|
|
||||||
- if (!strcmp(flag, flag_tbl[i].flag)) {
|
|
||||||
- *flags |= flag_tbl[i].val;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Unknown synproxy flag '%s'.", flag);
|
|
||||||
- return 1;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int json_parse_synproxy_flags(struct json_ctx *ctx, json_t *root)
|
|
||||||
-{
|
|
||||||
- int flags = 0;
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
-
|
|
||||||
- if (json_is_string(root)) {
|
|
||||||
- json_parse_synproxy_flag(ctx, root, &flags);
|
|
||||||
- return flags;
|
|
||||||
- } else if (!json_is_array(root)) {
|
|
||||||
- json_error(ctx, "Invalid synproxy flags type %s.",
|
|
||||||
- json_typename(root));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
- json_array_foreach(root, index, value) {
|
|
||||||
- if (json_parse_synproxy_flag(ctx, value, &flags))
|
|
||||||
- json_error(ctx, "Parsing synproxy flag at index %zu failed.",
|
|
||||||
- index);
|
|
||||||
+ if (!strcmp(flag, flag_tbl[i].flag))
|
|
||||||
+ return flag_tbl[i].val;
|
|
||||||
}
|
|
||||||
- return flags;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct stmt *json_parse_synproxy_stmt(struct json_ctx *ctx,
|
|
||||||
const char *key, json_t *value)
|
|
||||||
{
|
|
||||||
struct stmt *stmt = NULL;
|
|
||||||
- json_t *jflags;
|
|
||||||
int tmp, flags;
|
|
||||||
|
|
||||||
if (json_typeof(value) == JSON_NULL) {
|
|
||||||
@@ -2676,15 +2553,16 @@ static struct stmt *json_parse_synproxy_stmt(struct json_ctx *ctx,
|
|
||||||
stmt->synproxy.wscale = tmp;
|
|
||||||
stmt->synproxy.flags |= NF_SYNPROXY_OPT_WSCALE;
|
|
||||||
}
|
|
||||||
- if (!json_unpack(value, "{s:o}", "flags", &jflags)) {
|
|
||||||
+
|
|
||||||
+ flags = parse_flags_array(ctx, value, "flags",
|
|
||||||
+ json_parse_synproxy_flag);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ stmt_free(stmt);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ if (flags) {
|
|
||||||
if (!stmt)
|
|
||||||
stmt = synproxy_stmt_alloc(int_loc);
|
|
||||||
- flags = json_parse_synproxy_flags(ctx, jflags);
|
|
||||||
-
|
|
||||||
- if (flags < 0) {
|
|
||||||
- stmt_free(stmt);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
stmt->synproxy.flags |= flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2779,14 +2657,12 @@ static struct stmt *json_parse_meter_stmt(struct json_ctx *ctx,
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int queue_flag_parse(const char *name, uint16_t *flags)
|
|
||||||
+static unsigned int queue_flag_parse(const char *name)
|
|
||||||
{
|
|
||||||
if (!strcmp(name, "bypass"))
|
|
||||||
- *flags |= NFT_QUEUE_FLAG_BYPASS;
|
|
||||||
+ return NFT_QUEUE_FLAG_BYPASS;
|
|
||||||
else if (!strcmp(name, "fanout"))
|
|
||||||
- *flags |= NFT_QUEUE_FLAG_CPU_FANOUT;
|
|
||||||
- else
|
|
||||||
- return 1;
|
|
||||||
+ return NFT_QUEUE_FLAG_CPU_FANOUT;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2794,8 +2670,8 @@ static struct stmt *json_parse_queue_stmt(struct json_ctx *ctx,
|
|
||||||
const char *key, json_t *value)
|
|
||||||
{
|
|
||||||
struct expr *qexpr = NULL;
|
|
||||||
- uint16_t flags = 0;
|
|
||||||
json_t *tmp;
|
|
||||||
+ int flags;
|
|
||||||
|
|
||||||
if (!json_unpack(value, "{s:o}", "num", &tmp)) {
|
|
||||||
qexpr = json_parse_stmt_expr(ctx, tmp);
|
|
||||||
@@ -2804,43 +2680,13 @@ static struct stmt *json_parse_queue_stmt(struct json_ctx *ctx,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (!json_unpack(value, "{s:o}", "flags", &tmp)) {
|
|
||||||
- const char *flag;
|
|
||||||
- size_t index;
|
|
||||||
- json_t *val;
|
|
||||||
-
|
|
||||||
- if (json_is_string(tmp)) {
|
|
||||||
- flag = json_string_value(tmp);
|
|
||||||
-
|
|
||||||
- if (queue_flag_parse(flag, &flags)) {
|
|
||||||
- json_error(ctx, "Invalid queue flag '%s'.",
|
|
||||||
- flag);
|
|
||||||
- expr_free(qexpr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- } else if (!json_is_array(tmp)) {
|
|
||||||
- json_error(ctx, "Unexpected object type in queue flags.");
|
|
||||||
- expr_free(qexpr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
- json_array_foreach(tmp, index, val) {
|
|
||||||
- if (!json_is_string(val)) {
|
|
||||||
- json_error(ctx, "Invalid object in queue flag array at index %zu.",
|
|
||||||
- index);
|
|
||||||
- expr_free(qexpr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- flag = json_string_value(val);
|
|
||||||
-
|
|
||||||
- if (queue_flag_parse(flag, &flags)) {
|
|
||||||
- json_error(ctx, "Invalid queue flag '%s'.",
|
|
||||||
- flag);
|
|
||||||
- expr_free(qexpr);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ flags = parse_flags_array(ctx, value, "flags", queue_flag_parse);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ expr_free(qexpr);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
return queue_stmt_alloc(int_loc, qexpr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2950,45 +2796,6 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int json_parse_table_flags(struct json_ctx *ctx, json_t *root,
|
|
||||||
- enum table_flags *flags)
|
|
||||||
-{
|
|
||||||
- json_t *tmp, *tmp2;
|
|
||||||
- size_t index;
|
|
||||||
- int flag;
|
|
||||||
-
|
|
||||||
- if (json_unpack(root, "{s:o}", "flags", &tmp))
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- if (json_is_string(tmp)) {
|
|
||||||
- flag = parse_table_flag(json_string_value(tmp));
|
|
||||||
- if (flag) {
|
|
||||||
- *flags = flag;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Invalid table flag '%s'.",
|
|
||||||
- json_string_value(tmp));
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- if (!json_is_array(tmp)) {
|
|
||||||
- json_error(ctx, "Unexpected table flags value.");
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- json_array_foreach(tmp, index, tmp2) {
|
|
||||||
- if (json_is_string(tmp2)) {
|
|
||||||
- flag = parse_table_flag(json_string_value(tmp2));
|
|
||||||
-
|
|
||||||
- if (flag) {
|
|
||||||
- *flags |= flag;
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- json_error(ctx, "Invalid table flag at index %zu.", index);
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
enum cmd_ops op, enum cmd_obj obj)
|
|
||||||
{
|
|
||||||
@@ -2997,7 +2804,7 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
.table.location = *int_loc,
|
|
||||||
};
|
|
||||||
struct table *table = NULL;
|
|
||||||
- enum table_flags flags = 0;
|
|
||||||
+ int flags = 0;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s}",
|
|
||||||
"family", &family))
|
|
||||||
@@ -3008,9 +2815,10 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
json_unpack(root, "{s:s}", "comment", &comment);
|
|
||||||
- if (json_parse_table_flags(ctx, root, &flags))
|
|
||||||
- return NULL;
|
|
||||||
|
|
||||||
+ flags = parse_flags_array(ctx, root, "flags", parse_table_flag);
|
|
||||||
+ if (flags < 0)
|
|
||||||
+ return NULL;
|
|
||||||
} else if (op == CMD_DELETE &&
|
|
||||||
json_unpack(root, "{s:s}", "name", &h.table.name) &&
|
|
||||||
json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
|
|
||||||
@@ -3291,7 +3099,7 @@ static int string_to_nft_object(const char *str)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int string_to_set_flag(const char *str)
|
|
||||||
+static unsigned int string_to_set_flag(const char *str)
|
|
||||||
{
|
|
||||||
const struct {
|
|
||||||
enum nft_set_flags val;
|
|
||||||
@@ -3318,6 +3126,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
|
|
||||||
const char *family = "", *policy, *dtype_ext = NULL;
|
|
||||||
json_t *tmp, *stmt_json;
|
|
||||||
struct set *set;
|
|
||||||
+ int flags;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s, s:s}",
|
|
||||||
"family", &family,
|
|
||||||
@@ -3398,23 +3207,16 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (!json_unpack(root, "{s:o}", "flags", &tmp)) {
|
|
||||||
- json_t *value;
|
|
||||||
- size_t index;
|
|
||||||
|
|
||||||
- json_array_foreach(tmp, index, value) {
|
|
||||||
- int flag;
|
|
||||||
-
|
|
||||||
- if (!json_is_string(value) ||
|
|
||||||
- !(flag = string_to_set_flag(json_string_value(value)))) {
|
|
||||||
- json_error(ctx, "Invalid set flag at index %zu.", index);
|
|
||||||
- set_free(set);
|
|
||||||
- handle_free(&h);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- set->flags |= flag;
|
|
||||||
- }
|
|
||||||
+ flags = parse_flags_array(ctx, root, "flags", string_to_set_flag);
|
|
||||||
+ if (flags < 0) {
|
|
||||||
+ json_error(ctx, "Invalid set flags in set '%s'.", h.set.name);
|
|
||||||
+ set_free(set);
|
|
||||||
+ handle_free(&h);
|
|
||||||
+ return NULL;
|
|
||||||
}
|
|
||||||
+ set->flags |= flags;
|
|
||||||
+
|
|
||||||
if (!json_unpack(root, "{s:o}", "elem", &tmp)) {
|
|
||||||
set->init = json_parse_set_expr(ctx, "elem", tmp);
|
|
||||||
if (!set->init) {
|
|
||||||
@@ -3585,7 +3387,6 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
int inv = 0, flags = 0, i, j;
|
|
||||||
struct handle h = { 0 };
|
|
||||||
struct obj *obj;
|
|
||||||
- json_t *jflags;
|
|
||||||
|
|
||||||
if (json_unpack_err(ctx, root, "{s:s, s:s}",
|
|
||||||
"family", &family,
|
|
||||||
@@ -3765,13 +3566,12 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
|
|
||||||
obj->synproxy.wscale = j;
|
|
||||||
obj->synproxy.flags |= NF_SYNPROXY_OPT_MSS;
|
|
||||||
obj->synproxy.flags |= NF_SYNPROXY_OPT_WSCALE;
|
|
||||||
- if (!json_unpack(root, "{s:o}", "flags", &jflags)) {
|
|
||||||
- flags = json_parse_synproxy_flags(ctx, jflags);
|
|
||||||
- if (flags < 0)
|
|
||||||
- goto err_free_obj;
|
|
||||||
+ flags = parse_flags_array(ctx, root, "flags",
|
|
||||||
+ json_parse_synproxy_flag);
|
|
||||||
+ if (flags < 0)
|
|
||||||
+ goto err_free_obj;
|
|
||||||
|
|
||||||
- obj->synproxy.flags |= flags;
|
|
||||||
- }
|
|
||||||
+ obj->synproxy.flags |= flags;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG("Invalid CMD '%d'", cmd_obj);
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
From da4fc3c74125e4f5eb69ee4174713c7edb91f071 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:30:20 +0200
|
|
||||||
Subject: [PATCH] tests: py: fix json single-flag output for fib & synproxy
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit c2ee1d5978bf6ea10e3b1a74125da5b5e8468f26
|
|
||||||
|
|
||||||
commit c2ee1d5978bf6ea10e3b1a74125da5b5e8468f26
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Mon Jun 2 14:12:16 2025 +0200
|
|
||||||
|
|
||||||
tests: py: fix json single-flag output for fib & synproxy
|
|
||||||
|
|
||||||
Blamed commits change output format but did not adjust existing tests:
|
|
||||||
inet/fib.t: WARNING: line 16: '{"nftables": ..
|
|
||||||
|
|
||||||
Fixes: 38f99ee84fe6 ("json: Print single synproxy flags as non-array")
|
|
||||||
Fixes: dbe5c44f2b89 ("json: Print single fib flag as non-array")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Acked-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/fib.t.json.output | 32 ++++++++++++++++++++++++++++
|
|
||||||
tests/py/inet/synproxy.t.json.output | 17 +++++++++++++++
|
|
||||||
2 files changed, 49 insertions(+)
|
|
||||||
create mode 100644 tests/py/inet/synproxy.t.json.output
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/fib.t.json.output b/tests/py/inet/fib.t.json.output
|
|
||||||
index 52cd46b..e21f1e7 100644
|
|
||||||
--- a/tests/py/inet/fib.t.json.output
|
|
||||||
+++ b/tests/py/inet/fib.t.json.output
|
|
||||||
@@ -37,3 +37,35 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# fib daddr oif exists
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "fib": {
|
|
||||||
+ "flags": "daddr",
|
|
||||||
+ "result": "oif"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": true
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# fib daddr oif missing
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "fib": {
|
|
||||||
+ "flags": "daddr",
|
|
||||||
+ "result": "oif"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": false
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/inet/synproxy.t.json.output b/tests/py/inet/synproxy.t.json.output
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..e32cdfb
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/py/inet/synproxy.t.json.output
|
|
||||||
@@ -0,0 +1,17 @@
|
|
||||||
+# synproxy timestamp
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "synproxy": {
|
|
||||||
+ "flags": "timestamp"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# synproxy sack-perm
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "synproxy": {
|
|
||||||
+ "flags": "sack-perm"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,134 +0,0 @@
|
|||||||
From 3d8fe285a67b3e4dc38a48622834151f0449e314 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:00 +0200
|
|
||||||
Subject: [PATCH] fib: allow to use it in set statements
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 525b58568dca5ab9998595fc45313eac2764b6b1
|
|
||||||
|
|
||||||
commit 525b58568dca5ab9998595fc45313eac2764b6b1
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Tue Jun 24 18:11:10 2025 +0200
|
|
||||||
|
|
||||||
fib: allow to use it in set statements
|
|
||||||
|
|
||||||
Allow to use fib expression in set statements, eg.
|
|
||||||
|
|
||||||
meta mark set ip saddr . fib daddr check map { 1.2.3.4 . exists : 0x00000001 }
|
|
||||||
|
|
||||||
Fixes: 4a75ed32132d ("src: add fib expression")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_bison.y | 1 +
|
|
||||||
src/parser_json.c | 2 +-
|
|
||||||
tests/py/inet/fib.t | 2 ++
|
|
||||||
tests/py/inet/fib.t.json | 45 +++++++++++++++++++++++++++++++++++++
|
|
||||||
tests/py/inet/fib.t.payload | 8 +++++++
|
|
||||||
5 files changed, 57 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
||||||
index 174a339..a6a517f 100644
|
|
||||||
--- a/src/parser_bison.y
|
|
||||||
+++ b/src/parser_bison.y
|
|
||||||
@@ -3825,6 +3825,7 @@ primary_stmt_expr : symbol_expr { $$ = $1; }
|
|
||||||
| payload_expr { $$ = $1; }
|
|
||||||
| keyword_expr { $$ = $1; }
|
|
||||||
| socket_expr { $$ = $1; }
|
|
||||||
+ | fib_expr { $$ = $1; }
|
|
||||||
| osf_expr { $$ = $1; }
|
|
||||||
| '(' basic_stmt_expr ')' { $$ = $2; }
|
|
||||||
;
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 1b12445..8c9d365 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -1569,7 +1569,7 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root)
|
|
||||||
/* below two are hash expr */
|
|
||||||
{ "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
{ "symhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
- { "fib", json_parse_fib_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
+ { "fib", json_parse_fib_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
{ "|", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
{ "^", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
{ "&", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
|
|
||||||
diff --git a/tests/py/inet/fib.t b/tests/py/inet/fib.t
|
|
||||||
index f9c03b3..60b77a4 100644
|
|
||||||
--- a/tests/py/inet/fib.t
|
|
||||||
+++ b/tests/py/inet/fib.t
|
|
||||||
@@ -17,3 +17,5 @@ fib daddr check missing;ok
|
|
||||||
fib daddr oif exists;ok;fib daddr check exists
|
|
||||||
|
|
||||||
fib daddr check vmap { missing : drop, exists : accept };ok
|
|
||||||
+
|
|
||||||
+meta mark set fib daddr check . ct mark map { exists . 0x00000000 : 0x00000001 };ok
|
|
||||||
diff --git a/tests/py/inet/fib.t.json b/tests/py/inet/fib.t.json
|
|
||||||
index c2e9d45..14a6249 100644
|
|
||||||
--- a/tests/py/inet/fib.t.json
|
|
||||||
+++ b/tests/py/inet/fib.t.json
|
|
||||||
@@ -159,3 +159,48 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
+
|
|
||||||
+# meta mark set fib daddr check . ct mark map { exists . 0x00000000 : 0x00000001 }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "mangle": {
|
|
||||||
+ "key": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "value": {
|
|
||||||
+ "map": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ {
|
|
||||||
+ "concat": [
|
|
||||||
+ true,
|
|
||||||
+ 0
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ 1
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "concat": [
|
|
||||||
+ {
|
|
||||||
+ "fib": {
|
|
||||||
+ "flags": "daddr",
|
|
||||||
+ "result": "check"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "ct": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
diff --git a/tests/py/inet/fib.t.payload b/tests/py/inet/fib.t.payload
|
|
||||||
index e09a260..02d92b5 100644
|
|
||||||
--- a/tests/py/inet/fib.t.payload
|
|
||||||
+++ b/tests/py/inet/fib.t.payload
|
|
||||||
@@ -36,3 +36,11 @@ ip test-ip prerouting
|
|
||||||
ip test-ip prerouting
|
|
||||||
[ fib daddr oif present => reg 1 ]
|
|
||||||
[ lookup reg 1 set __map%d dreg 0 ]
|
|
||||||
+
|
|
||||||
+# meta mark set fib daddr check . ct mark map { exists . 0x00000000 : 0x00000001 }
|
|
||||||
+ element 00000001 00000000 : 00000001 0 [end]
|
|
||||||
+ip test-ip prerouting
|
|
||||||
+ [ fib daddr oif present => reg 1 ]
|
|
||||||
+ [ ct load mark => reg 9 ]
|
|
||||||
+ [ lookup reg 1 set __map%d dreg 1 ]
|
|
||||||
+ [ meta set mark with reg 1 ]
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
From 6bcaa14dfd285275ae797e963459088e6d5365eb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:00 +0200
|
|
||||||
Subject: [PATCH] tests: py: re-enables nft-test.py to load the local
|
|
||||||
nftables.py
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 0f3965a38aecaf1fda66c2ce5dcf3b755d8191c6
|
|
||||||
|
|
||||||
commit 0f3965a38aecaf1fda66c2ce5dcf3b755d8191c6
|
|
||||||
Author: Zhongqiu Duan <dzq.aishenghu0@gmail.com>
|
|
||||||
Date: Fri Jul 4 03:12:16 2025 +0000
|
|
||||||
|
|
||||||
tests: py: re-enables nft-test.py to load the local nftables.py
|
|
||||||
|
|
||||||
This is a needed follow-up of commit ce443afc21455 ("py: move
|
|
||||||
package source into src directory") from 2023. Since that change,
|
|
||||||
nft-test.py started using the host's nftables.py instead of the local
|
|
||||||
one. But since nft-test.py passes the local src/.libs/libnftables.so.1
|
|
||||||
as parameter when instantiating the Nftables class, we did nevertheless
|
|
||||||
use the local libnftables.
|
|
||||||
|
|
||||||
Fixes: ce443afc21455 ("py: move package source into src directory")
|
|
||||||
Reviewed-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Signed-off-by: Zhongqiu Duan <dzq.aishenghu0@gmail.com>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/nft-test.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
|
|
||||||
index 9a25503..35bf66e 100755
|
|
||||||
--- a/tests/py/nft-test.py
|
|
||||||
+++ b/tests/py/nft-test.py
|
|
||||||
@@ -23,7 +23,7 @@ import traceback
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
TESTS_PATH = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
-sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/'))
|
|
||||||
+sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/src'))
|
|
||||||
os.environ['TZ'] = 'UTC-2'
|
|
||||||
|
|
||||||
from nftables import Nftables
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
From d376d61e94ec31d1e6b8b452f12eb895eb0fdbd3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:00 +0200
|
|
||||||
Subject: [PATCH] tests/shell: cover long interface name in
|
|
||||||
"0042chain_variable_0" test
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit f773041121d6d0d112fa9cb003fd791eacd6e43d
|
|
||||||
|
|
||||||
commit f773041121d6d0d112fa9cb003fd791eacd6e43d
|
|
||||||
Author: Thomas Haller <thaller@redhat.com>
|
|
||||||
Date: Mon Oct 23 19:00:46 2023 +0200
|
|
||||||
|
|
||||||
tests/shell: cover long interface name in "0042chain_variable_0" test
|
|
||||||
|
|
||||||
IFNAMSIZ is 16. Adjust "0042chain_variable_0" to use an interface name
|
|
||||||
with the maximum allowed bytes length.
|
|
||||||
|
|
||||||
Instead of adding an entirely different test, adjust an existing one to
|
|
||||||
use another interface name. The aspect for testing for a long interface
|
|
||||||
name is not special enough, to warrant a separate test. We can cover it
|
|
||||||
by extending an existing test.
|
|
||||||
|
|
||||||
Note that the length check in "parser_bison.y" is wrong. The test checks
|
|
||||||
still for the wrong behavior and that "d23456789012345x" is accepted.
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
.../testcases/chains/0042chain_variable_0 | 36 ++++++++++++++++---
|
|
||||||
.../chains/dumps/0042chain_variable_0.nft | 4 +--
|
|
||||||
2 files changed, 34 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/chains/0042chain_variable_0 b/tests/shell/testcases/chains/0042chain_variable_0
|
|
||||||
index 1ea44e8..739dc05 100755
|
|
||||||
--- a/tests/shell/testcases/chains/0042chain_variable_0
|
|
||||||
+++ b/tests/shell/testcases/chains/0042chain_variable_0
|
|
||||||
@@ -2,7 +2,8 @@
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
-ip link add name dummy0 type dummy
|
|
||||||
+ip link add name d23456789012345 type dummy
|
|
||||||
+
|
|
||||||
|
|
||||||
EXPECTED="define if_main = \"lo\"
|
|
||||||
|
|
||||||
@@ -14,22 +15,50 @@ table netdev filter1 {
|
|
||||||
|
|
||||||
$NFT -f - <<< $EXPECTED
|
|
||||||
|
|
||||||
+
|
|
||||||
+EXPECTED="define if_main = \"lo\"
|
|
||||||
+
|
|
||||||
+table netdev filter2 {
|
|
||||||
+ chain Main_Ingress2 {
|
|
||||||
+ type filter hook ingress devices = { \$if_main, d23456789012345x } priority -500; policy accept;
|
|
||||||
+ }
|
|
||||||
+}"
|
|
||||||
+
|
|
||||||
+rc=0
|
|
||||||
+$NFT -f - <<< $EXPECTED || rc=$?
|
|
||||||
+test "$rc" = 0
|
|
||||||
+cat <<EOF | $DIFF -u <($NFT list ruleset) -
|
|
||||||
+table netdev filter1 {
|
|
||||||
+ chain Main_Ingress1 {
|
|
||||||
+ type filter hook ingress device "lo" priority -500; policy accept;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+table netdev filter2 {
|
|
||||||
+ chain Main_Ingress2 {
|
|
||||||
+ type filter hook ingress devices = { d23456789012345, lo } priority -500; policy accept;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+EOF
|
|
||||||
+
|
|
||||||
+
|
|
||||||
EXPECTED="define if_main = \"lo\"
|
|
||||||
|
|
||||||
table netdev filter2 {
|
|
||||||
chain Main_Ingress2 {
|
|
||||||
- type filter hook ingress devices = { \$if_main, dummy0 } priority -500; policy accept;
|
|
||||||
+ type filter hook ingress devices = { \$if_main, d23456789012345 } priority -500; policy accept;
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
|
|
||||||
$NFT -f - <<< $EXPECTED
|
|
||||||
|
|
||||||
+
|
|
||||||
if [ "$NFT_TEST_HAVE_netdev_egress" = n ] ; then
|
|
||||||
echo "Skip parts of the test due to NFT_TEST_HAVE_netdev_egress=n"
|
|
||||||
exit 77
|
|
||||||
fi
|
|
||||||
|
|
||||||
-EXPECTED="define if_main = { lo, dummy0 }
|
|
||||||
+
|
|
||||||
+EXPECTED="define if_main = { lo, d23456789012345 }
|
|
||||||
define lan_interfaces = { lo }
|
|
||||||
|
|
||||||
table netdev filter3 {
|
|
||||||
@@ -43,4 +72,3 @@ table netdev filter3 {
|
|
||||||
|
|
||||||
$NFT -f - <<< $EXPECTED
|
|
||||||
|
|
||||||
-
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft b/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
index 5ec230d..84a908d 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
@@ -5,12 +5,12 @@ table netdev filter1 {
|
|
||||||
}
|
|
||||||
table netdev filter2 {
|
|
||||||
chain Main_Ingress2 {
|
|
||||||
- type filter hook ingress devices = { dummy0, lo } priority -500; policy accept;
|
|
||||||
+ type filter hook ingress devices = { d23456789012345, lo } priority -500; policy accept;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table netdev filter3 {
|
|
||||||
chain Main_Ingress3 {
|
|
||||||
- type filter hook ingress devices = { dummy0, lo } priority -500; policy accept;
|
|
||||||
+ type filter hook ingress devices = { d23456789012345, lo } priority -500; policy accept;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain Main_Egress3 {
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
From a6b30991cc1f4ee116c7a5316af46cf1a9ee0c01 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:00 +0200
|
|
||||||
Subject: [PATCH] tests: shell: adjust add-after-delete flowtable for older
|
|
||||||
kernels
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 566182cd8259cfc22f9fd949e9ad3c15ed6a7945
|
|
||||||
|
|
||||||
commit 566182cd8259cfc22f9fd949e9ad3c15ed6a7945
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Mon Nov 20 13:54:03 2023 +0100
|
|
||||||
|
|
||||||
tests: shell: adjust add-after-delete flowtable for older kernels
|
|
||||||
|
|
||||||
Remove counter from flowtable, older kernels (<=5.4) do not support this
|
|
||||||
in testcases/flowtable/0013addafterdelete_0 so this bug is still
|
|
||||||
covered.
|
|
||||||
|
|
||||||
Skip testcases/flowtable/0014addafterdelete_0 if flowtable counter
|
|
||||||
support is not available.
|
|
||||||
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/shell/testcases/flowtable/0013addafterdelete_0 | 2 --
|
|
||||||
tests/shell/testcases/flowtable/0014addafterdelete_0 | 2 ++
|
|
||||||
tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft | 1 -
|
|
||||||
3 files changed, 2 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/0013addafterdelete_0 b/tests/shell/testcases/flowtable/0013addafterdelete_0
|
|
||||||
index b23ab97..56c9834 100755
|
|
||||||
--- a/tests/shell/testcases/flowtable/0013addafterdelete_0
|
|
||||||
+++ b/tests/shell/testcases/flowtable/0013addafterdelete_0
|
|
||||||
@@ -7,7 +7,6 @@ RULESET='table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter - 1
|
|
||||||
devices = { lo }
|
|
||||||
- counter
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
|
|
||||||
@@ -20,7 +19,6 @@ table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter - 1
|
|
||||||
devices = { lo }
|
|
||||||
- counter
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/0014addafterdelete_0 b/tests/shell/testcases/flowtable/0014addafterdelete_0
|
|
||||||
index 6a24c4b..1ac6510 100755
|
|
||||||
--- a/tests/shell/testcases/flowtable/0014addafterdelete_0
|
|
||||||
+++ b/tests/shell/testcases/flowtable/0014addafterdelete_0
|
|
||||||
@@ -1,5 +1,7 @@
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_flowtable_counter)
|
|
||||||
+
|
|
||||||
set -e
|
|
||||||
|
|
||||||
RULESET='table inet filter {
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft b/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
index 83fdd5d..67db7d0 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
@@ -2,6 +2,5 @@ table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter - 1
|
|
||||||
devices = { lo }
|
|
||||||
- counter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
From 3c78f54adfd9d130aeca4c779a8d82b27bb69e60 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: shell: skip if kernel does not support flowtable
|
|
||||||
counter
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 279654904d5186430588b475501b2ca0d3ab6517
|
|
||||||
|
|
||||||
commit 279654904d5186430588b475501b2ca0d3ab6517
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Tue Nov 14 16:57:22 2023 +0100
|
|
||||||
|
|
||||||
tests: shell: skip if kernel does not support flowtable counter
|
|
||||||
|
|
||||||
Check if kernel provides flowtable counter supports which is available
|
|
||||||
since 53c2b2899af7 ("netfilter: flowtable: add counter support").
|
|
||||||
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/shell/features/flowtable_counter.sh | 16 ++++++++++++++++
|
|
||||||
.../testcases/flowtable/0012flowtable_variable_0 | 2 ++
|
|
||||||
2 files changed, 18 insertions(+)
|
|
||||||
create mode 100755 tests/shell/features/flowtable_counter.sh
|
|
||||||
|
|
||||||
diff --git a/tests/shell/features/flowtable_counter.sh b/tests/shell/features/flowtable_counter.sh
|
|
||||||
new file mode 100755
|
|
||||||
index 0000000..a4c4c62
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/features/flowtable_counter.sh
|
|
||||||
@@ -0,0 +1,16 @@
|
|
||||||
+#!/bin/bash
|
|
||||||
+
|
|
||||||
+# 53c2b2899af7 ("netfilter: flowtable: add counter support")
|
|
||||||
+# v5.7-rc1~146^2~12^2~16
|
|
||||||
+
|
|
||||||
+EXPECTED="table ip filter2 {
|
|
||||||
+ flowtable main_ft2 {
|
|
||||||
+ hook ingress priority filter
|
|
||||||
+ devices = { lo }
|
|
||||||
+ counter
|
|
||||||
+ }
|
|
||||||
+}"
|
|
||||||
+
|
|
||||||
+$NFT -f - <<< $EXPECTED
|
|
||||||
+
|
|
||||||
+diff -u <($NFT list ruleset) - <<<"$EXPECTED"
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/0012flowtable_variable_0 b/tests/shell/testcases/flowtable/0012flowtable_variable_0
|
|
||||||
index 080059d..9c03820 100755
|
|
||||||
--- a/tests/shell/testcases/flowtable/0012flowtable_variable_0
|
|
||||||
+++ b/tests/shell/testcases/flowtable/0012flowtable_variable_0
|
|
||||||
@@ -1,5 +1,7 @@
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_flowtable_counter)
|
|
||||||
+
|
|
||||||
set -e
|
|
||||||
|
|
||||||
iface_cleanup() {
|
|
||||||
@ -1,263 +0,0 @@
|
|||||||
From f456bdb07b559c8ff46e46701b0d61729549de73 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] rule: print chain and flowtable devices in quotes
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit eb30f236d91a8d61ece789e28e6540b3a3fa2a6a
|
|
||||||
|
|
||||||
commit eb30f236d91a8d61ece789e28e6540b3a3fa2a6a
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Wed Jul 9 00:13:56 2025 +0200
|
|
||||||
|
|
||||||
rule: print chain and flowtable devices in quotes
|
|
||||||
|
|
||||||
Print devices in quotes, for consistency with:
|
|
||||||
|
|
||||||
- the existing chain listing with single device:
|
|
||||||
|
|
||||||
type filter hook ingress device "lo" priority filter; policy accept
|
|
||||||
|
|
||||||
- the ifname datatype used in sets.
|
|
||||||
|
|
||||||
In general, tokens that are user-defined, not coming in the datatype
|
|
||||||
symbol list, are enclosed in quotes.
|
|
||||||
|
|
||||||
Fixes: 3fdc7541fba0 ("src: add multidevice support for netdev chain")
|
|
||||||
Acked-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/rule.c | 4 ++--
|
|
||||||
tests/shell/features/flowtable_counter.sh | 2 +-
|
|
||||||
.../testcases/chains/dumps/0042chain_variable_0.nft | 4 ++--
|
|
||||||
.../testcases/flowtable/dumps/0001flowtable_0.nft | 2 +-
|
|
||||||
.../flowtable/dumps/0002create_flowtable_0.nft | 2 +-
|
|
||||||
.../flowtable/dumps/0003add_after_flush_0.nft | 2 +-
|
|
||||||
.../flowtable/dumps/0005delete_in_use_1.nft | 2 +-
|
|
||||||
.../flowtable/dumps/0012flowtable_variable_0.nft | 4 ++--
|
|
||||||
.../flowtable/dumps/0013addafterdelete_0.nft | 2 +-
|
|
||||||
.../flowtable/dumps/0014addafterdelete_0.nft | 2 +-
|
|
||||||
tests/shell/testcases/listing/0020flowtable_0 | 12 ++++++------
|
|
||||||
.../testcases/listing/dumps/0020flowtable_0.nft | 4 ++--
|
|
||||||
12 files changed, 21 insertions(+), 21 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index 6f97f77..c026d8d 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -1041,7 +1041,7 @@ static void chain_print_declaration(const struct chain *chain,
|
|
||||||
} else if (chain->dev_array_len > 1) {
|
|
||||||
nft_print(octx, " devices = { ");
|
|
||||||
for (i = 0; i < chain->dev_array_len; i++) {
|
|
||||||
- nft_print(octx, "%s", chain->dev_array[i]);
|
|
||||||
+ nft_print(octx, "\"%s\"", chain->dev_array[i]);
|
|
||||||
if (i + 1 != chain->dev_array_len)
|
|
||||||
nft_print(octx, ", ");
|
|
||||||
}
|
|
||||||
@@ -2123,7 +2123,7 @@ static void flowtable_print_declaration(const struct flowtable *flowtable,
|
|
||||||
if (flowtable->dev_array_len > 0) {
|
|
||||||
nft_print(octx, "%s%sdevices = { ", opts->tab, opts->tab);
|
|
||||||
for (i = 0; i < flowtable->dev_array_len; i++) {
|
|
||||||
- nft_print(octx, "%s", flowtable->dev_array[i]);
|
|
||||||
+ nft_print(octx, "\"%s\"", flowtable->dev_array[i]);
|
|
||||||
if (i + 1 != flowtable->dev_array_len)
|
|
||||||
nft_print(octx, ", ");
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/features/flowtable_counter.sh b/tests/shell/features/flowtable_counter.sh
|
|
||||||
index a4c4c62..5d47215 100755
|
|
||||||
--- a/tests/shell/features/flowtable_counter.sh
|
|
||||||
+++ b/tests/shell/features/flowtable_counter.sh
|
|
||||||
@@ -6,7 +6,7 @@
|
|
||||||
EXPECTED="table ip filter2 {
|
|
||||||
flowtable main_ft2 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { \"lo\" }
|
|
||||||
counter
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
diff --git a/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft b/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
index 84a908d..08a1901 100644
|
|
||||||
--- a/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/chains/dumps/0042chain_variable_0.nft
|
|
||||||
@@ -5,12 +5,12 @@ table netdev filter1 {
|
|
||||||
}
|
|
||||||
table netdev filter2 {
|
|
||||||
chain Main_Ingress2 {
|
|
||||||
- type filter hook ingress devices = { d23456789012345, lo } priority -500; policy accept;
|
|
||||||
+ type filter hook ingress devices = { "d23456789012345", "lo" } priority -500; policy accept;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table netdev filter3 {
|
|
||||||
chain Main_Ingress3 {
|
|
||||||
- type filter hook ingress devices = { d23456789012345, lo } priority -500; policy accept;
|
|
||||||
+ type filter hook ingress devices = { "d23456789012345", "lo" } priority -500; policy accept;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain Main_Egress3 {
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0001flowtable_0.nft b/tests/shell/testcases/flowtable/dumps/0001flowtable_0.nft
|
|
||||||
index 629bfe8..79fa591 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0001flowtable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0001flowtable_0.nft
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
table inet t {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter + 10
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c {
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0002create_flowtable_0.nft b/tests/shell/testcases/flowtable/dumps/0002create_flowtable_0.nft
|
|
||||||
index aecfb2a..2d0ea90 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0002create_flowtable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0002create_flowtable_0.nft
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
table ip t {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter + 10
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0003add_after_flush_0.nft b/tests/shell/testcases/flowtable/dumps/0003add_after_flush_0.nft
|
|
||||||
index dd904f4..39de91b 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0003add_after_flush_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0003add_after_flush_0.nft
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
table ip x {
|
|
||||||
flowtable y {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0005delete_in_use_1.nft b/tests/shell/testcases/flowtable/dumps/0005delete_in_use_1.nft
|
|
||||||
index c1d79e7..b01b302 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0005delete_in_use_1.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0005delete_in_use_1.nft
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
table ip x {
|
|
||||||
flowtable y {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain x {
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
|
|
||||||
index df1c51a..7863822 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0012flowtable_variable_0.nft
|
|
||||||
@@ -1,14 +1,14 @@
|
|
||||||
table ip filter1 {
|
|
||||||
flowtable Main_ft1 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
counter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table ip filter2 {
|
|
||||||
flowtable Main_ft2 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
counter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft b/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
index 67db7d0..585f63b 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0013addafterdelete_0.nft
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter - 1
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/flowtable/dumps/0014addafterdelete_0.nft b/tests/shell/testcases/flowtable/dumps/0014addafterdelete_0.nft
|
|
||||||
index 145aa08..12f97a7 100644
|
|
||||||
--- a/tests/shell/testcases/flowtable/dumps/0014addafterdelete_0.nft
|
|
||||||
+++ b/tests/shell/testcases/flowtable/dumps/0014addafterdelete_0.nft
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter - 1
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
counter
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/listing/0020flowtable_0 b/tests/shell/testcases/listing/0020flowtable_0
|
|
||||||
index 6eb82cf..8bd852b 100755
|
|
||||||
--- a/tests/shell/testcases/listing/0020flowtable_0
|
|
||||||
+++ b/tests/shell/testcases/listing/0020flowtable_0
|
|
||||||
@@ -6,11 +6,11 @@ set -e
|
|
||||||
|
|
||||||
FLOWTABLES="flowtable f {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { \"lo\" }
|
|
||||||
}
|
|
||||||
flowtable f2 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { d0 }
|
|
||||||
+ devices = { \"d0\" }
|
|
||||||
}"
|
|
||||||
|
|
||||||
RULESET="table inet filter {
|
|
||||||
@@ -23,23 +23,23 @@ table ip filter {
|
|
||||||
EXPECTED="table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { \"lo\" }
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
EXPECTED2="table ip filter {
|
|
||||||
flowtable f2 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { d0 }
|
|
||||||
+ devices = { \"d0\" }
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
EXPECTED3="table ip filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { \"lo\" }
|
|
||||||
}
|
|
||||||
flowtable f2 {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { d0 }
|
|
||||||
+ devices = { \"d0\" }
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/listing/dumps/0020flowtable_0.nft b/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
|
|
||||||
index 4a64e53..0962e73 100644
|
|
||||||
--- a/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
|
|
||||||
+++ b/tests/shell/testcases/listing/dumps/0020flowtable_0.nft
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
table inet filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
|
|
||||||
flowtable f2 {
|
|
||||||
@@ -11,7 +11,7 @@ table inet filter {
|
|
||||||
table ip filter {
|
|
||||||
flowtable f {
|
|
||||||
hook ingress priority filter
|
|
||||||
- devices = { lo }
|
|
||||||
+ devices = { "lo" }
|
|
||||||
}
|
|
||||||
|
|
||||||
flowtable f2 {
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 59239ade08feeb6abe45304632d6349eefabb5bf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] evaluate: validate set expression type before accessing flags
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 2022e8bb5cf0e0fa81ab0a5087bd1ab6e20280ee
|
|
||||||
|
|
||||||
commit 2022e8bb5cf0e0fa81ab0a5087bd1ab6e20280ee
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Wed Jul 9 00:21:49 2025 +0200
|
|
||||||
|
|
||||||
evaluate: validate set expression type before accessing flags
|
|
||||||
|
|
||||||
Validate set->init is of EXPR_SET expression type before accessing
|
|
||||||
set_flags.
|
|
||||||
|
|
||||||
Fixes: 81e36530fcac ("src: replace interval segment tree overlap and automerge")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/evaluate.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
||||||
index 711990a..5012dd2 100644
|
|
||||||
--- a/src/evaluate.c
|
|
||||||
+++ b/src/evaluate.c
|
|
||||||
@@ -4715,7 +4715,8 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
|
||||||
set->flags |= NFT_SET_EXPR;
|
|
||||||
|
|
||||||
if (set_is_anonymous(set->flags)) {
|
|
||||||
- if (set_is_interval(set->init->set_flags) &&
|
|
||||||
+ if (set->init->etype == EXPR_SET &&
|
|
||||||
+ set_is_interval(set->init->set_flags) &&
|
|
||||||
!(set->init->set_flags & NFT_SET_CONCAT) &&
|
|
||||||
interval_set_eval(ctx, set, set->init) < 0)
|
|
||||||
return -1;
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 093c9db2a767666a54bfc500ff940302d44775cb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] mnl: Call mnl_attr_nest_end() just once
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 8a1de0ec9709b58a80a86a20cfba107b11c85f6e
|
|
||||||
|
|
||||||
commit 8a1de0ec9709b58a80a86a20cfba107b11c85f6e
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Jul 16 14:26:08 2025 +0200
|
|
||||||
|
|
||||||
mnl: Call mnl_attr_nest_end() just once
|
|
||||||
|
|
||||||
Calling the function after each added nested attribute is harmless but
|
|
||||||
pointless.
|
|
||||||
|
|
||||||
Fixes: a66b5ad9540dd ("src: allow for updating devices on existing netdev chain")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mnl.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/mnl.c b/src/mnl.c
|
|
||||||
index 0fb36bd..c62b140 100644
|
|
||||||
--- a/src/mnl.c
|
|
||||||
+++ b/src/mnl.c
|
|
||||||
@@ -797,8 +797,8 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
|
|
||||||
for (i = 0; i < num_devs; i++) {
|
|
||||||
cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
|
|
||||||
mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
|
|
||||||
- mnl_attr_nest_end(nlh, nest_dev);
|
|
||||||
}
|
|
||||||
+ mnl_attr_nest_end(nlh, nest_dev);
|
|
||||||
}
|
|
||||||
nft_dev_array_free(dev_array);
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
From 77a991b09586a95f4f8d583fcc798e7e861d36d7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] doc: nft.8: Minor NAT STATEMENTS section review
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 9e1cbf667da2b9c30b41ff887de212b2c38b2eb7
|
|
||||||
|
|
||||||
commit 9e1cbf667da2b9c30b41ff887de212b2c38b2eb7
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Jul 31 12:40:11 2025 +0200
|
|
||||||
|
|
||||||
doc: nft.8: Minor NAT STATEMENTS section review
|
|
||||||
|
|
||||||
Synopsis insinuates an IP address argument is mandatory in snat/dnat
|
|
||||||
statements although specifying ports alone is perfectly fine. Adjust it
|
|
||||||
accordingly and add a paragraph briefly describing the behaviour.
|
|
||||||
|
|
||||||
While at it, update the redirect statement description with more
|
|
||||||
relevant examples, the current one is wrong: To *only* alter the
|
|
||||||
destination port, dnat statement must be used, not redirect.
|
|
||||||
|
|
||||||
Fixes: 6908a677ba04c ("nft.8: Enhance NAT documentation")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/statements.txt | 17 +++++++++++------
|
|
||||||
1 file changed, 11 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/statements.txt b/doc/statements.txt
|
|
||||||
index c7529ee..3aceb02 100644
|
|
||||||
--- a/doc/statements.txt
|
|
||||||
+++ b/doc/statements.txt
|
|
||||||
@@ -349,11 +349,12 @@ NAT STATEMENTS
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
[verse]
|
|
||||||
____
|
|
||||||
-*snat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'ADDR_SPEC' [*:*'PORT_SPEC'] ['FLAGS']
|
|
||||||
-*dnat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'ADDR_SPEC' [*:*'PORT_SPEC'] ['FLAGS']
|
|
||||||
+*snat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'TARGET_SPEC' ['FLAGS']
|
|
||||||
+*dnat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'TARGET_SPEC' ['FLAGS']
|
|
||||||
*masquerade* [*to :*'PORT_SPEC'] ['FLAGS']
|
|
||||||
*redirect* [*to :*'PORT_SPEC'] ['FLAGS']
|
|
||||||
|
|
||||||
+'TARGET_SPEC' := 'ADDR_SPEC' | ['ADDR_SPEC'] *:*'PORT_SPEC'
|
|
||||||
'ADDR_SPEC' := 'address' | 'address' *-* 'address'
|
|
||||||
'PORT_SPEC' := 'port' | 'port' *-* 'port'
|
|
||||||
|
|
||||||
@@ -363,11 +364,11 @@ ____
|
|
||||||
|
|
||||||
The nat statements are only valid from nat chain types. +
|
|
||||||
|
|
||||||
-The *snat* and *masquerade* statements specify that the source address of the
|
|
||||||
+The *snat* and *masquerade* statements specify that the source address/port of the
|
|
||||||
packet should be modified. While *snat* is only valid in the postrouting and
|
|
||||||
input chains, *masquerade* makes sense only in postrouting. The dnat and
|
|
||||||
redirect statements are only valid in the prerouting and output chains, they
|
|
||||||
-specify that the destination address of the packet should be modified. You can
|
|
||||||
+specify that the destination address/port of the packet should be modified. You can
|
|
||||||
use non-base chains which are called from base chains of nat chain type too.
|
|
||||||
All future packets in this connection will also be mangled, and rules should
|
|
||||||
cease being examined.
|
|
||||||
@@ -377,8 +378,12 @@ outgoing interface's IP address to translate to. It is particularly useful on
|
|
||||||
gateways with dynamic (public) IP addresses.
|
|
||||||
|
|
||||||
The *redirect* statement is a special form of dnat which always translates the
|
|
||||||
-destination address to the local host's one. It comes in handy if one only wants
|
|
||||||
-to alter the destination port of incoming traffic on different interfaces.
|
|
||||||
+destination address to the local host's one. It comes in handy to intercept
|
|
||||||
+traffic passing a router and feeding it to a locally running daemon, e.g. when
|
|
||||||
+building a transparent proxy or application-layer gateway.
|
|
||||||
+
|
|
||||||
+For 'TARGET_SPEC', one may specify addresses, ports, or both. If no address or
|
|
||||||
+no port is specified, the respective packet header field remains unchanged.
|
|
||||||
|
|
||||||
When used in the inet family (available with kernel 5.2), the dnat and snat
|
|
||||||
statements require the use of the ip and ip6 keyword in case an address is
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
From 123f57f8e49e53e8806e389cfd524f35dcfbc4a4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] src: netlink: netlink_delinearize_table() may return NULL
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit a69d552a005ba467d37e225032e35d01d9491241
|
|
||||||
|
|
||||||
commit a69d552a005ba467d37e225032e35d01d9491241
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Aug 8 14:21:41 2025 +0200
|
|
||||||
|
|
||||||
src: netlink: netlink_delinearize_table() may return NULL
|
|
||||||
|
|
||||||
Catch the error condition in callers to avoid crashes.
|
|
||||||
|
|
||||||
Fixes: c156232a530b3 ("src: add comment support when adding tables")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/monitor.c | 4 ++++
|
|
||||||
src/netlink.c | 3 ++-
|
|
||||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/monitor.c b/src/monitor.c
|
|
||||||
index 82762a0..bf59f2d 100644
|
|
||||||
--- a/src/monitor.c
|
|
||||||
+++ b/src/monitor.c
|
|
||||||
@@ -224,6 +224,10 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type,
|
|
||||||
|
|
||||||
nlt = netlink_table_alloc(nlh);
|
|
||||||
t = netlink_delinearize_table(monh->ctx, nlt);
|
|
||||||
+ if (!t) {
|
|
||||||
+ nftnl_table_free(nlt);
|
|
||||||
+ return MNL_CB_ERROR;
|
|
||||||
+ }
|
|
||||||
cmd = netlink_msg2cmd(type, nlh->nlmsg_flags);
|
|
||||||
|
|
||||||
switch (monh->format) {
|
|
||||||
diff --git a/src/netlink.c b/src/netlink.c
|
|
||||||
index aafc583..73123e9 100644
|
|
||||||
--- a/src/netlink.c
|
|
||||||
+++ b/src/netlink.c
|
|
||||||
@@ -754,7 +754,8 @@ static int list_table_cb(struct nftnl_table *nlt, void *arg)
|
|
||||||
struct table *table;
|
|
||||||
|
|
||||||
table = netlink_delinearize_table(ctx, nlt);
|
|
||||||
- list_add_tail(&table->list, &ctx->list);
|
|
||||||
+ if (table)
|
|
||||||
+ list_add_tail(&table->list, &ctx->list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,340 +0,0 @@
|
|||||||
From 9206bb36c6c238cb8019f3d021e52b359e416623 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop stale entries since redundant test case
|
|
||||||
removal
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 7db422da28349edcdeb3c96a410b242856ca74ac
|
|
||||||
|
|
||||||
commit 7db422da28349edcdeb3c96a410b242856ca74ac
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:14:45 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop stale entries since redundant test case removal
|
|
||||||
|
|
||||||
Fixed commit left stale JSON equivalents and payload records in place,
|
|
||||||
drop them.
|
|
||||||
|
|
||||||
Fixes: ec1ea13314fa5 ("tests: remove redundant test cases")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/any/meta.t.json | 38 ----------
|
|
||||||
tests/py/ip6/dst.t.json | 23 ------
|
|
||||||
tests/py/ip6/dst.t.payload.inet | 10 ---
|
|
||||||
tests/py/ip6/dst.t.payload.ip6 | 8 ---
|
|
||||||
tests/py/ip6/frag.t.json | 121 --------------------------------
|
|
||||||
tests/py/ip6/ip6.t.json | 40 -----------
|
|
||||||
6 files changed, 240 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/any/meta.t.json b/tests/py/any/meta.t.json
|
|
||||||
index 4734bbf..6bde76b 100644
|
|
||||||
--- a/tests/py/any/meta.t.json
|
|
||||||
+++ b/tests/py/any/meta.t.json
|
|
||||||
@@ -2294,44 +2294,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# meta cgroup {1048577-1048578}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": { "key": "cgroup" }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- {
|
|
||||||
- "range": [ 1048577, 1048578 ]
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# meta cgroup != { 1048577-1048578}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": { "key": "cgroup" }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- {
|
|
||||||
- "range": [ 1048577, 1048578 ]
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# meta iif . meta oif { "lo" . "lo" }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
diff --git a/tests/py/ip6/dst.t.json b/tests/py/ip6/dst.t.json
|
|
||||||
index e947a76..7ba4572 100644
|
|
||||||
--- a/tests/py/ip6/dst.t.json
|
|
||||||
+++ b/tests/py/ip6/dst.t.json
|
|
||||||
@@ -290,26 +290,3 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
-
|
|
||||||
-# dst hdrlength != { 33, 55, 67, 88}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "hdrlength",
|
|
||||||
- "name": "dst"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- 33,
|
|
||||||
- 55,
|
|
||||||
- 67,
|
|
||||||
- 88
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
diff --git a/tests/py/ip6/dst.t.payload.inet b/tests/py/ip6/dst.t.payload.inet
|
|
||||||
index 90d6bda..b2a79ed 100644
|
|
||||||
--- a/tests/py/ip6/dst.t.payload.inet
|
|
||||||
+++ b/tests/py/ip6/dst.t.payload.inet
|
|
||||||
@@ -119,13 +119,3 @@ ip6 test-ip6 input
|
|
||||||
[ cmp eq reg 1 0x0000000a ]
|
|
||||||
[ exthdr load ipv6 1b @ 60 + 1 => reg 1 ]
|
|
||||||
[ lookup reg 1 set __set%d ]
|
|
||||||
-
|
|
||||||
-# dst hdrlength != { 33, 55, 67, 88}
|
|
||||||
-__set%d test-ip6 3
|
|
||||||
-__set%d test-ip6 0
|
|
||||||
- element 00000021 : 0 [end] element 00000037 : 0 [end] element 00000043 : 0 [end] element 00000058 : 0 [end]
|
|
||||||
-ip6 test-ip6 input
|
|
||||||
- [ meta load nfproto => reg 1 ]
|
|
||||||
- [ cmp eq reg 1 0x0000000a ]
|
|
||||||
- [ exthdr load ipv6 1b @ 60 + 1 => reg 1 ]
|
|
||||||
- [ lookup reg 1 set __set%d 0x1 ]
|
|
||||||
diff --git a/tests/py/ip6/dst.t.payload.ip6 b/tests/py/ip6/dst.t.payload.ip6
|
|
||||||
index 941140d..5058b46 100644
|
|
||||||
--- a/tests/py/ip6/dst.t.payload.ip6
|
|
||||||
+++ b/tests/py/ip6/dst.t.payload.ip6
|
|
||||||
@@ -89,11 +89,3 @@ __set%d test-ip6 0
|
|
||||||
ip6 test-ip6 input
|
|
||||||
[ exthdr load ipv6 1b @ 60 + 1 => reg 1 ]
|
|
||||||
[ lookup reg 1 set __set%d ]
|
|
||||||
-
|
|
||||||
-# dst hdrlength != { 33, 55, 67, 88}
|
|
||||||
-__set%d test-ip6 3
|
|
||||||
-__set%d test-ip6 0
|
|
||||||
- element 00000021 : 0 [end] element 00000037 : 0 [end] element 00000043 : 0 [end] element 00000058 : 0 [end]
|
|
||||||
-ip6 test-ip6 input
|
|
||||||
- [ exthdr load ipv6 1b @ 60 + 1 => reg 1 ]
|
|
||||||
- [ lookup reg 1 set __set%d 0x1 ]
|
|
||||||
diff --git a/tests/py/ip6/frag.t.json b/tests/py/ip6/frag.t.json
|
|
||||||
index b8c06df..6953e87 100644
|
|
||||||
--- a/tests/py/ip6/frag.t.json
|
|
||||||
+++ b/tests/py/ip6/frag.t.json
|
|
||||||
@@ -230,46 +230,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# frag reserved { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "reserved",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# frag reserved != { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "reserved",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# frag frag-off 22
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -384,46 +344,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# frag frag-off { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "frag-off",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# frag frag-off != { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "frag-off",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# frag reserved2 1
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -601,44 +521,3 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
-
|
|
||||||
-# frag id { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "id",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# frag id != { 33-55}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "exthdr": {
|
|
||||||
- "field": "id",
|
|
||||||
- "name": "frag"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 55 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
diff --git a/tests/py/ip6/ip6.t.json b/tests/py/ip6/ip6.t.json
|
|
||||||
index cf80217..46d347d 100644
|
|
||||||
--- a/tests/py/ip6/ip6.t.json
|
|
||||||
+++ b/tests/py/ip6/ip6.t.json
|
|
||||||
@@ -471,46 +471,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# ip6 nexthdr { 33-44}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "nexthdr",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 44 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ip6 nexthdr != { 33-44}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "nexthdr",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- { "range": [ 33, 44 ] }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# ip6 nexthdr 33-44
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
From a1194b27b2f418e44608462212fbb90a0e2ded5d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop duplicate test from inet/geneve.t
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit a3b279794c2e26f9921445163e9bde0df5bda651
|
|
||||||
|
|
||||||
commit a3b279794c2e26f9921445163e9bde0df5bda651
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:19:31 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop duplicate test from inet/geneve.t
|
|
||||||
|
|
||||||
The test was duplicate since day 1. The duplicate JSON equivalent was
|
|
||||||
added later (semi-automated), remove it as well.
|
|
||||||
|
|
||||||
Fixes: 2b9143bc7ab81 ("tests: py: add geneve tests")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/geneve.t | 1 -
|
|
||||||
tests/py/inet/geneve.t.json | 29 -----------------------------
|
|
||||||
2 files changed, 30 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/geneve.t b/tests/py/inet/geneve.t
|
|
||||||
index 101f6df..ad46272 100644
|
|
||||||
--- a/tests/py/inet/geneve.t
|
|
||||||
+++ b/tests/py/inet/geneve.t
|
|
||||||
@@ -17,7 +17,6 @@ udp dport 6081 geneve icmp type echo-reply;ok
|
|
||||||
udp dport 6081 geneve ether saddr 62:87:4d:d6:19:05;ok
|
|
||||||
udp dport 6081 geneve vlan id 10;ok
|
|
||||||
udp dport 6081 geneve ip dscp 0x02;ok
|
|
||||||
-udp dport 6081 geneve ip dscp 0x02;ok
|
|
||||||
udp dport 6081 geneve ip saddr . geneve ip daddr { 1.2.3.4 . 4.3.2.1 };ok
|
|
||||||
|
|
||||||
udp dport 6081 geneve ip saddr set 1.2.3.4;fail
|
|
||||||
diff --git a/tests/py/inet/geneve.t.json b/tests/py/inet/geneve.t.json
|
|
||||||
index a299fcd..1589918 100644
|
|
||||||
--- a/tests/py/inet/geneve.t.json
|
|
||||||
+++ b/tests/py/inet/geneve.t.json
|
|
||||||
@@ -264,35 +264,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# udp dport 6081 geneve ip dscp 0x02
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dport",
|
|
||||||
- "protocol": "udp"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 6081
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip",
|
|
||||||
- "tunnel": "geneve"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 2
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# udp dport 6081 geneve ip saddr . geneve ip daddr { 1.2.3.4 . 4.3.2.1 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
From 564d6cdd405b352b08ecfb0f25ff43557dc94406 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop duplicate test from inet/gre.t
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 7a566cb4e7b98c5f6509d9cb25d0281d5198da28
|
|
||||||
|
|
||||||
commit 7a566cb4e7b98c5f6509d9cb25d0281d5198da28
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:22:07 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop duplicate test from inet/gre.t
|
|
||||||
|
|
||||||
The test was duplicate since day 1. The duplicate JSON equivalent was
|
|
||||||
added later (semi-automated), remove it as well.
|
|
||||||
|
|
||||||
Fixes: c04ef8d104ec6 ("tests: py: add gre tests")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/gre.t | 1 -
|
|
||||||
tests/py/inet/gre.t.json | 17 -----------------
|
|
||||||
2 files changed, 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/gre.t b/tests/py/inet/gre.t
|
|
||||||
index a3e046a..a21e67e 100644
|
|
||||||
--- a/tests/py/inet/gre.t
|
|
||||||
+++ b/tests/py/inet/gre.t
|
|
||||||
@@ -16,7 +16,6 @@ gre icmp type echo-reply;ok
|
|
||||||
gre ether saddr 62:87:4d:d6:19:05;fail
|
|
||||||
gre vlan id 10;fail
|
|
||||||
gre ip dscp 0x02;ok
|
|
||||||
-gre ip dscp 0x02;ok
|
|
||||||
gre ip saddr . gre ip daddr { 1.2.3.4 . 4.3.2.1 };ok
|
|
||||||
|
|
||||||
gre ip saddr set 1.2.3.4;fail
|
|
||||||
diff --git a/tests/py/inet/gre.t.json b/tests/py/inet/gre.t.json
|
|
||||||
index c443176..a354e6b 100644
|
|
||||||
--- a/tests/py/inet/gre.t.json
|
|
||||||
+++ b/tests/py/inet/gre.t.json
|
|
||||||
@@ -121,23 +121,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# gre ip dscp 0x02
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip",
|
|
||||||
- "tunnel": "gre"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 2
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# gre ip saddr . gre ip daddr { 1.2.3.4 . 4.3.2.1 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
From b90837cd1236b7a76fd482ed48c611f8d1317763 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop duplicate test from inet/gretap.t
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit e159957099746a294ce767c16665d77b5ef2d464
|
|
||||||
|
|
||||||
commit e159957099746a294ce767c16665d77b5ef2d464
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:23:30 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop duplicate test from inet/gretap.t
|
|
||||||
|
|
||||||
The test was duplicate since day 1. The duplicate JSON equivalent was
|
|
||||||
added later (semi-automated), remove it as well.
|
|
||||||
|
|
||||||
Fixes: 39a68d9ffd25c ("tests: py: add gretap tests")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/gretap.t | 1 -
|
|
||||||
tests/py/inet/gretap.t.json | 17 -----------------
|
|
||||||
2 files changed, 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/gretap.t b/tests/py/inet/gretap.t
|
|
||||||
index cd7ee21..f88896f 100644
|
|
||||||
--- a/tests/py/inet/gretap.t
|
|
||||||
+++ b/tests/py/inet/gretap.t
|
|
||||||
@@ -15,7 +15,6 @@ gretap icmp type echo-reply;ok
|
|
||||||
gretap ether saddr 62:87:4d:d6:19:05;ok
|
|
||||||
gretap vlan id 10;ok
|
|
||||||
gretap ip dscp 0x02;ok
|
|
||||||
-gretap ip dscp 0x02;ok
|
|
||||||
gretap ip saddr . gretap ip daddr { 1.2.3.4 . 4.3.2.1 };ok
|
|
||||||
|
|
||||||
gretap ip saddr set 1.2.3.4;fail
|
|
||||||
diff --git a/tests/py/inet/gretap.t.json b/tests/py/inet/gretap.t.json
|
|
||||||
index 36fa978..6c16a08 100644
|
|
||||||
--- a/tests/py/inet/gretap.t.json
|
|
||||||
+++ b/tests/py/inet/gretap.t.json
|
|
||||||
@@ -139,23 +139,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# gretap ip dscp 0x02
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip",
|
|
||||||
- "tunnel": "gretap"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 2
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# gretap ip saddr . gretap ip daddr { 1.2.3.4 . 4.3.2.1 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
From e7191aee64f0ac14a9d0fc2856d25832e281c33a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:01 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop stale entry from inet/tcp.t.json
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit f8fe3d56194f06bea9cd82d1d707064b202f5202
|
|
||||||
|
|
||||||
commit f8fe3d56194f06bea9cd82d1d707064b202f5202
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:32:11 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop stale entry from inet/tcp.t.json
|
|
||||||
|
|
||||||
The test was changed but JSON equivalents not updated. Commit
|
|
||||||
c0b685951fabb ("json: fix parse of flagcmp expression") then added an
|
|
||||||
equivalent matching the changed test, so just drop the old one.
|
|
||||||
|
|
||||||
Fixes: c3d57114f119b ("parser_bison: add shortcut syntax for matching flags without binary operations")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/tcp.t.json | 31 -------------------------------
|
|
||||||
1 file changed, 31 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json
|
|
||||||
index 8439c2b..cc2562c 100644
|
|
||||||
--- a/tests/py/inet/tcp.t.json
|
|
||||||
+++ b/tests/py/inet/tcp.t.json
|
|
||||||
@@ -910,37 +910,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# tcp flags & (syn|fin) == (syn|fin)
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "&": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "flags",
|
|
||||||
- "protocol": "tcp"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "|": [
|
|
||||||
- "syn",
|
|
||||||
- "fin"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "|": [
|
|
||||||
- "syn",
|
|
||||||
- "fin"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
From 1f8f043819ce263f4462ee43c0c8bb89cd238be9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop duplicate test from inet/vxlan.t
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit bc66b02a6bb86a71d0a42ea7851f9aeea20edf1c
|
|
||||||
|
|
||||||
commit bc66b02a6bb86a71d0a42ea7851f9aeea20edf1c
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 14:38:22 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop duplicate test from inet/vxlan.t
|
|
||||||
|
|
||||||
The test was duplicate since day 1. The duplicate JSON equivalent was
|
|
||||||
added later (semi-automated), remove it as well.
|
|
||||||
|
|
||||||
Fixes: df81baa4c2bef ("tests: py: add vxlan tests")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/vxlan.t | 1 -
|
|
||||||
tests/py/inet/vxlan.t.json | 29 -----------------------------
|
|
||||||
2 files changed, 30 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/vxlan.t b/tests/py/inet/vxlan.t
|
|
||||||
index 10cdb7a..b6db0fe 100644
|
|
||||||
--- a/tests/py/inet/vxlan.t
|
|
||||||
+++ b/tests/py/inet/vxlan.t
|
|
||||||
@@ -17,7 +17,6 @@ udp dport 4789 vxlan icmp type echo-reply;ok
|
|
||||||
udp dport 4789 vxlan ether saddr 62:87:4d:d6:19:05;ok
|
|
||||||
udp dport 4789 vxlan vlan id 10;ok
|
|
||||||
udp dport 4789 vxlan ip dscp 0x02;ok
|
|
||||||
-udp dport 4789 vxlan ip dscp 0x02;ok
|
|
||||||
udp dport 4789 vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 };ok
|
|
||||||
|
|
||||||
udp dport 4789 vxlan ip saddr set 1.2.3.4;fail
|
|
||||||
diff --git a/tests/py/inet/vxlan.t.json b/tests/py/inet/vxlan.t.json
|
|
||||||
index 91b3d29..3c147cb 100644
|
|
||||||
--- a/tests/py/inet/vxlan.t.json
|
|
||||||
+++ b/tests/py/inet/vxlan.t.json
|
|
||||||
@@ -264,35 +264,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# udp dport 4789 vxlan ip dscp 0x02
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dport",
|
|
||||||
- "protocol": "udp"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 4789
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip",
|
|
||||||
- "tunnel": "vxlan"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": 2
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# udp dport 4789 vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
From 4d71def249ec952bc0767061e5455244d7b1c823 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop stale entry from ip/snat.t.json
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 71d90776fc56b14250f2306c4e19b50c23bd3ae3
|
|
||||||
|
|
||||||
commit 71d90776fc56b14250f2306c4e19b50c23bd3ae3
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 15:03:29 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop stale entry from ip/snat.t.json
|
|
||||||
|
|
||||||
The test syntax was changed, but the respective JSON equivalent remained
|
|
||||||
in place.
|
|
||||||
|
|
||||||
Fixes: 9b169bfc650eb ("src: remove STMT_NAT_F_INTERVAL flags and interval keyword")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/ip/snat.t.json | 33 ---------------------------------
|
|
||||||
1 file changed, 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/ip/snat.t.json b/tests/py/ip/snat.t.json
|
|
||||||
index 967560e..60bd093 100644
|
|
||||||
--- a/tests/py/ip/snat.t.json
|
|
||||||
+++ b/tests/py/ip/snat.t.json
|
|
||||||
@@ -283,39 +283,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# snat ip interval to ip saddr map { 10.141.11.4 : 192.168.2.2-192.168.2.4 }
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "snat": {
|
|
||||||
- "addr": {
|
|
||||||
- "map": {
|
|
||||||
- "data": {
|
|
||||||
- "set": [
|
|
||||||
- [
|
|
||||||
- "10.141.11.4",
|
|
||||||
- {
|
|
||||||
- "range": [
|
|
||||||
- "192.168.2.2",
|
|
||||||
- "192.168.2.4"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- "key": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "saddr",
|
|
||||||
- "protocol": "ip"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "family": "ip",
|
|
||||||
- "type_flags": "interval"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# snat ip prefix to ip saddr map { 10.141.11.0/24 : 192.168.2.0/24 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,268 +0,0 @@
|
|||||||
From 21df45dace5eafc3bab216e049357f712abf690a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop stale entries from ip6/{ct,meta}.t.json
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 3be0bbe9a5ba21a3f6e3baf051c3aaadc393c587
|
|
||||||
|
|
||||||
commit 3be0bbe9a5ba21a3f6e3baf051c3aaadc393c587
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 15:50:54 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop stale entries from ip6/{ct,meta}.t.json
|
|
||||||
|
|
||||||
Looks like these were added by accident, fixed commit did not add these
|
|
||||||
test cases.
|
|
||||||
|
|
||||||
Fixes: 8221d86e616bd ("tests: py: add test-cases for ct and packet mark payload expressions")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/ip6/ct.t.json | 164 ---------------------------------------
|
|
||||||
tests/py/ip6/meta.t.json | 58 --------------
|
|
||||||
2 files changed, 222 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/ip6/ct.t.json b/tests/py/ip6/ct.t.json
|
|
||||||
index 7d8c88b..a7511b9 100644
|
|
||||||
--- a/tests/py/ip6/ct.t.json
|
|
||||||
+++ b/tests/py/ip6/ct.t.json
|
|
||||||
@@ -1,167 +1,3 @@
|
|
||||||
-# ct mark set ip6 dscp lshift 2 or 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 2
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ct mark set ip6 dscp lshift 26 or 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 26
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ct mark set ip6 dscp << 2 | 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 2
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ct mark set ip6 dscp << 26 | 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 26
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ct mark set ip6 dscp | 0x04
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 4
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# ct mark set ip6 dscp | 0xff000000
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 4278190080
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# ct mark set ip6 dscp << 2 | 0x10
|
|
||||||
[
|
|
||||||
{
|
|
||||||
diff --git a/tests/py/ip6/meta.t.json b/tests/py/ip6/meta.t.json
|
|
||||||
index 1a2394d..87251f0 100644
|
|
||||||
--- a/tests/py/ip6/meta.t.json
|
|
||||||
+++ b/tests/py/ip6/meta.t.json
|
|
||||||
@@ -195,64 +195,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# meta mark set ip6 dscp lshift 2 or 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "meta": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 2
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# meta mark set ip6 dscp lshift 26 or 0x10
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "mangle": {
|
|
||||||
- "key": {
|
|
||||||
- "meta": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "value": {
|
|
||||||
- "|": [
|
|
||||||
- {
|
|
||||||
- "<<": [
|
|
||||||
- {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "dscp",
|
|
||||||
- "protocol": "ip6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- 26
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- 16
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# meta mark set ip6 dscp << 2 | 0x10
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From 0e3d6eca63a637e22844a3461a06196fc0d00b66 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] tests: py: Drop stale entry from ip/snat.t.payload
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit c3c60ac84a4f64a98f9c2c22d9032d177ae6a212
|
|
||||||
|
|
||||||
commit c3c60ac84a4f64a98f9c2c22d9032d177ae6a212
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 16:06:46 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Drop stale entry from ip/snat.t.payload
|
|
||||||
|
|
||||||
This payload actually belongs to ip/dnat.t.payload, fixed commit added
|
|
||||||
it to the wrong file.
|
|
||||||
|
|
||||||
Fixes: 8f3048954d40d ("evaluate: postpone transport protocol match check after nat expression evaluation")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/ip/snat.t.payload | 14 --------------
|
|
||||||
1 file changed, 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/ip/snat.t.payload b/tests/py/ip/snat.t.payload
|
|
||||||
index 71a5e2f..9a59b71 100644
|
|
||||||
--- a/tests/py/ip/snat.t.payload
|
|
||||||
+++ b/tests/py/ip/snat.t.payload
|
|
||||||
@@ -138,17 +138,3 @@ ip
|
|
||||||
[ payload load 2b @ transport header + 2 => reg 9 ]
|
|
||||||
[ lookup reg 1 set __map%d dreg 1 ]
|
|
||||||
[ nat snat ip addr_min reg 1 proto_min reg 9 ]
|
|
||||||
-
|
|
||||||
-# ip daddr 192.168.0.1 dnat to tcp dport map { 443 : 10.141.10.4 . 8443, 80 : 10.141.10.4 . 8080 }
|
|
||||||
-__map%d x b size 2
|
|
||||||
-__map%d x 0
|
|
||||||
- element 0000bb01 : 040a8d0a 0000fb20 0 [end] element 00005000 : 040a8d0a 0000901f 0 [end]
|
|
||||||
-ip
|
|
||||||
- [ payload load 4b @ network header + 16 => reg 1 ]
|
|
||||||
- [ cmp eq reg 1 0x0100a8c0 ]
|
|
||||||
- [ meta load l4proto => reg 1 ]
|
|
||||||
- [ cmp eq reg 1 0x00000006 ]
|
|
||||||
- [ payload load 2b @ transport header + 2 => reg 1 ]
|
|
||||||
- [ lookup reg 1 set __map%d dreg 1 ]
|
|
||||||
- [ nat dnat ip addr_min reg 1 proto_min reg 9 ]
|
|
||||||
-
|
|
||||||
@ -1,155 +0,0 @@
|
|||||||
From 16de7abf588d74b78d9b8dc738ba2960ab90a3d2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] tests: py: Fix tests added for 'icmpv6 taddr' support
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit ef8b8ef36f80a2bfcc9df35cccb61ab490a8d6e7
|
|
||||||
|
|
||||||
commit ef8b8ef36f80a2bfcc9df35cccb61ab490a8d6e7
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Aug 13 16:14:08 2025 +0200
|
|
||||||
|
|
||||||
tests: py: Fix tests added for 'icmpv6 taddr' support
|
|
||||||
|
|
||||||
There was a duplicate test, also stored JSON equivalents should match
|
|
||||||
input as much as possible. The expected deviation in output (just like
|
|
||||||
with standard syntax) is stored in the .json.output file instead.
|
|
||||||
|
|
||||||
Fixes: 2e86f45d0260a ("icmpv6: Allow matching target address in NS/NA, redirect and MLD")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/ip6/icmpv6.t | 2 --
|
|
||||||
tests/py/ip6/icmpv6.t.json | 58 -------------------------------
|
|
||||||
tests/py/ip6/icmpv6.t.json.output | 36 +++++++++++++++++++
|
|
||||||
3 files changed, 36 insertions(+), 60 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t
|
|
||||||
index 35dad2b..00e6661 100644
|
|
||||||
--- a/tests/py/ip6/icmpv6.t
|
|
||||||
+++ b/tests/py/ip6/icmpv6.t
|
|
||||||
@@ -91,8 +91,6 @@ icmpv6 type nd-neighbor-solicit icmpv6 taddr 2001:db8::133;ok
|
|
||||||
icmpv6 type nd-neighbor-advert icmpv6 taddr 2001:db8::133;ok
|
|
||||||
icmpv6 taddr 2001:db8::133;ok;icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
|
|
||||||
|
|
||||||
-icmpv6 taddr 2001:db8::133;ok;icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
|
|
||||||
-
|
|
||||||
icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133;ok
|
|
||||||
icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } icmpv6 taddr 2001:db8::133;ok
|
|
||||||
icmpv6 daddr 2001:db8::133;ok
|
|
||||||
diff --git a/tests/py/ip6/icmpv6.t.json b/tests/py/ip6/icmpv6.t.json
|
|
||||||
index 224a8e8..b6f93b2 100644
|
|
||||||
--- a/tests/py/ip6/icmpv6.t.json
|
|
||||||
+++ b/tests/py/ip6/icmpv6.t.json
|
|
||||||
@@ -1250,64 +1250,6 @@
|
|
||||||
|
|
||||||
# icmpv6 taddr 2001:db8::133
|
|
||||||
[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "type",
|
|
||||||
- "protocol": "icmpv6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- "mld-listener-query",
|
|
||||||
- "mld-listener-report",
|
|
||||||
- "mld-listener-done",
|
|
||||||
- "nd-neighbor-solicit",
|
|
||||||
- "nd-neighbor-advert",
|
|
||||||
- "nd-redirect"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "taddr",
|
|
||||||
- "protocol": "icmpv6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": "2001:db8::133"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# icmpv6 taddr 2001:db8::133
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "payload": {
|
|
||||||
- "field": "type",
|
|
||||||
- "protocol": "icmpv6"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- "mld-listener-query",
|
|
||||||
- "mld-listener-report",
|
|
||||||
- "mld-listener-done",
|
|
||||||
- "nd-neighbor-solicit",
|
|
||||||
- "nd-neighbor-advert",
|
|
||||||
- "nd-redirect"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
{
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
diff --git a/tests/py/ip6/icmpv6.t.json.output b/tests/py/ip6/icmpv6.t.json.output
|
|
||||||
index 7b8f5c1..db25133 100644
|
|
||||||
--- a/tests/py/ip6/icmpv6.t.json.output
|
|
||||||
+++ b/tests/py/ip6/icmpv6.t.json.output
|
|
||||||
@@ -758,3 +758,39 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# icmpv6 taddr 2001:db8::133
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "type",
|
|
||||||
+ "protocol": "icmpv6"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": {
|
|
||||||
+ "set": [
|
|
||||||
+ "mld-listener-query",
|
|
||||||
+ "mld-listener-report",
|
|
||||||
+ "mld-listener-done",
|
|
||||||
+ "nd-neighbor-solicit",
|
|
||||||
+ "nd-neighbor-advert",
|
|
||||||
+ "nd-redirect"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "taddr",
|
|
||||||
+ "protocol": "icmpv6"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "2001:db8::133"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From 3ab9ef7229ebe3cd66da95e3aabf474342f9eab9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] segtree: incorrect type when aggregating concatenated set
|
|
||||||
ranges
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit c44995e31ba60c4823bb81fecd29020452b9e702
|
|
||||||
|
|
||||||
commit c44995e31ba60c4823bb81fecd29020452b9e702
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Wed Aug 13 15:19:23 2025 +0200
|
|
||||||
|
|
||||||
segtree: incorrect type when aggregating concatenated set ranges
|
|
||||||
|
|
||||||
Uncovered by the compound_expr_remove() replacement by type safe function
|
|
||||||
coming after this patch.
|
|
||||||
|
|
||||||
Add expression to the concatenation which is reachable via expr_value().
|
|
||||||
|
|
||||||
This bug is subtle, I could not spot any reproducible buggy behaviour
|
|
||||||
when using the wrong type when running the existing tests.
|
|
||||||
|
|
||||||
Fixes: 8ac2f3b2fca3 ("src: Add support for concatenated set ranges")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/segtree.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/segtree.c b/src/segtree.c
|
|
||||||
index c4029f9..a3a0fb4 100644
|
|
||||||
--- a/src/segtree.c
|
|
||||||
+++ b/src/segtree.c
|
|
||||||
@@ -447,7 +447,7 @@ next:
|
|
||||||
mpz_clear(range);
|
|
||||||
|
|
||||||
r2 = list_entry(r2_next, typeof(*r2), list);
|
|
||||||
- compound_expr_remove(start, r1);
|
|
||||||
+ compound_expr_remove(expr_value(start), r1);
|
|
||||||
|
|
||||||
if (free_r1)
|
|
||||||
expr_free(r1);
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
From 2970dcfbcb714b5e64d114229c9b46cbd9183e9d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] src: ensure chain policy evaluation when specified
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 01277922fede9fef8aacf5cc871bfbd55bbd78ef
|
|
||||||
|
|
||||||
commit 01277922fede9fef8aacf5cc871bfbd55bbd78ef
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Sun Aug 17 21:01:30 2025 +0200
|
|
||||||
|
|
||||||
src: ensure chain policy evaluation when specified
|
|
||||||
|
|
||||||
Set on CHAIN_F_BASECHAIN when policy is specified in chain, otherwise
|
|
||||||
chain priority is not evaluated.
|
|
||||||
|
|
||||||
Toggling this flag requires needs three adjustments to work though:
|
|
||||||
|
|
||||||
1) chain_evaluate() needs skip evaluation of hook name and priority if
|
|
||||||
not specified to allow for updating the default chain policy, e.g.
|
|
||||||
|
|
||||||
chain ip x y { policy accept; }
|
|
||||||
|
|
||||||
2) update netlink bytecode generation for chain to skip NFTA_CHAIN_HOOK
|
|
||||||
so update path is exercised in the kernel.
|
|
||||||
|
|
||||||
3) error reporting needs to check if basechain priority and type is
|
|
||||||
set on, otherwise skip further hints.
|
|
||||||
|
|
||||||
Fixes: acdfae9c3126 ("src: allow to specify the default policy for base chains")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cmd.c | 3 +++
|
|
||||||
src/evaluate.c | 27 ++++++++++---------
|
|
||||||
src/mnl.c | 8 ++++--
|
|
||||||
src/parser_bison.y | 1 +
|
|
||||||
.../bogons/nft-f/basechain_bad_policy | 2 ++
|
|
||||||
.../bogons/nft-f/unexisting_chain_set_policy | 5 ++++
|
|
||||||
6 files changed, 32 insertions(+), 14 deletions(-)
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-f/basechain_bad_policy
|
|
||||||
create mode 100644 tests/shell/testcases/bogons/nft-f/unexisting_chain_set_policy
|
|
||||||
|
|
||||||
diff --git a/src/cmd.c b/src/cmd.c
|
|
||||||
index 68c476c..f59e30c 100644
|
|
||||||
--- a/src/cmd.c
|
|
||||||
+++ b/src/cmd.c
|
|
||||||
@@ -264,6 +264,9 @@ static int nft_cmd_chain_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
if (!(chain->flags & CHAIN_F_BASECHAIN))
|
|
||||||
break;
|
|
||||||
|
|
||||||
+ if (!chain->priority.expr || !chain->type.str)
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
mpz_export_data(&priority, chain->priority.expr->value,
|
|
||||||
BYTEORDER_HOST_ENDIAN, sizeof(int));
|
|
||||||
if (priority <= -200 && !strcmp(chain->type.str, "nat"))
|
|
||||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
||||||
index 5012dd2..922821b 100644
|
|
||||||
--- a/src/evaluate.c
|
|
||||||
+++ b/src/evaluate.c
|
|
||||||
@@ -5070,18 +5070,21 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain->flags & CHAIN_F_BASECHAIN) {
|
|
||||||
- chain->hook.num = str2hooknum(chain->handle.family,
|
|
||||||
- chain->hook.name);
|
|
||||||
- if (chain->hook.num == NF_INET_NUMHOOKS)
|
|
||||||
- return __stmt_binary_error(ctx, &chain->hook.loc, NULL,
|
|
||||||
- "The %s family does not support this hook",
|
|
||||||
- family2str(chain->handle.family));
|
|
||||||
-
|
|
||||||
- if (!evaluate_priority(ctx, &chain->priority,
|
|
||||||
- chain->handle.family, chain->hook.num))
|
|
||||||
- return __stmt_binary_error(ctx, &chain->priority.loc, NULL,
|
|
||||||
- "invalid priority expression %s in this context.",
|
|
||||||
- expr_name(chain->priority.expr));
|
|
||||||
+ if (chain->hook.name) {
|
|
||||||
+ chain->hook.num = str2hooknum(chain->handle.family,
|
|
||||||
+ chain->hook.name);
|
|
||||||
+ if (chain->hook.num == NF_INET_NUMHOOKS)
|
|
||||||
+ return __stmt_binary_error(ctx, &chain->hook.loc, NULL,
|
|
||||||
+ "The %s family does not support this hook",
|
|
||||||
+ family2str(chain->handle.family));
|
|
||||||
+ }
|
|
||||||
+ if (chain->priority.expr) {
|
|
||||||
+ if (!evaluate_priority(ctx, &chain->priority,
|
|
||||||
+ chain->handle.family, chain->hook.num))
|
|
||||||
+ return __stmt_binary_error(ctx, &chain->priority.loc, NULL,
|
|
||||||
+ "invalid priority expression %s in this context.",
|
|
||||||
+ expr_name(chain->priority.expr));
|
|
||||||
+ }
|
|
||||||
if (chain->policy) {
|
|
||||||
expr_set_context(&ctx->ectx, &policy_type,
|
|
||||||
NFT_NAME_MAXLEN * BITS_PER_BYTE);
|
|
||||||
diff --git a/src/mnl.c b/src/mnl.c
|
|
||||||
index c62b140..6e8066a 100644
|
|
||||||
--- a/src/mnl.c
|
|
||||||
+++ b/src/mnl.c
|
|
||||||
@@ -875,7 +875,9 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, cmd->chain->type.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
- nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
|
|
||||||
+ if (cmd->chain->type.str ||
|
|
||||||
+ (cmd->chain && cmd->chain->dev_expr))
|
|
||||||
+ nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
|
|
||||||
|
|
||||||
if (cmd->chain->type.str) {
|
|
||||||
mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(cmd->chain->hook.num));
|
|
||||||
@@ -887,7 +889,9 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
if (cmd->chain && cmd->chain->dev_expr)
|
|
||||||
mnl_nft_chain_devs_build(nlh, cmd);
|
|
||||||
|
|
||||||
- mnl_attr_nest_end(nlh, nest);
|
|
||||||
+ if (cmd->chain->type.str ||
|
|
||||||
+ (cmd->chain && cmd->chain->dev_expr))
|
|
||||||
+ mnl_attr_nest_end(nlh, nest);
|
|
||||||
}
|
|
||||||
|
|
||||||
nftnl_chain_free(nlc);
|
|
||||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
||||||
index a6a517f..c3086c8 100644
|
|
||||||
--- a/src/parser_bison.y
|
|
||||||
+++ b/src/parser_bison.y
|
|
||||||
@@ -2756,6 +2756,7 @@ policy_spec : POLICY policy_expr close_scope_policy
|
|
||||||
}
|
|
||||||
$<chain>0->policy = $2;
|
|
||||||
$<chain>0->policy->location = @$;
|
|
||||||
+ $<chain>0->flags |= CHAIN_F_BASECHAIN;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-f/basechain_bad_policy b/tests/shell/testcases/bogons/nft-f/basechain_bad_policy
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..998e423
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-f/basechain_bad_policy
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+define MY_POLICY = deny
|
|
||||||
+table T { chain C { policy $MY_POLICY; };};
|
|
||||||
diff --git a/tests/shell/testcases/bogons/nft-f/unexisting_chain_set_policy b/tests/shell/testcases/bogons/nft-f/unexisting_chain_set_policy
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0889559
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/bogons/nft-f/unexisting_chain_set_policy
|
|
||||||
@@ -0,0 +1,5 @@
|
|
||||||
+table ip x {
|
|
||||||
+ chain y {
|
|
||||||
+ policy drop;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
@ -1,767 +0,0 @@
|
|||||||
From c47e93f5fa3ca3204080a09edbf854a1c9d7cd64 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:02 +0200
|
|
||||||
Subject: [PATCH] json: Do not reduce single-item arrays on output
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 5e492307c2c93b7eb654691ca87ddc7ad86640d8
|
|
||||||
Conflicts: Dropped changes to non-existent test and dump files
|
|
||||||
|
|
||||||
commit 5e492307c2c93b7eb654691ca87ddc7ad86640d8
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Tue Aug 12 17:31:47 2025 +0200
|
|
||||||
|
|
||||||
json: Do not reduce single-item arrays on output
|
|
||||||
|
|
||||||
This is a partial revert of commit a740f2036ad0d ("json: Introduce
|
|
||||||
json_add_array_new()"), keeping the function but eliminating its primary
|
|
||||||
task which is to replace arrays of size 1 by their only item. While
|
|
||||||
support for this on input is convenient for users, it means extra casing
|
|
||||||
in JSON output parsers to cover for it. The minor reduction in output
|
|
||||||
size does not justify that.
|
|
||||||
|
|
||||||
Fixes: a740f2036ad0d ("json: Introduce json_add_array_new()")
|
|
||||||
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1806
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 8 +-
|
|
||||||
tests/py/any/log.t.json.output | 15 +++-
|
|
||||||
tests/py/any/queue.t.json.output | 117 +++++++++++++++++++++++++
|
|
||||||
tests/py/inet/fib.t.json | 8 +-
|
|
||||||
tests/py/inet/fib.t.json.output | 87 ++++++++++++++++++-
|
|
||||||
tests/py/inet/snat.t.json.output | 22 +++++
|
|
||||||
tests/py/inet/synproxy.t.json | 8 +-
|
|
||||||
tests/py/inet/synproxy.t.json.output | 8 +-
|
|
||||||
tests/py/ip/masquerade.t.json.output | 46 ++++++++++
|
|
||||||
tests/py/ip/redirect.t.json.output | 118 ++++++++++++++++++++++++++
|
|
||||||
tests/py/ip/snat.t.json.output | 8 +-
|
|
||||||
tests/py/ip6/masquerade.t.json.output | 46 ++++++++++
|
|
||||||
tests/py/ip6/redirect.t.json.output | 70 +++++++++++++++
|
|
||||||
13 files changed, 536 insertions(+), 25 deletions(-)
|
|
||||||
create mode 100644 tests/py/inet/snat.t.json.output
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index a2523a4..183047a 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -53,14 +53,10 @@ static json_t *__nft_json_pack(unsigned int line, const char *fmt, ...)
|
|
||||||
|
|
||||||
static void json_add_array_new(json_t *obj, const char *name, json_t *array)
|
|
||||||
{
|
|
||||||
- if (json_array_size(array) > 1) {
|
|
||||||
+ if (json_array_size(array))
|
|
||||||
json_object_set_new(obj, name, array);
|
|
||||||
- } else {
|
|
||||||
- if (json_array_size(array))
|
|
||||||
- json_object_set(obj, name,
|
|
||||||
- json_array_get(array, 0));
|
|
||||||
+ else
|
|
||||||
json_decref(array);
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
|
|
||||||
static json_t *expr_print_json(const struct expr *expr, struct output_ctx *octx)
|
|
||||||
diff --git a/tests/py/any/log.t.json.output b/tests/py/any/log.t.json.output
|
|
||||||
index 051c448..bec70a3 100644
|
|
||||||
--- a/tests/py/any/log.t.json.output
|
|
||||||
+++ b/tests/py/any/log.t.json.output
|
|
||||||
@@ -9,7 +9,20 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"log": {
|
|
||||||
- "flags": "all"
|
|
||||||
+ "flags": [
|
|
||||||
+ "all"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# log flags all
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "log": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "all"
|
|
||||||
+ ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/tests/py/any/queue.t.json.output b/tests/py/any/queue.t.json.output
|
|
||||||
index 1104d76..ea37223 100644
|
|
||||||
--- a/tests/py/any/queue.t.json.output
|
|
||||||
+++ b/tests/py/any/queue.t.json.output
|
|
||||||
@@ -7,3 +7,120 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# queue num 4-5 fanout
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "fanout"
|
|
||||||
+ ],
|
|
||||||
+ "num": {
|
|
||||||
+ "range": [
|
|
||||||
+ 4,
|
|
||||||
+ 5
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# queue num 4-5 bypass
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "bypass"
|
|
||||||
+ ],
|
|
||||||
+ "num": {
|
|
||||||
+ "range": [
|
|
||||||
+ 4,
|
|
||||||
+ 5
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# queue flags bypass to numgen inc mod 65536
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "bypass"
|
|
||||||
+ ],
|
|
||||||
+ "num": {
|
|
||||||
+ "numgen": {
|
|
||||||
+ "mod": 65536,
|
|
||||||
+ "mode": "inc",
|
|
||||||
+ "offset": 0
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# queue flags bypass to 65535
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "bypass"
|
|
||||||
+ ],
|
|
||||||
+ "num": 65535
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# queue flags bypass to 1-65535
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "bypass"
|
|
||||||
+ ],
|
|
||||||
+ "num": {
|
|
||||||
+ "range": [
|
|
||||||
+ 1,
|
|
||||||
+ 65535
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# queue flags bypass to oifname map { "eth0" : 0, "ppp0" : 2, "eth1" : 2 }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "queue": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "bypass"
|
|
||||||
+ ],
|
|
||||||
+ "num": {
|
|
||||||
+ "map": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ "eth0",
|
|
||||||
+ 0
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ "ppp0",
|
|
||||||
+ 2
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ "eth1",
|
|
||||||
+ 2
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "oifname"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/inet/fib.t.json b/tests/py/inet/fib.t.json
|
|
||||||
index 14a6249..2bfe4f7 100644
|
|
||||||
--- a/tests/py/inet/fib.t.json
|
|
||||||
+++ b/tests/py/inet/fib.t.json
|
|
||||||
@@ -100,9 +100,7 @@
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
"fib": {
|
|
||||||
- "flags": [
|
|
||||||
- "daddr"
|
|
||||||
- ],
|
|
||||||
+ "flags": "daddr",
|
|
||||||
"result": "check"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -118,9 +116,7 @@
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
"fib": {
|
|
||||||
- "flags": [
|
|
||||||
- "daddr"
|
|
||||||
- ],
|
|
||||||
+ "flags": "daddr",
|
|
||||||
"result": "check"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
diff --git a/tests/py/inet/fib.t.json.output b/tests/py/inet/fib.t.json.output
|
|
||||||
index e8d0166..d3396dd 100644
|
|
||||||
--- a/tests/py/inet/fib.t.json.output
|
|
||||||
+++ b/tests/py/inet/fib.t.json.output
|
|
||||||
@@ -43,7 +43,9 @@
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
"fib": {
|
|
||||||
- "flags": "daddr",
|
|
||||||
+ "flags": [
|
|
||||||
+ "daddr"
|
|
||||||
+ ],
|
|
||||||
"result": "check"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -59,7 +61,9 @@
|
|
||||||
"match": {
|
|
||||||
"left": {
|
|
||||||
"fib": {
|
|
||||||
- "flags": "daddr",
|
|
||||||
+ "flags": [
|
|
||||||
+ "daddr"
|
|
||||||
+ ],
|
|
||||||
"result": "check"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -69,3 +73,82 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# fib daddr check vmap { missing : drop, exists : accept }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "vmap": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ false,
|
|
||||||
+ {
|
|
||||||
+ "drop": null
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ true,
|
|
||||||
+ {
|
|
||||||
+ "accept": null
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "fib": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "daddr"
|
|
||||||
+ ],
|
|
||||||
+ "result": "check"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# meta mark set fib daddr check . ct mark map { exists . 0x00000000 : 0x00000001 }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "mangle": {
|
|
||||||
+ "key": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "value": {
|
|
||||||
+ "map": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ {
|
|
||||||
+ "concat": [
|
|
||||||
+ true,
|
|
||||||
+ 0
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ 1
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "concat": [
|
|
||||||
+ {
|
|
||||||
+ "fib": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "daddr"
|
|
||||||
+ ],
|
|
||||||
+ "result": "check"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "ct": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/inet/snat.t.json.output b/tests/py/inet/snat.t.json.output
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..5b95886
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/py/inet/snat.t.json.output
|
|
||||||
@@ -0,0 +1,22 @@
|
|
||||||
+# iifname "foo" masquerade random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "meta": {
|
|
||||||
+ "key": "iifname"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": "foo"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "masquerade": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/inet/synproxy.t.json b/tests/py/inet/synproxy.t.json
|
|
||||||
index 1dd85a6..b3cec09 100644
|
|
||||||
--- a/tests/py/inet/synproxy.t.json
|
|
||||||
+++ b/tests/py/inet/synproxy.t.json
|
|
||||||
@@ -19,9 +19,7 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"synproxy": {
|
|
||||||
- "flags": [
|
|
||||||
- "timestamp"
|
|
||||||
- ]
|
|
||||||
+ "flags": "timestamp"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -56,9 +54,7 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"synproxy": {
|
|
||||||
- "flags": [
|
|
||||||
- "sack-perm"
|
|
||||||
- ]
|
|
||||||
+ "flags": "sack-perm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/tests/py/inet/synproxy.t.json.output b/tests/py/inet/synproxy.t.json.output
|
|
||||||
index e32cdfb..a1d81bf 100644
|
|
||||||
--- a/tests/py/inet/synproxy.t.json.output
|
|
||||||
+++ b/tests/py/inet/synproxy.t.json.output
|
|
||||||
@@ -2,7 +2,9 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"synproxy": {
|
|
||||||
- "flags": "timestamp"
|
|
||||||
+ "flags": [
|
|
||||||
+ "timestamp"
|
|
||||||
+ ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -11,7 +13,9 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"synproxy": {
|
|
||||||
- "flags": "sack-perm"
|
|
||||||
+ "flags": [
|
|
||||||
+ "sack-perm"
|
|
||||||
+ ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/tests/py/ip/masquerade.t.json.output b/tests/py/ip/masquerade.t.json.output
|
|
||||||
index 58e7e29..8ca5a42 100644
|
|
||||||
--- a/tests/py/ip/masquerade.t.json.output
|
|
||||||
+++ b/tests/py/ip/masquerade.t.json.output
|
|
||||||
@@ -121,3 +121,49 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# udp dport 53 masquerade random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "masquerade": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# udp dport 53 masquerade persistent
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "masquerade": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "persistent"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/ip/redirect.t.json.output b/tests/py/ip/redirect.t.json.output
|
|
||||||
index 4646c60..09f1e48 100644
|
|
||||||
--- a/tests/py/ip/redirect.t.json.output
|
|
||||||
+++ b/tests/py/ip/redirect.t.json.output
|
|
||||||
@@ -1,3 +1,49 @@
|
|
||||||
+# udp dport 53 redirect random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# udp dport 53 redirect persistent
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "persistent"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
# udp dport 53 redirect random,persistent,fully-random
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -144,3 +190,75 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# tcp dport 9128 redirect to :993 random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "tcp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 9128
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ],
|
|
||||||
+ "port": 993
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# tcp dport 9128 redirect to :993 fully-random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "tcp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 9128
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "fully-random"
|
|
||||||
+ ],
|
|
||||||
+ "port": 993
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# tcp dport 9128 redirect to :123 persistent
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "tcp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 9128
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "persistent"
|
|
||||||
+ ],
|
|
||||||
+ "port": 123
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/ip/snat.t.json.output b/tests/py/ip/snat.t.json.output
|
|
||||||
index 2a99780..19eba25 100644
|
|
||||||
--- a/tests/py/ip/snat.t.json.output
|
|
||||||
+++ b/tests/py/ip/snat.t.json.output
|
|
||||||
@@ -241,8 +241,12 @@
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"family": "ip",
|
|
||||||
- "flags": "netmap",
|
|
||||||
- "type_flags": "prefix"
|
|
||||||
+ "flags": [
|
|
||||||
+ "netmap"
|
|
||||||
+ ],
|
|
||||||
+ "type_flags": [
|
|
||||||
+ "prefix"
|
|
||||||
+ ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
diff --git a/tests/py/ip6/masquerade.t.json.output b/tests/py/ip6/masquerade.t.json.output
|
|
||||||
index 31d0cd9..21ed4f6 100644
|
|
||||||
--- a/tests/py/ip6/masquerade.t.json.output
|
|
||||||
+++ b/tests/py/ip6/masquerade.t.json.output
|
|
||||||
@@ -96,3 +96,49 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# udp dport 53 masquerade random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "masquerade": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# udp dport 53 masquerade persistent
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "masquerade": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "persistent"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
diff --git a/tests/py/ip6/redirect.t.json.output b/tests/py/ip6/redirect.t.json.output
|
|
||||||
index 0174cc7..69c7b03 100644
|
|
||||||
--- a/tests/py/ip6/redirect.t.json.output
|
|
||||||
+++ b/tests/py/ip6/redirect.t.json.output
|
|
||||||
@@ -144,3 +144,73 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# udp dport 53 redirect random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# udp dport 53 redirect persistent
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "udp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 53
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "persistent"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# tcp dport 9128 redirect to :993 random
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "payload": {
|
|
||||||
+ "field": "dport",
|
|
||||||
+ "protocol": "tcp"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": 9128
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "redirect": {
|
|
||||||
+ "flags": [
|
|
||||||
+ "random"
|
|
||||||
+ ],
|
|
||||||
+ "port": 993
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,55 +0,0 @@
|
|||||||
From 0ba786e77b069dee73f6fbfd910e6404d28193a8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:50 +0200
|
|
||||||
Subject: [PATCH] mnl: silence compiler warning
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit cd9f168875aca72caacdcfb552c15b6484a82bd5
|
|
||||||
|
|
||||||
commit cd9f168875aca72caacdcfb552c15b6484a82bd5
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Wed Aug 20 14:44:43 2025 +0200
|
|
||||||
|
|
||||||
mnl: silence compiler warning
|
|
||||||
|
|
||||||
gcc 14.3.0 reports this:
|
|
||||||
|
|
||||||
src/mnl.c: In function 'mnl_nft_chain_add':
|
|
||||||
src/mnl.c:916:25: warning: 'nest' may be used uninitialized [-Wmaybe-uninitialized]
|
|
||||||
916 | mnl_attr_nest_end(nlh, nest);
|
|
||||||
|
|
||||||
I guess its because compiler can't know that the conditions cannot change
|
|
||||||
in-between and assumes nest_end() can be called without nest_start().
|
|
||||||
|
|
||||||
Fixes: 01277922fede ("src: ensure chain policy evaluation when specified")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mnl.c | 5 ++---
|
|
||||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/mnl.c b/src/mnl.c
|
|
||||||
index 6e8066a..6ba2d85 100644
|
|
||||||
--- a/src/mnl.c
|
|
||||||
+++ b/src/mnl.c
|
|
||||||
@@ -868,7 +868,7 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
nftnl_chain_nlmsg_build_payload(nlh, nlc);
|
|
||||||
|
|
||||||
if (cmd->chain && cmd->chain->flags & CHAIN_F_BASECHAIN) {
|
|
||||||
- struct nlattr *nest;
|
|
||||||
+ struct nlattr *nest = NULL;
|
|
||||||
|
|
||||||
if (cmd->chain->type.str) {
|
|
||||||
cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->chain->type.loc);
|
|
||||||
@@ -889,8 +889,7 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
if (cmd->chain && cmd->chain->dev_expr)
|
|
||||||
mnl_nft_chain_devs_build(nlh, cmd);
|
|
||||||
|
|
||||||
- if (cmd->chain->type.str ||
|
|
||||||
- (cmd->chain && cmd->chain->dev_expr))
|
|
||||||
+ if (nest)
|
|
||||||
mnl_attr_nest_end(nlh, nest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
From 02efc5f458b73e02dd05ef1f6e4736b3a8999ac2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:50 +0200
|
|
||||||
Subject: [PATCH] mnl: continue on ENOBUFS errors when processing batch
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 47e9aaf0227daf16f43a7442e1dceae8851817a5
|
|
||||||
|
|
||||||
commit 47e9aaf0227daf16f43a7442e1dceae8851817a5
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Tue Aug 26 10:09:13 2025 +0200
|
|
||||||
|
|
||||||
mnl: continue on ENOBUFS errors when processing batch
|
|
||||||
|
|
||||||
A user reports that:
|
|
||||||
|
|
||||||
nft -f ruleset.nft
|
|
||||||
|
|
||||||
fails with:
|
|
||||||
|
|
||||||
netlink: Error: Could not process rule: No buffer space available
|
|
||||||
|
|
||||||
This was triggered by:
|
|
||||||
|
|
||||||
table ip6 fule {
|
|
||||||
set domestic_ip6 {
|
|
||||||
type ipv6_addr
|
|
||||||
flags dynamic,interval
|
|
||||||
elements = $domestic_ip6
|
|
||||||
}
|
|
||||||
chain prerouting {
|
|
||||||
type filter hook prerouting priority 0;
|
|
||||||
ip6 daddr @domestic_ip6 counter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
where $domestic_ip6 contains a large number of IPv6 addresses.
|
|
||||||
|
|
||||||
This set declaration is not supported currently, because dynamic sets
|
|
||||||
with intervals are not supported, then every IPv6 address that is added
|
|
||||||
triggers an error, overruning the userspace socket buffer with lots of
|
|
||||||
NLMSG_ERROR messages (or too big NLMSG_ERROR message to fit into the
|
|
||||||
socket buffer).
|
|
||||||
|
|
||||||
In the particular context of batch processing, ENOBUFS is just an
|
|
||||||
indication that too many errors have occurred. The kernel cannot store
|
|
||||||
any more NLMSG_ERROR messages into the userspace socket buffer.
|
|
||||||
|
|
||||||
However, there are still NLMSG_ERROR messages in the socket buffer to be
|
|
||||||
processed that can provide a hint on what is going on.
|
|
||||||
|
|
||||||
Instead of breaking on ENOBUFS in batches, continue error processing.
|
|
||||||
|
|
||||||
After this patch, the ruleset above displays:
|
|
||||||
|
|
||||||
ruleset.nft:2367:7-18: Error: Could not process rule: Operation not supported
|
|
||||||
set domestic_ip6 {
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
ruleset.nft:2367:7-18: Error: Could not process rule: No such file or directory
|
|
||||||
set domestic_ip6 {
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Fixes: a72315d2bad4 ("src: add rule batching support")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mnl.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/mnl.c b/src/mnl.c
|
|
||||||
index 6ba2d85..96a86aa 100644
|
|
||||||
--- a/src/mnl.c
|
|
||||||
+++ b/src/mnl.c
|
|
||||||
@@ -445,8 +445,13 @@ int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list,
|
|
||||||
break;
|
|
||||||
|
|
||||||
ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
|
|
||||||
- if (ret == -1)
|
|
||||||
+ if (ret == -1) {
|
|
||||||
+ /* Too many errors, not all errors are displayed. */
|
|
||||||
+ if (errno == ENOBUFS)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
return -1;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Continue on error, make sure we get all acknowledgments */
|
|
||||||
ret = mnl_cb_run2(rcv_buf, ret, 0, portid,
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From 50c0c4910132783578eee7b2aa767b88f504e366 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:50 +0200
|
|
||||||
Subject: [PATCH] monitor: Quote device names in chain declarations, too
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit ed1b5b672b2eeb6244bed566227bee2aa7a1e4b4
|
|
||||||
|
|
||||||
commit ed1b5b672b2eeb6244bed566227bee2aa7a1e4b4
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Aug 28 16:47:03 2025 +0200
|
|
||||||
|
|
||||||
monitor: Quote device names in chain declarations, too
|
|
||||||
|
|
||||||
Fixed commit missed the fact that there are two routines printing chain
|
|
||||||
declarations.
|
|
||||||
|
|
||||||
Fixes: eb30f236d91a8 ("rule: print chain and flowtable devices in quotes")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/rule.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index c026d8d..3b75736 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -1110,7 +1110,7 @@ void chain_print_plain(const struct chain *chain, struct output_ctx *octx)
|
|
||||||
|
|
||||||
nft_print(octx, "devices = { ");
|
|
||||||
for (i = 0; i < chain->dev_array_len; i++) {
|
|
||||||
- nft_print(octx, "%s", chain->dev_array[i]);
|
|
||||||
+ nft_print(octx, "\"%s\"", chain->dev_array[i]);
|
|
||||||
if (i + 1 != chain->dev_array_len)
|
|
||||||
nft_print(octx, ", ");
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From cae7e6924f2857b6e66db1425abc6beff07bb2ac Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:50 +0200
|
|
||||||
Subject: [PATCH] tests: monitor: Fix regex collecting expected echo output
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 419338d96bdb19c10e241387c54f416c551a47c3
|
|
||||||
|
|
||||||
commit 419338d96bdb19c10e241387c54f416c551a47c3
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Sep 3 15:23:12 2025 +0200
|
|
||||||
|
|
||||||
tests: monitor: Fix regex collecting expected echo output
|
|
||||||
|
|
||||||
No input triggered this bug, but the match would accept "insert" and
|
|
||||||
"replace" keywords anywhere in the line not just at the beginning as was
|
|
||||||
intended.
|
|
||||||
|
|
||||||
Fixes: b2506e5504fed ("tests: Merge monitor and echo test suites")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/monitor/run-tests.sh | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh
|
|
||||||
index f1ac790..c6a3322 100755
|
|
||||||
--- a/tests/monitor/run-tests.sh
|
|
||||||
+++ b/tests/monitor/run-tests.sh
|
|
||||||
@@ -53,7 +53,7 @@ echo_output_append() {
|
|
||||||
grep '^\(add\|replace\|insert\)' $command_file >>$output_file
|
|
||||||
return
|
|
||||||
}
|
|
||||||
- [[ "$*" =~ ^add|replace|insert ]] && echo "$*" >>$output_file
|
|
||||||
+ [[ "$*" =~ ^(add|replace|insert) ]] && echo "$*" >>$output_file
|
|
||||||
}
|
|
||||||
json_output_filter() { # (filename)
|
|
||||||
# unify handle values
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
From c6b5059905d5e1ba029027cecd8e62d7b70c1c51 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:31:50 +0200
|
|
||||||
Subject: [PATCH] monitor: Inform JSON printer when reporting an object delete
|
|
||||||
event
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 6c04d24d16f1d15f216f2b3c8e64c9062cd77487
|
|
||||||
Conflicts:
|
|
||||||
- Context change due to missing commit 73a8adfc2432e
|
|
||||||
("monitor: Recognize flowtable add/del events")
|
|
||||||
- Adjusted to missing commit 3a957f8f1ff1e
|
|
||||||
("tunnel: add tunnel object and statement json support")
|
|
||||||
|
|
||||||
commit 6c04d24d16f1d15f216f2b3c8e64c9062cd77487
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Aug 29 01:07:05 2025 +0200
|
|
||||||
|
|
||||||
monitor: Inform JSON printer when reporting an object delete event
|
|
||||||
|
|
||||||
Since kernel commit a1050dd07168 ("netfilter: nf_tables: Reintroduce
|
|
||||||
shortened deletion notifications"), type-specific data is no longer
|
|
||||||
dumped when notifying for a deleted object. JSON output was not aware of
|
|
||||||
this and tried to print bogus data.
|
|
||||||
|
|
||||||
Fixes: 9e88aae28e9f4 ("monitor: Use libnftables JSON output")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
include/json.h | 5 +++--
|
|
||||||
src/json.c | 16 ++++++++++------
|
|
||||||
src/monitor.c | 2 +-
|
|
||||||
tests/monitor/testcases/object.t | 10 +++++-----
|
|
||||||
4 files changed, 19 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/json.h b/include/json.h
|
|
||||||
index 39be892..23ca49e 100644
|
|
||||||
--- a/include/json.h
|
|
||||||
+++ b/include/json.h
|
|
||||||
@@ -112,7 +112,7 @@ void monitor_print_set_json(struct netlink_mon_handler *monh,
|
|
||||||
void monitor_print_element_json(struct netlink_mon_handler *monh,
|
|
||||||
const char *cmd, struct set *s);
|
|
||||||
void monitor_print_obj_json(struct netlink_mon_handler *monh,
|
|
||||||
- const char *cmd, struct obj *o);
|
|
||||||
+ const char *cmd, struct obj *o, bool delete);
|
|
||||||
void monitor_print_rule_json(struct netlink_mon_handler *monh,
|
|
||||||
const char *cmd, struct rule *r);
|
|
||||||
|
|
||||||
@@ -249,7 +249,8 @@ static inline void monitor_print_element_json(struct netlink_mon_handler *monh,
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void monitor_print_obj_json(struct netlink_mon_handler *monh,
|
|
||||||
- const char *cmd, struct obj *o)
|
|
||||||
+ const char *cmd, struct obj *o,
|
|
||||||
+ bool delete)
|
|
||||||
{
|
|
||||||
/* empty */
|
|
||||||
}
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index 57b7664..fc2e962 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -353,7 +353,7 @@ static json_t *timeout_policy_json(uint8_t l4, const uint32_t *timeout)
|
|
||||||
return root ? : json_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
-static json_t *obj_print_json(const struct obj *obj)
|
|
||||||
+static json_t *obj_print_json(const struct obj *obj, bool delete)
|
|
||||||
{
|
|
||||||
const char *rate_unit = NULL, *burst_unit = NULL;
|
|
||||||
const char *type = obj_type_name(obj->type);
|
|
||||||
@@ -366,6 +366,9 @@ static json_t *obj_print_json(const struct obj *obj)
|
|
||||||
"table", obj->handle.table.name,
|
|
||||||
"handle", obj->handle.handle.id);
|
|
||||||
|
|
||||||
+ if (delete)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
if (obj->comment) {
|
|
||||||
tmp = nft_json_pack("{s:s}", "comment", obj->comment);
|
|
||||||
json_object_update(root, tmp);
|
|
||||||
@@ -469,6 +472,7 @@ static json_t *obj_print_json(const struct obj *obj)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+out:
|
|
||||||
return nft_json_pack("{s:o}", type, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1699,7 +1703,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
|
|
||||||
json_array_append_new(root, tmp);
|
|
||||||
|
|
||||||
list_for_each_entry(obj, &table->obj_cache.list, cache.list) {
|
|
||||||
- tmp = obj_print_json(obj);
|
|
||||||
+ tmp = obj_print_json(obj, false);
|
|
||||||
json_array_append_new(root, tmp);
|
|
||||||
}
|
|
||||||
list_for_each_entry(set, &table->set_cache.list, cache.list) {
|
|
||||||
@@ -1861,7 +1865,7 @@ static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
|
||||||
static json_t *do_list_obj_json(struct netlink_ctx *ctx,
|
|
||||||
struct cmd *cmd, uint32_t type)
|
|
||||||
{
|
|
||||||
- json_t *root = json_array();
|
|
||||||
+ json_t *root = json_array(), *tmp;
|
|
||||||
struct table *table;
|
|
||||||
struct obj *obj;
|
|
||||||
|
|
||||||
@@ -1880,7 +1884,7 @@ static json_t *do_list_obj_json(struct netlink_ctx *ctx,
|
|
||||||
strcmp(cmd->handle.obj.name, obj->handle.obj.name)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- json_array_append_new(root, obj_print_json(obj));
|
|
||||||
+ json_array_append_new(root, obj_print_json(obj, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2066,9 +2070,9 @@ void monitor_print_element_json(struct netlink_mon_handler *monh,
|
|
||||||
}
|
|
||||||
|
|
||||||
void monitor_print_obj_json(struct netlink_mon_handler *monh,
|
|
||||||
- const char *cmd, struct obj *o)
|
|
||||||
+ const char *cmd, struct obj *o, bool delete)
|
|
||||||
{
|
|
||||||
- monitor_print_json(monh, cmd, obj_print_json(o));
|
|
||||||
+ monitor_print_json(monh, cmd, obj_print_json(o, delete));
|
|
||||||
}
|
|
||||||
|
|
||||||
void monitor_print_rule_json(struct netlink_mon_handler *monh,
|
|
||||||
diff --git a/src/monitor.c b/src/monitor.c
|
|
||||||
index bf59f2d..87ff2a3 100644
|
|
||||||
--- a/src/monitor.c
|
|
||||||
+++ b/src/monitor.c
|
|
||||||
@@ -529,7 +529,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type,
|
|
||||||
nft_mon_print(monh, "\n");
|
|
||||||
break;
|
|
||||||
case NFTNL_OUTPUT_JSON:
|
|
||||||
- monitor_print_obj_json(monh, cmd, obj);
|
|
||||||
+ monitor_print_obj_json(monh, cmd, obj, type == NFT_MSG_DELOBJ);
|
|
||||||
if (!nft_output_echo(&monh->ctx->nft->output))
|
|
||||||
nft_mon_print(monh, "\n");
|
|
||||||
break;
|
|
||||||
diff --git a/tests/monitor/testcases/object.t b/tests/monitor/testcases/object.t
|
|
||||||
index 53a9f8c..b60dc98 100644
|
|
||||||
--- a/tests/monitor/testcases/object.t
|
|
||||||
+++ b/tests/monitor/testcases/object.t
|
|
||||||
@@ -9,7 +9,7 @@ J {"add": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "
|
|
||||||
|
|
||||||
I delete counter ip t c
|
|
||||||
O -
|
|
||||||
-J {"delete": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "packets": 0, "bytes": 0}}}
|
|
||||||
+J {"delete": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0}}}
|
|
||||||
|
|
||||||
# FIXME: input/output shouldn't be asynchronous here
|
|
||||||
I add quota ip t q 25 mbytes
|
|
||||||
@@ -18,7 +18,7 @@ J {"add": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "by
|
|
||||||
|
|
||||||
I delete quota ip t q
|
|
||||||
O -
|
|
||||||
-J {"delete": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "bytes": 26214400, "used": 0, "inv": false}}}
|
|
||||||
+J {"delete": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0}}}
|
|
||||||
|
|
||||||
# FIXME: input/output shouldn't be asynchronous here
|
|
||||||
I add limit ip t l rate 1/second
|
|
||||||
@@ -27,7 +27,7 @@ J {"add": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "ra
|
|
||||||
|
|
||||||
I delete limit ip t l
|
|
||||||
O -
|
|
||||||
-J {"delete": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "rate": 1, "per": "second", "burst": 5}}}
|
|
||||||
+J {"delete": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0}}}
|
|
||||||
|
|
||||||
I add ct helper ip t cth { type "sip" protocol tcp; l3proto ip; }
|
|
||||||
O -
|
|
||||||
@@ -35,7 +35,7 @@ J {"add": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle":
|
|
||||||
|
|
||||||
I delete ct helper ip t cth
|
|
||||||
O -
|
|
||||||
-J {"delete": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0, "type": "sip", "protocol": "tcp", "l3proto": "ip"}}}
|
|
||||||
+J {"delete": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0}}}
|
|
||||||
|
|
||||||
I add ct timeout ip t ctt { protocol udp; l3proto ip; policy = { unreplied : 15s, replied : 12s }; }
|
|
||||||
O -
|
|
||||||
@@ -43,4 +43,4 @@ J {"add": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle":
|
|
||||||
|
|
||||||
I delete ct timeout ip t ctt
|
|
||||||
O -
|
|
||||||
-J {"delete": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle": 0, "protocol": "udp", "l3proto": "ip", "policy": {"unreplied": 15, "replied": 12}}}}
|
|
||||||
+J {"delete": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle": 0}}}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
From 69e126ef0536e2b792b970edf0b132dc2aa3548f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] fib: Fix for existence check on Big Endian
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 98e51e687616a4b54efa3b723917c292e3acc380
|
|
||||||
|
|
||||||
commit 98e51e687616a4b54efa3b723917c292e3acc380
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Tue Sep 9 22:27:19 2025 +0200
|
|
||||||
|
|
||||||
fib: Fix for existence check on Big Endian
|
|
||||||
|
|
||||||
Adjust the expression size to 1B so cmp expression value is correct.
|
|
||||||
Without this, the rule 'fib saddr . iif check exists' generates
|
|
||||||
following byte code on BE:
|
|
||||||
|
|
||||||
| [ fib saddr . iif oif present => reg 1 ]
|
|
||||||
| [ cmp eq reg 1 0x00000001 ]
|
|
||||||
|
|
||||||
Though with NFTA_FIB_F_PRESENT flag set, nft_fib.ko writes to the first
|
|
||||||
byte of reg 1 only (using nft_reg_store8()). With this patch in place,
|
|
||||||
byte code is correct:
|
|
||||||
|
|
||||||
| [ fib saddr . iif oif present => reg 1 ]
|
|
||||||
| [ cmp eq reg 1 0x01000000 ]
|
|
||||||
|
|
||||||
Fixes: f686a17eafa0b ("fib: Support existence check")
|
|
||||||
Cc: Yi Chen <yiche@redhat.com>
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/evaluate.c | 1 +
|
|
||||||
src/fib.c | 4 +++-
|
|
||||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
||||||
index 922821b..6046716 100644
|
|
||||||
--- a/src/evaluate.c
|
|
||||||
+++ b/src/evaluate.c
|
|
||||||
@@ -2574,6 +2574,7 @@ static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp)
|
|
||||||
if (expr->flags & EXPR_F_BOOLEAN) {
|
|
||||||
expr->fib.flags |= NFTA_FIB_F_PRESENT;
|
|
||||||
datatype_set(expr, &boolean_type);
|
|
||||||
+ expr->len = BITS_PER_BYTE;
|
|
||||||
}
|
|
||||||
return expr_evaluate_primary(ctx, exprp);
|
|
||||||
}
|
|
||||||
diff --git a/src/fib.c b/src/fib.c
|
|
||||||
index 80ff292..bfedcb7 100644
|
|
||||||
--- a/src/fib.c
|
|
||||||
+++ b/src/fib.c
|
|
||||||
@@ -198,8 +198,10 @@ struct expr *fib_expr_alloc(const struct location *loc,
|
|
||||||
BUG("Unknown result %d\n", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (flags & NFTA_FIB_F_PRESENT)
|
|
||||||
+ if (flags & NFTA_FIB_F_PRESENT) {
|
|
||||||
type = &boolean_type;
|
|
||||||
+ len = BITS_PER_BYTE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
expr = expr_alloc(loc, EXPR_FIB, type,
|
|
||||||
BYTEORDER_HOST_ENDIAN, len);
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From 84642c28fab20ef3f0bef23919a45f7b7d7d18db Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] doc: fix tcpdump example
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b9516b0a4dfb6e16e3e11c3024683a2df1ea09ab
|
|
||||||
|
|
||||||
commit b9516b0a4dfb6e16e3e11c3024683a2df1ea09ab
|
|
||||||
Author: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
|
|
||||||
Date: Mon Oct 13 19:17:31 2025 +0200
|
|
||||||
|
|
||||||
doc: fix tcpdump example
|
|
||||||
|
|
||||||
The expression needs to be enclosed in a single string and combined with
|
|
||||||
a logical AND to have the desired effect.
|
|
||||||
|
|
||||||
Fixes: 1188a69604c3 ("src: introduce SYNPROXY matching")
|
|
||||||
Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
|
|
||||||
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/statements.txt | 3 +--
|
|
||||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/statements.txt b/doc/statements.txt
|
|
||||||
index 3aceb02..ad928eb 100644
|
|
||||||
--- a/doc/statements.txt
|
|
||||||
+++ b/doc/statements.txt
|
|
||||||
@@ -592,8 +592,7 @@ needed for selective acknowledgement and window scaling).
|
|
||||||
---------------------------------------
|
|
||||||
Determine tcp options used by backend, from an external system
|
|
||||||
|
|
||||||
- tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack)'
|
|
||||||
- port 80 &
|
|
||||||
+ tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack) && port 80' &
|
|
||||||
telnet 192.0.2.42 80
|
|
||||||
18:57:24.693307 IP 192.0.2.42.80 > 192.0.2.43.48757:
|
|
||||||
Flags [S.], seq 360414582, ack 788841994, win 14480,
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
From 32ab7685f938713f927c1ed312ba6089cb2cf65b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] src: parser_json: fix format string bugs
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b30ad0c25b7b4a289dd73e8da6fa101b66fbf0d7
|
|
||||||
|
|
||||||
commit b30ad0c25b7b4a289dd73e8da6fa101b66fbf0d7
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Thu Oct 23 14:17:00 2025 +0200
|
|
||||||
|
|
||||||
src: parser_json: fix format string bugs
|
|
||||||
|
|
||||||
After adding fmt attribute annotation:
|
|
||||||
warning: format not a string literal and no format arguments [-Wformat-security]
|
|
||||||
131 | erec_queue(error(&loc, err->text), ctx->msgs);
|
|
||||||
In function 'json_events_cb':
|
|
||||||
warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type '__u32' {aka 'unsigned int'} [-Wformat=]
|
|
||||||
|
|
||||||
Fix that up too.
|
|
||||||
|
|
||||||
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_json.c | 5 +++--
|
|
||||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 8c9d365..cce5ee2 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -127,7 +127,7 @@ static void json_lib_error(struct json_ctx *ctx, json_error_t *err)
|
|
||||||
.last_column = err->column,
|
|
||||||
};
|
|
||||||
|
|
||||||
- erec_queue(error(&loc, err->text), ctx->msgs);
|
|
||||||
+ erec_queue(error(&loc, "%s", err->text), ctx->msgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((format(printf, 2, 3)))
|
|
||||||
@@ -4176,6 +4176,7 @@ int nft_parse_json_filename(struct nft_ctx *nft, const char *filename,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+__attribute__((format(printf, 2, 3)))
|
|
||||||
static int json_echo_error(struct netlink_mon_handler *monh,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
@@ -4242,7 +4243,7 @@ int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh)
|
|
||||||
|
|
||||||
json = seqnum_to_json(nlh->nlmsg_seq);
|
|
||||||
if (!json) {
|
|
||||||
- json_echo_error(monh, "No JSON command found with seqnum %lu\n",
|
|
||||||
+ json_echo_error(monh, "No JSON command found with seqnum %u\n",
|
|
||||||
nlh->nlmsg_seq);
|
|
||||||
return MNL_CB_OK;
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
From 247ed03d1d9e2c03744d7c47db95be813f17ce54 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] datatype: clamp boolean value to 0 and 1
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit afb6a8e66a11178cbdbfc152c4aa9dda961b2140
|
|
||||||
|
|
||||||
commit afb6a8e66a11178cbdbfc152c4aa9dda961b2140
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Fri Jan 31 12:54:32 2025 +0100
|
|
||||||
|
|
||||||
datatype: clamp boolean value to 0 and 1
|
|
||||||
|
|
||||||
If user provides a numeric value larger than 0 or 1, match never
|
|
||||||
happens:
|
|
||||||
|
|
||||||
# nft --debug=netlink add rule x y tcp option sack-perm 4
|
|
||||||
ip x y
|
|
||||||
[ exthdr load tcpopt 1b @ 4 + 0 present => reg 1 ]
|
|
||||||
[ cmp eq reg 1 0x00000004 ]
|
|
||||||
|
|
||||||
After this update:
|
|
||||||
|
|
||||||
# nft --debug=netlink add rule x y tcp option sack-perm 4
|
|
||||||
ip x y
|
|
||||||
[ exthdr load tcpopt 1b @ 4 + 0 present => reg 1 ]
|
|
||||||
[ cmp eq reg 1 0x00000001 ]
|
|
||||||
|
|
||||||
This is to address a rare corner case, in case user specifies the
|
|
||||||
boolean value through the integer base type.
|
|
||||||
|
|
||||||
Fixes: 9fd9baba43c8 ("Introduce boolean datatype and boolean expression")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/datatype.c | 24 ++++++++++++++++++++++++
|
|
||||||
1 file changed, 24 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/datatype.c b/src/datatype.c
|
|
||||||
index 9530ae7..93703f8 100644
|
|
||||||
--- a/src/datatype.c
|
|
||||||
+++ b/src/datatype.c
|
|
||||||
@@ -1417,11 +1417,35 @@ static const struct symbol_table boolean_tbl = {
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct error_record *boolean_type_parse(struct parse_ctx *ctx,
|
|
||||||
+ const struct expr *sym,
|
|
||||||
+ struct expr **res)
|
|
||||||
+{
|
|
||||||
+ struct error_record *erec;
|
|
||||||
+ int num;
|
|
||||||
+
|
|
||||||
+ erec = integer_type_parse(ctx, sym, res);
|
|
||||||
+ if (erec)
|
|
||||||
+ return erec;
|
|
||||||
+
|
|
||||||
+ if (mpz_cmp_ui((*res)->value, 0))
|
|
||||||
+ num = 1;
|
|
||||||
+ else
|
|
||||||
+ num = 0;
|
|
||||||
+
|
|
||||||
+ expr_free(*res);
|
|
||||||
+
|
|
||||||
+ *res = constant_expr_alloc(&sym->location, &boolean_type,
|
|
||||||
+ BYTEORDER_HOST_ENDIAN, 1, &num);
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
const struct datatype boolean_type = {
|
|
||||||
.type = TYPE_BOOLEAN,
|
|
||||||
.name = "boolean",
|
|
||||||
.desc = "boolean type",
|
|
||||||
.size = 1,
|
|
||||||
+ .parse = boolean_type_parse,
|
|
||||||
.basetype = &integer_type,
|
|
||||||
.sym_tbl = &boolean_tbl,
|
|
||||||
.json = boolean_type_json,
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From d48369a36876854039882dc8981f49c7e42574c5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] datatype: Fix boolean type on Big Endian
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit aec699af2a006b1dd6580abb95910c402e306fa9
|
|
||||||
|
|
||||||
commit aec699af2a006b1dd6580abb95910c402e306fa9
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Oct 8 23:19:08 2025 +0200
|
|
||||||
|
|
||||||
datatype: Fix boolean type on Big Endian
|
|
||||||
|
|
||||||
Pass a reference to a variable with correct size when creating the
|
|
||||||
expression, otherwise mpz_import_data() will read only the always zero
|
|
||||||
upper byte on Big Endian hosts.
|
|
||||||
|
|
||||||
Fixes: afb6a8e66a111 ("datatype: clamp boolean value to 0 and 1")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/datatype.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/datatype.c b/src/datatype.c
|
|
||||||
index 93703f8..bb93ef3 100644
|
|
||||||
--- a/src/datatype.c
|
|
||||||
+++ b/src/datatype.c
|
|
||||||
@@ -1422,7 +1422,7 @@ static struct error_record *boolean_type_parse(struct parse_ctx *ctx,
|
|
||||||
struct expr **res)
|
|
||||||
{
|
|
||||||
struct error_record *erec;
|
|
||||||
- int num;
|
|
||||||
+ uint8_t num;
|
|
||||||
|
|
||||||
erec = integer_type_parse(ctx, sym, res);
|
|
||||||
if (erec)
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
From 6fdf4d2a6a114044a9932d5031d6d461e12505df Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] optimize: Fix verdict expression comparison
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 695ee5a8b174f86e2e64786530147e56d8d27f19
|
|
||||||
|
|
||||||
commit 695ee5a8b174f86e2e64786530147e56d8d27f19
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Oct 22 14:03:37 2025 +0200
|
|
||||||
|
|
||||||
optimize: Fix verdict expression comparison
|
|
||||||
|
|
||||||
In verdict expression, 'chain' points at a constant expression of
|
|
||||||
verdict_type, not a symbol expression. Therefore 'chain->identifier'
|
|
||||||
points eight bytes (on 64bit systems) into the mpz_t 'value' holding the
|
|
||||||
chain name. This matches the '_mp_d' data pointer, so works by accident.
|
|
||||||
|
|
||||||
Fix this by copying what verdict_jump_chain_print() does and export
|
|
||||||
chain names before comparing.
|
|
||||||
|
|
||||||
Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/optimize.c | 11 ++++++++---
|
|
||||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/optimize.c b/src/optimize.c
|
|
||||||
index 27e0ffe..7b4d036 100644
|
|
||||||
--- a/src/optimize.c
|
|
||||||
+++ b/src/optimize.c
|
|
||||||
@@ -302,13 +302,18 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
|
|
||||||
|
|
||||||
static bool expr_verdict_eq(const struct expr *expr_a, const struct expr *expr_b)
|
|
||||||
{
|
|
||||||
+ char chain_a[NFT_CHAIN_MAXNAMELEN];
|
|
||||||
+ char chain_b[NFT_CHAIN_MAXNAMELEN];
|
|
||||||
+
|
|
||||||
if (expr_a->verdict != expr_b->verdict)
|
|
||||||
return false;
|
|
||||||
if (expr_a->chain && expr_b->chain) {
|
|
||||||
- if (expr_a->chain->etype != expr_b->chain->etype)
|
|
||||||
+ if (expr_a->chain->etype != EXPR_VALUE ||
|
|
||||||
+ expr_a->chain->etype != expr_b->chain->etype)
|
|
||||||
return false;
|
|
||||||
- if (expr_a->chain->etype == EXPR_VALUE &&
|
|
||||||
- strcmp(expr_a->chain->identifier, expr_b->chain->identifier))
|
|
||||||
+ expr_chain_export(expr_a->chain, chain_a);
|
|
||||||
+ expr_chain_export(expr_b->chain, chain_b);
|
|
||||||
+ if (strcmp(chain_a, chain_b))
|
|
||||||
return false;
|
|
||||||
} else if (expr_a->chain || expr_b->chain) {
|
|
||||||
return false;
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
From 6f5224890b16acddb72ce4c02a6ffc3c2afa12cb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] tests: py: any/ct.t.json.output: Drop leftover entry
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 1801480314bf2baa6abf9cb15ccdef975b966867
|
|
||||||
|
|
||||||
commit 1801480314bf2baa6abf9cb15ccdef975b966867
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Oct 16 16:23:12 2025 +0200
|
|
||||||
|
|
||||||
tests: py: any/ct.t.json.output: Drop leftover entry
|
|
||||||
|
|
||||||
The rule with single element anonymous set was replaced, drop this
|
|
||||||
leftover.
|
|
||||||
|
|
||||||
Fixes: 27f6a4c68b4fd ("tests: replace single element sets")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/any/ct.t.json.output | 33 ---------------------------------
|
|
||||||
1 file changed, 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/py/any/ct.t.json.output b/tests/py/any/ct.t.json.output
|
|
||||||
index 70ade7e..82634c2 100644
|
|
||||||
--- a/tests/py/any/ct.t.json.output
|
|
||||||
+++ b/tests/py/any/ct.t.json.output
|
|
||||||
@@ -471,39 +471,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# ct state . ct mark { new . 0x12345678}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "concat": [
|
|
||||||
- {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "state"
|
|
||||||
- }
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "ct": {
|
|
||||||
- "key": "mark"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- {
|
|
||||||
- "concat": [
|
|
||||||
- "new",
|
|
||||||
- 305419896
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# ct state . ct mark { new . 0x12345678, new . 0x34127856, established . 0x12785634}
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
From 9811fa070a0e2b0f33e719080e9f10cda366ca58 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] tests: py: inet/osf.t: Fix element ordering in JSON
|
|
||||||
equivalents
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b028f8ce616bb5a219a10844357b9a3822d99a8c
|
|
||||||
|
|
||||||
commit b028f8ce616bb5a219a10844357b9a3822d99a8c
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Oct 9 02:06:54 2025 +0200
|
|
||||||
|
|
||||||
tests: py: inet/osf.t: Fix element ordering in JSON equivalents
|
|
||||||
|
|
||||||
The original rules order set elements differently. Stick to that and add
|
|
||||||
entries to inet/osf.t.json.output to cover for nftables reordering
|
|
||||||
entries.
|
|
||||||
|
|
||||||
Fixes: 92029c1282958 ("src: osf: add json support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/py/inet/osf.t.json | 12 ++++----
|
|
||||||
tests/py/inet/osf.t.json.output | 53 +++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 59 insertions(+), 6 deletions(-)
|
|
||||||
create mode 100644 tests/py/inet/osf.t.json.output
|
|
||||||
|
|
||||||
diff --git a/tests/py/inet/osf.t.json b/tests/py/inet/osf.t.json
|
|
||||||
index cedb7f6..b1bf747 100644
|
|
||||||
--- a/tests/py/inet/osf.t.json
|
|
||||||
+++ b/tests/py/inet/osf.t.json
|
|
||||||
@@ -73,8 +73,8 @@
|
|
||||||
"op": "==",
|
|
||||||
"right": {
|
|
||||||
"set": [
|
|
||||||
- "MacOs",
|
|
||||||
- "Windows"
|
|
||||||
+ "Windows",
|
|
||||||
+ "MacOs"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -114,13 +114,13 @@
|
|
||||||
"map": {
|
|
||||||
"data": {
|
|
||||||
"set": [
|
|
||||||
- [
|
|
||||||
- "MacOs",
|
|
||||||
- 2
|
|
||||||
- ],
|
|
||||||
[
|
|
||||||
"Windows",
|
|
||||||
1
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ "MacOs",
|
|
||||||
+ 2
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
diff --git a/tests/py/inet/osf.t.json.output b/tests/py/inet/osf.t.json.output
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..922e395
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/py/inet/osf.t.json.output
|
|
||||||
@@ -0,0 +1,53 @@
|
|
||||||
+# osf name { "Windows", "MacOs" }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "osf": {
|
|
||||||
+ "key": "name"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": {
|
|
||||||
+ "set": [
|
|
||||||
+ "MacOs",
|
|
||||||
+ "Windows"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+# ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "mangle": {
|
|
||||||
+ "key": {
|
|
||||||
+ "ct": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "value": {
|
|
||||||
+ "map": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ "MacOs",
|
|
||||||
+ 2
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ "Windows",
|
|
||||||
+ 1
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "osf": {
|
|
||||||
+ "key": "name"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
From 722fc9bde92c202e740ced94023fc2ad5a3ce343 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] doc: don't suggest to disable GSO
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 35cd3e7cff079c561ba616c792d5fdf13f6bd331
|
|
||||||
|
|
||||||
commit 35cd3e7cff079c561ba616c792d5fdf13f6bd331
|
|
||||||
Author: Ronan Pigott <ronan@rjp.ie>
|
|
||||||
Date: Sun Oct 6 09:36:03 2024 -0700
|
|
||||||
|
|
||||||
doc: don't suggest to disable GSO
|
|
||||||
|
|
||||||
The kernel can form aggregate packets whether or not GSO is enabled.
|
|
||||||
Disabling GSO is not a useful suggestion in this case.
|
|
||||||
|
|
||||||
Fixes: 05628cdd677d (doc: describe behaviour of {ip,ip6} length)
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/payload-expression.txt | 26 ++++++++++++--------------
|
|
||||||
1 file changed, 12 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
|
|
||||||
index 8afeb71..6733846 100644
|
|
||||||
--- a/doc/payload-expression.txt
|
|
||||||
+++ b/doc/payload-expression.txt
|
|
||||||
@@ -134,13 +134,12 @@ Destination address |
|
|
||||||
ipv4_addr
|
|
||||||
|======================
|
|
||||||
|
|
||||||
-Careful with matching on *ip length*: If GRO/GSO is enabled, then the Linux
|
|
||||||
-kernel might aggregate several packets into one big packet that is larger than
|
|
||||||
-MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8),
|
|
||||||
-specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip length* might
|
|
||||||
-be 0 for such jumbo packets. *meta length* allows you to match on the packet
|
|
||||||
-length including the IP header size. If you want to perform heuristics on the
|
|
||||||
-*ip length* field, then disable GRO/GSO.
|
|
||||||
+Careful with matching on *ip length*: The Linux kernel might aggregate several
|
|
||||||
+packets into one big packet that is larger than MTU. Moreover, if GRO/GSO
|
|
||||||
+maximum size is larger than 65535 (see man ip-link(8), specifically
|
|
||||||
+gro_ipv4_max_size and gso_ipv4_max_size), then *ip length* might be 0 for such
|
|
||||||
+jumbo packets. *meta length* allows you to match on the packet length including
|
|
||||||
+the IP header size.
|
|
||||||
|
|
||||||
ICMP HEADER EXPRESSION
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
@@ -252,13 +251,12 @@ Destination address |
|
|
||||||
ipv6_addr
|
|
||||||
|=======================
|
|
||||||
|
|
||||||
-Careful with matching on *ip6 length*: If GRO/GSO is enabled, then the Linux
|
|
||||||
-kernel might aggregate several packets into one big packet that is larger than
|
|
||||||
-MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8),
|
|
||||||
-specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip6 length* might
|
|
||||||
-be 0 for such jumbo packets. *meta length* allows you to match on the packet
|
|
||||||
-length including the IP header size. If you want to perform heuristics on the
|
|
||||||
-*ip6 length* field, then disable GRO/GSO.
|
|
||||||
+Careful with matching on *ip6 length*: The Linux kernel might aggregate several
|
|
||||||
+packets into one big packet that is larger than MTU. Moreover, if GRO/GSO
|
|
||||||
+maximum size is larger than 65535 (see man ip-link(8), specifically
|
|
||||||
+gro_max_size and gso_max_size), then *ip6 length* might be 0 for such
|
|
||||||
+jumbo packets. *meta length* allows you to match on the packet length including
|
|
||||||
+the IPv6 header size.
|
|
||||||
|
|
||||||
.Using ip6 header expressions
|
|
||||||
-----------------------------
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From 8287f290fe2883de894cd1f4388bed5a6076cc18 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] doc: libnftables-json: Describe RULESET object
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 454f361434522bbeba32e114a14c336e1ebf20a1
|
|
||||||
|
|
||||||
commit 454f361434522bbeba32e114a14c336e1ebf20a1
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Nov 6 12:14:56 2025 +0100
|
|
||||||
|
|
||||||
doc: libnftables-json: Describe RULESET object
|
|
||||||
|
|
||||||
Document the syntax of this meta-object used by "list" and "flush"
|
|
||||||
commands only.
|
|
||||||
|
|
||||||
Fixes: 872f373dc50f7 ("doc: Add JSON schema documentation")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
doc/libnftables-json.adoc | 12 ++++++++++++
|
|
||||||
1 file changed, 12 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
|
||||||
index 27c96c3..ada53c4 100644
|
|
||||||
--- a/doc/libnftables-json.adoc
|
|
||||||
+++ b/doc/libnftables-json.adoc
|
|
||||||
@@ -200,6 +200,18 @@ Rename a chain. The new name is expected in a dedicated property named
|
|
||||||
|
|
||||||
== RULESET ELEMENTS
|
|
||||||
|
|
||||||
+=== RULESET
|
|
||||||
+[verse]
|
|
||||||
+____
|
|
||||||
+*{ "ruleset":* 'RULSET_PROPERTIES' *}*
|
|
||||||
+
|
|
||||||
+'RULESET_PROPERTIES' := *null* | *{ "family":* 'STRING' *}*
|
|
||||||
+____
|
|
||||||
+
|
|
||||||
+This is a special object for use with *list* and *flush* commands which will
|
|
||||||
+then operate on either the whole ruleset or the parts of it belonging to the
|
|
||||||
+given family.
|
|
||||||
+
|
|
||||||
=== TABLE
|
|
||||||
[verse]
|
|
||||||
____
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From e4980d25274d5afc8360b0fd704f5d1b18d22ff6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] rule: skip CMD_OBJ_SETELEMS with no elements after set flush
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 8b7a533f8f8b276bfa71dcb306d6857e54015234
|
|
||||||
|
|
||||||
commit 8b7a533f8f8b276bfa71dcb306d6857e54015234
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Thu Nov 20 00:41:13 2025 +0100
|
|
||||||
|
|
||||||
rule: skip CMD_OBJ_SETELEMS with no elements after set flush
|
|
||||||
|
|
||||||
Set declaration + set flush results in a crash because CMD_OBJ_SETELEMS
|
|
||||||
does not expect no elements. This internal command only shows up if set
|
|
||||||
contains elements, however, evaluation flushes set content after the set
|
|
||||||
expansion. Skip this command CMD_OBJ_SETELEMS if set is empty.
|
|
||||||
|
|
||||||
Fixes: d3c8051cb767 ("rule: rework CMD_OBJ_SETELEMS logic")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/rule.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/rule.c b/src/rule.c
|
|
||||||
index 3b75736..0d6186a 100644
|
|
||||||
--- a/src/rule.c
|
|
||||||
+++ b/src/rule.c
|
|
||||||
@@ -1461,6 +1461,9 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
|
|
||||||
{
|
|
||||||
struct set *set = cmd->set;
|
|
||||||
|
|
||||||
+ if (!set->init)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
return __do_add_elements(ctx, cmd, set, set->init, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
From 00d91f581bd0f8df0796c10aa1bdaaa93097be69 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:19 +0200
|
|
||||||
Subject: [PATCH] tests: json_echo: Drop rule handle before multi-add
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit ad74cbd63a9782e8285f7198a5055d7947998b7f
|
|
||||||
|
|
||||||
commit ad74cbd63a9782e8285f7198a5055d7947998b7f
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Tue Jan 20 22:47:02 2026 +0100
|
|
||||||
|
|
||||||
tests: json_echo: Drop rule handle before multi-add
|
|
||||||
|
|
||||||
Now that JSON parser respects rule handles in explicit add commands, the
|
|
||||||
still present rule handle causes an error since the old rule does not
|
|
||||||
exist anymore.
|
|
||||||
|
|
||||||
Fixes: 50b5b71ebeee3 ("parser_json: Rewrite echo support")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
tests/json_echo/run-test.py | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/tests/json_echo/run-test.py b/tests/json_echo/run-test.py
|
|
||||||
index a6bdfc6..7217746 100755
|
|
||||||
--- a/tests/json_echo/run-test.py
|
|
||||||
+++ b/tests/json_echo/run-test.py
|
|
||||||
@@ -286,6 +286,7 @@ add_quota["add"]["quota"]["name"] = "q"
|
|
||||||
do_flush()
|
|
||||||
|
|
||||||
print("doing multi add")
|
|
||||||
+del(add_rule["add"]["rule"]["handle"])
|
|
||||||
add_multi = [ add_table, add_chain, add_set, add_rule ]
|
|
||||||
out = do_command(add_multi)
|
|
||||||
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
From 62de57c6207d475b952b54a668db811ac0933d89 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:20 +0200
|
|
||||||
Subject: [PATCH] monitor: fix memleak in setelem cb
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit d2a427c4abfadd2ce51bdab54c40fbf3d990c724
|
|
||||||
|
|
||||||
commit d2a427c4abfadd2ce51bdab54c40fbf3d990c724
|
|
||||||
Author: Florian Westphal <fw@strlen.de>
|
|
||||||
Date: Wed Jan 21 14:33:21 2026 +0100
|
|
||||||
|
|
||||||
monitor: fix memleak in setelem cb
|
|
||||||
|
|
||||||
since 4521732ebbf3 ("monitor: missing cache and set handle initialization")
|
|
||||||
these fields are set via handle_merge(), so don't clobber those
|
|
||||||
fields in json output case:
|
|
||||||
|
|
||||||
==31877==ERROR: LeakSanitizer: detected memory leaks
|
|
||||||
Direct leak of 16 byte(s) in 2 object(s) allocated from:
|
|
||||||
#0 0x7f0cb9f29d4b in strdup asan/asan_interceptors.cpp:593
|
|
||||||
#1 0x7f0cb9b584fd in xstrdup src/utils.c:80
|
|
||||||
#2 0x7f0cb9b355b3 in handle_merge src/rule.c:127
|
|
||||||
#3 0x7f0cb9ae12b8 in netlink_events_setelem_cb src/monitor.c:457
|
|
||||||
|
|
||||||
Seen when running tests/monitor with asan enabled.
|
|
||||||
|
|
||||||
Fixes: 4521732ebbf3 ("monitor: missing cache and set handle initialization")
|
|
||||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/monitor.c | 6 ------
|
|
||||||
1 file changed, 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/monitor.c b/src/monitor.c
|
|
||||||
index 87ff2a3..0b00207 100644
|
|
||||||
--- a/src/monitor.c
|
|
||||||
+++ b/src/monitor.c
|
|
||||||
@@ -476,13 +476,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type,
|
|
||||||
nft_mon_print(monh, "\n");
|
|
||||||
break;
|
|
||||||
case NFTNL_OUTPUT_JSON:
|
|
||||||
- dummyset->handle.family = family;
|
|
||||||
- dummyset->handle.set.name = setname;
|
|
||||||
- dummyset->handle.table.name = table;
|
|
||||||
monitor_print_element_json(monh, cmd, dummyset);
|
|
||||||
- /* prevent set_free() from trying to free those */
|
|
||||||
- dummyset->handle.set.name = NULL;
|
|
||||||
- dummyset->handle.table.name = NULL;
|
|
||||||
if (!nft_output_echo(&monh->ctx->nft->output))
|
|
||||||
nft_mon_print(monh, "\n");
|
|
||||||
break;
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
From 5cf2ee0c11f8d985b7b060db9ddf769f7e8e8ed0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:20 +0200
|
|
||||||
Subject: [PATCH] segtree: Fix range aggregation on Big Endian
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit e8b17865833b8c2b9f31a4dfb98069651572494d
|
|
||||||
|
|
||||||
commit e8b17865833b8c2b9f31a4dfb98069651572494d
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Tue Oct 21 18:36:10 2025 +0200
|
|
||||||
|
|
||||||
segtree: Fix range aggregation on Big Endian
|
|
||||||
|
|
||||||
Interface name wildcards are received as ranges from prefix with zero
|
|
||||||
padding to prefix with ones padding. E.g. with "abcd*" (in hex):
|
|
||||||
|
|
||||||
61626364000000000000000000000000 - 61626364ffffffffffffffffffffffff
|
|
||||||
|
|
||||||
The faulty code tries to export the prefix from the lower boundary (r1)
|
|
||||||
into a buffer, append "*" and allocate a constant expression from the
|
|
||||||
resulting string. This does not work on Big Endian though:
|
|
||||||
mpz_export_data() seems to zero-pad data upon export and not necessarily
|
|
||||||
respect the passed length value. Moreover, this padding appears in the
|
|
||||||
first bytes of the buffer. The amount of padding seems illogical, too:
|
|
||||||
While a 6B prefix causes 2B padding and 8B prefix no padding, 10B prefix
|
|
||||||
causes 4B padding and 12B prefix even 8B padding.
|
|
||||||
|
|
||||||
Work around the odd behaviour by exporting the full data into a larger
|
|
||||||
buffer.
|
|
||||||
|
|
||||||
A similar issue is caused by increasing the constant expression's length
|
|
||||||
to match the upper boundary data length: Data export when printing puts
|
|
||||||
the padding upfront, so the resulting string starts with NUL-chars.
|
|
||||||
Since this length adjustment seems not to have any effect in practice,
|
|
||||||
just drop it.
|
|
||||||
|
|
||||||
Fixes: 88b2345a215ef ("segtree: add pretty-print support for wildcard strings in concatenated sets")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/segtree.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/segtree.c b/src/segtree.c
|
|
||||||
index a3a0fb4..2b4c4af 100644
|
|
||||||
--- a/src/segtree.c
|
|
||||||
+++ b/src/segtree.c
|
|
||||||
@@ -408,16 +408,16 @@ void concat_range_aggregate(struct expr *set)
|
|
||||||
if (prefix_len >= 0 &&
|
|
||||||
(prefix_len % BITS_PER_BYTE) == 0 &&
|
|
||||||
string_type) {
|
|
||||||
+ unsigned int r1len = div_round_up(r1->len, BITS_PER_BYTE);
|
|
||||||
unsigned int str_len = prefix_len / BITS_PER_BYTE;
|
|
||||||
- char data[str_len + 2];
|
|
||||||
+ char data[r1len + 1] = {};
|
|
||||||
|
|
||||||
- mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, str_len);
|
|
||||||
+ mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, r1len);
|
|
||||||
data[str_len] = '*';
|
|
||||||
|
|
||||||
tmp = constant_expr_alloc(&r1->location, r1->dtype,
|
|
||||||
BYTEORDER_HOST_ENDIAN,
|
|
||||||
(str_len + 1) * BITS_PER_BYTE, data);
|
|
||||||
- tmp->len = r2->len;
|
|
||||||
list_replace(&r2->list, &tmp->list);
|
|
||||||
r2_next = tmp->list.next;
|
|
||||||
expr_free(r2);
|
|
||||||
@ -1,244 +0,0 @@
|
|||||||
From 01bd864e3c9daf0121516109af0e7aca1ebfae38 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:20 +0200
|
|
||||||
Subject: [PATCH] mergesort: Fix sorting of string values
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 340d904a974ed206fcc4d8ca32540762fd8e59e0
|
|
||||||
Conflicts: Dropped changes to non-existent dump files
|
|
||||||
|
|
||||||
commit 340d904a974ed206fcc4d8ca32540762fd8e59e0
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Nov 13 00:03:37 2025 +0100
|
|
||||||
|
|
||||||
mergesort: Fix sorting of string values
|
|
||||||
|
|
||||||
Sorting order was obviously wrong, e.g. "ppp0" ordered before "eth1".
|
|
||||||
Moreover, this happened on Little Endian only so sorting order actually
|
|
||||||
depended on host's byteorder. By reimporting string values as Big
|
|
||||||
Endian, both issues are fixed: On one hand, GMP-internal byteorder no
|
|
||||||
longer depends on host's byteorder, on the other comparing strings
|
|
||||||
really starts with the first character, not the last.
|
|
||||||
|
|
||||||
Fixes: 14ee0a979b622 ("src: sort set elements in netlink_get_setelems()")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mergesort.c | 7 +++
|
|
||||||
tests/py/any/meta.t.json.output | 54 -------------------
|
|
||||||
tests/py/any/queue.t.json.output | 4 +-
|
|
||||||
tests/py/inet/osf.t.json.output | 54 +++++++++++++++++++
|
|
||||||
.../shell/testcases/maps/dumps/0012map_0.nft | 8 +--
|
|
||||||
.../sets/dumps/sets_with_ifnames.nft | 2 +-
|
|
||||||
6 files changed, 68 insertions(+), 61 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/mergesort.c b/src/mergesort.c
|
|
||||||
index 4d0e280..4157b5b 100644
|
|
||||||
--- a/src/mergesort.c
|
|
||||||
+++ b/src/mergesort.c
|
|
||||||
@@ -37,6 +37,13 @@ static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
|
|
||||||
case EXPR_RANGE:
|
|
||||||
return expr_msort_value(expr->left, value);
|
|
||||||
case EXPR_VALUE:
|
|
||||||
+ if (expr_basetype(expr)->type == TYPE_STRING) {
|
|
||||||
+ char buf[expr->len];
|
|
||||||
+
|
|
||||||
+ mpz_export_data(buf, expr->value, BYTEORDER_HOST_ENDIAN, expr->len);
|
|
||||||
+ mpz_import_data(value, buf, BYTEORDER_BIG_ENDIAN, expr->len);
|
|
||||||
+ return value;
|
|
||||||
+ }
|
|
||||||
return expr->value;
|
|
||||||
case EXPR_CONCAT:
|
|
||||||
concat_expr_msort_value(expr, value);
|
|
||||||
diff --git a/tests/py/any/meta.t.json.output b/tests/py/any/meta.t.json.output
|
|
||||||
index 4e9e669..329073e 100644
|
|
||||||
--- a/tests/py/any/meta.t.json.output
|
|
||||||
+++ b/tests/py/any/meta.t.json.output
|
|
||||||
@@ -233,60 +233,6 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
-# meta iifname {"dummy0", "lo"}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": { "key": "iifname" }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- "lo",
|
|
||||||
- "dummy0"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# meta iifname != {"dummy0", "lo"}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": { "key": "iifname" }
|
|
||||||
- },
|
|
||||||
- "op": "!=",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- "lo",
|
|
||||||
- "dummy0"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
-# meta oifname { "dummy0", "lo"}
|
|
||||||
-[
|
|
||||||
- {
|
|
||||||
- "match": {
|
|
||||||
- "left": {
|
|
||||||
- "meta": { "key": "oifname" }
|
|
||||||
- },
|
|
||||||
- "op": "==",
|
|
||||||
- "right": {
|
|
||||||
- "set": [
|
|
||||||
- "lo",
|
|
||||||
- "dummy0"
|
|
||||||
- ]
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-]
|
|
||||||
-
|
|
||||||
# meta skuid {"bin", "root", "daemon"} accept
|
|
||||||
[
|
|
||||||
{
|
|
||||||
diff --git a/tests/py/any/queue.t.json.output b/tests/py/any/queue.t.json.output
|
|
||||||
index ea37223..90670cc 100644
|
|
||||||
--- a/tests/py/any/queue.t.json.output
|
|
||||||
+++ b/tests/py/any/queue.t.json.output
|
|
||||||
@@ -104,11 +104,11 @@
|
|
||||||
0
|
|
||||||
],
|
|
||||||
[
|
|
||||||
- "ppp0",
|
|
||||||
+ "eth1",
|
|
||||||
2
|
|
||||||
],
|
|
||||||
[
|
|
||||||
- "eth1",
|
|
||||||
+ "ppp0",
|
|
||||||
2
|
|
||||||
]
|
|
||||||
]
|
|
||||||
diff --git a/tests/py/inet/osf.t.json.output b/tests/py/inet/osf.t.json.output
|
|
||||||
index 922e395..77ca7e3 100644
|
|
||||||
--- a/tests/py/inet/osf.t.json.output
|
|
||||||
+++ b/tests/py/inet/osf.t.json.output
|
|
||||||
@@ -18,6 +18,26 @@
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
+# osf version { "Windows:XP", "MacOs:Sierra" }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "match": {
|
|
||||||
+ "left": {
|
|
||||||
+ "osf": {
|
|
||||||
+ "key": "version"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "op": "==",
|
|
||||||
+ "right": {
|
|
||||||
+ "set": [
|
|
||||||
+ "MacOs:Sierra",
|
|
||||||
+ "Windows:XP"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
# ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
|
|
||||||
[
|
|
||||||
{
|
|
||||||
@@ -51,3 +71,37 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
+
|
|
||||||
+# ct mark set osf version map { "Windows:XP" : 0x00000003, "MacOs:Sierra" : 0x00000004 }
|
|
||||||
+[
|
|
||||||
+ {
|
|
||||||
+ "mangle": {
|
|
||||||
+ "key": {
|
|
||||||
+ "ct": {
|
|
||||||
+ "key": "mark"
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "value": {
|
|
||||||
+ "map": {
|
|
||||||
+ "data": {
|
|
||||||
+ "set": [
|
|
||||||
+ [
|
|
||||||
+ "MacOs:Sierra",
|
|
||||||
+ 4
|
|
||||||
+ ],
|
|
||||||
+ [
|
|
||||||
+ "Windows:XP",
|
|
||||||
+ 3
|
|
||||||
+ ]
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ "key": {
|
|
||||||
+ "osf": {
|
|
||||||
+ "key": "version"
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+]
|
|
||||||
diff --git a/tests/shell/testcases/maps/dumps/0012map_0.nft b/tests/shell/testcases/maps/dumps/0012map_0.nft
|
|
||||||
index 895490c..b199a00 100644
|
|
||||||
--- a/tests/shell/testcases/maps/dumps/0012map_0.nft
|
|
||||||
+++ b/tests/shell/testcases/maps/dumps/0012map_0.nft
|
|
||||||
@@ -1,9 +1,9 @@
|
|
||||||
table ip x {
|
|
||||||
map z {
|
|
||||||
type ifname : verdict
|
|
||||||
- elements = { "lo" : accept,
|
|
||||||
- "eth0" : drop,
|
|
||||||
- "eth1" : drop }
|
|
||||||
+ elements = { "eth0" : drop,
|
|
||||||
+ "eth1" : drop,
|
|
||||||
+ "lo" : accept }
|
|
||||||
}
|
|
||||||
|
|
||||||
map w {
|
|
||||||
@@ -14,7 +14,7 @@ table ip x {
|
|
||||||
}
|
|
||||||
|
|
||||||
chain y {
|
|
||||||
- iifname vmap { "lo" : accept, "eth0" : drop, "eth1" : drop }
|
|
||||||
+ iifname vmap { "eth0" : drop, "eth1" : drop, "lo" : accept }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain k {
|
|
||||||
diff --git a/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
|
|
||||||
index 77a8baf..8abca03 100644
|
|
||||||
--- a/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
|
|
||||||
+++ b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
|
|
||||||
@@ -39,7 +39,7 @@ table inet testifsets {
|
|
||||||
chain v4icmp {
|
|
||||||
iifname @simple counter packets 0 bytes 0
|
|
||||||
iifname @simple_wild counter packets 0 bytes 0
|
|
||||||
- iifname { "eth0", "abcdef0" } counter packets 0 bytes 0
|
|
||||||
+ iifname { "abcdef0", "eth0" } counter packets 0 bytes 0
|
|
||||||
iifname { "abcdef*", "eth0" } counter packets 0 bytes 0
|
|
||||||
iifname vmap @map_wild
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
From c0a28182c114262bc1d4f4557091b0f0ab71c656 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:36 +0200
|
|
||||||
Subject: [PATCH] optimize: expand expression list when merging into
|
|
||||||
concatenation
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 0d17d28bb06bf2a04862d5cd879a14bcb9a2d2dc
|
|
||||||
Conflicts: Drop changes to non-existent dump file
|
|
||||||
|
|
||||||
commit 0d17d28bb06bf2a04862d5cd879a14bcb9a2d2dc
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Tue Apr 1 18:11:45 2025 +0200
|
|
||||||
|
|
||||||
optimize: expand expression list when merging into concatenation
|
|
||||||
|
|
||||||
The following rules:
|
|
||||||
|
|
||||||
udp dport 137 ct state new,untracked accept
|
|
||||||
udp dport 138 ct state new,untracked accept
|
|
||||||
|
|
||||||
results in:
|
|
||||||
|
|
||||||
nft: src/optimize.c:670: __merge_concat: Assertion `0' failed.
|
|
||||||
|
|
||||||
The logic to expand to the new,untracked list in the concatenation is
|
|
||||||
missing.
|
|
||||||
|
|
||||||
Fixes: 187c6d01d357 ("optimize: expand implicit set element when merging into concatenation")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/optimize.c | 10 ++++++++++
|
|
||||||
.../optimizations/dumps/merge_stmts_concat.nft | 1 +
|
|
||||||
tests/shell/testcases/optimizations/merge_stmts_concat | 2 ++
|
|
||||||
3 files changed, 13 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/optimize.c b/src/optimize.c
|
|
||||||
index 7b4d036..dd96fc7 100644
|
|
||||||
--- a/src/optimize.c
|
|
||||||
+++ b/src/optimize.c
|
|
||||||
@@ -635,6 +635,16 @@ static void __merge_concat(const struct optimize_ctx *ctx, uint32_t i,
|
|
||||||
clone = expr_clone(stmt_a->expr->right);
|
|
||||||
compound_expr_add(concat, clone);
|
|
||||||
break;
|
|
||||||
+ case EXPR_LIST:
|
|
||||||
+ list_for_each_entry(expr, &stmt_a->expr->right->expressions, list) {
|
|
||||||
+ concat_clone = expr_clone(concat);
|
|
||||||
+ clone = expr_clone(expr);
|
|
||||||
+ compound_expr_add(concat_clone, clone);
|
|
||||||
+ list_add_tail(&concat_clone->list, &pending_list);
|
|
||||||
+ }
|
|
||||||
+ list_del(&concat->list);
|
|
||||||
+ expr_free(concat);
|
|
||||||
+ break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
break;
|
|
||||||
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
index f56cea1..d00ac41 100644
|
|
||||||
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
@@ -2,6 +2,7 @@ table ip x {
|
|
||||||
chain y {
|
|
||||||
iifname . ip saddr . ip daddr { "eth1" . 1.1.1.1 . 2.2.2.3, "eth1" . 1.1.1.2 . 2.2.2.4, "eth1" . 1.1.1.2 . 2.2.3.0/24, "eth1" . 1.1.1.2 . 2.2.4.0-2.2.4.10, "eth2" . 1.1.1.3 . 2.2.2.5 } accept
|
|
||||||
ip protocol . th dport { tcp . 22, udp . 67 }
|
|
||||||
+ udp dport . ct state { 137 . new, 138 . new, 137 . untracked, 138 . untracked } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c1 {
|
|
||||||
diff --git a/tests/shell/testcases/optimizations/merge_stmts_concat b/tests/shell/testcases/optimizations/merge_stmts_concat
|
|
||||||
index 9679d86..1fd1a30 100755
|
|
||||||
--- a/tests/shell/testcases/optimizations/merge_stmts_concat
|
|
||||||
+++ b/tests/shell/testcases/optimizations/merge_stmts_concat
|
|
||||||
@@ -10,6 +10,8 @@ RULESET="table ip x {
|
|
||||||
meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.4.0-2.2.4.10 accept
|
|
||||||
meta iifname eth2 ip saddr 1.1.1.3 ip daddr 2.2.2.5 accept
|
|
||||||
ip protocol . th dport { tcp . 22, udp . 67 }
|
|
||||||
+ udp dport 137 ct state new,untracked accept
|
|
||||||
+ udp dport 138 ct state new,untracked accept
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
|
|
||||||
@ -1,228 +0,0 @@
|
|||||||
From b676be66a623fd718cb7bc5875e9193e8c4f0b35 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:32:51 +0200
|
|
||||||
Subject: [PATCH] mergesort: Align concatenation sort order with Big Endian
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 0d819bcbbf36d324b5344ac29bd82a5017098c4b
|
|
||||||
Conflicts: Drop changes to non-existent dumps and test cases
|
|
||||||
|
|
||||||
commit 0d819bcbbf36d324b5344ac29bd82a5017098c4b
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Thu Nov 13 00:14:43 2025 +0100
|
|
||||||
|
|
||||||
mergesort: Align concatenation sort order with Big Endian
|
|
||||||
|
|
||||||
By exporting all concat components in a way independent from host
|
|
||||||
byteorder and importing that blob of data in the same way aligns sort
|
|
||||||
order between hosts of different Endianness.
|
|
||||||
|
|
||||||
Fixes: 741a06ac15d2b ("mergesort: find base value expression type via recursion")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mergesort.c | 4 ++--
|
|
||||||
tests/py/any/ct.t.json.output | 20 +++++++++----------
|
|
||||||
.../testcases/maps/dumps/typeof_integer_0.nft | 4 ++--
|
|
||||||
.../nft-f/dumps/0012different_defines_0.nft | 2 +-
|
|
||||||
.../optimizations/dumps/merge_reject.nft | 4 ++--
|
|
||||||
.../dumps/merge_stmts_concat.nft | 8 ++++----
|
|
||||||
.../dumps/merge_stmts_concat_vmap.nft | 2 +-
|
|
||||||
.../sets/dumps/0029named_ifname_dtype_0.nft | 4 ++--
|
|
||||||
.../dumps/0037_set_with_inet_service_0.nft | 8 ++++----
|
|
||||||
9 files changed, 28 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/mergesort.c b/src/mergesort.c
|
|
||||||
index 4157b5b..5c4cfeb 100644
|
|
||||||
--- a/src/mergesort.c
|
|
||||||
+++ b/src/mergesort.c
|
|
||||||
@@ -20,11 +20,11 @@ static void concat_expr_msort_value(const struct expr *expr, mpz_t value)
|
|
||||||
|
|
||||||
list_for_each_entry(i, &expr->expressions, list) {
|
|
||||||
ilen = div_round_up(i->len, BITS_PER_BYTE);
|
|
||||||
- mpz_export_data(data + len, i->value, i->byteorder, ilen);
|
|
||||||
+ mpz_export_data(data + len, i->value, BYTEORDER_BIG_ENDIAN, ilen);
|
|
||||||
len += ilen;
|
|
||||||
}
|
|
||||||
|
|
||||||
- mpz_import_data(value, data, BYTEORDER_HOST_ENDIAN, len);
|
|
||||||
+ mpz_import_data(value, data, BYTEORDER_BIG_ENDIAN, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
|
|
||||||
diff --git a/tests/py/any/ct.t.json.output b/tests/py/any/ct.t.json.output
|
|
||||||
index 82634c2..3f79593 100644
|
|
||||||
--- a/tests/py/any/ct.t.json.output
|
|
||||||
+++ b/tests/py/any/ct.t.json.output
|
|
||||||
@@ -494,14 +494,14 @@
|
|
||||||
"set": [
|
|
||||||
{
|
|
||||||
"concat": [
|
|
||||||
- "new",
|
|
||||||
- 305419896
|
|
||||||
+ "established",
|
|
||||||
+ 309876276
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"concat": [
|
|
||||||
- "established",
|
|
||||||
- 309876276
|
|
||||||
+ "new",
|
|
||||||
+ 305419896
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
@@ -578,23 +578,23 @@
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"concat": [
|
|
||||||
- "new",
|
|
||||||
- 305419896
|
|
||||||
+ "established",
|
|
||||||
+ 2271560481
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
- "drop": null
|
|
||||||
+ "accept": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"concat": [
|
|
||||||
- "established",
|
|
||||||
- 2271560481
|
|
||||||
+ "new",
|
|
||||||
+ 305419896
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
- "accept": null
|
|
||||||
+ "drop": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
|
|
||||||
index 19c24fe..7bd7daa 100644
|
|
||||||
--- a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
|
|
||||||
+++ b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
|
|
||||||
@@ -8,8 +8,8 @@ table inet t {
|
|
||||||
|
|
||||||
map m2 {
|
|
||||||
typeof udp length . @ih,32,32 : verdict
|
|
||||||
- elements = { 30 . 0x1e : drop,
|
|
||||||
- 20 . 0x24 : accept }
|
|
||||||
+ elements = { 20 . 0x24 : accept,
|
|
||||||
+ 30 . 0x1e : drop }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c {
|
|
||||||
diff --git a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
|
|
||||||
index 4734b2f..a6e16e7 100644
|
|
||||||
--- a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
|
|
||||||
+++ b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
|
|
||||||
@@ -8,7 +8,7 @@ table inet t {
|
|
||||||
ip6 daddr fe0::1 ip6 saddr fe0::2
|
|
||||||
ip saddr vmap { 10.0.0.0 : drop, 10.0.0.2 : accept }
|
|
||||||
ip6 daddr vmap { fe0::1 : drop, fe0::2 : accept }
|
|
||||||
- ip6 saddr . ip6 nexthdr { fe0::2 . tcp, fe0::1 . udp }
|
|
||||||
+ ip6 saddr . ip6 nexthdr { fe0::1 . udp, fe0::2 . tcp }
|
|
||||||
ip daddr . iif vmap { 10.0.0.0 . "lo" : accept }
|
|
||||||
tcp dport 100-222
|
|
||||||
udp dport vmap { 100-222 : accept }
|
|
||||||
diff --git a/tests/shell/testcases/optimizations/dumps/merge_reject.nft b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
|
|
||||||
index c29ad6d..1727d02 100644
|
|
||||||
--- a/tests/shell/testcases/optimizations/dumps/merge_reject.nft
|
|
||||||
+++ b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
|
|
||||||
@@ -1,13 +1,13 @@
|
|
||||||
table ip x {
|
|
||||||
chain y {
|
|
||||||
ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
|
|
||||||
- meta l4proto . ip daddr . tcp dport { tcp . 172.30.238.117 . 8080, tcp . 172.30.33.71 . 3306, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
|
|
||||||
+ meta l4proto . ip daddr . tcp dport { tcp . 172.30.33.71 . 3306, tcp . 172.30.238.117 . 8080, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
|
|
||||||
ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table ip6 x {
|
|
||||||
chain y {
|
|
||||||
- meta l4proto . ip6 daddr . tcp dport { tcp . aaaa::3 . 8080, tcp . aaaa::2 . 3306, tcp . aaaa::4 . 3306 } counter packets 0 bytes 0 reject
|
|
||||||
+ meta l4proto . ip6 daddr . tcp dport { tcp . aaaa::2 . 3306, tcp . aaaa::3 . 8080, tcp . aaaa::4 . 3306 } counter packets 0 bytes 0 reject
|
|
||||||
ip6 daddr aaaa::5 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
index d00ac41..6150258 100644
|
|
||||||
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
|
|
||||||
@@ -2,18 +2,18 @@ table ip x {
|
|
||||||
chain y {
|
|
||||||
iifname . ip saddr . ip daddr { "eth1" . 1.1.1.1 . 2.2.2.3, "eth1" . 1.1.1.2 . 2.2.2.4, "eth1" . 1.1.1.2 . 2.2.3.0/24, "eth1" . 1.1.1.2 . 2.2.4.0-2.2.4.10, "eth2" . 1.1.1.3 . 2.2.2.5 } accept
|
|
||||||
ip protocol . th dport { tcp . 22, udp . 67 }
|
|
||||||
- udp dport . ct state { 137 . new, 138 . new, 137 . untracked, 138 . untracked } accept
|
|
||||||
+ udp dport . ct state { 137 . new, 137 . untracked, 138 . new, 138 . untracked } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c1 {
|
|
||||||
- udp dport . iifname { 51820 . "foo", 514 . "bar", 67 . "bar" } accept
|
|
||||||
+ udp dport . iifname { 67 . "bar", 514 . "bar", 51820 . "foo" } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c2 {
|
|
||||||
- udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar" } accept
|
|
||||||
+ udp dport . iifname { 67 . "bar", 100 . "foo", 514 . "bar", 51820 . "foo" } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain c3 {
|
|
||||||
- udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar", 100 . "test", 51820 . "test" } accept
|
|
||||||
+ udp dport . iifname { 67 . "bar", 100 . "foo", 100 . "test", 514 . "bar", 51820 . "foo", 51820 . "test" } accept
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
|
|
||||||
index 780aa09..81abb99 100644
|
|
||||||
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
|
|
||||||
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
table ip x {
|
|
||||||
chain x {
|
|
||||||
- meta pkttype . udp dport vmap { broadcast . 547 : accept, broadcast . 67 : accept, multicast . 1900 : drop }
|
|
||||||
+ meta pkttype . udp dport vmap { broadcast . 67 : accept, broadcast . 547 : accept, multicast . 1900 : drop }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain y {
|
|
||||||
diff --git a/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
|
|
||||||
index 55cd4f2..0ea2926 100644
|
|
||||||
--- a/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
|
|
||||||
+++ b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
|
|
||||||
@@ -12,8 +12,8 @@ table inet t {
|
|
||||||
type inet_service . ifname
|
|
||||||
elements = { 22 . "eth0",
|
|
||||||
80 . "eth0",
|
|
||||||
- 81 . "eth0",
|
|
||||||
- 80 . "eth1" }
|
|
||||||
+ 80 . "eth1",
|
|
||||||
+ 81 . "eth0" }
|
|
||||||
}
|
|
||||||
|
|
||||||
set nv {
|
|
||||||
diff --git a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
|
|
||||||
index 68b1f7b..0e85f7c 100644
|
|
||||||
--- a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
|
|
||||||
+++ b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
|
|
||||||
@@ -1,11 +1,11 @@
|
|
||||||
table inet filter {
|
|
||||||
set myset {
|
|
||||||
type ipv4_addr . inet_proto . inet_service
|
|
||||||
- elements = { 192.168.0.113 . tcp . 22,
|
|
||||||
- 192.168.0.12 . tcp . 53,
|
|
||||||
- 192.168.0.12 . udp . 53,
|
|
||||||
+ elements = { 192.168.0.12 . tcp . 53,
|
|
||||||
192.168.0.12 . tcp . 80,
|
|
||||||
- 192.168.0.13 . tcp . 80 }
|
|
||||||
+ 192.168.0.12 . udp . 53,
|
|
||||||
+ 192.168.0.13 . tcp . 80,
|
|
||||||
+ 192.168.0.113 . tcp . 22 }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain forward {
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From d4c926c17ef1383d37d1c101f12b0d4b5712546c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:22 +0200
|
|
||||||
Subject: [PATCH] json: complete multi-statement set element support
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 14dc90737a57bd1c6dc0ebc3eb30ab3090cc0afb
|
|
||||||
Conflicts: Drop changes to non-existent test cases
|
|
||||||
|
|
||||||
commit 14dc90737a57bd1c6dc0ebc3eb30ab3090cc0afb
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Mon Feb 16 12:26:45 2026 +0100
|
|
||||||
|
|
||||||
json: complete multi-statement set element support
|
|
||||||
|
|
||||||
Remove artificial limitation on the maximum number of statements per
|
|
||||||
element in listings.
|
|
||||||
|
|
||||||
Moreover, update tests/shell which are currently incorrect.
|
|
||||||
|
|
||||||
Fixes: e6d1d0d61195 ("src: add set element multi-statement support")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/json.c | 2 --
|
|
||||||
1 file changed, 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/json.c b/src/json.c
|
|
||||||
index fc2e962..0d3b535 100644
|
|
||||||
--- a/src/json.c
|
|
||||||
+++ b/src/json.c
|
|
||||||
@@ -705,8 +705,6 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx)
|
|
||||||
/* XXX: detect and complain about clashes? */
|
|
||||||
json_object_update_missing(root, tmp);
|
|
||||||
json_decref(tmp);
|
|
||||||
- /* TODO: only one statement per element. */
|
|
||||||
- break;
|
|
||||||
}
|
|
||||||
return nft_json_pack("{s:o}", "elem", root);
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
From cdcae37b8fc86c232ccb64e9d6feb98b455abf39 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:37 +0200
|
|
||||||
Subject: [PATCH] cache: Respect family in all list commands
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit f4a5334f503dc9d99bce45020c105b6812dd15f0
|
|
||||||
|
|
||||||
commit f4a5334f503dc9d99bce45020c105b6812dd15f0
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Sat Feb 14 14:58:03 2026 +0100
|
|
||||||
|
|
||||||
cache: Respect family in all list commands
|
|
||||||
|
|
||||||
Some list commands did not set filter->list.family even if one was given
|
|
||||||
on command line, fix this.
|
|
||||||
|
|
||||||
Fixes: b3ed8fd8c9f33 ("cache: missing family in cache filtering")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Tested-by: Eric Garver <eric@garver.life>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 6 ++-
|
|
||||||
tests/shell/testcases/listing/cache_filters | 46 +++++++++++++++++++++
|
|
||||||
2 files changed, 51 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100755 tests/shell/testcases/listing/cache_filters
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index 2330112..40b6c01 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -234,10 +234,12 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
flags |= NFT_CACHE_FULL;
|
|
||||||
break;
|
|
||||||
case CMD_OBJ_CHAINS:
|
|
||||||
+ filter->list.family = cmd->handle.family;
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_CHAIN;
|
|
||||||
break;
|
|
||||||
case CMD_OBJ_SETS:
|
|
||||||
case CMD_OBJ_MAPS:
|
|
||||||
+ filter->list.family = cmd->handle.family;
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_SET;
|
|
||||||
if (!nft_output_terse(&nft->output))
|
|
||||||
flags |= NFT_CACHE_SETELEM;
|
|
||||||
@@ -246,15 +248,17 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
if (filter &&
|
|
||||||
cmd->handle.table.name &&
|
|
||||||
cmd->handle.flowtable.name) {
|
|
||||||
- filter->list.family = cmd->handle.family;
|
|
||||||
filter->list.table = cmd->handle.table.name;
|
|
||||||
filter->list.ft = cmd->handle.flowtable.name;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case CMD_OBJ_FLOWTABLES:
|
|
||||||
+ filter->list.family = cmd->handle.family;
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_FLOWTABLE;
|
|
||||||
break;
|
|
||||||
case CMD_OBJ_RULESET:
|
|
||||||
+ filter->list.family = cmd->handle.family;
|
|
||||||
+ /* fall through */
|
|
||||||
default:
|
|
||||||
flags |= NFT_CACHE_FULL;
|
|
||||||
break;
|
|
||||||
diff --git a/tests/shell/testcases/listing/cache_filters b/tests/shell/testcases/listing/cache_filters
|
|
||||||
new file mode 100755
|
|
||||||
index 0000000..37c8f84
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/shell/testcases/listing/cache_filters
|
|
||||||
@@ -0,0 +1,46 @@
|
|
||||||
+#!/bin/bash
|
|
||||||
+
|
|
||||||
+set -e
|
|
||||||
+
|
|
||||||
+fail() {
|
|
||||||
+ echo "$*"
|
|
||||||
+ exit 1
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+$NFT -f - <<EOF
|
|
||||||
+table ip ip_t {
|
|
||||||
+ flowtable ip_t_ft {
|
|
||||||
+ hook ingress priority 0
|
|
||||||
+ }
|
|
||||||
+ set ip_t_s {
|
|
||||||
+ type inet_service
|
|
||||||
+ elements = { 22, 80, 443 }
|
|
||||||
+ }
|
|
||||||
+ chain ip_t_c {
|
|
||||||
+ tcp dport 22 accept
|
|
||||||
+ }
|
|
||||||
+ chain ip_t_c2 {
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+EOF
|
|
||||||
+
|
|
||||||
+$NFT --debug=netlink list ruleset | \
|
|
||||||
+ grep -q 'payload load' || fail "broken list ruleset"
|
|
||||||
+$NFT --debug=netlink list ruleset ip6 | \
|
|
||||||
+ grep -q 'payload load' && fail "broken list ruleset family filter"
|
|
||||||
+
|
|
||||||
+$NFT --debug=netlink list chains | \
|
|
||||||
+ grep -q 'ip ip_t ip_t_c' || fail "broken list chains"
|
|
||||||
+$NFT --debug=netlink list chains ip6 | \
|
|
||||||
+ grep -q 'ip ip_t ip_t_c' && fail "broken list chains family filter"
|
|
||||||
+
|
|
||||||
+$NFT --debug=netlink list sets | \
|
|
||||||
+ grep -q 'family 2 ip_t_s ip_t' || fail "broken list sets"
|
|
||||||
+$NFT --debug=netlink list sets ip6 | \
|
|
||||||
+ grep -q 'family 2 ip_t_s ip_t' && fail "broken list sets family filter"
|
|
||||||
+
|
|
||||||
+$NFT --debug=netlink list flowtables | \
|
|
||||||
+ grep -q 'flow table ip_t ip_t_ft' || fail "broken list flowtables"
|
|
||||||
+$NFT --debug=netlink list flowtables ip6 | \
|
|
||||||
+ grep -q 'flow table ip_t ip_t_ft' && fail "broken list flowtables family filter"
|
|
||||||
+exit 0
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
From 78bb602d61f6577540807495f5aa72e61c0fb1e4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:37 +0200
|
|
||||||
Subject: [PATCH] cache: Relax chain_cache_dump filter application
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 18cd6edf86139621dc6bfe0f17a391e46218c027
|
|
||||||
|
|
||||||
commit 18cd6edf86139621dc6bfe0f17a391e46218c027
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Mar 6 17:02:17 2026 +0100
|
|
||||||
|
|
||||||
cache: Relax chain_cache_dump filter application
|
|
||||||
|
|
||||||
While populating chain cache, a filter was only effective if it limited
|
|
||||||
fetching to both a table and a chain. Make it apply to 'list chains'
|
|
||||||
command as well which at most specifies a family and table.
|
|
||||||
|
|
||||||
Since the code is OK with filter->list fields being NULL, merely check
|
|
||||||
for filter to be non-NULL (which is the case if nft_cache_update() is
|
|
||||||
called by nft_cmd_enoent_chain()).
|
|
||||||
|
|
||||||
Fixes: 17297d1acbbf ("cache: Filter chain list on kernel side")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Tested-by: Eric Garver <eric@garver.life>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index 40b6c01..b8c065d 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -559,7 +559,7 @@ chain_cache_dump(struct netlink_ctx *ctx,
|
|
||||||
const char *chain = NULL;
|
|
||||||
int family = NFPROTO_UNSPEC;
|
|
||||||
|
|
||||||
- if (filter && filter->list.table && filter->list.chain) {
|
|
||||||
+ if (filter) {
|
|
||||||
family = filter->list.family;
|
|
||||||
table = filter->list.table;
|
|
||||||
chain = filter->list.chain;
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
From 8f721b98622ac4c68a2ad30b610037016ebc0312 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:37 +0200
|
|
||||||
Subject: [PATCH] cache: Filter for table when listing sets or maps
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit b7225cda2a4388f38293fba281fc001dff70a16e
|
|
||||||
|
|
||||||
commit b7225cda2a4388f38293fba281fc001dff70a16e
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Sat Feb 14 15:02:04 2026 +0100
|
|
||||||
|
|
||||||
cache: Filter for table when listing sets or maps
|
|
||||||
|
|
||||||
Respect an optionally specified table name to filter listed sets or maps
|
|
||||||
to by populating the filter accordingly.
|
|
||||||
|
|
||||||
Fixes: a1a6b0a5c3c4 ("cache: finer grain cache population for list commands")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Tested-by: Eric Garver <eric@garver.life>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 1 +
|
|
||||||
tests/shell/testcases/listing/cache_filters | 4 ++++
|
|
||||||
2 files changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index b8c065d..d448bb9 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -240,6 +240,7 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
case CMD_OBJ_SETS:
|
|
||||||
case CMD_OBJ_MAPS:
|
|
||||||
filter->list.family = cmd->handle.family;
|
|
||||||
+ filter->list.table = cmd->handle.table.name;
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_SET;
|
|
||||||
if (!nft_output_terse(&nft->output))
|
|
||||||
flags |= NFT_CACHE_SETELEM;
|
|
||||||
diff --git a/tests/shell/testcases/listing/cache_filters b/tests/shell/testcases/listing/cache_filters
|
|
||||||
index 37c8f84..7a89330 100755
|
|
||||||
--- a/tests/shell/testcases/listing/cache_filters
|
|
||||||
+++ b/tests/shell/testcases/listing/cache_filters
|
|
||||||
@@ -22,6 +22,8 @@ table ip ip_t {
|
|
||||||
chain ip_t_c2 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+table ip ip_t2 {
|
|
||||||
+}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
$NFT --debug=netlink list ruleset | \
|
|
||||||
@@ -38,6 +40,8 @@ $NFT --debug=netlink list sets | \
|
|
||||||
grep -q 'family 2 ip_t_s ip_t' || fail "broken list sets"
|
|
||||||
$NFT --debug=netlink list sets ip6 | \
|
|
||||||
grep -q 'family 2 ip_t_s ip_t' && fail "broken list sets family filter"
|
|
||||||
+$NFT --debug=netlink list sets ip ip_t2 | \
|
|
||||||
+ grep -q 'family 2 ip_t_s ip_t' && fail "broken list sets table filter"
|
|
||||||
|
|
||||||
$NFT --debug=netlink list flowtables | \
|
|
||||||
grep -q 'flow table ip_t ip_t_ft' || fail "broken list flowtables"
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
From e778b997601e2c23cf918905873e88ba22c8c06a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:37 +0200
|
|
||||||
Subject: [PATCH] cache: Filter for table when listing flowtables
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit fa5d7fba4bcc9b7c5c9ec37bbe8d3df3f8298745
|
|
||||||
|
|
||||||
commit fa5d7fba4bcc9b7c5c9ec37bbe8d3df3f8298745
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Feb 25 21:07:32 2026 +0100
|
|
||||||
|
|
||||||
cache: Filter for table when listing flowtables
|
|
||||||
|
|
||||||
Respect an optionally specified table name to filter listed flowtables
|
|
||||||
to by populating the filter accordingly.
|
|
||||||
|
|
||||||
Fixes: a1a6b0a5c3c4 ("cache: finer grain cache population for list commands")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Tested-by: Eric Garver <eric@garver.life>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 1 +
|
|
||||||
tests/shell/testcases/listing/cache_filters | 3 +++
|
|
||||||
2 files changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index d448bb9..dd159ea 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -255,6 +255,7 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
|
|
||||||
/* fall through */
|
|
||||||
case CMD_OBJ_FLOWTABLES:
|
|
||||||
filter->list.family = cmd->handle.family;
|
|
||||||
+ filter->list.table = cmd->handle.table.name;
|
|
||||||
flags |= NFT_CACHE_TABLE | NFT_CACHE_FLOWTABLE;
|
|
||||||
break;
|
|
||||||
case CMD_OBJ_RULESET:
|
|
||||||
diff --git a/tests/shell/testcases/listing/cache_filters b/tests/shell/testcases/listing/cache_filters
|
|
||||||
index 7a89330..e3d0e5e 100755
|
|
||||||
--- a/tests/shell/testcases/listing/cache_filters
|
|
||||||
+++ b/tests/shell/testcases/listing/cache_filters
|
|
||||||
@@ -47,4 +47,7 @@ $NFT --debug=netlink list flowtables | \
|
|
||||||
grep -q 'flow table ip_t ip_t_ft' || fail "broken list flowtables"
|
|
||||||
$NFT --debug=netlink list flowtables ip6 | \
|
|
||||||
grep -q 'flow table ip_t ip_t_ft' && fail "broken list flowtables family filter"
|
|
||||||
+$NFT --debug=netlink list flowtables ip ip_t2 | \
|
|
||||||
+ grep -q 'flow table ip_t ip_t_ft' && fail "broken list flowtables table filter"
|
|
||||||
+
|
|
||||||
exit 0
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From 3c99a1ec75bdc3adcecfbc150a842aace7ab9af3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:37 +0200
|
|
||||||
Subject: [PATCH] segtree: Fix for variable-sized object may not be initialized
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 96ba00889f9d4932d8bc2b08461f05793a9a2ac4
|
|
||||||
|
|
||||||
commit 96ba00889f9d4932d8bc2b08461f05793a9a2ac4
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Wed Mar 18 22:05:34 2026 +0100
|
|
||||||
|
|
||||||
segtree: Fix for variable-sized object may not be initialized
|
|
||||||
|
|
||||||
Seen with gcc-11.5.0 on an aarch64 machine, build failed. Looking at the
|
|
||||||
code, r1len (or r1->len, actually) really seems variable. So use
|
|
||||||
memset() and fix build for that older compiler version at least.
|
|
||||||
|
|
||||||
Fixes: e8b17865833b8 ("segtree: Fix range aggregation on Big Endian")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
Acked-by: Florian Westphal <fw@strlen.de>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/segtree.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/segtree.c b/src/segtree.c
|
|
||||||
index 2b4c4af..05664d1 100644
|
|
||||||
--- a/src/segtree.c
|
|
||||||
+++ b/src/segtree.c
|
|
||||||
@@ -410,8 +410,9 @@ void concat_range_aggregate(struct expr *set)
|
|
||||||
string_type) {
|
|
||||||
unsigned int r1len = div_round_up(r1->len, BITS_PER_BYTE);
|
|
||||||
unsigned int str_len = prefix_len / BITS_PER_BYTE;
|
|
||||||
- char data[r1len + 1] = {};
|
|
||||||
+ char data[r1len + 1];
|
|
||||||
|
|
||||||
+ memset(data, 0, r1len + 1);
|
|
||||||
mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, r1len);
|
|
||||||
data[str_len] = '*';
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From a0cdde12907855d417322df4acf177bfd9af2236 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:38 +0200
|
|
||||||
Subject: [PATCH] mnl: Fix ordering of hooks in 'list hooks' output
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 2f3b8d37c2e46f2ddf086c50affcd224b1f7f7dd
|
|
||||||
|
|
||||||
commit 2f3b8d37c2e46f2ddf086c50affcd224b1f7f7dd
|
|
||||||
Author: Phil Sutter <phil@nwl.cc>
|
|
||||||
Date: Fri Mar 20 13:30:52 2026 +0100
|
|
||||||
|
|
||||||
mnl: Fix ordering of hooks in 'list hooks' output
|
|
||||||
|
|
||||||
Hooks with same family, basehook and priority were inadvertently
|
|
||||||
inserted into the list in reverse ordering, fix that.
|
|
||||||
|
|
||||||
Suggested-by: Florian Westphal <fw@strlen.de>
|
|
||||||
Fixes: b98fee20bfe23 ("mnl: revisit hook listing")
|
|
||||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/mnl.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/mnl.c b/src/mnl.c
|
|
||||||
index 96a86aa..2b7e1cf 100644
|
|
||||||
--- a/src/mnl.c
|
|
||||||
+++ b/src/mnl.c
|
|
||||||
@@ -2199,7 +2199,7 @@ static void basehook_list_add_tail(struct basehook *b, struct list_head *head)
|
|
||||||
continue;
|
|
||||||
if (hook->num != b->num)
|
|
||||||
continue;
|
|
||||||
- if (hook->prio < b->prio)
|
|
||||||
+ if (hook->prio <= b->prio)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
list_add(&b->list, &hook->list);
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
From 7a7dbc549c9297f93c393eb70c01c24c15cc36be Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:33:38 +0200
|
|
||||||
Subject: [PATCH] cache: honor -c/--check for reset commands
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 25f2ff13cf6bc84a16febddcf8c3eda2018c7ece
|
|
||||||
Conflicts: Adjust to missing commit 68c8fb5f7c988
|
|
||||||
("cache: accumulate flags in batch")
|
|
||||||
|
|
||||||
commit 25f2ff13cf6bc84a16febddcf8c3eda2018c7ece
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Mon May 11 21:51:43 2026 +0200
|
|
||||||
|
|
||||||
cache: honor -c/--check for reset commands
|
|
||||||
|
|
||||||
Currently:
|
|
||||||
|
|
||||||
nft -c reset rules ip x
|
|
||||||
|
|
||||||
ignores -c/--check.
|
|
||||||
|
|
||||||
The reset and list commands use the netlink GET/DUMP nfnetlink API which
|
|
||||||
provides no check semantics, compared to the NEW/DELETE nfnetlink batch
|
|
||||||
API which indeed does.
|
|
||||||
|
|
||||||
Emulate -c/--check for the reset command by handling this as a list
|
|
||||||
command, so the state of the objects is just listed, not reset. This
|
|
||||||
allows to check for presence and dump the content of the objects.
|
|
||||||
|
|
||||||
Fixes: dbff26bfba83 ("cache: consolidate reset command")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/cache.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/cache.c b/src/cache.c
|
|
||||||
index dd159ea..eef5957 100644
|
|
||||||
--- a/src/cache.c
|
|
||||||
+++ b/src/cache.c
|
|
||||||
@@ -447,7 +447,10 @@ int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
|
|
||||||
flags = evaluate_cache_get(cmd, flags);
|
|
||||||
break;
|
|
||||||
case CMD_RESET:
|
|
||||||
- flags |= evaluate_cache_reset(cmd, flags, filter);
|
|
||||||
+ if (nft->check)
|
|
||||||
+ flags |= evaluate_cache_list(nft, cmd, flags, filter);
|
|
||||||
+ else
|
|
||||||
+ flags |= evaluate_cache_reset(cmd, flags, filter);
|
|
||||||
break;
|
|
||||||
case CMD_LIST:
|
|
||||||
flags |= evaluate_cache_list(nft, cmd, flags, filter);
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
From 0d1a648aa0a32dae21323c4bdcdc8d5184663ba2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:34:06 +0200
|
|
||||||
Subject: [PATCH] parser_json: fix crash in json_parse_set_stmt_list
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 26d9cbefb10e6bc3765df7e9e7a4fc3b951a80f3
|
|
||||||
|
|
||||||
commit 26d9cbefb10e6bc3765df7e9e7a4fc3b951a80f3
|
|
||||||
Author: Sebastian Walz (sivizius) <sebastian.walz@secunet.com>
|
|
||||||
Date: Tue Aug 20 00:09:26 2024 +0200
|
|
||||||
|
|
||||||
parser_json: fix crash in json_parse_set_stmt_list
|
|
||||||
|
|
||||||
Due to missing `NULL`-check, there will be a segfault for invalid statements.
|
|
||||||
|
|
||||||
Fixes: 07958ec53830 ("json: add set statement list support")
|
|
||||||
Signed-off-by: Sebastian Walz (sivizius) <sebastian.walz@secunet.com>
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_json.c | 13 +++++++++----
|
|
||||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index cce5ee2..7b75a88 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -2317,7 +2317,7 @@ static void json_parse_set_stmt_list(struct json_ctx *ctx,
|
|
||||||
json_t *stmt_json)
|
|
||||||
{
|
|
||||||
struct list_head *head;
|
|
||||||
- struct stmt *tmp;
|
|
||||||
+ struct stmt *stmt;
|
|
||||||
json_t *value;
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
@@ -2329,9 +2329,14 @@ static void json_parse_set_stmt_list(struct json_ctx *ctx,
|
|
||||||
|
|
||||||
head = stmt_list;
|
|
||||||
json_array_foreach(stmt_json, index, value) {
|
|
||||||
- tmp = json_parse_stmt(ctx, value);
|
|
||||||
- list_add(&tmp->list, head);
|
|
||||||
- head = &tmp->list;
|
|
||||||
+ stmt = json_parse_stmt(ctx, value);
|
|
||||||
+ if (!stmt) {
|
|
||||||
+ json_error(ctx, "Parsing set statements array at index %zd failed.", index);
|
|
||||||
+ stmt_list_free(stmt_list);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ list_add(&stmt->list, head);
|
|
||||||
+ head = &stmt->list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
From f2e3c291c8d1ca5879697abf87f96c5097cdf50b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Phil Sutter <psutter@redhat.com>
|
|
||||||
Date: Tue, 30 Jun 2026 14:34:06 +0200
|
|
||||||
Subject: [PATCH] parser_json: allow statement stateful statement only in set
|
|
||||||
elements
|
|
||||||
|
|
||||||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
||||||
Upstream Status: nftables commit 85b5b051f0e64f106cee078fc6d66d0872770e79
|
|
||||||
|
|
||||||
commit 85b5b051f0e64f106cee078fc6d66d0872770e79
|
|
||||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
Date: Tue Apr 1 09:49:48 2025 +0200
|
|
||||||
|
|
||||||
parser_json: allow statement stateful statement only in set elements
|
|
||||||
|
|
||||||
Upfront reject of non stateful statements in set elements.
|
|
||||||
|
|
||||||
Fixes: 07958ec53830 ("json: add set statement list support")
|
|
||||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
||||||
|
|
||||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
||||||
---
|
|
||||||
src/parser_json.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
||||||
index 7b75a88..cfeef3c 100644
|
|
||||||
--- a/src/parser_json.c
|
|
||||||
+++ b/src/parser_json.c
|
|
||||||
@@ -2335,6 +2335,11 @@ static void json_parse_set_stmt_list(struct json_ctx *ctx,
|
|
||||||
stmt_list_free(stmt_list);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
+ if (!(stmt->flags & STMT_F_STATEFUL)) {
|
|
||||||
+ stmt_free(stmt);
|
|
||||||
+ json_error(ctx, "Unsupported set statements array at index %zd failed.", index);
|
|
||||||
+ stmt_list_free(stmt_list);
|
|
||||||
+ }
|
|
||||||
list_add(&stmt->list, head);
|
|
||||||
head = &stmt->list;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user