nftables-1.1.1-1.el10
* Thu Nov 07 2024 Phil Sutter <psutter@redhat.com> [1.1.1-1.el10] - monitor: Recognize flowtable add/del events (Phil Sutter) [RHEL-65346] - tests: py: Fix for storing payload into missing file (Phil Sutter) [RHEL-65346] - json: Support typeof in set and map types (Phil Sutter) [RHEL-65346] - json: collapse set element commands from parser (Phil Sutter) [RHEL-65346] - doc: extend description of fib expression (Phil Sutter) [RHEL-65346] - tests: monitor: fix up test case breakage (Phil Sutter) [RHEL-65346] - src: fix extended netlink error reporting with large set elements (Phil Sutter) [RHEL-65346] - rule: netlink attribute offset is uint32_t for struct nlerr_loc (Phil Sutter) [RHEL-65346] - mnl: update cmd_add_loc() to take struct nlmsghdr (Phil Sutter) [RHEL-65346] - mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc() (Phil Sutter) [RHEL-65346] - src: collapse set element commands from parser (Phil Sutter) [RHEL-65346] - libnftables-json: fix raw payload expression documentation (Phil Sutter) [RHEL-65346] - tests: shell: fix spurious dump failure in vmap timeout test (Phil Sutter) [RHEL-65346] - Rebase onto version 1.1.1 (Phil Sutter) [RHEL-65346] Resolves: RHEL-65346
This commit is contained in:
parent
b733980906
commit
d9f08f29ae
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@
|
||||
/nftables-1.0.5.tar.bz2
|
||||
/nftables-1.0.7.tar.xz
|
||||
/nftables-1.0.9.tar.xz
|
||||
/nftables-1.1.1.tar.xz
|
||||
|
@ -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
|
@ -0,0 +1,45 @@
|
||||
From 1ce7bc1ca89494fdbb2fa10b176d33a5944ede01 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] tests: shell: fix spurious dump failure in vmap timeout test
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 95017b8c8f10ada09c2faa7e6bae71b60f38f259
|
||||
|
||||
commit 95017b8c8f10ada09c2faa7e6bae71b60f38f259
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Fri Oct 11 02:32:08 2024 +0200
|
||||
|
||||
tests: shell: fix spurious dump failure in vmap timeout test
|
||||
|
||||
Blamed commit can update the timeout to 6s, but last line waits
|
||||
for 5 seconds and expects that to be enough to have all elements vanish.
|
||||
|
||||
Fix the typo to limit update timeout also to 5 seconds and not 6.
|
||||
This fixes spurious dump failures like this one:
|
||||
|
||||
- elements = { 1.2.3.4 . 22 : jump ssh_input }
|
||||
+ elements = { 1.2.3.4 . 22 : jump ssh_input,
|
||||
+ 10.0.95.144 . 38023 timeout 6s expires 545ms : jump other_input }
|
||||
|
||||
Fixes: db80037c0279 ("tests: shell: extend vmap test with updates")
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
tests/shell/testcases/maps/vmap_timeout | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/shell/testcases/maps/vmap_timeout b/tests/shell/testcases/maps/vmap_timeout
|
||||
index 3f0563a..6d73f3c 100755
|
||||
--- a/tests/shell/testcases/maps/vmap_timeout
|
||||
+++ b/tests/shell/testcases/maps/vmap_timeout
|
||||
@@ -32,7 +32,7 @@ for i in $(seq 1 100) ; do
|
||||
timeout=$((timeout+1))
|
||||
expire=$((RANDOM%timeout))
|
||||
utimeout=$((RANDOM%5))
|
||||
- utimeout=$((timeout+1))
|
||||
+ utimeout=$((utimeout+1))
|
||||
|
||||
timeout_str="timeout ${timeout}s"
|
||||
expire_str=""
|
@ -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;
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 08d33851ff012bb14237127553be80dbb00fa07d Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] libnftables-json: fix raw payload expression documentation
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 570320ab9a0752c7749a6c9cc85b34a5e7ab91b5
|
||||
|
||||
commit 570320ab9a0752c7749a6c9cc85b34a5e7ab91b5
|
||||
Author: Eric Long <i@hack3r.moe>
|
||||
Date: Thu Oct 17 23:33:17 2024 +0800
|
||||
|
||||
libnftables-json: fix raw payload expression documentation
|
||||
|
||||
Raw payload expression accesses payload data in bits, not bytes.
|
||||
|
||||
Fixes: 872f373dc50f7 ("doc: Add JSON schema documentation")
|
||||
Signed-off-by: Eric Long <i@hack3r.moe>
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
doc/libnftables-json.adoc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
||||
index a8a6165..2f29ac0 100644
|
||||
--- a/doc/libnftables-json.adoc
|
||||
+++ b/doc/libnftables-json.adoc
|
||||
@@ -1182,7 +1182,7 @@ ____
|
||||
|
||||
Construct a payload expression, i.e. a reference to a certain part of packet
|
||||
data. The first form creates a raw payload expression to point at a random
|
||||
-number (*len*) of bytes at a certain offset (*offset*) from a given reference
|
||||
+number (*len*) of bits at a certain offset (*offset*) from a given reference
|
||||
point (*base*). The following *base* values are accepted:
|
||||
|
||||
*"ll"*::
|
339
0003-src-collapse-set-element-commands-from-parser.patch
Normal file
339
0003-src-collapse-set-element-commands-from-parser.patch
Normal file
@ -0,0 +1,339 @@
|
||||
From 005c220f08964958eae2ca6e40a070b5bc9d6f79 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] src: collapse set element commands from parser
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 20f1c60ac8c88be3bdf3096083b24ada06570a77
|
||||
|
||||
commit 20f1c60ac8c88be3bdf3096083b24ada06570a77
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Wed Oct 23 11:43:58 2024 +0200
|
||||
|
||||
src: collapse set element commands from parser
|
||||
|
||||
498a5f0c219d ("rule: collapse set element commands") does not help to
|
||||
reduce memory consumption in the case of large sets defined by one
|
||||
element per line:
|
||||
|
||||
add element ip x y { 1.1.1.1 }
|
||||
add element ip x y { 1.1.1.2 }
|
||||
...
|
||||
|
||||
This patch reduces memory consumption by ~75%, set elements are
|
||||
collapsed into an existing cmd object wherever possible to reduce the
|
||||
number of cmd objects.
|
||||
|
||||
This patch also adds a special case for variables for sets similar to:
|
||||
|
||||
be055af5c58d ("cmd: skip variable set elements when collapsing commands")
|
||||
|
||||
This patch requires this small kernel fix:
|
||||
|
||||
commit b53c116642502b0c85ecef78bff4f826a7dd4145
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Fri May 20 00:02:06 2022 +0200
|
||||
|
||||
netfilter: nf_tables: set element extended ACK reporting support
|
||||
|
||||
which is already included in recent -stable kernels:
|
||||
|
||||
# cat ruleset.nft
|
||||
add table ip x
|
||||
add chain ip x y
|
||||
add set ip x y { type ipv4_addr; }
|
||||
create element ip x y { 1.1.1.1 }
|
||||
create element ip x y { 1.1.1.1 }
|
||||
|
||||
# nft -f ruleset.nft
|
||||
ruleset.nft:5:25-31: Error: Could not process rule: File exists
|
||||
create element ip x y { 1.1.1.1 }
|
||||
^^^^^^^
|
||||
|
||||
since there is no need to relate commands via sequence number anymore,
|
||||
this allows also removes the uncollapse step.
|
||||
|
||||
Fixes: 498a5f0c219d ("rule: collapse set element commands")
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/cmd.h | 7 +--
|
||||
include/expression.h | 1 -
|
||||
include/list.h | 11 +++++
|
||||
include/rule.h | 1 -
|
||||
src/cmd.c | 105 +++++++++++--------------------------------
|
||||
src/libnftables.c | 7 ---
|
||||
src/parser_bison.y | 13 ++++++
|
||||
src/rule.c | 1 -
|
||||
8 files changed, 54 insertions(+), 92 deletions(-)
|
||||
|
||||
diff --git a/include/cmd.h b/include/cmd.h
|
||||
index 92a4152..0a8779b 100644
|
||||
--- a/include/cmd.h
|
||||
+++ b/include/cmd.h
|
||||
@@ -2,12 +2,13 @@
|
||||
#define _NFT_CMD_H_
|
||||
|
||||
void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc);
|
||||
+struct mnl_err;
|
||||
void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
struct mnl_err *err);
|
||||
|
||||
+bool nft_cmd_collapse_elems(enum cmd_ops op, struct list_head *cmds,
|
||||
+ struct handle *handle, struct expr *init);
|
||||
+
|
||||
void nft_cmd_expand(struct cmd *cmd);
|
||||
-void nft_cmd_post_expand(struct cmd *cmd);
|
||||
-bool nft_cmd_collapse(struct list_head *cmds);
|
||||
-void nft_cmd_uncollapse(struct list_head *cmds);
|
||||
|
||||
#endif
|
||||
diff --git a/include/expression.h b/include/expression.h
|
||||
index 8982110..da2f693 100644
|
||||
--- a/include/expression.h
|
||||
+++ b/include/expression.h
|
||||
@@ -255,7 +255,6 @@ struct expr {
|
||||
enum expr_types etype:8;
|
||||
enum ops op:8;
|
||||
unsigned int len;
|
||||
- struct cmd *cmd;
|
||||
|
||||
union {
|
||||
struct {
|
||||
diff --git a/include/list.h b/include/list.h
|
||||
index 857921e..37fbe3e 100644
|
||||
--- a/include/list.h
|
||||
+++ b/include/list.h
|
||||
@@ -348,6 +348,17 @@ static inline void list_splice_tail_init(struct list_head *list,
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
+/**
|
||||
+ * list_last_entry - get the last element from a list
|
||||
+ * @ptr: the list head to take the element from.
|
||||
+ * @type: the type of the struct this is embedded in.
|
||||
+ * @member: the name of the list_head within the struct.
|
||||
+ *
|
||||
+ * Note, that list is expected to be not empty.
|
||||
+ */
|
||||
+#define list_last_entry(ptr, type, member) \
|
||||
+ list_entry((ptr)->prev, type, member)
|
||||
+
|
||||
/**
|
||||
* list_next_entry - get the next element in list
|
||||
* @pos: the type * to cursor
|
||||
diff --git a/include/rule.h b/include/rule.h
|
||||
index 5b3e12b..a1628d8 100644
|
||||
--- a/include/rule.h
|
||||
+++ b/include/rule.h
|
||||
@@ -718,7 +718,6 @@ struct cmd {
|
||||
enum cmd_obj obj;
|
||||
struct handle handle;
|
||||
uint32_t seqnum;
|
||||
- struct list_head collapse_list;
|
||||
union {
|
||||
void *data;
|
||||
struct expr *expr;
|
||||
diff --git a/src/cmd.c b/src/cmd.c
|
||||
index 9a572b5..e010dcb 100644
|
||||
--- a/src/cmd.c
|
||||
+++ b/src/cmd.c
|
||||
@@ -378,6 +378,32 @@ static void nft_cmd_expand_chain(struct chain *chain, struct list_head *new_cmds
|
||||
}
|
||||
}
|
||||
|
||||
+bool nft_cmd_collapse_elems(enum cmd_ops op, struct list_head *cmds,
|
||||
+ struct handle *handle, struct expr *init)
|
||||
+{
|
||||
+ struct cmd *last_cmd;
|
||||
+
|
||||
+ if (list_empty(cmds))
|
||||
+ return false;
|
||||
+
|
||||
+ if (init->etype == EXPR_VARIABLE)
|
||||
+ return false;
|
||||
+
|
||||
+ last_cmd = list_last_entry(cmds, struct cmd, list);
|
||||
+ if (last_cmd->op != op ||
|
||||
+ last_cmd->obj != CMD_OBJ_ELEMENTS ||
|
||||
+ last_cmd->expr->etype == EXPR_VARIABLE ||
|
||||
+ last_cmd->handle.family != handle->family ||
|
||||
+ strcmp(last_cmd->handle.table.name, handle->table.name) ||
|
||||
+ strcmp(last_cmd->handle.set.name, handle->set.name))
|
||||
+ return false;
|
||||
+
|
||||
+ list_splice_tail_init(&init->expressions, &last_cmd->expr->expressions);
|
||||
+ last_cmd->expr->size += init->size;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
void nft_cmd_expand(struct cmd *cmd)
|
||||
{
|
||||
struct list_head new_cmds;
|
||||
@@ -459,82 +485,3 @@ void nft_cmd_expand(struct cmd *cmd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
-
|
||||
-bool nft_cmd_collapse(struct list_head *cmds)
|
||||
-{
|
||||
- struct cmd *cmd, *next, *elems = NULL;
|
||||
- struct expr *expr, *enext;
|
||||
- bool collapse = false;
|
||||
-
|
||||
- list_for_each_entry_safe(cmd, next, cmds, list) {
|
||||
- if (cmd->op != CMD_ADD &&
|
||||
- cmd->op != CMD_CREATE) {
|
||||
- elems = NULL;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (cmd->obj != CMD_OBJ_ELEMENTS) {
|
||||
- elems = NULL;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (cmd->expr->etype == EXPR_VARIABLE)
|
||||
- continue;
|
||||
-
|
||||
- if (!elems) {
|
||||
- elems = cmd;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (cmd->op != elems->op) {
|
||||
- elems = cmd;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (elems->handle.family != cmd->handle.family ||
|
||||
- strcmp(elems->handle.table.name, cmd->handle.table.name) ||
|
||||
- strcmp(elems->handle.set.name, cmd->handle.set.name)) {
|
||||
- elems = cmd;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- collapse = true;
|
||||
- list_for_each_entry_safe(expr, enext, &cmd->expr->expressions, list) {
|
||||
- expr->cmd = cmd;
|
||||
- list_move_tail(&expr->list, &elems->expr->expressions);
|
||||
- }
|
||||
- elems->expr->size += cmd->expr->size;
|
||||
- list_move_tail(&cmd->list, &elems->collapse_list);
|
||||
- }
|
||||
-
|
||||
- return collapse;
|
||||
-}
|
||||
-
|
||||
-void nft_cmd_uncollapse(struct list_head *cmds)
|
||||
-{
|
||||
- struct cmd *cmd, *cmd_next, *collapse_cmd, *collapse_cmd_next;
|
||||
- struct expr *expr, *next;
|
||||
-
|
||||
- list_for_each_entry_safe(cmd, cmd_next, cmds, list) {
|
||||
- if (list_empty(&cmd->collapse_list))
|
||||
- continue;
|
||||
-
|
||||
- assert(cmd->obj == CMD_OBJ_ELEMENTS);
|
||||
-
|
||||
- list_for_each_entry_safe(expr, next, &cmd->expr->expressions, list) {
|
||||
- if (!expr->cmd)
|
||||
- continue;
|
||||
-
|
||||
- list_move_tail(&expr->list, &expr->cmd->expr->expressions);
|
||||
- cmd->expr->size--;
|
||||
- expr->cmd = NULL;
|
||||
- }
|
||||
-
|
||||
- list_for_each_entry_safe(collapse_cmd, collapse_cmd_next, &cmd->collapse_list, list) {
|
||||
- if (cmd->elem.set)
|
||||
- collapse_cmd->elem.set = set_get(cmd->elem.set);
|
||||
-
|
||||
- list_add(&collapse_cmd->list, &cmd->list);
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
diff --git a/src/libnftables.c b/src/libnftables.c
|
||||
index 2ae2150..2834c99 100644
|
||||
--- a/src/libnftables.c
|
||||
+++ b/src/libnftables.c
|
||||
@@ -513,7 +513,6 @@ static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs,
|
||||
{
|
||||
struct nft_cache_filter *filter;
|
||||
struct cmd *cmd, *next;
|
||||
- bool collapsed = false;
|
||||
unsigned int flags;
|
||||
int err = 0;
|
||||
|
||||
@@ -529,9 +528,6 @@ static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs,
|
||||
|
||||
nft_cache_filter_fini(filter);
|
||||
|
||||
- if (nft_cmd_collapse(cmds))
|
||||
- collapsed = true;
|
||||
-
|
||||
list_for_each_entry(cmd, cmds, list) {
|
||||
if (cmd->op != CMD_ADD &&
|
||||
cmd->op != CMD_CREATE)
|
||||
@@ -553,9 +549,6 @@ static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs,
|
||||
}
|
||||
}
|
||||
|
||||
- if (collapsed)
|
||||
- nft_cmd_uncollapse(cmds);
|
||||
-
|
||||
if (err < 0 || nft->state->nerrs)
|
||||
return -1;
|
||||
|
||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
||||
index e2936d1..602fc60 100644
|
||||
--- a/src/parser_bison.y
|
||||
+++ b/src/parser_bison.y
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <libnftnl/udata.h>
|
||||
|
||||
#include <rule.h>
|
||||
+#include <cmd.h>
|
||||
#include <statement.h>
|
||||
#include <expression.h>
|
||||
#include <headers.h>
|
||||
@@ -1219,6 +1220,12 @@ add_cmd : TABLE table_spec
|
||||
}
|
||||
| ELEMENT set_spec set_block_expr
|
||||
{
|
||||
+ if (nft_cmd_collapse_elems(CMD_ADD, state->cmds, &$2, $3)) {
|
||||
+ handle_free(&$2);
|
||||
+ expr_free($3);
|
||||
+ $$ = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
$$ = cmd_alloc(CMD_ADD, CMD_OBJ_ELEMENTS, &$2, &@$, $3);
|
||||
}
|
||||
| FLOWTABLE flowtable_spec flowtable_block_alloc
|
||||
@@ -1336,6 +1343,12 @@ create_cmd : TABLE table_spec
|
||||
}
|
||||
| ELEMENT set_spec set_block_expr
|
||||
{
|
||||
+ if (nft_cmd_collapse_elems(CMD_CREATE, state->cmds, &$2, $3)) {
|
||||
+ handle_free(&$2);
|
||||
+ expr_free($3);
|
||||
+ $$ = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_ELEMENTS, &$2, &@$, $3);
|
||||
}
|
||||
| FLOWTABLE flowtable_spec flowtable_block_alloc
|
||||
diff --git a/src/rule.c b/src/rule.c
|
||||
index 9bc160e..9536e68 100644
|
||||
--- a/src/rule.c
|
||||
+++ b/src/rule.c
|
||||
@@ -1332,7 +1332,6 @@ struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj,
|
||||
cmd->attr = xzalloc_array(NFT_NLATTR_LOC_MAX,
|
||||
sizeof(struct nlerr_loc));
|
||||
cmd->attr_array_len = NFT_NLATTR_LOC_MAX;
|
||||
- init_list_head(&cmd->collapse_list);
|
||||
|
||||
return cmd;
|
||||
}
|
78
0004-mnl-rename-to-mnl_seqnum_alloc-to-mnl_seqnum_inc.patch
Normal file
78
0004-mnl-rename-to-mnl_seqnum_alloc-to-mnl_seqnum_inc.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From c2e328edd47ac3d3ed127b313d35ed05839441db Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit b4ce90d52d564efaced298f6e9c575d6942ecf91
|
||||
|
||||
commit b4ce90d52d564efaced298f6e9c575d6942ecf91
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Wed Oct 23 22:15:24 2024 +0200
|
||||
|
||||
mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc()
|
||||
|
||||
rename mnl_seqnum_alloc() to mnl_seqnum_inc().
|
||||
|
||||
No functional change is intended.
|
||||
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/mnl.h | 2 +-
|
||||
src/libnftables.c | 6 +++---
|
||||
src/mnl.c | 2 +-
|
||||
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/include/mnl.h b/include/mnl.h
|
||||
index c9502f3..7c465d4 100644
|
||||
--- a/include/mnl.h
|
||||
+++ b/include/mnl.h
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
struct mnl_socket *nft_mnl_socket_open(void);
|
||||
|
||||
-uint32_t mnl_seqnum_alloc(uint32_t *seqnum);
|
||||
+uint32_t mnl_seqnum_inc(uint32_t *seqnum);
|
||||
uint32_t mnl_genid_get(struct netlink_ctx *ctx);
|
||||
|
||||
struct mnl_err {
|
||||
diff --git a/src/libnftables.c b/src/libnftables.c
|
||||
index 2834c99..3550961 100644
|
||||
--- a/src/libnftables.c
|
||||
+++ b/src/libnftables.c
|
||||
@@ -37,9 +37,9 @@ static int nft_netlink(struct nft_ctx *nft,
|
||||
if (list_empty(cmds))
|
||||
goto out;
|
||||
|
||||
- batch_seqnum = mnl_batch_begin(ctx.batch, mnl_seqnum_alloc(&seqnum));
|
||||
+ batch_seqnum = mnl_batch_begin(ctx.batch, mnl_seqnum_inc(&seqnum));
|
||||
list_for_each_entry(cmd, cmds, list) {
|
||||
- ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum);
|
||||
+ ctx.seqnum = cmd->seqnum = mnl_seqnum_inc(&seqnum);
|
||||
ret = do_command(&ctx, cmd);
|
||||
if (ret < 0) {
|
||||
netlink_io_error(&ctx, &cmd->location,
|
||||
@@ -50,7 +50,7 @@ static int nft_netlink(struct nft_ctx *nft,
|
||||
num_cmds++;
|
||||
}
|
||||
if (!nft->check)
|
||||
- mnl_batch_end(ctx.batch, mnl_seqnum_alloc(&seqnum));
|
||||
+ mnl_batch_end(ctx.batch, mnl_seqnum_inc(&seqnum));
|
||||
|
||||
if (!mnl_batch_ready(ctx.batch))
|
||||
goto out;
|
||||
diff --git a/src/mnl.c b/src/mnl.c
|
||||
index db53a60..c1691da 100644
|
||||
--- a/src/mnl.c
|
||||
+++ b/src/mnl.c
|
||||
@@ -70,7 +70,7 @@ struct mnl_socket *nft_mnl_socket_open(void)
|
||||
return nf_sock;
|
||||
}
|
||||
|
||||
-uint32_t mnl_seqnum_alloc(unsigned int *seqnum)
|
||||
+uint32_t mnl_seqnum_inc(unsigned int *seqnum)
|
||||
{
|
||||
return (*seqnum)++;
|
||||
}
|
312
0005-mnl-update-cmd_add_loc-to-take-struct-nlmsghdr.patch
Normal file
312
0005-mnl-update-cmd_add_loc-to-take-struct-nlmsghdr.patch
Normal file
@ -0,0 +1,312 @@
|
||||
From ed5989c26e998985a01dcd6c57415d8110c63f64 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] mnl: update cmd_add_loc() to take struct nlmsghdr
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit f7c2b27c9f8356c634f0405347444e03e10e151b
|
||||
|
||||
commit f7c2b27c9f8356c634f0405347444e03e10e151b
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Wed Oct 23 23:07:31 2024 +0200
|
||||
|
||||
mnl: update cmd_add_loc() to take struct nlmsghdr
|
||||
|
||||
To prepare for a fix for very large sets.
|
||||
|
||||
No functional change is intended.
|
||||
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/cmd.h | 2 +-
|
||||
src/cmd.c | 4 +--
|
||||
src/mnl.c | 77 +++++++++++++++++++++++++--------------------------
|
||||
3 files changed, 41 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/include/cmd.h b/include/cmd.h
|
||||
index 0a8779b..cf7e43b 100644
|
||||
--- a/include/cmd.h
|
||||
+++ b/include/cmd.h
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _NFT_CMD_H_
|
||||
#define _NFT_CMD_H_
|
||||
|
||||
-void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc);
|
||||
+void cmd_add_loc(struct cmd *cmd, const struct nlmsghdr *nlh, const struct location *loc);
|
||||
struct mnl_err;
|
||||
void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
struct mnl_err *err);
|
||||
diff --git a/src/cmd.c b/src/cmd.c
|
||||
index e010dcb..78a2aa3 100644
|
||||
--- a/src/cmd.c
|
||||
+++ b/src/cmd.c
|
||||
@@ -17,14 +17,14 @@
|
||||
#include <errno.h>
|
||||
#include <cache.h>
|
||||
|
||||
-void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc)
|
||||
+void cmd_add_loc(struct cmd *cmd, const struct nlmsghdr *nlh, const struct location *loc)
|
||||
{
|
||||
if (cmd->num_attrs >= cmd->attr_array_len) {
|
||||
cmd->attr_array_len *= 2;
|
||||
cmd->attr = xrealloc(cmd->attr, sizeof(struct nlerr_loc) * cmd->attr_array_len);
|
||||
}
|
||||
|
||||
- cmd->attr[cmd->num_attrs].offset = offset;
|
||||
+ cmd->attr[cmd->num_attrs].offset = nlh->nlmsg_len;
|
||||
cmd->attr[cmd->num_attrs].location = loc;
|
||||
cmd->num_attrs++;
|
||||
}
|
||||
diff --git a/src/mnl.c b/src/mnl.c
|
||||
index c1691da..42d1b0d 100644
|
||||
--- a/src/mnl.c
|
||||
+++ b/src/mnl.c
|
||||
@@ -474,7 +474,7 @@ static int mnl_nft_expr_build_cb(struct nftnl_expr *nle, void *data)
|
||||
|
||||
eloc = nft_expr_loc_find(nle, ctx->lctx);
|
||||
if (eloc)
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, eloc->loc);
|
||||
+ cmd_add_loc(cmd, nlh, eloc->loc);
|
||||
|
||||
nest = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
|
||||
nftnl_expr_build_payload(nlh, nle);
|
||||
@@ -527,9 +527,9 @@ int mnl_nft_rule_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
cmd->handle.family,
|
||||
NLM_F_CREATE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, h->table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->chain.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->chain.location);
|
||||
|
||||
if (h->chain_id)
|
||||
mnl_attr_put_u32(nlh, NFTA_RULE_CHAIN_ID, htonl(h->chain_id));
|
||||
@@ -578,11 +578,11 @@ int mnl_nft_rule_replace(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
cmd->handle.family,
|
||||
NLM_F_REPLACE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, h->table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->chain.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->chain.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, h->chain.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(h->handle.id));
|
||||
|
||||
mnl_nft_rule_build_ctx_init(&rule_ctx, nlh, cmd, &lctx);
|
||||
@@ -621,14 +621,14 @@ int mnl_nft_rule_del(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY),
|
||||
0, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, h->table.name);
|
||||
if (h->chain.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->chain.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->chain.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, h->chain.name);
|
||||
}
|
||||
if (h->handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(h->handle.id));
|
||||
}
|
||||
|
||||
@@ -792,12 +792,12 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
|
||||
|
||||
dev_array = nft_dev_array(dev_expr, &num_devs);
|
||||
if (num_devs == 1) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[0].location);
|
||||
+ cmd_add_loc(cmd, nlh, dev_array[0].location);
|
||||
mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, dev_array[0].ifname);
|
||||
} else {
|
||||
nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
|
||||
for (i = 0; i < num_devs; i++) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
|
||||
+ cmd_add_loc(cmd, nlh, dev_array[i].location);
|
||||
mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
|
||||
mnl_attr_nest_end(nlh, nest_dev);
|
||||
}
|
||||
@@ -842,9 +842,9 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
cmd->handle.family,
|
||||
NLM_F_CREATE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, cmd->handle.table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.chain.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.chain.location);
|
||||
|
||||
if (!cmd->chain || !(cmd->chain->flags & CHAIN_F_BINDING)) {
|
||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, cmd->handle.chain.name);
|
||||
@@ -861,7 +861,7 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
if (cmd->chain && cmd->chain->policy) {
|
||||
mpz_export_data(&policy, cmd->chain->policy->value,
|
||||
BYTEORDER_HOST_ENDIAN, sizeof(int));
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->chain->policy->location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->chain->policy->location);
|
||||
mnl_attr_put_u32(nlh, NFTA_CHAIN_POLICY, htonl(policy));
|
||||
}
|
||||
|
||||
@@ -873,7 +873,7 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
struct nlattr *nest;
|
||||
|
||||
if (cmd->chain->type.str) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->chain->type.loc);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->chain->type.loc);
|
||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, cmd->chain->type.str);
|
||||
}
|
||||
|
||||
@@ -949,13 +949,13 @@ int mnl_nft_chain_del(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
cmd->handle.family,
|
||||
0, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, cmd->handle.table.name);
|
||||
if (cmd->handle.chain.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.chain.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.chain.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, cmd->handle.chain.name);
|
||||
} else if (cmd->handle.handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_CHAIN_HANDLE,
|
||||
htobe64(cmd->handle.handle.id));
|
||||
}
|
||||
@@ -1077,7 +1077,7 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
cmd->handle.family,
|
||||
flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, cmd->handle.table.name);
|
||||
nftnl_table_nlmsg_build_payload(nlh, nlt);
|
||||
nftnl_table_free(nlt);
|
||||
@@ -1106,10 +1106,10 @@ int mnl_nft_table_del(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
cmd->handle.family, 0, ctx->seqnum);
|
||||
|
||||
if (cmd->handle.table.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, cmd->handle.table.name);
|
||||
} else if (cmd->handle.handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_TABLE_HANDLE,
|
||||
htobe64(cmd->handle.handle.id));
|
||||
}
|
||||
@@ -1325,9 +1325,9 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
h->family,
|
||||
NLM_F_CREATE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_SET_TABLE, h->table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &h->set.location);
|
||||
+ cmd_add_loc(cmd, nlh, &h->set.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_SET_NAME, h->set.name);
|
||||
|
||||
nftnl_set_nlmsg_build_payload(nlh, nls);
|
||||
@@ -1359,13 +1359,13 @@ int mnl_nft_set_del(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
h->family,
|
||||
0, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_SET_TABLE, cmd->handle.table.name);
|
||||
if (h->set.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.set.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.set.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_SET_NAME, cmd->handle.set.name);
|
||||
} else if (h->handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_SET_HANDLE,
|
||||
htobe64(cmd->handle.handle.id));
|
||||
}
|
||||
@@ -1544,9 +1544,9 @@ int mnl_nft_obj_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
NFT_MSG_NEWOBJ, cmd->handle.family,
|
||||
NLM_F_CREATE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_OBJ_TABLE, cmd->handle.table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.obj.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.obj.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_OBJ_NAME, cmd->handle.obj.name);
|
||||
|
||||
nftnl_obj_nlmsg_build_payload(nlh, nlo);
|
||||
@@ -1577,14 +1577,14 @@ int mnl_nft_obj_del(struct netlink_ctx *ctx, struct cmd *cmd, int type)
|
||||
msg_type, cmd->handle.family,
|
||||
0, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_OBJ_TABLE, cmd->handle.table.name);
|
||||
|
||||
if (cmd->handle.obj.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.obj.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.obj.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_OBJ_NAME, cmd->handle.obj.name);
|
||||
} else if (cmd->handle.handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_OBJ_HANDLE,
|
||||
htobe64(cmd->handle.handle.id));
|
||||
}
|
||||
@@ -1764,7 +1764,7 @@ next:
|
||||
list_for_each_entry_from(expr, &set->expressions, list) {
|
||||
nlse = alloc_nftnl_setelem(set, expr);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &expr->location);
|
||||
+ cmd_add_loc(cmd, nlh, &expr->location);
|
||||
nest2 = mnl_attr_nest_start(nlh, ++i);
|
||||
nftnl_set_elem_nlmsg_build_payload(nlh, nlse);
|
||||
mnl_attr_nest_end(nlh, nest2);
|
||||
@@ -2005,7 +2005,7 @@ static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
|
||||
dev_array = nft_dev_array(dev_expr, &num_devs);
|
||||
nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
|
||||
for (i = 0; i < num_devs; i++) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
|
||||
+ cmd_add_loc(cmd, nlh, dev_array[i].location);
|
||||
mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
|
||||
}
|
||||
|
||||
@@ -2037,9 +2037,9 @@ int mnl_nft_flowtable_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
NFT_MSG_NEWFLOWTABLE, cmd->handle.family,
|
||||
NLM_F_CREATE | flags, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_TABLE, cmd->handle.table.name);
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.flowtable.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.flowtable.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_NAME, cmd->handle.flowtable.name);
|
||||
|
||||
nftnl_flowtable_nlmsg_build_payload(nlh, flo);
|
||||
@@ -2086,16 +2086,15 @@ int mnl_nft_flowtable_del(struct netlink_ctx *ctx, struct cmd *cmd)
|
||||
msg_type, cmd->handle.family,
|
||||
0, ctx->seqnum);
|
||||
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.table.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_TABLE, cmd->handle.table.name);
|
||||
|
||||
if (cmd->handle.flowtable.name) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len,
|
||||
- &cmd->handle.flowtable.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.flowtable.location);
|
||||
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_NAME,
|
||||
cmd->handle.flowtable.name);
|
||||
} else if (cmd->handle.handle.id) {
|
||||
- cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.handle.location);
|
||||
+ cmd_add_loc(cmd, nlh, &cmd->handle.handle.location);
|
||||
mnl_attr_put_u64(nlh, NFTA_FLOWTABLE_HANDLE,
|
||||
htobe64(cmd->handle.handle.id));
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
From 66dc95d7a3f7c0e4527f4e960f5c397fd3b82af5 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] rule: netlink attribute offset is uint32_t for struct
|
||||
nlerr_loc
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 42b081df747729b0d83b69d2816be4091af56a58
|
||||
|
||||
commit 42b081df747729b0d83b69d2816be4091af56a58
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Thu Oct 24 00:08:24 2024 +0200
|
||||
|
||||
rule: netlink attribute offset is uint32_t for struct nlerr_loc
|
||||
|
||||
The maximum netlink message length (nlh->nlmsg_len) is uint32_t, struct
|
||||
nlerr_loc stores the offset to the netlink attribute which must be
|
||||
uint32_t, not uint16_t.
|
||||
|
||||
While at it, remove check for zero netlink attribute offset in
|
||||
nft_cmd_error() which should not ever happen, likely this check was
|
||||
there to prevent the uint16_t offset overflow.
|
||||
|
||||
Fixes: f8aec603aa7e ("src: initial extended netlink error reporting")
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/rule.h | 2 +-
|
||||
src/cmd.c | 2 --
|
||||
2 files changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/rule.h b/include/rule.h
|
||||
index a1628d8..3fcfa44 100644
|
||||
--- a/include/rule.h
|
||||
+++ b/include/rule.h
|
||||
@@ -695,7 +695,7 @@ void monitor_free(struct monitor *m);
|
||||
#define NFT_NLATTR_LOC_MAX 32
|
||||
|
||||
struct nlerr_loc {
|
||||
- uint16_t offset;
|
||||
+ uint32_t offset;
|
||||
const struct location *location;
|
||||
};
|
||||
|
||||
diff --git a/src/cmd.c b/src/cmd.c
|
||||
index 78a2aa3..0c7a43e 100644
|
||||
--- a/src/cmd.c
|
||||
+++ b/src/cmd.c
|
||||
@@ -323,8 +323,6 @@ void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < cmd->num_attrs; i++) {
|
||||
- if (!cmd->attr[i].offset)
|
||||
- break;
|
||||
if (cmd->attr[i].offset == err->offset)
|
||||
loc = cmd->attr[i].location;
|
||||
}
|
193
0007-src-fix-extended-netlink-error-reporting-with-large-.patch
Normal file
193
0007-src-fix-extended-netlink-error-reporting-with-large-.patch
Normal file
@ -0,0 +1,193 @@
|
||||
From c62c11ee27daf90c74a46353df4936b869624e72 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] src: fix extended netlink error reporting with large set
|
||||
elements
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 68d2de3ca6c6eb18f5b32f7b4324a85c9c6c358e
|
||||
|
||||
commit 68d2de3ca6c6eb18f5b32f7b4324a85c9c6c358e
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Thu Oct 24 00:24:55 2024 +0200
|
||||
|
||||
src: fix extended netlink error reporting with large set elements
|
||||
|
||||
Large sets can expand into several netlink messages, use sequence number
|
||||
and attribute offset to correlate the set element and the location.
|
||||
|
||||
When set element command expands into several netlink messages,
|
||||
increment sequence number for each netlink message. Update struct cmd to
|
||||
store the range of netlink messages that result from this command.
|
||||
|
||||
struct nlerr_loc remains in the same size in x86_64.
|
||||
|
||||
# nft -f set-65535.nft
|
||||
set-65535.nft:65029:22-32: Error: Could not process rule: File exists
|
||||
create element x y { 1.1.254.253 }
|
||||
^^^^^^^^^^^
|
||||
|
||||
Fixes: f8aec603aa7e ("src: initial extended netlink error reporting")
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/rule.h | 4 +++-
|
||||
src/cmd.c | 4 +++-
|
||||
src/libnftables.c | 12 ++++++++----
|
||||
src/mnl.c | 9 +++++----
|
||||
src/parser_json.c | 4 ++--
|
||||
5 files changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/rule.h b/include/rule.h
|
||||
index 3fcfa44..48e148e 100644
|
||||
--- a/include/rule.h
|
||||
+++ b/include/rule.h
|
||||
@@ -695,6 +695,7 @@ void monitor_free(struct monitor *m);
|
||||
#define NFT_NLATTR_LOC_MAX 32
|
||||
|
||||
struct nlerr_loc {
|
||||
+ uint32_t seqnum;
|
||||
uint32_t offset;
|
||||
const struct location *location;
|
||||
};
|
||||
@@ -717,7 +718,8 @@ struct cmd {
|
||||
enum cmd_ops op;
|
||||
enum cmd_obj obj;
|
||||
struct handle handle;
|
||||
- uint32_t seqnum;
|
||||
+ uint32_t seqnum_from;
|
||||
+ uint32_t seqnum_to;
|
||||
union {
|
||||
void *data;
|
||||
struct expr *expr;
|
||||
diff --git a/src/cmd.c b/src/cmd.c
|
||||
index 0c7a43e..eb44b98 100644
|
||||
--- a/src/cmd.c
|
||||
+++ b/src/cmd.c
|
||||
@@ -24,6 +24,7 @@ void cmd_add_loc(struct cmd *cmd, const struct nlmsghdr *nlh, const struct locat
|
||||
cmd->attr = xrealloc(cmd->attr, sizeof(struct nlerr_loc) * cmd->attr_array_len);
|
||||
}
|
||||
|
||||
+ cmd->attr[cmd->num_attrs].seqnum = nlh->nlmsg_seq;
|
||||
cmd->attr[cmd->num_attrs].offset = nlh->nlmsg_len;
|
||||
cmd->attr[cmd->num_attrs].location = loc;
|
||||
cmd->num_attrs++;
|
||||
@@ -323,7 +324,8 @@ void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < cmd->num_attrs; i++) {
|
||||
- if (cmd->attr[i].offset == err->offset)
|
||||
+ if (cmd->attr[i].seqnum == err->seqnum &&
|
||||
+ cmd->attr[i].offset == err->offset)
|
||||
loc = cmd->attr[i].location;
|
||||
}
|
||||
|
||||
diff --git a/src/libnftables.c b/src/libnftables.c
|
||||
index 3550961..1df22b3 100644
|
||||
--- a/src/libnftables.c
|
||||
+++ b/src/libnftables.c
|
||||
@@ -39,7 +39,7 @@ static int nft_netlink(struct nft_ctx *nft,
|
||||
|
||||
batch_seqnum = mnl_batch_begin(ctx.batch, mnl_seqnum_inc(&seqnum));
|
||||
list_for_each_entry(cmd, cmds, list) {
|
||||
- ctx.seqnum = cmd->seqnum = mnl_seqnum_inc(&seqnum);
|
||||
+ ctx.seqnum = cmd->seqnum_from = mnl_seqnum_inc(&seqnum);
|
||||
ret = do_command(&ctx, cmd);
|
||||
if (ret < 0) {
|
||||
netlink_io_error(&ctx, &cmd->location,
|
||||
@@ -47,6 +47,8 @@ static int nft_netlink(struct nft_ctx *nft,
|
||||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
+ seqnum = cmd->seqnum_to = ctx.seqnum;
|
||||
+ mnl_seqnum_inc(&seqnum);
|
||||
num_cmds++;
|
||||
}
|
||||
if (!nft->check)
|
||||
@@ -80,12 +82,14 @@ static int nft_netlink(struct nft_ctx *nft,
|
||||
cmd = list_first_entry(cmds, struct cmd, list);
|
||||
|
||||
list_for_each_entry_from(cmd, cmds, list) {
|
||||
- last_seqnum = cmd->seqnum;
|
||||
- if (err->seqnum == cmd->seqnum ||
|
||||
+ last_seqnum = cmd->seqnum_to;
|
||||
+ if ((err->seqnum >= cmd->seqnum_from &&
|
||||
+ err->seqnum <= cmd->seqnum_to) ||
|
||||
err->seqnum == batch_seqnum) {
|
||||
nft_cmd_error(&ctx, cmd, err);
|
||||
errno = err->err;
|
||||
- if (err->seqnum == cmd->seqnum) {
|
||||
+ if (err->seqnum >= cmd->seqnum_from ||
|
||||
+ err->seqnum <= cmd->seqnum_to) {
|
||||
mnl_err_list_free(err);
|
||||
break;
|
||||
}
|
||||
diff --git a/src/mnl.c b/src/mnl.c
|
||||
index 42d1b0d..12a6345 100644
|
||||
--- a/src/mnl.c
|
||||
+++ b/src/mnl.c
|
||||
@@ -1722,7 +1722,7 @@ static void netlink_dump_setelem_done(struct netlink_ctx *ctx)
|
||||
static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd,
|
||||
struct nftnl_batch *batch,
|
||||
enum nf_tables_msg_types msg_type,
|
||||
- unsigned int flags, uint32_t seqnum,
|
||||
+ unsigned int flags, uint32_t *seqnum,
|
||||
const struct expr *set,
|
||||
struct netlink_ctx *ctx)
|
||||
{
|
||||
@@ -1741,7 +1741,7 @@ static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd,
|
||||
next:
|
||||
nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), msg_type,
|
||||
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
|
||||
- flags, seqnum);
|
||||
+ flags, *seqnum);
|
||||
|
||||
if (nftnl_set_is_set(nls, NFTNL_SET_TABLE)) {
|
||||
mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_TABLE,
|
||||
@@ -1774,6 +1774,7 @@ next:
|
||||
if (mnl_nft_attr_nest_overflow(nlh, nest1, nest2)) {
|
||||
mnl_attr_nest_end(nlh, nest1);
|
||||
mnl_nft_batch_continue(batch);
|
||||
+ mnl_seqnum_inc(seqnum);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
@@ -1808,7 +1809,7 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
netlink_dump_set(nls, ctx);
|
||||
|
||||
err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, NFT_MSG_NEWSETELEM,
|
||||
- flags, ctx->seqnum, expr, ctx);
|
||||
+ flags, &ctx->seqnum, expr, ctx);
|
||||
nftnl_set_free(nls);
|
||||
|
||||
return err;
|
||||
@@ -1868,7 +1869,7 @@ int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd,
|
||||
msg_type = NFT_MSG_DESTROYSETELEM;
|
||||
|
||||
err = mnl_nft_setelem_batch(nls, cmd, ctx->batch, msg_type, 0,
|
||||
- ctx->seqnum, init, ctx);
|
||||
+ &ctx->seqnum, init, ctx);
|
||||
nftnl_set_free(nls);
|
||||
|
||||
return err;
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index bbe3b1c..37ec34c 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -4269,13 +4269,13 @@ static json_t *seqnum_to_json(const uint32_t seqnum)
|
||||
cur = json_cmd_assoc_list;
|
||||
json_cmd_assoc_list = cur->next;
|
||||
|
||||
- key = cur->cmd->seqnum % CMD_ASSOC_HSIZE;
|
||||
+ key = cur->cmd->seqnum_from % CMD_ASSOC_HSIZE;
|
||||
hlist_add_head(&cur->hnode, &json_cmd_assoc_hash[key]);
|
||||
}
|
||||
|
||||
key = seqnum % CMD_ASSOC_HSIZE;
|
||||
hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
|
||||
- if (cur->cmd->seqnum == seqnum)
|
||||
+ if (cur->cmd->seqnum_from == seqnum)
|
||||
return cur->json;
|
||||
}
|
||||
|
62
0008-tests-monitor-fix-up-test-case-breakage.patch
Normal file
62
0008-tests-monitor-fix-up-test-case-breakage.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 42ba69f76beabde5f22a8616469fb296ac72e16e Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] tests: monitor: fix up test case breakage
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit c416416b03d804663c5f7a738a3e1449eeb28157
|
||||
|
||||
commit c416416b03d804663c5f7a738a3e1449eeb28157
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Tue Oct 29 21:12:19 2024 +0100
|
||||
|
||||
tests: monitor: fix up test case breakage
|
||||
|
||||
Monitor test fails:
|
||||
|
||||
echo: running tests from file set-simple.t
|
||||
echo output differs!
|
||||
-add element ip t portrange { 1024-65535 }
|
||||
add element ip t portrange { 100-200 }
|
||||
+add element ip t portrange { 1024-65535 }
|
||||
+# new generation 510 by process 129009 (nft)
|
||||
|
||||
I also noticed -j mode did not work correctly, add missing json annotations
|
||||
in set-concat-interval.t while at it.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
tests/monitor/testcases/set-concat-interval.t | 3 +++
|
||||
tests/monitor/testcases/set-simple.t | 5 +++--
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tests/monitor/testcases/set-concat-interval.t b/tests/monitor/testcases/set-concat-interval.t
|
||||
index 763dc31..75f3828 100644
|
||||
--- a/tests/monitor/testcases/set-concat-interval.t
|
||||
+++ b/tests/monitor/testcases/set-concat-interval.t
|
||||
@@ -10,3 +10,6 @@ I add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; elem
|
||||
O add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; }
|
||||
O add element ip t s { 20-80 . 0x14 : accept }
|
||||
O add element ip t s { 1-10 . 0xa : drop }
|
||||
+J {"add": {"map": {"family": "ip", "name": "s", "table": "t", "type": ["integer", "integer"], "handle": 0, "map": "verdict", "flags": ["interval"]}}}
|
||||
+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [20, 80]}, 20]}, {"accept": null}]]}}}}
|
||||
+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [1, 10]}, 10]}, {"drop": null}]]}}}}
|
||||
diff --git a/tests/monitor/testcases/set-simple.t b/tests/monitor/testcases/set-simple.t
|
||||
index 8ca4f32..6853a0e 100644
|
||||
--- a/tests/monitor/testcases/set-simple.t
|
||||
+++ b/tests/monitor/testcases/set-simple.t
|
||||
@@ -37,9 +37,10 @@ J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem"
|
||||
# make sure half open before other element works
|
||||
I add element ip t portrange { 1024-65535 }
|
||||
I add element ip t portrange { 100-200 }
|
||||
-O -
|
||||
-J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}}
|
||||
+O add element ip t portrange { 100-200 }
|
||||
+O add element ip t portrange { 1024-65535 }
|
||||
J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [100, 200]}]}}}}
|
||||
+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}}
|
||||
|
||||
# make sure deletion of elements works
|
||||
I delete element ip t portrange { 0-10 }
|
142
0009-doc-extend-description-of-fib-expression.patch
Normal file
142
0009-doc-extend-description-of-fib-expression.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 86deb09d9886a9ef9c089a6edc0859419e8b4dfd Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:45 +0100
|
||||
Subject: [PATCH] doc: extend description of fib expression
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
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 782494b..c6a33bb 100644
|
||||
--- a/doc/primary-expression.txt
|
||||
+++ b/doc/primary-expression.txt
|
||||
@@ -310,17 +310,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)
|
||||
@@ -329,25 +360,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 }
|
||||
----------------------
|
83
0010-json-collapse-set-element-commands-from-parser.patch
Normal file
83
0010-json-collapse-set-element-commands-from-parser.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From 21295af879d5cc6a41bd823e708a97684034ed1e Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:46 +0100
|
||||
Subject: [PATCH] json: collapse set element commands from parser
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 193faa5475a5df7d9ac0b1a8fe647196de3e5688
|
||||
|
||||
commit 193faa5475a5df7d9ac0b1a8fe647196de3e5688
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Thu Oct 31 21:38:02 2024 +0100
|
||||
|
||||
json: collapse set element commands from parser
|
||||
|
||||
Update json parser to collapse {add,create} element commands to reduce
|
||||
memory consumption in the case of large sets defined by one element per
|
||||
command:
|
||||
|
||||
{"nftables": [{"add": {"element": {"family": "ip", "table": "x", "name":
|
||||
"y", "elem": [{"set": ["1.1.0.0"]}]}}},...]}
|
||||
|
||||
Add CTX_F_COLLAPSED flag to report that command has been collapsed.
|
||||
|
||||
This patch reduces memory consumption by ~32% this case.
|
||||
|
||||
Fixes: 20f1c60ac8c8 ("src: collapse set element commands from parser")
|
||||
Reported-by: Eric Garver <eric@garver.life>
|
||||
Tested-by: Eric Garver <eric@garver.life>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
src/parser_json.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index 37ec34c..68c0600 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <netlink.h>
|
||||
#include <parser.h>
|
||||
#include <rule.h>
|
||||
+#include <cmd.h>
|
||||
#include <sctp_chunk.h>
|
||||
#include <socket.h>
|
||||
|
||||
@@ -49,6 +50,7 @@
|
||||
#define CTX_F_SES (1 << 6) /* set_elem_expr_stmt */
|
||||
#define CTX_F_MAP (1 << 7) /* LHS of map_expr */
|
||||
#define CTX_F_CONCAT (1 << 8) /* inside concat_expr */
|
||||
+#define CTX_F_COLLAPSED (1 << 9)
|
||||
|
||||
struct json_ctx {
|
||||
struct nft_ctx *nft;
|
||||
@@ -3490,6 +3492,15 @@ static struct cmd *json_parse_cmd_add_element(struct json_ctx *ctx,
|
||||
handle_free(&h);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
+ if ((op == CMD_CREATE || op == CMD_ADD) &&
|
||||
+ nft_cmd_collapse_elems(op, ctx->cmds, &h, expr)) {
|
||||
+ handle_free(&h);
|
||||
+ expr_free(expr);
|
||||
+ ctx->flags |= CTX_F_COLLAPSED;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return cmd_alloc(op, cmd_obj, &h, int_loc, expr);
|
||||
}
|
||||
|
||||
@@ -4319,6 +4330,11 @@ static int __json_parse(struct json_ctx *ctx)
|
||||
cmd = json_parse_cmd(ctx, value);
|
||||
|
||||
if (!cmd) {
|
||||
+ if (ctx->flags & CTX_F_COLLAPSED) {
|
||||
+ ctx->flags &= ~CTX_F_COLLAPSED;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
json_error(ctx, "Parsing command array at index %zd failed.", index);
|
||||
return -1;
|
||||
}
|
526
0011-json-Support-typeof-in-set-and-map-types.patch
Normal file
526
0011-json-Support-typeof-in-set-and-map-types.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From d66b043a46f4b8e48ab96503613d4ea7483899d4 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:46 +0100
|
||||
Subject: [PATCH] json: Support typeof in set and map types
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit bb6312484af93a83a9ec8716f3887a43566a775a
|
||||
|
||||
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 +-
|
||||
tests/monitor/testcases/set-concat-interval.t | 2 +-
|
||||
.../maps/dumps/0012map_concat_0.json-nft | 21 +++++--
|
||||
.../maps/dumps/0017_map_variable_0.json-nft | 18 +++++-
|
||||
.../maps/dumps/named_limits.json-nft | 55 ++++++++++++++++---
|
||||
.../dumps/typeof_maps_add_delete.json-nft | 9 ++-
|
||||
.../maps/dumps/typeof_maps_update_0.json-nft | 9 ++-
|
||||
.../maps/dumps/vmap_timeout.json-nft | 22 ++++++--
|
||||
.../packetpath/dumps/set_lookups.json-nft | 42 +++++++++++---
|
||||
.../sets/dumps/0048set_counters_0.json-nft | 9 ++-
|
||||
.../testcases/sets/dumps/inner_0.json-nft | 34 ++++++++++--
|
||||
.../set_element_timeout_updates.json-nft | 9 ++-
|
||||
15 files changed, 220 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
|
||||
index 2f29ac0..244eb41 100644
|
||||
--- a/doc/libnftables-json.adoc
|
||||
+++ b/doc/libnftables-json.adoc
|
||||
@@ -341,7 +341,7 @@ ____
|
||||
"auto-merge":* 'BOOLEAN'
|
||||
*}}*
|
||||
|
||||
-'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' ]
|
||||
@@ -381,8 +381,9 @@ that they translate a unique key to a value.
|
||||
Automatic merging of adjacent/overlapping set elements in interval sets.
|
||||
|
||||
==== 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 b1531ff..1f609bf 100644
|
||||
--- a/src/json.c
|
||||
+++ b/src/json.c
|
||||
@@ -96,6 +96,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];
|
||||
@@ -158,7 +169,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 68c0600..02cfcd6 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -1731,7 +1731,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}]}}}
|
||||
diff --git a/tests/monitor/testcases/set-concat-interval.t b/tests/monitor/testcases/set-concat-interval.t
|
||||
index 75f3828..3542b82 100644
|
||||
--- a/tests/monitor/testcases/set-concat-interval.t
|
||||
+++ b/tests/monitor/testcases/set-concat-interval.t
|
||||
@@ -10,6 +10,6 @@ I add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; elem
|
||||
O add map ip t s { typeof udp length . @ih,32,32 : verdict; flags interval; }
|
||||
O add element ip t s { 20-80 . 0x14 : accept }
|
||||
O add element ip t s { 1-10 . 0xa : drop }
|
||||
-J {"add": {"map": {"family": "ip", "name": "s", "table": "t", "type": ["integer", "integer"], "handle": 0, "map": "verdict", "flags": ["interval"]}}}
|
||||
+J {"add": {"map": {"family": "ip", "name": "s", "table": "t", "type": {"typeof": {"concat": [{"payload": {"protocol": "udp", "field": "length"}}, {"payload": {"base": "ih", "offset": 32, "len": 32}}]}}, "handle": 0, "map": "verdict", "flags": ["interval"]}}}
|
||||
J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [20, 80]}, 20]}, {"accept": null}]]}}}}
|
||||
J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [[{"concat": [{"range": [1, 10]}, 10]}, {"drop": null}]]}}}}
|
||||
diff --git a/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft b/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
|
||||
index 0005223..88bf498 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/0012map_concat_0.json-nft
|
||||
@@ -31,10 +31,23 @@
|
||||
"family": "ip",
|
||||
"name": "w",
|
||||
"table": "x",
|
||||
- "type": [
|
||||
- "ipv4_addr",
|
||||
- "mark"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "meta": {
|
||||
+ "key": "mark"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "verdict",
|
||||
"flags": [
|
||||
diff --git a/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft b/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
|
||||
index 725498c..8eacf61 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/0017_map_variable_0.json-nft
|
||||
@@ -19,7 +19,14 @@
|
||||
"family": "ip",
|
||||
"name": "y",
|
||||
"table": "x",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "mark",
|
||||
"elem": [
|
||||
@@ -39,7 +46,14 @@
|
||||
"family": "ip",
|
||||
"name": "z",
|
||||
"table": "x",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "mark",
|
||||
"elem": [
|
||||
diff --git a/tests/shell/testcases/maps/dumps/named_limits.json-nft b/tests/shell/testcases/maps/dumps/named_limits.json-nft
|
||||
index 7fa1298..3c6845a 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/named_limits.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/named_limits.json-nft
|
||||
@@ -75,7 +75,14 @@
|
||||
"family": "inet",
|
||||
"name": "tarpit4",
|
||||
"table": "filter",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"size": 10000,
|
||||
"flags": [
|
||||
@@ -90,7 +97,14 @@
|
||||
"family": "inet",
|
||||
"name": "tarpit6",
|
||||
"table": "filter",
|
||||
- "type": "ipv6_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip6",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"size": 10000,
|
||||
"flags": [
|
||||
@@ -105,11 +119,29 @@
|
||||
"family": "inet",
|
||||
"name": "addr4limit",
|
||||
"table": "filter",
|
||||
- "type": [
|
||||
- "inet_proto",
|
||||
- "ipv4_addr",
|
||||
- "inet_service"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "meta": {
|
||||
+ "key": "l4proto"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "tcp",
|
||||
+ "field": "sport"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "limit",
|
||||
"flags": [
|
||||
@@ -244,7 +276,14 @@
|
||||
"family": "inet",
|
||||
"name": "saddr6limit",
|
||||
"table": "filter",
|
||||
- "type": "ipv6_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip6",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "limit",
|
||||
"flags": [
|
||||
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
|
||||
index b3204a2..effe02d 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_add_delete.json-nft
|
||||
@@ -39,7 +39,14 @@
|
||||
"family": "ip",
|
||||
"name": "dynmark",
|
||||
"table": "dynset",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "daddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "mark",
|
||||
"size": 64,
|
||||
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
|
||||
index 1d50477..7315146 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_update_0.json-nft
|
||||
@@ -50,7 +50,14 @@
|
||||
"family": "ip",
|
||||
"name": "sticky-set-svc-153CN2XYVUHRQ7UB",
|
||||
"table": "kube-nfproxy-v4",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "daddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "mark",
|
||||
"size": 65535,
|
||||
diff --git a/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft b/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
|
||||
index 1c3aa59..71e9a9e 100644
|
||||
--- a/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
|
||||
+++ b/tests/shell/testcases/maps/dumps/vmap_timeout.json-nft
|
||||
@@ -87,10 +87,24 @@
|
||||
"family": "inet",
|
||||
"name": "portaddrmap",
|
||||
"table": "filter",
|
||||
- "type": [
|
||||
- "ipv4_addr",
|
||||
- "inet_service"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "daddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "th",
|
||||
+ "field": "dport"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"map": "verdict",
|
||||
"flags": [
|
||||
diff --git a/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
|
||||
index 24363f9..bcf6914 100644
|
||||
--- a/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
|
||||
+++ b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
|
||||
@@ -60,10 +60,23 @@
|
||||
"family": "ip",
|
||||
"name": "s2",
|
||||
"table": "t",
|
||||
- "type": [
|
||||
- "ipv4_addr",
|
||||
- "iface_index"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "meta": {
|
||||
+ "key": "iif"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"elem": [
|
||||
{
|
||||
@@ -113,10 +126,23 @@
|
||||
"family": "ip",
|
||||
"name": "nomatch",
|
||||
"table": "t",
|
||||
- "type": [
|
||||
- "ipv4_addr",
|
||||
- "iface_index"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "meta": {
|
||||
+ "key": "iif"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"elem": [
|
||||
{
|
||||
diff --git a/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft b/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
|
||||
index 62a6a17..4be4112 100644
|
||||
--- a/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
|
||||
+++ b/tests/shell/testcases/sets/dumps/0048set_counters_0.json-nft
|
||||
@@ -31,7 +31,14 @@
|
||||
"family": "ip",
|
||||
"name": "y",
|
||||
"table": "x",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"elem": [
|
||||
{
|
||||
diff --git a/tests/shell/testcases/sets/dumps/inner_0.json-nft b/tests/shell/testcases/sets/dumps/inner_0.json-nft
|
||||
index 8d84e1c..e5dc198 100644
|
||||
--- a/tests/shell/testcases/sets/dumps/inner_0.json-nft
|
||||
+++ b/tests/shell/testcases/sets/dumps/inner_0.json-nft
|
||||
@@ -27,10 +27,26 @@
|
||||
"family": "netdev",
|
||||
"name": "x",
|
||||
"table": "x",
|
||||
- "type": [
|
||||
- "ipv4_addr",
|
||||
- "ipv4_addr"
|
||||
- ],
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "concat": [
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "tunnel": "vxlan",
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "payload": {
|
||||
+ "tunnel": "vxlan",
|
||||
+ "protocol": "ip",
|
||||
+ "field": "daddr"
|
||||
+ }
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"elem": [
|
||||
{
|
||||
@@ -47,7 +63,15 @@
|
||||
"family": "netdev",
|
||||
"name": "y",
|
||||
"table": "x",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "tunnel": "vxlan",
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"size": 65535,
|
||||
"flags": [
|
||||
diff --git a/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft b/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
|
||||
index aa90829..d92d8d7 100644
|
||||
--- a/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
|
||||
+++ b/tests/shell/testcases/sets/dumps/set_element_timeout_updates.json-nft
|
||||
@@ -31,7 +31,14 @@
|
||||
"family": "ip",
|
||||
"name": "s",
|
||||
"table": "t",
|
||||
- "type": "ipv4_addr",
|
||||
+ "type": {
|
||||
+ "typeof": {
|
||||
+ "payload": {
|
||||
+ "protocol": "ip",
|
||||
+ "field": "saddr"
|
||||
+ }
|
||||
+ }
|
||||
+ },
|
||||
"handle": 0,
|
||||
"flags": [
|
||||
"timeout"
|
@ -0,0 +1,43 @@
|
||||
From 6c31db6766df3bdeb1ff6039e651a54850b68aa3 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:46 +0100
|
||||
Subject: [PATCH] tests: py: Fix for storing payload into missing file
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit c1c0c54e237c880adaa8172b93d7450e6c617cfc
|
||||
|
||||
commit c1c0c54e237c880adaa8172b93d7450e6c617cfc
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Wed Oct 2 19:55:49 2024 +0200
|
||||
|
||||
tests: py: Fix for storing payload into missing file
|
||||
|
||||
When running a test for which no corresponding *.payload file exists,
|
||||
the *.payload.got file name was incorrectly constructed due to
|
||||
'payload_path' variable not being set.
|
||||
|
||||
Fixes: 2cfab7a3e10fc ("tests/py: Write dissenting payload into the right file")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
tests/py/nft-test.py | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
|
||||
index 00799e2..7acdb77 100755
|
||||
--- a/tests/py/nft-test.py
|
||||
+++ b/tests/py/nft-test.py
|
||||
@@ -769,10 +769,9 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
|
||||
|
||||
if rule[1].strip() == "ok":
|
||||
payload_expected = None
|
||||
- payload_path = None
|
||||
+ payload_path = "%s.payload" % filename_path
|
||||
try:
|
||||
- payload_log = open("%s.payload" % filename_path)
|
||||
- payload_path = payload_log.name
|
||||
+ payload_log = open(payload_path)
|
||||
payload_expected = payload_find_expected(payload_log, rule[0])
|
||||
except:
|
||||
payload_log = None
|
260
0013-monitor-Recognize-flowtable-add-del-events.patch
Normal file
260
0013-monitor-Recognize-flowtable-add-del-events.patch
Normal file
@ -0,0 +1,260 @@
|
||||
From 8cfbb8c3427f232484bacab3116f6925f3976c7b Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Thu, 7 Nov 2024 18:38:46 +0100
|
||||
Subject: [PATCH] monitor: Recognize flowtable add/del events
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-65346
|
||||
Upstream Status: nftables commit 73a8adfc2432ec8337288cc90e7c9f4509139846
|
||||
|
||||
commit 73a8adfc2432ec8337288cc90e7c9f4509139846
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Wed May 15 16:01:20 2024 +0200
|
||||
|
||||
monitor: Recognize flowtable add/del events
|
||||
|
||||
These were entirely ignored before, add the necessary code analogous to
|
||||
e.g. objects.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
|
||||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||||
---
|
||||
include/json.h | 10 ++++
|
||||
include/netlink.h | 1 +
|
||||
include/rule.h | 1 +
|
||||
src/json.c | 6 +++
|
||||
src/monitor.c | 61 ++++++++++++++++++++++
|
||||
src/parser_json.c | 6 +++
|
||||
src/rule.c | 15 ++++++
|
||||
tests/monitor/testcases/flowtable-simple.t | 10 ++++
|
||||
8 files changed, 110 insertions(+)
|
||||
create mode 100644 tests/monitor/testcases/flowtable-simple.t
|
||||
|
||||
diff --git a/include/json.h b/include/json.h
|
||||
index 39be892..0670b87 100644
|
||||
--- a/include/json.h
|
||||
+++ b/include/json.h
|
||||
@@ -11,6 +11,7 @@ struct nlmsghdr;
|
||||
struct rule;
|
||||
struct set;
|
||||
struct obj;
|
||||
+struct flowtable;
|
||||
struct stmt;
|
||||
struct symbol_table;
|
||||
struct table;
|
||||
@@ -113,6 +114,8 @@ 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);
|
||||
+void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
|
||||
+ const char *cmd, struct flowtable *ft);
|
||||
void monitor_print_rule_json(struct netlink_mon_handler *monh,
|
||||
const char *cmd, struct rule *r);
|
||||
|
||||
@@ -254,6 +257,13 @@ static inline void monitor_print_obj_json(struct netlink_mon_handler *monh,
|
||||
/* empty */
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+monitor_print_flowtable_json(struct netlink_mon_handler *monh,
|
||||
+ const char *cmd, struct flowtable *ft)
|
||||
+{
|
||||
+ /* empty */
|
||||
+}
|
||||
+
|
||||
static inline void monitor_print_rule_json(struct netlink_mon_handler *monh,
|
||||
const char *cmd, struct rule *r)
|
||||
{
|
||||
diff --git a/include/netlink.h b/include/netlink.h
|
||||
index cf7ba36..e9667a2 100644
|
||||
--- a/include/netlink.h
|
||||
+++ b/include/netlink.h
|
||||
@@ -97,6 +97,7 @@ extern struct nftnl_table *netlink_table_alloc(const struct nlmsghdr *nlh);
|
||||
extern struct nftnl_chain *netlink_chain_alloc(const struct nlmsghdr *nlh);
|
||||
extern struct nftnl_set *netlink_set_alloc(const struct nlmsghdr *nlh);
|
||||
extern struct nftnl_obj *netlink_obj_alloc(const struct nlmsghdr *nlh);
|
||||
+extern struct nftnl_flowtable *netlink_flowtable_alloc(const struct nlmsghdr *nlh);
|
||||
extern struct nftnl_rule *netlink_rule_alloc(const struct nlmsghdr *nlh);
|
||||
|
||||
struct nft_data_linearize {
|
||||
diff --git a/include/rule.h b/include/rule.h
|
||||
index 48e148e..238be23 100644
|
||||
--- a/include/rule.h
|
||||
+++ b/include/rule.h
|
||||
@@ -551,6 +551,7 @@ extern struct flowtable *flowtable_lookup_fuzzy(const char *ft_name,
|
||||
const struct table **table);
|
||||
|
||||
void flowtable_print(const struct flowtable *n, struct output_ctx *octx);
|
||||
+void flowtable_print_plain(const struct flowtable *ft, struct output_ctx *octx);
|
||||
|
||||
/**
|
||||
* enum cmd_ops - command operations
|
||||
diff --git a/src/json.c b/src/json.c
|
||||
index 1f609bf..64a6888 100644
|
||||
--- a/src/json.c
|
||||
+++ b/src/json.c
|
||||
@@ -2108,6 +2108,12 @@ void monitor_print_obj_json(struct netlink_mon_handler *monh,
|
||||
monitor_print_json(monh, cmd, obj_print_json(o));
|
||||
}
|
||||
|
||||
+void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
|
||||
+ const char *cmd, struct flowtable *ft)
|
||||
+{
|
||||
+ monitor_print_json(monh, cmd, flowtable_print_json(ft));
|
||||
+}
|
||||
+
|
||||
void monitor_print_rule_json(struct netlink_mon_handler *monh,
|
||||
const char *cmd, struct rule *r)
|
||||
{
|
||||
diff --git a/src/monitor.c b/src/monitor.c
|
||||
index 2fc16d6..a787db8 100644
|
||||
--- a/src/monitor.c
|
||||
+++ b/src/monitor.c
|
||||
@@ -127,6 +127,19 @@ struct nftnl_obj *netlink_obj_alloc(const struct nlmsghdr *nlh)
|
||||
return nlo;
|
||||
}
|
||||
|
||||
+struct nftnl_flowtable *netlink_flowtable_alloc(const struct nlmsghdr *nlh)
|
||||
+{
|
||||
+ struct nftnl_flowtable *nlf;
|
||||
+
|
||||
+ nlf = nftnl_flowtable_alloc();
|
||||
+ if (nlf == NULL)
|
||||
+ memory_allocation_error();
|
||||
+ if (nftnl_flowtable_nlmsg_parse(nlh, nlf) < 0)
|
||||
+ netlink_abi_error();
|
||||
+
|
||||
+ return nlf;
|
||||
+}
|
||||
+
|
||||
static uint32_t netlink_msg2nftnl_of(uint32_t type, uint16_t flags)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -542,6 +555,50 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type,
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
+static int netlink_events_flowtable_cb(const struct nlmsghdr *nlh, int type,
|
||||
+ struct netlink_mon_handler *monh)
|
||||
+{
|
||||
+ const char *family, *cmd;
|
||||
+ struct nftnl_flowtable *nlf;
|
||||
+ struct flowtable *ft;
|
||||
+
|
||||
+ nlf = netlink_flowtable_alloc(nlh);
|
||||
+
|
||||
+ ft = netlink_delinearize_flowtable(monh->ctx, nlf);
|
||||
+ if (!ft) {
|
||||
+ nftnl_flowtable_free(nlf);
|
||||
+ return MNL_CB_ERROR;
|
||||
+ }
|
||||
+ family = family2str(ft->handle.family);
|
||||
+ cmd = netlink_msg2cmd(type, nlh->nlmsg_flags);
|
||||
+
|
||||
+ switch (monh->format) {
|
||||
+ case NFTNL_OUTPUT_DEFAULT:
|
||||
+ nft_mon_print(monh, "%s ", cmd);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NFT_MSG_NEWFLOWTABLE:
|
||||
+ flowtable_print_plain(ft, &monh->ctx->nft->output);
|
||||
+ break;
|
||||
+ case NFT_MSG_DELFLOWTABLE:
|
||||
+ nft_mon_print(monh, "flowtable %s %s %s", family,
|
||||
+ ft->handle.table.name,
|
||||
+ ft->handle.flowtable.name);
|
||||
+ break;
|
||||
+ }
|
||||
+ nft_mon_print(monh, "\n");
|
||||
+ break;
|
||||
+ case NFTNL_OUTPUT_JSON:
|
||||
+ monitor_print_flowtable_json(monh, cmd, ft);
|
||||
+ if (!nft_output_echo(&monh->ctx->nft->output))
|
||||
+ nft_mon_print(monh, "\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ flowtable_free(ft);
|
||||
+ nftnl_flowtable_free(nlf);
|
||||
+ return MNL_CB_OK;
|
||||
+}
|
||||
+
|
||||
static void rule_map_decompose_cb(struct set *s, void *data)
|
||||
{
|
||||
if (!set_is_anonymous(s->flags))
|
||||
@@ -962,6 +1019,10 @@ static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
|
||||
case NFT_MSG_DELOBJ:
|
||||
ret = netlink_events_obj_cb(nlh, type, monh);
|
||||
break;
|
||||
+ case NFT_MSG_NEWFLOWTABLE:
|
||||
+ case NFT_MSG_DELFLOWTABLE:
|
||||
+ ret = netlink_events_flowtable_cb(nlh, type, monh);
|
||||
+ break;
|
||||
case NFT_MSG_NEWGEN:
|
||||
ret = netlink_events_newgen_cb(nlh, type, monh);
|
||||
break;
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index 02cfcd6..bae2c3c 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -4437,6 +4437,7 @@ static int json_echo_error(struct netlink_mon_handler *monh,
|
||||
|
||||
static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
|
||||
{
|
||||
+ struct nftnl_flowtable *nlf;
|
||||
struct nftnl_table *nlt;
|
||||
struct nftnl_chain *nlc;
|
||||
struct nftnl_rule *nlr;
|
||||
@@ -4473,6 +4474,11 @@ static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
|
||||
handle = nftnl_obj_get_u64(nlo, NFTNL_OBJ_HANDLE);
|
||||
nftnl_obj_free(nlo);
|
||||
break;
|
||||
+ case NFT_MSG_NEWFLOWTABLE:
|
||||
+ nlf = netlink_flowtable_alloc(nlh);
|
||||
+ handle = nftnl_flowtable_get_u64(nlf, NFTNL_FLOWTABLE_HANDLE);
|
||||
+ nftnl_flowtable_free(nlf);
|
||||
+ break;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
diff --git a/src/rule.c b/src/rule.c
|
||||
index 9536e68..151ed53 100644
|
||||
--- a/src/rule.c
|
||||
+++ b/src/rule.c
|
||||
@@ -2154,6 +2154,21 @@ void flowtable_print(const struct flowtable *s, struct output_ctx *octx)
|
||||
do_flowtable_print(s, &opts, octx);
|
||||
}
|
||||
|
||||
+void flowtable_print_plain(const struct flowtable *ft, struct output_ctx *octx)
|
||||
+{
|
||||
+ struct print_fmt_options opts = {
|
||||
+ .tab = "",
|
||||
+ .nl = " ",
|
||||
+ .table = ft->handle.table.name,
|
||||
+ .family = family2str(ft->handle.family),
|
||||
+ .stmt_separator = "; ",
|
||||
+ };
|
||||
+
|
||||
+ flowtable_print_declaration(ft, &opts, octx);
|
||||
+ nft_print(octx, "}");
|
||||
+}
|
||||
+
|
||||
+
|
||||
struct flowtable *flowtable_lookup_fuzzy(const char *ft_name,
|
||||
const struct nft_cache *cache,
|
||||
const struct table **t)
|
||||
diff --git a/tests/monitor/testcases/flowtable-simple.t b/tests/monitor/testcases/flowtable-simple.t
|
||||
new file mode 100644
|
||||
index 0000000..df8eccb
|
||||
--- /dev/null
|
||||
+++ b/tests/monitor/testcases/flowtable-simple.t
|
||||
@@ -0,0 +1,10 @@
|
||||
+# setup first
|
||||
+I add table ip t
|
||||
+I add flowtable ip t ft { hook ingress priority 0; devices = { lo }; }
|
||||
+O -
|
||||
+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}}
|
||||
+J {"add": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "lo"}}}
|
||||
+
|
||||
+I delete flowtable ip t ft
|
||||
+O -
|
||||
+J {"delete": {"flowtable": {"family": "ip", "name": "ft", "table": "t", "handle": 0, "hook": "ingress", "prio": 0, "dev": "lo"}}}
|
@ -1,7 +1,7 @@
|
||||
# Gating rhel
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-*
|
||||
- rhel-10
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-gating.functional}
|
||||
# - !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1-gating.functional}
|
||||
|
@ -1,9 +1,6 @@
|
||||
%define nft_rpmversion 1.0.9
|
||||
%define nft_specrelease 5
|
||||
|
||||
Name: nftables
|
||||
Version: %{nft_rpmversion}
|
||||
Release: %{nft_specrelease}%{?dist}%{?buildid}.1
|
||||
Version: 1.1.1
|
||||
Release: 1%{?dist}
|
||||
# Upstream released a 0.100 version, then 0.4. Need Epoch to get back on track.
|
||||
Epoch: 1
|
||||
Summary: Netfilter Tables userspace utilities
|
||||
@ -19,8 +16,19 @@ Source5: nat.nft
|
||||
Source6: nft-test.stderr.expect
|
||||
Source7: run-tests.stderr.expect
|
||||
|
||||
Patch1: 0001-Add-support-for-table-s-persist-flag.patch
|
||||
Patch2: 0002-cache-Always-set-NFT_CACHE_TERSE-for-list-cmd-with-t.patch
|
||||
Patch1: 0001-tests-shell-fix-spurious-dump-failure-in-vmap-timeou.patch
|
||||
Patch2: 0002-libnftables-json-fix-raw-payload-expression-document.patch
|
||||
Patch3: 0003-src-collapse-set-element-commands-from-parser.patch
|
||||
Patch4: 0004-mnl-rename-to-mnl_seqnum_alloc-to-mnl_seqnum_inc.patch
|
||||
Patch5: 0005-mnl-update-cmd_add_loc-to-take-struct-nlmsghdr.patch
|
||||
Patch6: 0006-rule-netlink-attribute-offset-is-uint32_t-for-struct.patch
|
||||
Patch7: 0007-src-fix-extended-netlink-error-reporting-with-large-.patch
|
||||
Patch8: 0008-tests-monitor-fix-up-test-case-breakage.patch
|
||||
Patch9: 0009-doc-extend-description-of-fib-expression.patch
|
||||
Patch10: 0010-json-collapse-set-element-commands-from-parser.patch
|
||||
Patch11: 0011-json-Support-typeof-in-set-and-map-types.patch
|
||||
Patch12: 0012-tests-py-Fix-for-storing-payload-into-missing-file.patch
|
||||
Patch13: 0013-monitor-Recognize-flowtable-add-del-events.patch
|
||||
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: automake
|
||||
@ -31,7 +39,7 @@ BuildRequires: flex
|
||||
BuildRequires: bison
|
||||
BuildRequires: pkgconfig(libmnl) >= 1.0.4
|
||||
BuildRequires: gmp-devel
|
||||
BuildRequires: pkgconfig(libnftnl) >= 1.2.6
|
||||
BuildRequires: pkgconfig(libnftnl) >= 1.2.8
|
||||
BuildRequires: systemd
|
||||
BuildRequires: asciidoc
|
||||
BuildRequires: pkgconfig(xtables) >= 1.6.1
|
||||
@ -135,6 +143,22 @@ cd py/
|
||||
%files -n python3-nftables -f %{pyproject_files}
|
||||
|
||||
%changelog
|
||||
* Thu Nov 07 2024 Phil Sutter <psutter@redhat.com> [1.1.1-1.el10]
|
||||
- monitor: Recognize flowtable add/del events (Phil Sutter) [RHEL-65346]
|
||||
- tests: py: Fix for storing payload into missing file (Phil Sutter) [RHEL-65346]
|
||||
- json: Support typeof in set and map types (Phil Sutter) [RHEL-65346]
|
||||
- json: collapse set element commands from parser (Phil Sutter) [RHEL-65346]
|
||||
- doc: extend description of fib expression (Phil Sutter) [RHEL-65346]
|
||||
- tests: monitor: fix up test case breakage (Phil Sutter) [RHEL-65346]
|
||||
- src: fix extended netlink error reporting with large set elements (Phil Sutter) [RHEL-65346]
|
||||
- rule: netlink attribute offset is uint32_t for struct nlerr_loc (Phil Sutter) [RHEL-65346]
|
||||
- mnl: update cmd_add_loc() to take struct nlmsghdr (Phil Sutter) [RHEL-65346]
|
||||
- mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc() (Phil Sutter) [RHEL-65346]
|
||||
- src: collapse set element commands from parser (Phil Sutter) [RHEL-65346]
|
||||
- libnftables-json: fix raw payload expression documentation (Phil Sutter) [RHEL-65346]
|
||||
- tests: shell: fix spurious dump failure in vmap timeout test (Phil Sutter) [RHEL-65346]
|
||||
- Rebase onto version 1.1.1 (Phil Sutter) [RHEL-65346]
|
||||
|
||||
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1:1.0.9-5.1
|
||||
- Bump release for October 2024 mass rebuild:
|
||||
Resolves: RHEL-64018
|
||||
|
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (nftables-1.0.9.tar.xz) = dc34099658e283d9fd4d06264b593710121074558305ea23ab298c5f6a6b564a826f186241b6e106fbaa4e11160cf77e68bb52b4ce401b28d8d2e403cd4b88e8
|
||||
SHA512 (nftables-1.1.1.tar.xz) = 676413d4adadffb15d52c1f8f6432636cab83a7bcda1a18d9f0e6b58819a2c027a49922588c02bd9ad386de930eaa697bfe74c0938b595bf1ee485bfa7cf2e50
|
||||
|
Loading…
Reference in New Issue
Block a user