import UBI nftables-1.1.5-3.el10

This commit is contained in:
AlmaLinux RelEng Bot 2026-05-19 18:39:04 -04:00
parent 2cf6cd965d
commit 36b5c1e31d
50 changed files with 1897 additions and 4485 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
nftables-1.1.1.tar.xz
nftables-1.1.5.tar.xz

View File

@ -1,11 +1,10 @@
From 50afb84d7064806ad7acc8364455062fc0751528 Mon Sep 17 00:00:00 2001
From df4f84d17daf107d9dc21d5b42ae6255b53f0ffd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 9 Sep 2025 16:49:27 +0200
Subject: [PATCH] table: Embed creating nft version into userdata
JIRA: https://issues.redhat.com/browse/RHEL-108851
Upstream Status: nftables commit 64c07e38f0494093a399a68a31056f5866c4d705
Conflicts: Context change due to missing --with-unitdir option.
commit 64c07e38f0494093a399a68a31056f5866c4d705
Author: Phil Sutter <phil@nwl.cc>
@ -32,7 +31,7 @@ Signed-off-by: Phil Sutter <psutter@redhat.com>
6 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index ba09e7f..c2a6908 100644
index e292d3b..243071e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,6 +33,7 @@ sbin_PROGRAMS =
@ -43,7 +42,7 @@ index ba09e7f..c2a6908 100644
###############################################################################
@@ -105,6 +106,8 @@ noinst_HEADERS = \
@@ -106,6 +107,8 @@ noinst_HEADERS = \
\
$(NULL)
@ -53,12 +52,12 @@ index ba09e7f..c2a6908 100644
AM_CPPFLAGS = \
diff --git a/configure.ac b/configure.ac
index 816e920..bac8319 100644
index 3a751cb..da16a6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,30 @@ AC_CHECK_DECLS([getprotobyname_r, getprotobynumber_r, getservbyport_r], [], [],
#include <netdb.h>
]])
@@ -131,6 +131,30 @@ AC_ARG_WITH([unitdir],
)
AC_SUBST([unitdir])
+AC_ARG_WITH([stable-release], [AS_HELP_STRING([--with-stable-release],
+ [Stable release number])],
@ -88,7 +87,7 @@ index 816e920..bac8319 100644
Makefile \
libnftables.pc \
diff --git a/include/rule.h b/include/rule.h
index 238be23..1b52972 100644
index 470ae10..319f9c3 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -170,6 +170,7 @@ struct table {
@ -100,7 +99,7 @@ index 238be23..1b52972 100644
extern struct table *table_alloc(void);
diff --git a/src/mnl.c b/src/mnl.c
index 12a6345..e748ab6 100644
index 892fb8b..25cd872 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -10,6 +10,7 @@
@ -111,7 +110,7 @@ index 12a6345..e748ab6 100644
#include <libmnl/libmnl.h>
#include <libnftnl/common.h>
@@ -1054,24 +1055,32 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
@@ -1082,24 +1083,32 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
if (nlt == NULL)
memory_allocation_error();
@ -151,7 +150,7 @@ index 12a6345..e748ab6 100644
NFT_MSG_NEWTABLE,
cmd->handle.family,
diff --git a/src/netlink.c b/src/netlink.c
index 2ced863..7f9730d 100644
index 94cbcbf..b5da33e 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -10,6 +10,7 @@
@ -162,7 +161,7 @@ index 2ced863..7f9730d 100644
#include <errno.h>
#include <libmnl/libmnl.h>
@@ -728,6 +729,14 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
@@ -799,6 +800,14 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
if (value[len - 1] != '\0')
return -1;
break;
@ -177,7 +176,7 @@ index 2ced863..7f9730d 100644
default:
return 0;
}
@@ -735,6 +744,29 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
@@ -806,6 +815,29 @@ static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
return 0;
}
@ -207,7 +206,7 @@ index 2ced863..7f9730d 100644
struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
const struct nftnl_table *nlt)
{
@@ -759,6 +791,7 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
@@ -830,6 +862,7 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
}
if (ud[NFTNL_UDATA_TABLE_COMMENT])
table->comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_TABLE_COMMENT]));
@ -216,10 +215,10 @@ index 2ced863..7f9730d 100644
return table;
diff --git a/src/rule.c b/src/rule.c
index 151ed53..e4d6f53 100644
index 0ad948e..398e5bd 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1274,6 +1274,10 @@ static void table_print(const struct table *table, struct output_ctx *octx)
@@ -1298,6 +1298,10 @@ static void table_print(const struct table *table, struct output_ctx *octx)
fprintf(octx->error_fp,
"# Warning: table %s %s is managed by iptables-nft, do not touch!\n",
family, table->handle.table.name);

View File

@ -1,45 +0,0 @@
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=""

View File

@ -1,4 +1,4 @@
From 575c0a20b143f5487a184c2c5c866dd8b14a69f5 Mon Sep 17 00:00:00 2001
From d930a5aa54976ceb1a28bc5002273f7b96fc8684 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 9 Sep 2025 16:50:13 +0200
Subject: [PATCH] Makefile: Fix for 'make CFLAGS=...'
@ -26,10 +26,10 @@ Signed-off-by: Phil Sutter <psutter@redhat.com>
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index c2a6908..58c6959 100644
index 243071e..4035e65 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,6 +154,8 @@ AM_CFLAGS = \
@@ -155,6 +155,8 @@ AM_CFLAGS = \
\
$(GCC_FVISIBILITY_HIDDEN) \
\
@ -39,10 +39,10 @@ index c2a6908..58c6959 100644
AM_YFLAGS = -d -Wno-yacc
diff --git a/configure.ac b/configure.ac
index bac8319..c14aa67 100644
index da16a6e..3517ea0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,7 +136,6 @@ AC_CONFIG_COMMANDS([nftversion.h], [
@@ -153,7 +153,6 @@ AC_CONFIG_COMMANDS([nftversion.h], [
# Current date should be fetched exactly once per build,
# so have 'make' call date and pass the value to every 'gcc' call
AC_SUBST([MAKE_STAMP], ["\$(shell date +%s)"])

View File

@ -1,38 +0,0 @@
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"*::

View File

@ -1,4 +1,4 @@
From 5dafd1cfd00116d0c6f289a0dc32b8a10d7c4c06 Mon Sep 17 00:00:00 2001
From 14a205946dd436385ff141604794e64754290fe1 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 4 Nov 2025 16:20:14 +0100
Subject: [PATCH] fib: Fix for existence check on Big Endian
@ -38,10 +38,10 @@ Signed-off-by: Phil Sutter <psutter@redhat.com>
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index c9cbaa6..474dc64 100644
index aaeb7b4..9125d5f 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2795,6 +2795,7 @@ static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp)
@@ -3001,6 +3001,7 @@ static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp)
if (expr->flags & EXPR_F_BOOLEAN) {
expr->fib.flags |= NFTA_FIB_F_PRESENT;
datatype_set(expr, &boolean_type);
@ -50,10 +50,10 @@ index c9cbaa6..474dc64 100644
return expr_evaluate_primary(ctx, exprp);
}
diff --git a/src/fib.c b/src/fib.c
index e95271c..0749007 100644
index 5383613..4db7cd2 100644
--- a/src/fib.c
+++ b/src/fib.c
@@ -189,8 +189,10 @@ struct expr *fib_expr_alloc(const struct location *loc,
@@ -198,8 +198,10 @@ struct expr *fib_expr_alloc(const struct location *loc,
BUG("Unknown result %d\n", result);
}

View File

@ -1,339 +0,0 @@
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;
}

View File

@ -1,78 +0,0 @@
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)++;
}

View File

@ -0,0 +1,40 @@
From b049bc68b06669875fe687c0686d65ff11653675 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] parser_bison: remove leftover utf-8 character in error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 7f37f3ca55810c2dc0e245ca7df108f160acb359
commit 7f37f3ca55810c2dc0e245ca7df108f160acb359
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sun Aug 31 23:37:51 2025 +0200
parser_bison: remove leftover utf-8 character in error
replace "" (UTF-8, 0xe280 0x98) with "'" (ASCII 0x27).
Fixes: c92ec3b21979 ("src: remove utf-8 character in printf lines")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/parser_bison.y | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 1e4b3f8..9ac1ca3 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4292,7 +4292,7 @@ variable_expr : '$' identifier
sym = symbol_lookup_fuzzy(scope, $2);
if (sym) {
erec_queue(error(&@2, "unknown identifier '%s'; "
- "did you mean identifier '%s?",
+ "did you mean identifier '%s'?",
$2, sym->identifier),
state->msgs);
} else {

View File

@ -1,312 +0,0 @@
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));
}

View File

@ -0,0 +1,30 @@
From 77d195c0d761978971c17504a2775fb4896ff4e7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] tools: gitignore nftables.service file
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 441ff666cb22921f23b14146a70c1111210364a2
commit 441ff666cb22921f23b14146a70c1111210364a2
Author: Phil Sutter <phil@nwl.cc>
Date: Fri Aug 29 01:51:01 2025 +0200
tools: gitignore nftables.service file
Fixes: c4b17cf830510 ("tools: add a systemd unit for static rulesets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tools/.gitignore | 1 +
1 file changed, 1 insertion(+)
create mode 100644 tools/.gitignore
diff --git a/tools/.gitignore b/tools/.gitignore
new file mode 100644
index 0000000..2d06c49
--- /dev/null
+++ b/tools/.gitignore
@@ -0,0 +1 @@
+nftables.service

View File

@ -0,0 +1,38 @@
From e514f0bbb4ca1cfdd7f2d719377e0276f759ec31 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] monitor: Quote device names in chain declarations, too
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit ed1b5b672b2eeb6244bed566227bee2aa7a1e4b4
commit ed1b5b672b2eeb6244bed566227bee2aa7a1e4b4
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Aug 28 16:47:03 2025 +0200
monitor: Quote device names in chain declarations, too
Fixed commit missed the fact that there are two routines printing chain
declarations.
Fixes: eb30f236d91a8 ("rule: print chain and flowtable devices in quotes")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/rule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rule.c b/src/rule.c
index 398e5bd..94f5eab 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1131,7 +1131,7 @@ void chain_print_plain(const struct chain *chain, struct output_ctx *octx)
nft_print(octx, "devices = { ");
for (i = 0; i < chain->dev_array_len; i++) {
- nft_print(octx, "%s", chain->dev_array[i]);
+ nft_print(octx, "\"%s\"", chain->dev_array[i]);
if (i + 1 != chain->dev_array_len)
nft_print(octx, ", ");
}

View File

@ -1,58 +0,0 @@
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;
}

View File

@ -1,193 +0,0 @@
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;
}

View File

@ -0,0 +1,39 @@
From 4f2bf41778c16cbf49c2af275f8391de14814cb3 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] tests: monitor: Fix regex collecting expected echo output
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 419338d96bdb19c10e241387c54f416c551a47c3
commit 419338d96bdb19c10e241387c54f416c551a47c3
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Sep 3 15:23:12 2025 +0200
tests: monitor: Fix regex collecting expected echo output
No input triggered this bug, but the match would accept "insert" and
"replace" keywords anywhere in the line not just at the beginning as was
intended.
Fixes: b2506e5504fed ("tests: Merge monitor and echo test suites")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/monitor/run-tests.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh
index 67d3e61..76355e8 100755
--- a/tests/monitor/run-tests.sh
+++ b/tests/monitor/run-tests.sh
@@ -52,7 +52,7 @@ echo_output_append() {
grep '^\(add\|replace\|insert\)' $command_file >>$output_file
return
}
- [[ "$*" =~ ^add|replace|insert ]] && echo "$*" >>$output_file
+ [[ "$*" =~ ^(add|replace|insert) ]] && echo "$*" >>$output_file
}
json_output_filter() { # (filename)
# unify handle values

View File

@ -1,62 +0,0 @@
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 }

View File

@ -0,0 +1,50 @@
From 82d38b67556dbebf42def4abefa6dca951fbd79e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] tests: shell: skip two bitwise tests if multi-register
support isn't available
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 083c532a2e179ec350881ff5444f35c58b99937f
commit 083c532a2e179ec350881ff5444f35c58b99937f
Author: Florian Westphal <fw@strlen.de>
Date: Mon Sep 8 11:06:35 2025 +0200
tests: shell: skip two bitwise tests if multi-register support isn't available
These tests fail in case kernel requires bitwise RHS to be a constant
value.
Fixes: 67d2a8d4c86f ("tests: shell: add parser and packetpath test")
Reported-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/shell/testcases/bitwise/bitwise_in_sets_and_maps | 1 +
tests/shell/testcases/packetpath/bitwise_with_map | 1 +
2 files changed, 2 insertions(+)
diff --git a/tests/shell/testcases/bitwise/bitwise_in_sets_and_maps b/tests/shell/testcases/bitwise/bitwise_in_sets_and_maps
index 4f5044f..e574f78 100755
--- a/tests/shell/testcases/bitwise/bitwise_in_sets_and_maps
+++ b/tests/shell/testcases/bitwise/bitwise_in_sets_and_maps
@@ -1,5 +1,6 @@
#!/bin/bash
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitwise_multireg)
# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitshift)
set -e
diff --git a/tests/shell/testcases/packetpath/bitwise_with_map b/tests/shell/testcases/packetpath/bitwise_with_map
index 33419e4..127b341 100755
--- a/tests/shell/testcases/packetpath/bitwise_with_map
+++ b/tests/shell/testcases/packetpath/bitwise_with_map
@@ -1,5 +1,6 @@
#!/bin/bash
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitwise_multireg)
# NFT_TEST_REQUIRES(NFT_TEST_HAVE_bitshift)
set -e

View File

@ -1,142 +0,0 @@
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 }
----------------------

View File

@ -0,0 +1,186 @@
From 010b8bbdeb96a873fc030782394dd5e922554bed Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:32 +0100
Subject: [PATCH] monitor: Inform JSON printer when reporting an object delete
event
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 6c04d24d16f1d15f216f2b3c8e64c9062cd77487
Conflicts: Adjusted to missing commit 3a957f8f1ff1e
("tunnel: add tunnel object and statement json support")
commit 6c04d24d16f1d15f216f2b3c8e64c9062cd77487
Author: Phil Sutter <phil@nwl.cc>
Date: Fri Aug 29 01:07:05 2025 +0200
monitor: Inform JSON printer when reporting an object delete event
Since kernel commit a1050dd07168 ("netfilter: nf_tables: Reintroduce
shortened deletion notifications"), type-specific data is no longer
dumped when notifying for a deleted object. JSON output was not aware of
this and tried to print bogus data.
Fixes: 9e88aae28e9f4 ("monitor: Use libnftables JSON output")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/json.h | 5 +++--
src/json.c | 16 ++++++++++------
src/monitor.c | 2 +-
tests/monitor/testcases/object.t | 10 +++++-----
4 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/include/json.h b/include/json.h
index b61eeaf..8ce517b 100644
--- a/include/json.h
+++ b/include/json.h
@@ -112,7 +112,7 @@ void monitor_print_set_json(struct netlink_mon_handler *monh,
void monitor_print_element_json(struct netlink_mon_handler *monh,
const char *cmd, struct set *s);
void monitor_print_obj_json(struct netlink_mon_handler *monh,
- const char *cmd, struct obj *o);
+ const char *cmd, struct obj *o, bool delete);
void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
const char *cmd, struct flowtable *ft);
void monitor_print_rule_json(struct netlink_mon_handler *monh,
@@ -250,7 +250,8 @@ static inline void monitor_print_element_json(struct netlink_mon_handler *monh,
}
static inline void monitor_print_obj_json(struct netlink_mon_handler *monh,
- const char *cmd, struct obj *o)
+ const char *cmd, struct obj *o,
+ bool delete)
{
/* empty */
}
diff --git a/src/json.c b/src/json.c
index a1e8c04..851b157 100644
--- a/src/json.c
+++ b/src/json.c
@@ -373,7 +373,7 @@ static json_t *timeout_policy_json(uint8_t l4, const uint32_t *timeout)
return root ? : json_null();
}
-static json_t *obj_print_json(const struct obj *obj)
+static json_t *obj_print_json(const struct obj *obj, bool delete)
{
const char *rate_unit = NULL, *burst_unit = NULL;
const char *type = obj_type_name(obj->type);
@@ -386,6 +386,9 @@ static json_t *obj_print_json(const struct obj *obj)
"table", obj->handle.table.name,
"handle", obj->handle.handle.id);
+ if (delete)
+ goto out;
+
if (obj->comment) {
tmp = nft_json_pack("{s:s}", "comment", obj->comment);
json_object_update(root, tmp);
@@ -489,6 +492,7 @@ static json_t *obj_print_json(const struct obj *obj)
break;
}
+out:
return nft_json_pack("{s:o}", type, root);
}
@@ -1728,7 +1732,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
json_array_append_new(root, tmp);
}
list_for_each_entry(obj, &table->obj_cache.list, cache.list) {
- tmp = obj_print_json(obj);
+ tmp = obj_print_json(obj, false);
json_array_append_new(root, tmp);
}
list_for_each_entry(set, &table->set_cache.list, cache.list) {
@@ -1884,7 +1888,7 @@ static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
static json_t *do_list_obj_json(struct netlink_ctx *ctx,
struct cmd *cmd, uint32_t type)
{
- json_t *root = json_array();
+ json_t *root = json_array(), *tmp;
struct table *table;
struct obj *obj;
@@ -1903,7 +1907,7 @@ static json_t *do_list_obj_json(struct netlink_ctx *ctx,
strcmp(cmd->handle.obj.name, obj->handle.obj.name)))
continue;
- json_array_append_new(root, obj_print_json(obj));
+ json_array_append_new(root, obj_print_json(obj, false));
}
}
@@ -2116,9 +2120,9 @@ void monitor_print_element_json(struct netlink_mon_handler *monh,
}
void monitor_print_obj_json(struct netlink_mon_handler *monh,
- const char *cmd, struct obj *o)
+ const char *cmd, struct obj *o, bool delete)
{
- monitor_print_json(monh, cmd, obj_print_json(o));
+ monitor_print_json(monh, cmd, obj_print_json(o, delete));
}
void monitor_print_flowtable_json(struct netlink_mon_handler *monh,
diff --git a/src/monitor.c b/src/monitor.c
index da1ad88..676bf61 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -549,7 +549,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type,
nft_mon_print(monh, "\n");
break;
case NFTNL_OUTPUT_JSON:
- monitor_print_obj_json(monh, cmd, obj);
+ monitor_print_obj_json(monh, cmd, obj, type == NFT_MSG_DELOBJ);
if (!nft_output_echo(&monh->ctx->nft->output))
nft_mon_print(monh, "\n");
break;
diff --git a/tests/monitor/testcases/object.t b/tests/monitor/testcases/object.t
index 53a9f8c..b60dc98 100644
--- a/tests/monitor/testcases/object.t
+++ b/tests/monitor/testcases/object.t
@@ -9,7 +9,7 @@ J {"add": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "
I delete counter ip t c
O -
-J {"delete": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "packets": 0, "bytes": 0}}}
+J {"delete": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0}}}
# FIXME: input/output shouldn't be asynchronous here
I add quota ip t q 25 mbytes
@@ -18,7 +18,7 @@ J {"add": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "by
I delete quota ip t q
O -
-J {"delete": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "bytes": 26214400, "used": 0, "inv": false}}}
+J {"delete": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0}}}
# FIXME: input/output shouldn't be asynchronous here
I add limit ip t l rate 1/second
@@ -27,7 +27,7 @@ J {"add": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "ra
I delete limit ip t l
O -
-J {"delete": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "rate": 1, "per": "second", "burst": 5}}}
+J {"delete": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0}}}
I add ct helper ip t cth { type "sip" protocol tcp; l3proto ip; }
O -
@@ -35,7 +35,7 @@ J {"add": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle":
I delete ct helper ip t cth
O -
-J {"delete": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0, "type": "sip", "protocol": "tcp", "l3proto": "ip"}}}
+J {"delete": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0}}}
I add ct timeout ip t ctt { protocol udp; l3proto ip; policy = { unreplied : 15s, replied : 12s }; }
O -
@@ -43,4 +43,4 @@ J {"add": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle":
I delete ct timeout ip t ctt
O -
-J {"delete": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle": 0, "protocol": "udp", "l3proto": "ip", "policy": {"unreplied": 15, "replied": 12}}}}
+J {"delete": {"ct timeout": {"family": "ip", "name": "ctt", "table": "t", "handle": 0}}}

View File

@ -1,83 +0,0 @@
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;
}

View File

@ -0,0 +1,41 @@
From a440e595cd5f61948684de3ab0c666769cb9f695 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] libnftables: do not re-add default include directory in
include search path
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 3af59817b8d3994d52db0f1aa5dabeebc84dae45
commit 3af59817b8d3994d52db0f1aa5dabeebc84dae45
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed Sep 24 23:54:12 2025 +0200
libnftables: do not re-add default include directory in include search path
Otherwise globbing might duplicate included files because
include_path_glob() is called twice.
Fixes: 7eb950a8e8fa ("libnftables: include canonical path to avoid duplicates")
Tested-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/libnftables.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libnftables.c b/src/libnftables.c
index c8293f7..9f6a1bc 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -176,6 +176,9 @@ static bool nft_ctx_find_include_path(struct nft_ctx *ctx, const char *path)
return true;
}
+ if (!strcmp(path, DEFAULT_INCLUDE_PATH))
+ return true;
+
return false;
}

View File

@ -0,0 +1,41 @@
From a67f0be23c3d90dc1148c4ad6b9b9215676acbe5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] doc: fix tcpdump example
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit b9516b0a4dfb6e16e3e11c3024683a2df1ea09ab
commit b9516b0a4dfb6e16e3e11c3024683a2df1ea09ab
Author: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
Date: Mon Oct 13 19:17:31 2025 +0200
doc: fix tcpdump example
The expression needs to be enclosed in a single string and combined with
a logical AND to have the desired effect.
Fixes: 1188a69604c3 ("src: introduce SYNPROXY matching")
Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/statements.txt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/doc/statements.txt b/doc/statements.txt
index 6226713..834f95f 100644
--- a/doc/statements.txt
+++ b/doc/statements.txt
@@ -691,8 +691,7 @@ needed for selective acknowledgement and window scaling).
---------------------------------------
Determine tcp options used by backend, from an external system
- tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack)'
- port 80 &
+ tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack) && port 80' &
telnet 192.0.2.42 80
18:57:24.693307 IP 192.0.2.42.80 > 192.0.2.43.48757:
Flags [S.], seq 360414582, ack 788841994, win 14480,

View File

@ -1,526 +0,0 @@
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"

View File

@ -0,0 +1,60 @@
From 8cc3c94a06c23d37827b4c02537d691bf2b713a7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] src: parser_json: fix format string bugs
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit b30ad0c25b7b4a289dd73e8da6fa101b66fbf0d7
commit b30ad0c25b7b4a289dd73e8da6fa101b66fbf0d7
Author: Florian Westphal <fw@strlen.de>
Date: Thu Oct 23 14:17:00 2025 +0200
src: parser_json: fix format string bugs
After adding fmt attribute annotation:
warning: format not a string literal and no format arguments [-Wformat-security]
131 | erec_queue(error(&loc, err->text), ctx->msgs);
In function 'json_events_cb':
warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type '__u32' {aka 'unsigned int'} [-Wformat=]
Fix that up too.
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/parser_json.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/parser_json.c b/src/parser_json.c
index 71e44f1..3a50c86 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -128,7 +128,7 @@ static void json_lib_error(struct json_ctx *ctx, json_error_t *err)
.last_column = err->column,
};
- erec_queue(error(&loc, err->text), ctx->msgs);
+ erec_queue(error(&loc, "%s", err->text), ctx->msgs);
}
__attribute__((format(printf, 2, 3)))
@@ -4320,6 +4320,7 @@ int nft_parse_json_filename(struct nft_ctx *nft, const char *filename,
return ret;
}
+__attribute__((format(printf, 2, 3)))
static int json_echo_error(struct netlink_mon_handler *monh,
const char *fmt, ...)
{
@@ -4392,7 +4393,7 @@ int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh)
json = seqnum_to_json(nlh->nlmsg_seq);
if (!json) {
- json_echo_error(monh, "No JSON command found with seqnum %lu\n",
+ json_echo_error(monh, "No JSON command found with seqnum %u\n",
nlh->nlmsg_seq);
return MNL_CB_OK;
}

View File

@ -1,43 +0,0 @@
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

View File

@ -0,0 +1,39 @@
From 8c0c1f8820891bffd7fd992643eef8d3ffaf9937 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] datatype: Fix boolean type on Big Endian
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit aec699af2a006b1dd6580abb95910c402e306fa9
commit aec699af2a006b1dd6580abb95910c402e306fa9
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Oct 8 23:19:08 2025 +0200
datatype: Fix boolean type on Big Endian
Pass a reference to a variable with correct size when creating the
expression, otherwise mpz_import_data() will read only the always zero
upper byte on Big Endian hosts.
Fixes: afb6a8e66a111 ("datatype: clamp boolean value to 0 and 1")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/datatype.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/datatype.c b/src/datatype.c
index f347010..7104ae8 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1559,7 +1559,7 @@ static struct error_record *boolean_type_parse(struct parse_ctx *ctx,
struct expr **res)
{
struct error_record *erec;
- int num;
+ uint8_t num;
erec = integer_type_parse(ctx, sym, res);
if (erec)

View File

@ -1,260 +0,0 @@
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"}}}

View File

@ -1,268 +0,0 @@
From 75c95b2f59fb09c6375ca1e10277af9d0641e71d Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Wed, 22 Jan 2025 10:18:04 +0100
Subject: [PATCH] evaluate: allow to re-use existing metered set
JIRA: https://issues.redhat.com/browse/RHEL-75507
Upstream Status: nftables commit 639a111e91341cffdc6d86b847aa654646c799cf
commit 639a111e91341cffdc6d86b847aa654646c799cf
Author: Florian Westphal <fw@strlen.de>
Date: Wed Jan 22 10:18:04 2025 +0100
evaluate: allow to re-use existing metered set
Blamed commit translates old meter syntax (which used to allocate an
anonymous set) to dynamic sets.
A side effect of this is that re-adding a meter rule after chain was
flushed results in an error, unlike anonymous sets named sets are not
impacted by the flush.
Refine this: if a set of the same name exists and is compatible, then
re-use it instead of returning an error.
Also pick up the reproducer kindly provided by the reporter and place it
in the shell test directory.
Fixes: b8f8ddfff733 ("evaluate: translate meter into dynamic set")
Reported-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Eric Garver <egarver@redhat.com>
---
src/evaluate.c | 43 +++++--
.../sets/dumps/meter_set_reuse.json-nft | 105 ++++++++++++++++++
.../testcases/sets/dumps/meter_set_reuse.nft | 11 ++
tests/shell/testcases/sets/meter_set_reuse | 20 ++++
4 files changed, 170 insertions(+), 9 deletions(-)
create mode 100644 tests/shell/testcases/sets/dumps/meter_set_reuse.json-nft
create mode 100644 tests/shell/testcases/sets/dumps/meter_set_reuse.nft
create mode 100755 tests/shell/testcases/sets/meter_set_reuse
diff --git a/src/evaluate.c b/src/evaluate.c
index 593a014..c9cbaa6 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3338,7 +3338,7 @@ static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
{
- struct expr *key, *set, *setref;
+ struct expr *key, *setref;
struct set *existing_set;
struct table *table;
@@ -3349,7 +3349,9 @@ static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
return table_not_found(ctx);
existing_set = set_cache_find(table, stmt->meter.name);
- if (existing_set)
+ if (existing_set &&
+ (!set_is_meter_compat(existing_set->flags) ||
+ set_is_map(existing_set->flags)))
return cmd_error(ctx, &stmt->location,
"%s; meter '%s' overlaps an existing %s '%s' in family %s",
strerror(EEXIST),
@@ -3370,17 +3372,40 @@ static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
/* Declare an empty set */
key = stmt->meter.key;
- set = set_expr_alloc(&key->location, NULL);
- set->set_flags |= NFT_SET_EVAL;
- if (key->timeout)
- set->set_flags |= NFT_SET_TIMEOUT;
+ if (existing_set) {
+ if ((existing_set->flags & NFT_SET_TIMEOUT) && !key->timeout)
+ return expr_error(ctx->msgs, stmt->meter.key,
+ "existing set '%s' has timeout flag",
+ stmt->meter.name);
+
+ if ((existing_set->flags & NFT_SET_TIMEOUT) == 0 && key->timeout)
+ return expr_error(ctx->msgs, stmt->meter.key,
+ "existing set '%s' lacks timeout flag",
+ stmt->meter.name);
+
+ if (stmt->meter.size > 0 && existing_set->desc.size != stmt->meter.size)
+ return expr_error(ctx->msgs, stmt->meter.key,
+ "existing set '%s' has size %u, meter has %u",
+ stmt->meter.name, existing_set->desc.size,
+ stmt->meter.size);
+ setref = set_ref_expr_alloc(&key->location, existing_set);
+ } else {
+ struct expr *set;
+
+ set = set_expr_alloc(&key->location, existing_set);
+ if (key->timeout)
+ set->set_flags |= NFT_SET_TIMEOUT;
+
+ set->set_flags |= NFT_SET_EVAL;
+ setref = implicit_set_declaration(ctx, stmt->meter.name,
+ expr_get(key), NULL, set, 0);
+ if (setref)
+ setref->set->desc.size = stmt->meter.size;
+ }
- setref = implicit_set_declaration(ctx, stmt->meter.name,
- expr_get(key), NULL, set, 0);
if (!setref)
return -1;
- setref->set->desc.size = stmt->meter.size;
stmt->meter.set = setref;
if (stmt_evaluate(ctx, stmt->meter.stmt) < 0)
diff --git a/tests/shell/testcases/sets/dumps/meter_set_reuse.json-nft b/tests/shell/testcases/sets/dumps/meter_set_reuse.json-nft
new file mode 100644
index 0000000..ab4ac06
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/meter_set_reuse.json-nft
@@ -0,0 +1,105 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "ip",
+ "name": "filter",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "ip",
+ "table": "filter",
+ "name": "input",
+ "handle": 0
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "http1",
+ "table": "filter",
+ "type": [
+ "inet_service",
+ "ipv4_addr"
+ ],
+ "handle": 0,
+ "size": 65535,
+ "flags": [
+ "dynamic"
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ "right": 80
+ }
+ },
+ {
+ "set": {
+ "op": "add",
+ "elem": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ }
+ ]
+ },
+ "set": "@http1",
+ "stmt": [
+ {
+ "limit": {
+ "rate": 200,
+ "burst": 5,
+ "per": "second",
+ "inv": true
+ }
+ }
+ ]
+ }
+ },
+ {
+ "counter": {
+ "packets": 0,
+ "bytes": 0
+ }
+ },
+ {
+ "drop": null
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/sets/dumps/meter_set_reuse.nft b/tests/shell/testcases/sets/dumps/meter_set_reuse.nft
new file mode 100644
index 0000000..f911aca
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/meter_set_reuse.nft
@@ -0,0 +1,11 @@
+table ip filter {
+ set http1 {
+ type inet_service . ipv4_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain input {
+ tcp dport 80 add @http1 { tcp dport . ip saddr limit rate over 200/second burst 5 packets } counter packets 0 bytes 0 drop
+ }
+}
diff --git a/tests/shell/testcases/sets/meter_set_reuse b/tests/shell/testcases/sets/meter_set_reuse
new file mode 100755
index 0000000..94eccc1
--- /dev/null
+++ b/tests/shell/testcases/sets/meter_set_reuse
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -e
+
+addrule()
+{
+ $NFT add rule ip filter input tcp dport 80 meter http1 { tcp dport . ip saddr limit rate over 200/second } counter drop
+}
+
+$NFT add table filter
+$NFT add chain filter input
+addrule
+
+$NFT list meters
+
+# This used to remove the anon set, but not anymore
+$NFT flush chain filter input
+
+# This re-add should work.
+addrule

View File

@ -0,0 +1,56 @@
From 0550a1f430aa42cc4195adb3ac505d515d570a3a Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] optimize: Fix verdict expression comparison
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 695ee5a8b174f86e2e64786530147e56d8d27f19
commit 695ee5a8b174f86e2e64786530147e56d8d27f19
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Oct 22 14:03:37 2025 +0200
optimize: Fix verdict expression comparison
In verdict expression, 'chain' points at a constant expression of
verdict_type, not a symbol expression. Therefore 'chain->identifier'
points eight bytes (on 64bit systems) into the mpz_t 'value' holding the
chain name. This matches the '_mp_d' data pointer, so works by accident.
Fix this by copying what verdict_jump_chain_print() does and export
chain names before comparing.
Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/optimize.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/optimize.c b/src/optimize.c
index 40756ce..ffad525 100644
--- a/src/optimize.c
+++ b/src/optimize.c
@@ -341,13 +341,18 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
static bool expr_verdict_eq(const struct expr *expr_a, const struct expr *expr_b)
{
+ char chain_a[NFT_CHAIN_MAXNAMELEN];
+ char chain_b[NFT_CHAIN_MAXNAMELEN];
+
if (expr_a->verdict != expr_b->verdict)
return false;
if (expr_a->chain && expr_b->chain) {
- if (expr_a->chain->etype != expr_b->chain->etype)
+ if (expr_a->chain->etype != EXPR_VALUE ||
+ expr_a->chain->etype != expr_b->chain->etype)
return false;
- if (expr_a->chain->etype == EXPR_VALUE &&
- strcmp(expr_a->chain->identifier, expr_b->chain->identifier))
+ expr_chain_export(expr_a->chain, chain_a);
+ expr_chain_export(expr_b->chain, chain_b);
+ if (strcmp(chain_a, chain_b))
return false;
} else if (expr_a->chain || expr_b->chain) {
return false;

View File

@ -1,807 +0,0 @@
From bb46381b2d378729d709480806c9522aaa32deeb Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 15 Jul 2025 22:50:32 +0200
Subject: [PATCH] src: split monitor trace code into new trace.c
JIRA: https://issues.redhat.com/browse/RHEL-102994
Upstream Status: nftables commit 8e03d59b5aa46b960454b4fd30541cee77125f77
commit 8e03d59b5aa46b960454b4fd30541cee77125f77
Author: Florian Westphal <fw@strlen.de>
Date: Mon Jul 7 11:47:13 2025 +0200
src: split monitor trace code into new trace.c
Preparation patch to avoid putting more trace functionality into
netlink.c.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
Makefile.am | 1 +
include/netlink.h | 5 -
include/trace.h | 8 ++
src/monitor.c | 2 +-
src/netlink.c | 332 -------------------------------------------
src/trace.c | 353 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 363 insertions(+), 338 deletions(-)
create mode 100644 include/trace.h
create mode 100644 src/trace.c
diff --git a/Makefile.am b/Makefile.am
index fb64105..ba09e7f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -220,6 +220,7 @@ src_libnftables_la_SOURCES = \
src/misspell.c \
src/mnl.c \
src/monitor.c \
+ src/trace.c \
src/netlink.c \
src/netlink_delinearize.c \
src/netlink_linearize.c \
diff --git a/include/netlink.h b/include/netlink.h
index e9667a2..609f213 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -227,11 +227,6 @@ struct ruleset_parse {
struct cmd *cmd;
};
-struct nftnl_parse_ctx;
-
-int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
- struct netlink_mon_handler *monh);
-
enum nft_data_types dtype_map_to_kernel(const struct datatype *dtype);
void netlink_linearize_init(struct netlink_linearize_ctx *lctx,
diff --git a/include/trace.h b/include/trace.h
new file mode 100644
index 0000000..ebebb47
--- /dev/null
+++ b/include/trace.h
@@ -0,0 +1,8 @@
+#ifndef NFTABLES_TRACE_H
+#define NFTABLES_TRACE_H
+#include <linux/netlink.h>
+
+struct netlink_mon_handler;
+int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
+ struct netlink_mon_handler *monh);
+#endif /* NFTABLES_TRACE_H */
diff --git a/src/monitor.c b/src/monitor.c
index a787db8..01325c9 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -16,7 +16,6 @@
#include <inttypes.h>
#include <libnftnl/table.h>
-#include <libnftnl/trace.h>
#include <libnftnl/chain.h>
#include <libnftnl/expr.h>
#include <libnftnl/object.h>
@@ -32,6 +31,7 @@
#include <nftables.h>
#include <netlink.h>
#include <mnl.h>
+#include <trace.h>
#include <expression.h>
#include <statement.h>
#include <gmputil.h>
diff --git a/src/netlink.c b/src/netlink.c
index 25ee341..2ced863 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -18,7 +18,6 @@
#include <inttypes.h>
#include <libnftnl/table.h>
-#include <libnftnl/trace.h>
#include <libnftnl/chain.h>
#include <libnftnl/expr.h>
#include <libnftnl/object.h>
@@ -41,7 +40,6 @@
#include <gmputil.h>
#include <utils.h>
#include <erec.h>
-#include <iface.h>
#define nft_mon_print(monh, ...) nft_print(&monh->ctx->nft->output, __VA_ARGS__)
@@ -1859,333 +1857,3 @@ int netlink_list_flowtables(struct netlink_ctx *ctx, const struct handle *h)
nftnl_flowtable_list_free(flowtable_cache);
return err;
}
-
-static void trace_print_hdr(const struct nftnl_trace *nlt,
- struct output_ctx *octx)
-{
- nft_print(octx, "trace id %08x %s ",
- nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID),
- family2str(nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY)));
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_TABLE))
- nft_print(octx, "%s ",
- nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE));
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CHAIN))
- nft_print(octx, "%s ",
- nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN));
-}
-
-static void trace_print_expr(const struct nftnl_trace *nlt, unsigned int attr,
- struct expr *lhs, struct output_ctx *octx)
-{
- struct expr *rhs, *rel;
- const void *data;
- uint32_t len;
-
- data = nftnl_trace_get_data(nlt, attr, &len);
- rhs = constant_expr_alloc(&netlink_location,
- lhs->dtype, lhs->byteorder,
- len * BITS_PER_BYTE, data);
- rel = relational_expr_alloc(&netlink_location, OP_EQ, lhs, rhs);
-
- expr_print(rel, octx);
- nft_print(octx, " ");
- expr_free(rel);
-}
-
-static void trace_print_verdict(const struct nftnl_trace *nlt,
- struct output_ctx *octx)
-{
- struct expr *chain_expr = NULL;
- const char *chain = NULL;
- unsigned int verdict;
- struct expr *expr;
-
- verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT);
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
- chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET));
- chain_expr = constant_expr_alloc(&netlink_location,
- &string_type,
- BYTEORDER_HOST_ENDIAN,
- strlen(chain) * BITS_PER_BYTE,
- chain);
- }
- expr = verdict_expr_alloc(&netlink_location, verdict, chain_expr);
-
- nft_print(octx, "verdict ");
- expr_print(expr, octx);
- expr_free(expr);
-}
-
-static void trace_print_policy(const struct nftnl_trace *nlt,
- struct output_ctx *octx)
-{
- unsigned int policy;
- struct expr *expr;
-
- policy = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY);
-
- expr = verdict_expr_alloc(&netlink_location, policy, NULL);
-
- nft_print(octx, "policy ");
- expr_print(expr, octx);
- expr_free(expr);
-}
-
-static struct rule *trace_lookup_rule(const struct nftnl_trace *nlt,
- uint64_t rule_handle,
- struct nft_cache *cache)
-{
- struct chain *chain;
- struct table *table;
- struct handle h;
-
- h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
- h.table.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
- h.chain.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
-
- if (!h.table.name)
- return NULL;
-
- table = table_cache_find(&cache->table_cache, h.table.name, h.family);
- if (!table)
- return NULL;
-
- chain = chain_cache_find(table, h.chain.name);
- if (!chain)
- return NULL;
-
- return rule_lookup(chain, rule_handle);
-}
-
-static void trace_print_rule(const struct nftnl_trace *nlt,
- struct output_ctx *octx, struct nft_cache *cache)
-{
- uint64_t rule_handle;
- struct rule *rule;
-
- rule_handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
- rule = trace_lookup_rule(nlt, rule_handle, cache);
-
- trace_print_hdr(nlt, octx);
-
- if (rule) {
- nft_print(octx, "rule ");
- rule_print(rule, octx);
- } else {
- nft_print(octx, "unknown rule handle %" PRIu64, rule_handle);
- }
-
- nft_print(octx, " (");
- trace_print_verdict(nlt, octx);
- nft_print(octx, ")\n");
-}
-
-static void trace_gen_stmts(struct list_head *stmts,
- struct proto_ctx *ctx, struct payload_dep_ctx *pctx,
- const struct nftnl_trace *nlt, unsigned int attr,
- enum proto_bases base)
-{
- struct list_head unordered = LIST_HEAD_INIT(unordered);
- struct list_head list;
- struct expr *rel, *lhs, *rhs, *tmp, *nexpr;
- struct stmt *stmt;
- const struct proto_desc *desc;
- const void *hdr;
- uint32_t hlen;
- unsigned int n;
-
- if (!nftnl_trace_is_set(nlt, attr))
- return;
- hdr = nftnl_trace_get_data(nlt, attr, &hlen);
-
- lhs = payload_expr_alloc(&netlink_location, NULL, 0);
- payload_init_raw(lhs, base, 0, hlen * BITS_PER_BYTE);
- rhs = constant_expr_alloc(&netlink_location,
- &invalid_type, BYTEORDER_INVALID,
- hlen * BITS_PER_BYTE, hdr);
-
-restart:
- init_list_head(&list);
- payload_expr_expand(&list, lhs, ctx);
- expr_free(lhs);
-
- desc = NULL;
- list_for_each_entry_safe(lhs, nexpr, &list, list) {
- if (desc && desc != ctx->protocol[base].desc) {
- /* Chained protocols */
- lhs->payload.offset = 0;
- if (ctx->protocol[base].desc == NULL)
- break;
- goto restart;
- }
-
- tmp = constant_expr_splice(rhs, lhs->len);
- expr_set_type(tmp, lhs->dtype, lhs->byteorder);
- if (tmp->byteorder == BYTEORDER_HOST_ENDIAN)
- mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE);
-
- /* Skip unknown and filtered expressions */
- desc = lhs->payload.desc;
- if (lhs->dtype == &invalid_type ||
- lhs->payload.tmpl == &proto_unknown_template ||
- desc->checksum_key == payload_hdr_field(lhs) ||
- desc->format.filter & (1 << payload_hdr_field(lhs))) {
- expr_free(lhs);
- expr_free(tmp);
- continue;
- }
-
- rel = relational_expr_alloc(&lhs->location, OP_EQ, lhs, tmp);
- stmt = expr_stmt_alloc(&rel->location, rel);
- list_add_tail(&stmt->list, &unordered);
-
- desc = ctx->protocol[base].desc;
- relational_expr_pctx_update(ctx, rel);
- }
-
- expr_free(rhs);
-
- n = 0;
-next:
- list_for_each_entry(stmt, &unordered, list) {
- enum proto_bases b = base;
-
- rel = stmt->expr;
- lhs = rel->left;
-
- /* Move statements to result list in defined order */
- desc = lhs->payload.desc;
- if (desc->format.order[n] &&
- desc->format.order[n] != payload_hdr_field(lhs))
- continue;
-
- list_move_tail(&stmt->list, stmts);
- n++;
-
- if (payload_is_stacked(desc, rel))
- b--;
-
- /* Don't strip 'icmp type' from payload dump. */
- if (pctx->icmp_type == 0)
- payload_dependency_kill(pctx, lhs, ctx->family);
- if (lhs->flags & EXPR_F_PROTOCOL)
- payload_dependency_store(pctx, stmt, b);
-
- goto next;
- }
-}
-
-static void trace_print_packet(const struct nftnl_trace *nlt,
- struct output_ctx *octx)
-{
- struct list_head stmts = LIST_HEAD_INIT(stmts);
- const struct proto_desc *ll_desc;
- struct payload_dep_ctx pctx = {};
- struct proto_ctx ctx;
- uint16_t dev_type;
- uint32_t nfproto;
- struct stmt *stmt, *next;
-
- trace_print_hdr(nlt, octx);
-
- nft_print(octx, "packet: ");
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF))
- trace_print_expr(nlt, NFTNL_TRACE_IIF,
- meta_expr_alloc(&netlink_location,
- NFT_META_IIF), octx);
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF))
- trace_print_expr(nlt, NFTNL_TRACE_OIF,
- meta_expr_alloc(&netlink_location,
- NFT_META_OIF), octx);
-
- proto_ctx_init(&ctx, nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY), 0, false);
- ll_desc = ctx.protocol[PROTO_BASE_LL_HDR].desc;
- if ((ll_desc == &proto_inet || ll_desc == &proto_netdev) &&
- nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) {
- nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO);
-
- proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location, NULL);
- proto_ctx_update(&ctx, PROTO_BASE_NETWORK_HDR, &netlink_location,
- proto_find_upper(ll_desc, nfproto));
- }
- if (ctx.protocol[PROTO_BASE_LL_HDR].desc == NULL &&
- nftnl_trace_is_set(nlt, NFTNL_TRACE_IIFTYPE)) {
- dev_type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);
- proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location,
- proto_dev_desc(dev_type));
- }
-
- trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_LL_HEADER,
- PROTO_BASE_LL_HDR);
- trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_NETWORK_HEADER,
- PROTO_BASE_NETWORK_HDR);
- trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_TRANSPORT_HEADER,
- PROTO_BASE_TRANSPORT_HDR);
-
- list_for_each_entry_safe(stmt, next, &stmts, list) {
- stmt_print(stmt, octx);
- nft_print(octx, " ");
- stmt_free(stmt);
- }
- nft_print(octx, "\n");
-}
-
-int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
- struct netlink_mon_handler *monh)
-{
- struct nftnl_trace *nlt;
-
- assert(type == NFT_MSG_TRACE);
-
- nlt = nftnl_trace_alloc();
- if (!nlt)
- memory_allocation_error();
-
- if (nftnl_trace_nlmsg_parse(nlh, nlt) < 0)
- netlink_abi_error();
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) ||
- nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER))
- trace_print_packet(nlt, &monh->ctx->nft->output);
-
- switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) {
- case NFT_TRACETYPE_RULE:
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE))
- trace_print_rule(nlt, &monh->ctx->nft->output,
- &monh->ctx->nft->cache);
- break;
- case NFT_TRACETYPE_POLICY:
- trace_print_hdr(nlt, &monh->ctx->nft->output);
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_POLICY)) {
- trace_print_policy(nlt, &monh->ctx->nft->output);
- nft_mon_print(monh, " ");
- }
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK))
- trace_print_expr(nlt, NFTNL_TRACE_MARK,
- meta_expr_alloc(&netlink_location,
- NFT_META_MARK),
- &monh->ctx->nft->output);
- nft_mon_print(monh, "\n");
- break;
- case NFT_TRACETYPE_RETURN:
- trace_print_hdr(nlt, &monh->ctx->nft->output);
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_VERDICT)) {
- trace_print_verdict(nlt, &monh->ctx->nft->output);
- nft_mon_print(monh, " ");
- }
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK))
- trace_print_expr(nlt, NFTNL_TRACE_MARK,
- meta_expr_alloc(&netlink_location,
- NFT_META_MARK),
- &monh->ctx->nft->output);
- nft_mon_print(monh, "\n");
- break;
- }
-
- nftnl_trace_free(nlt);
- return MNL_CB_OK;
-}
diff --git a/src/trace.c b/src/trace.c
new file mode 100644
index 0000000..a7cc8ff
--- /dev/null
+++ b/src/trace.c
@@ -0,0 +1,353 @@
+#include <nft.h>
+#include <trace.h>
+
+#include <libnftnl/trace.h>
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter.h>
+
+#include <nftables.h>
+#include <mnl.h>
+#include <parser.h>
+#include <netlink.h>
+#include <expression.h>
+#include <statement.h>
+#include <utils.h>
+
+#define nft_mon_print(monh, ...) nft_print(&monh->ctx->nft->output, __VA_ARGS__)
+
+static void trace_print_hdr(const struct nftnl_trace *nlt,
+ struct output_ctx *octx)
+{
+ nft_print(octx, "trace id %08x %s ",
+ nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID),
+ family2str(nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY)));
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_TABLE))
+ nft_print(octx, "%s ",
+ nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE));
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CHAIN))
+ nft_print(octx, "%s ",
+ nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN));
+}
+
+static void trace_print_expr(const struct nftnl_trace *nlt, unsigned int attr,
+ struct expr *lhs, struct output_ctx *octx)
+{
+ struct expr *rhs, *rel;
+ const void *data;
+ uint32_t len;
+
+ data = nftnl_trace_get_data(nlt, attr, &len);
+ rhs = constant_expr_alloc(&netlink_location,
+ lhs->dtype, lhs->byteorder,
+ len * BITS_PER_BYTE, data);
+ rel = relational_expr_alloc(&netlink_location, OP_EQ, lhs, rhs);
+
+ expr_print(rel, octx);
+ nft_print(octx, " ");
+ expr_free(rel);
+}
+
+static void trace_print_verdict(const struct nftnl_trace *nlt,
+ struct output_ctx *octx)
+{
+ struct expr *chain_expr = NULL;
+ const char *chain = NULL;
+ unsigned int verdict;
+ struct expr *expr;
+
+ verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT);
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
+ chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET));
+ chain_expr = constant_expr_alloc(&netlink_location,
+ &string_type,
+ BYTEORDER_HOST_ENDIAN,
+ strlen(chain) * BITS_PER_BYTE,
+ chain);
+ }
+ expr = verdict_expr_alloc(&netlink_location, verdict, chain_expr);
+
+ nft_print(octx, "verdict ");
+ expr_print(expr, octx);
+ expr_free(expr);
+}
+
+static void trace_print_policy(const struct nftnl_trace *nlt,
+ struct output_ctx *octx)
+{
+ unsigned int policy;
+ struct expr *expr;
+
+ policy = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY);
+
+ expr = verdict_expr_alloc(&netlink_location, policy, NULL);
+
+ nft_print(octx, "policy ");
+ expr_print(expr, octx);
+ expr_free(expr);
+}
+
+static struct rule *trace_lookup_rule(const struct nftnl_trace *nlt,
+ uint64_t rule_handle,
+ struct nft_cache *cache)
+{
+ struct chain *chain;
+ struct table *table;
+ struct handle h;
+
+ h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
+ h.table.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
+ h.chain.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
+
+ if (!h.table.name)
+ return NULL;
+
+ table = table_cache_find(&cache->table_cache, h.table.name, h.family);
+ if (!table)
+ return NULL;
+
+ chain = chain_cache_find(table, h.chain.name);
+ if (!chain)
+ return NULL;
+
+ return rule_lookup(chain, rule_handle);
+}
+
+static void trace_print_rule(const struct nftnl_trace *nlt,
+ struct output_ctx *octx, struct nft_cache *cache)
+{
+ uint64_t rule_handle;
+ struct rule *rule;
+
+ rule_handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
+ rule = trace_lookup_rule(nlt, rule_handle, cache);
+
+ trace_print_hdr(nlt, octx);
+
+ if (rule) {
+ nft_print(octx, "rule ");
+ rule_print(rule, octx);
+ } else {
+ nft_print(octx, "unknown rule handle %" PRIu64, rule_handle);
+ }
+
+ nft_print(octx, " (");
+ trace_print_verdict(nlt, octx);
+ nft_print(octx, ")\n");
+}
+
+static void trace_gen_stmts(struct list_head *stmts,
+ struct proto_ctx *ctx, struct payload_dep_ctx *pctx,
+ const struct nftnl_trace *nlt, unsigned int attr,
+ enum proto_bases base)
+{
+ struct list_head unordered = LIST_HEAD_INIT(unordered);
+ struct list_head list;
+ struct expr *rel, *lhs, *rhs, *tmp, *nexpr;
+ struct stmt *stmt;
+ const struct proto_desc *desc;
+ const void *hdr;
+ uint32_t hlen;
+ unsigned int n;
+
+ if (!nftnl_trace_is_set(nlt, attr))
+ return;
+ hdr = nftnl_trace_get_data(nlt, attr, &hlen);
+
+ lhs = payload_expr_alloc(&netlink_location, NULL, 0);
+ payload_init_raw(lhs, base, 0, hlen * BITS_PER_BYTE);
+ rhs = constant_expr_alloc(&netlink_location,
+ &invalid_type, BYTEORDER_INVALID,
+ hlen * BITS_PER_BYTE, hdr);
+
+restart:
+ init_list_head(&list);
+ payload_expr_expand(&list, lhs, ctx);
+ expr_free(lhs);
+
+ desc = NULL;
+ list_for_each_entry_safe(lhs, nexpr, &list, list) {
+ if (desc && desc != ctx->protocol[base].desc) {
+ /* Chained protocols */
+ lhs->payload.offset = 0;
+ if (ctx->protocol[base].desc == NULL)
+ break;
+ goto restart;
+ }
+
+ tmp = constant_expr_splice(rhs, lhs->len);
+ expr_set_type(tmp, lhs->dtype, lhs->byteorder);
+ if (tmp->byteorder == BYTEORDER_HOST_ENDIAN)
+ mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE);
+
+ /* Skip unknown and filtered expressions */
+ desc = lhs->payload.desc;
+ if (lhs->dtype == &invalid_type ||
+ lhs->payload.tmpl == &proto_unknown_template ||
+ desc->checksum_key == payload_hdr_field(lhs) ||
+ desc->format.filter & (1 << payload_hdr_field(lhs))) {
+ expr_free(lhs);
+ expr_free(tmp);
+ continue;
+ }
+
+ rel = relational_expr_alloc(&lhs->location, OP_EQ, lhs, tmp);
+ stmt = expr_stmt_alloc(&rel->location, rel);
+ list_add_tail(&stmt->list, &unordered);
+
+ desc = ctx->protocol[base].desc;
+ relational_expr_pctx_update(ctx, rel);
+ }
+
+ expr_free(rhs);
+
+ n = 0;
+next:
+ list_for_each_entry(stmt, &unordered, list) {
+ enum proto_bases b = base;
+
+ rel = stmt->expr;
+ lhs = rel->left;
+
+ /* Move statements to result list in defined order */
+ desc = lhs->payload.desc;
+ if (desc->format.order[n] &&
+ desc->format.order[n] != payload_hdr_field(lhs))
+ continue;
+
+ list_move_tail(&stmt->list, stmts);
+ n++;
+
+ if (payload_is_stacked(desc, rel))
+ b--;
+
+ /* Don't strip 'icmp type' from payload dump. */
+ if (pctx->icmp_type == 0)
+ payload_dependency_kill(pctx, lhs, ctx->family);
+ if (lhs->flags & EXPR_F_PROTOCOL)
+ payload_dependency_store(pctx, stmt, b);
+
+ goto next;
+ }
+}
+
+static void trace_print_packet(const struct nftnl_trace *nlt,
+ struct output_ctx *octx)
+{
+ struct list_head stmts = LIST_HEAD_INIT(stmts);
+ const struct proto_desc *ll_desc;
+ struct payload_dep_ctx pctx = {};
+ struct proto_ctx ctx;
+ uint16_t dev_type;
+ uint32_t nfproto;
+ struct stmt *stmt, *next;
+
+ trace_print_hdr(nlt, octx);
+
+ nft_print(octx, "packet: ");
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF))
+ trace_print_expr(nlt, NFTNL_TRACE_IIF,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_IIF), octx);
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF))
+ trace_print_expr(nlt, NFTNL_TRACE_OIF,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_OIF), octx);
+
+ proto_ctx_init(&ctx, nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY), 0, false);
+ ll_desc = ctx.protocol[PROTO_BASE_LL_HDR].desc;
+ if ((ll_desc == &proto_inet || ll_desc == &proto_netdev) &&
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) {
+ nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO);
+
+ proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location, NULL);
+ proto_ctx_update(&ctx, PROTO_BASE_NETWORK_HDR, &netlink_location,
+ proto_find_upper(ll_desc, nfproto));
+ }
+ if (ctx.protocol[PROTO_BASE_LL_HDR].desc == NULL &&
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_IIFTYPE)) {
+ dev_type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);
+ proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location,
+ proto_dev_desc(dev_type));
+ }
+
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_LL_HEADER,
+ PROTO_BASE_LL_HDR);
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_NETWORK_HEADER,
+ PROTO_BASE_NETWORK_HDR);
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_TRANSPORT_HEADER,
+ PROTO_BASE_TRANSPORT_HDR);
+
+ list_for_each_entry_safe(stmt, next, &stmts, list) {
+ stmt_print(stmt, octx);
+ nft_print(octx, " ");
+ stmt_free(stmt);
+ }
+ nft_print(octx, "\n");
+}
+
+int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
+ struct netlink_mon_handler *monh)
+{
+ struct nftnl_trace *nlt;
+
+ assert(type == NFT_MSG_TRACE);
+
+ nlt = nftnl_trace_alloc();
+ if (!nlt)
+ memory_allocation_error();
+
+ if (nftnl_trace_nlmsg_parse(nlh, nlt) < 0)
+ netlink_abi_error();
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) ||
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER))
+ trace_print_packet(nlt, &monh->ctx->nft->output);
+
+ switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) {
+ case NFT_TRACETYPE_RULE:
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE))
+ trace_print_rule(nlt, &monh->ctx->nft->output,
+ &monh->ctx->nft->cache);
+ break;
+ case NFT_TRACETYPE_POLICY:
+ trace_print_hdr(nlt, &monh->ctx->nft->output);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_POLICY)) {
+ trace_print_policy(nlt, &monh->ctx->nft->output);
+ nft_mon_print(monh, " ");
+ }
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK))
+ trace_print_expr(nlt, NFTNL_TRACE_MARK,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_MARK),
+ &monh->ctx->nft->output);
+ nft_mon_print(monh, "\n");
+ break;
+ case NFT_TRACETYPE_RETURN:
+ trace_print_hdr(nlt, &monh->ctx->nft->output);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_VERDICT)) {
+ trace_print_verdict(nlt, &monh->ctx->nft->output);
+ nft_mon_print(monh, " ");
+ }
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK))
+ trace_print_expr(nlt, NFTNL_TRACE_MARK,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_MARK),
+ &monh->ctx->nft->output);
+ nft_mon_print(monh, "\n");
+ break;
+ }
+
+ nftnl_trace_free(nlt);
+ return MNL_CB_OK;
+}

View File

@ -0,0 +1,167 @@
From 116111d7182fba61985a5fae750e275da397d1a6 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] tests: py: any/tcpopt.t.json: Fix JSON equivalent
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 4282c50e4986cf0414282306dbff5fbad2f3c686
commit 4282c50e4986cf0414282306dbff5fbad2f3c686
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Oct 8 23:46:34 2025 +0200
tests: py: any/tcpopt.t.json: Fix JSON equivalent
Set element ordering differed from the rule in standard syntax.
Fixes: d199cca92f9eb ("expression: expr_build_udata_recurse should recurse")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/any/tcpopt.t.json | 24 +++++-----
tests/py/any/tcpopt.t.json.output | 76 +++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json
index e712a5e..65fa1de 100644
--- a/tests/py/any/tcpopt.t.json
+++ b/tests/py/any/tcpopt.t.json
@@ -622,20 +622,20 @@
},
{
"concat": [
- "remove-addr",
- 300
+ "mp-join",
+ 100
]
},
{
"concat": [
- "mp-fastclose",
- 600
+ "add-addr",
+ 200
]
},
{
"concat": [
- "mp-join",
- 100
+ "remove-addr",
+ 300
]
},
{
@@ -646,20 +646,20 @@
},
{
"concat": [
- "mp-tcprst",
- 700
+ "mp-fail",
+ 500
]
},
{
"concat": [
- "add-addr",
- 200
+ "mp-fastclose",
+ 600
]
},
{
"concat": [
- "mp-fail",
- 500
+ "mp-tcprst",
+ 700
]
}
]
diff --git a/tests/py/any/tcpopt.t.json.output b/tests/py/any/tcpopt.t.json.output
index ad0d25f..ae979e7 100644
--- a/tests/py/any/tcpopt.t.json.output
+++ b/tests/py/any/tcpopt.t.json.output
@@ -30,3 +30,79 @@
}
]
+# tcp option mptcp subtype . tcp dport { mp-capable . 10, mp-join . 100, add-addr . 200, remove-addr . 300, mp-prio . 400, mp-fail . 500, mp-fastclose . 600, mp-tcprst . 700 }
+[
+ {
+ "match": {
+ "left": {
+ "concat": [
+ {
+ "tcp option": {
+ "field": "subtype",
+ "name": "mptcp"
+ }
+ },
+ {
+ "payload": {
+ "field": "dport",
+ "protocol": "tcp"
+ }
+ }
+ ]
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ {
+ "concat": [
+ "mp-capable",
+ 10
+ ]
+ },
+ {
+ "concat": [
+ "remove-addr",
+ 300
+ ]
+ },
+ {
+ "concat": [
+ "mp-fastclose",
+ 600
+ ]
+ },
+ {
+ "concat": [
+ "mp-join",
+ 100
+ ]
+ },
+ {
+ "concat": [
+ "mp-prio",
+ 400
+ ]
+ },
+ {
+ "concat": [
+ "mp-tcprst",
+ 700
+ ]
+ },
+ {
+ "concat": [
+ "add-addr",
+ 200
+ ]
+ },
+ {
+ "concat": [
+ "mp-fail",
+ 500
+ ]
+ }
+ ]
+ }
+ }
+ }
+]

View File

@ -1,268 +0,0 @@
From 0d28ee52a20e8441f66dc11b690fb595f63db6a3 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 15 Jul 2025 22:50:32 +0200
Subject: [PATCH] src: add conntrack information to trace monitor mode
JIRA: https://issues.redhat.com/browse/RHEL-102994
Upstream Status: nftables commit cfd768615235bb89650f15498c70d19813502825
commit cfd768615235bb89650f15498c70d19813502825
Author: Florian Westphal <fw@strlen.de>
Date: Mon Jul 7 22:38:13 2025 +0200
src: add conntrack information to trace monitor mode
Upcoming kernel change provides the packets conntrack state in the
trace message data.
This allows to see if packet is seen as original or reply, the conntrack
state (new, establieshed, related) and the status bits which show if e.g.
NAT was applied. Alsoi include conntrack ID so users can use conntrack
tool to query the kernel for more information via ctnetlink.
This improves debugging when e.g. packets do not pick up the expected
NAT mapping, which could e.g. also happen because of expectations
following the NAT binding of the owning conntrack entry.
Example output ("conntrack: " lines are new):
trace id 32 t PRE_RAW packet: iif "enp0s3" ether saddr [..]
trace id 32 t PRE_RAW rule tcp flags syn meta nftrace set 1 (verdict continue)
trace id 32 t PRE_RAW policy accept
trace id 32 t PRE_MANGLE conntrack: ct direction original ct state new ct id 2641368242
trace id 32 t PRE_MANGLE packet: iif "enp0s3" ether saddr [..]
trace id 32 t ct_new_pre rule jump rpfilter (verdict jump rpfilter)
trace id 32 t PRE_MANGLE policy accept
trace id 32 t INPUT conntrack: ct direction original ct state new ct status dnat-done ct id 2641368242
trace id 32 t INPUT packet: iif "enp0s3" [..]
trace id 32 t public_in rule tcp dport 443 accept (verdict accept)
v3: remove clash bit again, kernel won't expose it anymore.
v2: add more status bits: helper, clash, offload, hw-offload.
add flag explanation to documentation.
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/data-types.txt | 30 ++---
include/linux/netfilter/nf_conntrack_common.h | 16 +++
src/ct.c | 7 ++
src/trace.c | 109 ++++++++++++++++++
4 files changed, 147 insertions(+), 15 deletions(-)
diff --git a/doc/data-types.txt b/doc/data-types.txt
index 6c0e2f9..abbb7fd 100644
--- a/doc/data-types.txt
+++ b/doc/data-types.txt
@@ -378,21 +378,21 @@ For each of the types above, keywords are available for convenience:
.conntrack status (ct_status)
[options="header"]
|==================
-|Keyword| Value
-|expected|
-1
-|seen-reply|
-2
-|assured|
-4
-|confirmed|
-8
-|snat|
-16
-|dnat|
-32
-|dying|
-512
+|Keyword| Value | Description
+|expected|1| Expected connection; conntrack helper set it up
+|seen-reply|2| Conntrack has seen packets in both directions
+|assured| 4 |Conntrack entry will not be removed if hash table is full
+|confirmed | 8 | Initial packet processed
+|snat| 16 | Original source address differs from reply destination
+|dnat| 32 | Original destination differs from reply source
+|seq-adjust| 64 | tcp sequence number rewrite due to conntrack helper or synproxy
+|snat-done| 128 | tried to find matching snat/masquerade rule
+|dnat-done| 256 | tried to find matching dnat/redirect rule
+|dying| 512 | Connection about to be deleted
+|fixed-timeout | 1024 | entry expires even if traffic is active
+|helper | 8192 | connection is monitored by conntrack helper
+|offload | 16384 | connection is offloaded to a flow table
+|hw-offload | 32768 | connection is offloaded to hardware
|================
.conntrack event bits (ct_event)
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 768ff25..22bbb6c 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -77,6 +77,22 @@ enum ip_conntrack_status {
/* Connection has fixed timeout. */
IPS_FIXED_TIMEOUT_BIT = 10,
IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+
+ /* Conntrack is a fake untracked entry. Obsolete and not used anymore */
+ IPS_UNTRACKED_BIT = 12,
+ IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
+
+ /* Conntrack got a helper explicitly attached (ruleset, ctnetlink). */
+ IPS_HELPER_BIT = 13,
+ IPS_HELPER = (1 << IPS_HELPER_BIT),
+
+ /* Conntrack has been offloaded to flow table. */
+ IPS_OFFLOAD_BIT = 14,
+ IPS_OFFLOAD = (1 << IPS_OFFLOAD_BIT),
+
+ /* Conntrack has been offloaded to hardware. */
+ IPS_HW_OFFLOAD_BIT = 15,
+ IPS_HW_OFFLOAD = (1 << IPS_HW_OFFLOAD_BIT),
};
/* Connection tracking event types */
diff --git a/src/ct.c b/src/ct.c
index 6793464..cd97d82 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -98,7 +98,14 @@ static const struct symbol_table ct_status_tbl = {
SYMBOL("confirmed", IPS_CONFIRMED),
SYMBOL("snat", IPS_SRC_NAT),
SYMBOL("dnat", IPS_DST_NAT),
+ SYMBOL("seq-adjust", IPS_SEQ_ADJUST),
+ SYMBOL("snat-done", IPS_SRC_NAT_DONE),
+ SYMBOL("dnat-done", IPS_DST_NAT_DONE),
SYMBOL("dying", IPS_DYING),
+ SYMBOL("fixed-timeout", IPS_FIXED_TIMEOUT),
+ SYMBOL("helper", IPS_HELPER_BIT),
+ SYMBOL("offload", IPS_OFFLOAD_BIT),
+ SYMBOL("hw-offload", IPS_HW_OFFLOAD_BIT),
SYMBOL_LIST_END
},
};
diff --git a/src/trace.c b/src/trace.c
index a7cc8ff..b270951 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -237,6 +237,114 @@ next:
}
}
+static struct expr *trace_alloc_list(const struct datatype *dtype,
+ enum byteorder byteorder,
+ unsigned int len, const void *data)
+{
+ struct expr *list_expr;
+ unsigned int i;
+ mpz_t value;
+ uint32_t v;
+
+ if (len != sizeof(v))
+ return constant_expr_alloc(&netlink_location,
+ dtype, byteorder,
+ len * BITS_PER_BYTE, data);
+
+ list_expr = list_expr_alloc(&netlink_location);
+
+ mpz_init2(value, 32);
+ mpz_import_data(value, data, byteorder, len);
+ v = mpz_get_uint32(value);
+ if (v == 0) {
+ mpz_clear(value);
+ return NULL;
+ }
+
+ for (i = 0; i < 32; i++) {
+ uint32_t bitv = v & (1 << i);
+
+ if (bitv == 0)
+ continue;
+
+ compound_expr_add(list_expr,
+ constant_expr_alloc(&netlink_location,
+ dtype, byteorder,
+ len * BITS_PER_BYTE,
+ &bitv));
+ }
+
+ mpz_clear(value);
+ return list_expr;
+}
+
+static void trace_print_ct_expr(const struct nftnl_trace *nlt, unsigned int attr,
+ enum nft_ct_keys key, struct output_ctx *octx)
+{
+ struct expr *lhs, *rhs, *rel;
+ const void *data;
+ uint32_t len;
+
+ data = nftnl_trace_get_data(nlt, attr, &len);
+ lhs = ct_expr_alloc(&netlink_location, key, -1);
+
+ switch (key) {
+ case NFT_CT_STATUS:
+ rhs = trace_alloc_list(lhs->dtype, lhs->byteorder, len, data);
+ if (!rhs) {
+ expr_free(lhs);
+ return;
+ }
+ rel = binop_expr_alloc(&netlink_location, OP_IMPLICIT, lhs, rhs);
+ break;
+ case NFT_CT_DIRECTION:
+ case NFT_CT_STATE:
+ case NFT_CT_ID:
+ /* fallthrough */
+ default:
+ rhs = constant_expr_alloc(&netlink_location,
+ lhs->dtype, lhs->byteorder,
+ len * BITS_PER_BYTE, data);
+ rel = relational_expr_alloc(&netlink_location, OP_IMPLICIT, lhs, rhs);
+ break;
+ }
+
+ expr_print(rel, octx);
+ nft_print(octx, " ");
+ expr_free(rel);
+}
+
+static void trace_print_ct(const struct nftnl_trace *nlt,
+ struct output_ctx *octx)
+{
+ bool ct = nftnl_trace_is_set(nlt, NFTNL_TRACE_CT_STATE);
+
+ if (!ct)
+ return;
+
+ trace_print_hdr(nlt, octx);
+
+ nft_print(octx, "conntrack: ");
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CT_DIRECTION))
+ trace_print_ct_expr(nlt, NFTNL_TRACE_CT_DIRECTION,
+ NFT_CT_DIRECTION, octx);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CT_STATE))
+ trace_print_ct_expr(nlt, NFTNL_TRACE_CT_STATE,
+ NFT_CT_STATE, octx);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CT_STATUS))
+ trace_print_ct_expr(nlt, NFTNL_TRACE_CT_STATUS,
+ NFT_CT_STATUS, octx);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CT_ID))
+ trace_print_ct_expr(nlt, NFTNL_TRACE_CT_ID,
+ NFT_CT_ID, octx);
+
+ nft_print(octx, "\n");
+}
+
static void trace_print_packet(const struct nftnl_trace *nlt,
struct output_ctx *octx)
{
@@ -248,6 +356,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt,
uint32_t nfproto;
struct stmt *stmt, *next;
+ trace_print_ct(nlt, octx);
trace_print_hdr(nlt, octx);
nft_print(octx, "packet: ");

View File

@ -0,0 +1,69 @@
From af563649df51ad00c1d0f3897af04ba1051c808e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] tests: py: any/ct.t.json.output: Drop leftover entry
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 1801480314bf2baa6abf9cb15ccdef975b966867
commit 1801480314bf2baa6abf9cb15ccdef975b966867
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 16 16:23:12 2025 +0200
tests: py: any/ct.t.json.output: Drop leftover entry
The rule with single element anonymous set was replaced, drop this
leftover.
Fixes: 27f6a4c68b4fd ("tests: replace single element sets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/any/ct.t.json.output | 33 ---------------------------------
1 file changed, 33 deletions(-)
diff --git a/tests/py/any/ct.t.json.output b/tests/py/any/ct.t.json.output
index 70ade7e..82634c2 100644
--- a/tests/py/any/ct.t.json.output
+++ b/tests/py/any/ct.t.json.output
@@ -471,39 +471,6 @@
}
]
-# ct state . ct mark { new . 0x12345678}
-[
- {
- "match": {
- "left": {
- "concat": [
- {
- "ct": {
- "key": "state"
- }
- },
- {
- "ct": {
- "key": "mark"
- }
- }
- ]
- },
- "op": "==",
- "right": {
- "set": [
- {
- "concat": [
- "new",
- 305419896
- ]
- }
- ]
- }
- }
- }
-]
-
# ct state . ct mark { new . 0x12345678, new . 0x34127856, established . 0x12785634}
[
{

View File

@ -0,0 +1,121 @@
From 6b193bf44047e8ffac8520980ef4763caaf38886 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] tests: py: inet/osf.t: Fix element ordering in JSON
equivalents
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit b028f8ce616bb5a219a10844357b9a3822d99a8c
commit b028f8ce616bb5a219a10844357b9a3822d99a8c
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 9 02:06:54 2025 +0200
tests: py: inet/osf.t: Fix element ordering in JSON equivalents
The original rules order set elements differently. Stick to that and add
entries to inet/osf.t.json.output to cover for nftables reordering
entries.
Fixes: 92029c1282958 ("src: osf: add json support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/inet/osf.t.json | 12 ++++----
tests/py/inet/osf.t.json.output | 53 +++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 6 deletions(-)
create mode 100644 tests/py/inet/osf.t.json.output
diff --git a/tests/py/inet/osf.t.json b/tests/py/inet/osf.t.json
index cedb7f6..b1bf747 100644
--- a/tests/py/inet/osf.t.json
+++ b/tests/py/inet/osf.t.json
@@ -73,8 +73,8 @@
"op": "==",
"right": {
"set": [
- "MacOs",
- "Windows"
+ "Windows",
+ "MacOs"
]
}
}
@@ -114,13 +114,13 @@
"map": {
"data": {
"set": [
- [
- "MacOs",
- 2
- ],
[
"Windows",
1
+ ],
+ [
+ "MacOs",
+ 2
]
]
},
diff --git a/tests/py/inet/osf.t.json.output b/tests/py/inet/osf.t.json.output
new file mode 100644
index 0000000..922e395
--- /dev/null
+++ b/tests/py/inet/osf.t.json.output
@@ -0,0 +1,53 @@
+# osf name { "Windows", "MacOs" }
+[
+ {
+ "match": {
+ "left": {
+ "osf": {
+ "key": "name"
+ }
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ "MacOs",
+ "Windows"
+ ]
+ }
+ }
+ }
+]
+
+# ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
+[
+ {
+ "mangle": {
+ "key": {
+ "ct": {
+ "key": "mark"
+ }
+ },
+ "value": {
+ "map": {
+ "data": {
+ "set": [
+ [
+ "MacOs",
+ 2
+ ],
+ [
+ "Windows",
+ 1
+ ]
+ ]
+ },
+ "key": {
+ "osf": {
+ "key": "name"
+ }
+ }
+ }
+ }
+ }
+ }
+]

View File

@ -1,38 +0,0 @@
From 5ed024ecfaf596ec0298f8ad75c5695f9889464c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 9 Sep 2025 16:27:52 +0200
Subject: [PATCH] trace: Fix for memleak in trace_alloc_list() error path
JIRA: https://issues.redhat.com/browse/RHEL-111205
Upstream Status: nftables commit fdbb0ec57b5c891c1de17f367b693ab787ea9c2d
commit fdbb0ec57b5c891c1de17f367b693ab787ea9c2d
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Aug 26 12:57:37 2025 +0200
trace: Fix for memleak in trace_alloc_list() error path
The allocated 'list_expr' may leak.
Fixes: cfd768615235b ("src: add conntrack information to trace monitor mode")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/trace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/trace.c b/src/trace.c
index b270951..47f4c21 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -258,6 +258,7 @@ static struct expr *trace_alloc_list(const struct datatype *dtype,
v = mpz_get_uint32(value);
if (v == 0) {
mpz_clear(value);
+ expr_free(list_expr);
return NULL;
}

View File

@ -1,78 +0,0 @@
From 3bb2e6c3d03fa60724ab72b96d1e97fa02d7eed9 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 9 Sep 2025 16:53:21 +0200
Subject: [PATCH] doc: nft.8: Minor NAT STATEMENTS section review
JIRA: https://issues.redhat.com/browse/RHEL-106743
Upstream Status: nftables commit 9e1cbf667da2b9c30b41ff887de212b2c38b2eb7
commit 9e1cbf667da2b9c30b41ff887de212b2c38b2eb7
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Jul 31 12:40:11 2025 +0200
doc: nft.8: Minor NAT STATEMENTS section review
Synopsis insinuates an IP address argument is mandatory in snat/dnat
statements although specifying ports alone is perfectly fine. Adjust it
accordingly and add a paragraph briefly describing the behaviour.
While at it, update the redirect statement description with more
relevant examples, the current one is wrong: To *only* alter the
destination port, dnat statement must be used, not redirect.
Fixes: 6908a677ba04c ("nft.8: Enhance NAT documentation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/statements.txt | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/doc/statements.txt b/doc/statements.txt
index 74af1d1..7fe9ed3 100644
--- a/doc/statements.txt
+++ b/doc/statements.txt
@@ -399,11 +399,12 @@ NAT STATEMENTS
~~~~~~~~~~~~~~
[verse]
____
-*snat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'ADDR_SPEC' [*:*'PORT_SPEC'] ['FLAGS']
-*dnat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'ADDR_SPEC' [*:*'PORT_SPEC'] ['FLAGS']
+*snat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'TARGET_SPEC' ['FLAGS']
+*dnat* [[*ip* | *ip6*] [ *prefix* ] *to*] 'TARGET_SPEC' ['FLAGS']
*masquerade* [*to :*'PORT_SPEC'] ['FLAGS']
*redirect* [*to :*'PORT_SPEC'] ['FLAGS']
+'TARGET_SPEC' := 'ADDR_SPEC' | ['ADDR_SPEC'] *:*'PORT_SPEC'
'ADDR_SPEC' := 'address' | 'address' *-* 'address'
'PORT_SPEC' := 'port' | 'port' *-* 'port'
@@ -413,11 +414,11 @@ ____
The nat statements are only valid from nat chain types. +
-The *snat* and *masquerade* statements specify that the source address of the
+The *snat* and *masquerade* statements specify that the source address/port of the
packet should be modified. While *snat* is only valid in the postrouting and
input chains, *masquerade* makes sense only in postrouting. The dnat and
redirect statements are only valid in the prerouting and output chains, they
-specify that the destination address of the packet should be modified. You can
+specify that the destination address/port of the packet should be modified. You can
use non-base chains which are called from base chains of nat chain type too.
All future packets in this connection will also be mangled, and rules should
cease being examined.
@@ -427,8 +428,12 @@ outgoing interface's IP address to translate to. It is particularly useful on
gateways with dynamic (public) IP addresses.
The *redirect* statement is a special form of dnat which always translates the
-destination address to the local host's one. It comes in handy if one only wants
-to alter the destination port of incoming traffic on different interfaces.
+destination address to the local host's one. It comes in handy to intercept
+traffic passing a router and feeding it to a locally running daemon, e.g. when
+building a transparent proxy or application-layer gateway.
+
+For 'TARGET_SPEC', one may specify addresses, ports, or both. If no address or
+no port is specified, the respective packet header field remains unchanged.
When used in the inet family (available with kernel 5.2), the dnat and snat
statements require the use of the ip and ip6 keyword in case an address is

View File

@ -0,0 +1,47 @@
From 2f0cfe33e3e2eba28b61421ea8b592426313b9ed Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] tests: shell: fix typo in vmap_timeout test script
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit b39ba950325bba7b00da57684c99e9466522bb07
commit b39ba950325bba7b00da57684c99e9466522bb07
Author: Gyorgy Sarvari <skandigraun@gmail.com>
Date: Sun Oct 26 21:41:07 2025 +0100
tests: shell: fix typo in vmap_timeout test script
While executing the test suite from tests/shell folder, the following error
is displayed many times:
tests/shell/testcases/maps/vmap_timeout: line 48: [: : integer expected
Looking at the script, a non-existing variable (expires) is tested instead of
the existing one (expire).
Reproduction:
tests/shell/run-tests.sh -v
Fixes: db80037c0279 ("tests: shell: extend vmap test with updates")
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
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 8ac7e8e..55d1c1b 100755
--- a/tests/shell/testcases/maps/vmap_timeout
+++ b/tests/shell/testcases/maps/vmap_timeout
@@ -45,7 +45,7 @@ for i in $(seq 1 100) ; do
expire=$((RANDOM%utimeout))
expire_str=""
- if [ "$expires" -gt 0 ]; then
+ if [ "$expire" -gt 0 ]; then
expire_str="expires ${expire}s"
fi

View File

@ -0,0 +1,67 @@
From 50fd26900311b0eb0e35fa421541dba42c64927b Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:10:59 +0100
Subject: [PATCH] build: don't install ancillary files without systemd service
file
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 31007975ccf5a389b76e1bc6f5f7215847f394ef
Conflicts: Context change due to missing commit df19bf51d49be
("Makefile: Enable support for 'make check'")
commit 31007975ccf5a389b76e1bc6f5f7215847f394ef
Author: Jeremy Sowden <jeremy@azazel.net>
Date: Wed Sep 17 21:34:54 2025 +0100
build: don't install ancillary files without systemd service file
If the systemd service file is not installed, currently the related man-page
and example nft file are still installed. Instead only install them when the
service file is installed.
Fixes: 107580cfa85c ("build: disable --with-unitdir by default")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
Makefile.am | 5 +++++
configure.ac | 1 +
2 files changed, 6 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 4035e65..ebf64c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -418,10 +418,14 @@ EXTRA_DIST += \
tools/nftables.service.in \
$(NULL)
+if BUILD_SERVICE
CLEANFILES += tools/nftables.service
+endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnftables.pc
+
+if BUILD_SERVICE
unit_DATA = tools/nftables.service
man_MANS = tools/nftables.service.8
doc_DATA = files/nftables/main.nft
@@ -429,3 +433,4 @@ doc_DATA = files/nftables/main.nft
tools/nftables.service: tools/nftables.service.in ${top_builddir}/config.status
${AM_V_GEN}${MKDIR_P} tools
${AM_V_at}sed -e 's|@''sbindir''@|${sbindir}|g;s|@''pkgsysconfdir''@|${pkgsysconfdir}|g' <${srcdir}/tools/nftables.service.in >$@
+endif
diff --git a/configure.ac b/configure.ac
index 3517ea0..09d1ee5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,7 @@ AC_ARG_WITH([unitdir],
[unitdir=""]
)
AC_SUBST([unitdir])
+AM_CONDITIONAL([BUILD_SERVICE], [test "x$unitdir" != x])
AC_ARG_WITH([stable-release], [AS_HELP_STRING([--with-stable-release],
[Stable release number])],

View File

@ -0,0 +1,69 @@
From ea26c89c4428c324f53827e4e1e0b7be9878dad8 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:11:18 +0100
Subject: [PATCH] doc: don't suggest to disable GSO
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 35cd3e7cff079c561ba616c792d5fdf13f6bd331
commit 35cd3e7cff079c561ba616c792d5fdf13f6bd331
Author: Ronan Pigott <ronan@rjp.ie>
Date: Sun Oct 6 09:36:03 2024 -0700
doc: don't suggest to disable GSO
The kernel can form aggregate packets whether or not GSO is enabled.
Disabling GSO is not a useful suggestion in this case.
Fixes: 05628cdd677d (doc: describe behaviour of {ip,ip6} length)
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/payload-expression.txt | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
index ce0c6a2..8c27fe4 100644
--- a/doc/payload-expression.txt
+++ b/doc/payload-expression.txt
@@ -134,13 +134,12 @@ Destination address |
ipv4_addr
|======================
-Careful with matching on *ip length*: If GRO/GSO is enabled, then the Linux
-kernel might aggregate several packets into one big packet that is larger than
-MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8),
-specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip length* might
-be 0 for such jumbo packets. *meta length* allows you to match on the packet
-length including the IP header size. If you want to perform heuristics on the
-*ip length* field, then disable GRO/GSO.
+Careful with matching on *ip length*: The Linux kernel might aggregate several
+packets into one big packet that is larger than MTU. Moreover, if GRO/GSO
+maximum size is larger than 65535 (see man ip-link(8), specifically
+gro_ipv4_max_size and gso_ipv4_max_size), then *ip length* might be 0 for such
+jumbo packets. *meta length* allows you to match on the packet length including
+the IP header size.
ICMP HEADER EXPRESSION
~~~~~~~~~~~~~~~~~~~~~~
@@ -252,13 +251,12 @@ Destination address |
ipv6_addr
|=======================
-Careful with matching on *ip6 length*: If GRO/GSO is enabled, then the Linux
-kernel might aggregate several packets into one big packet that is larger than
-MTU. Moreover, if GRO/GSO maximum size is larger than 65535 (see man ip-link(8),
-specifically gro_ipv6_max_size and gso_ipv6_max_size), then *ip6 length* might
-be 0 for such jumbo packets. *meta length* allows you to match on the packet
-length including the IP header size. If you want to perform heuristics on the
-*ip6 length* field, then disable GRO/GSO.
+Careful with matching on *ip6 length*: The Linux kernel might aggregate several
+packets into one big packet that is larger than MTU. Moreover, if GRO/GSO
+maximum size is larger than 65535 (see man ip-link(8), specifically
+gro_max_size and gso_max_size), then *ip6 length* might be 0 for such
+jumbo packets. *meta length* allows you to match on the packet length including
+the IPv6 header size.
.Using ip6 header expressions
-----------------------------

View File

@ -0,0 +1,48 @@
From 6bd71d875043356fb8e6b8ed24e8d2d9c4f7f491 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 20 Nov 2025 20:11:18 +0100
Subject: [PATCH] doc: libnftables-json: Describe RULESET object
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 454f361434522bbeba32e114a14c336e1ebf20a1
commit 454f361434522bbeba32e114a14c336e1ebf20a1
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 6 12:14:56 2025 +0100
doc: libnftables-json: Describe RULESET object
Document the syntax of this meta-object used by "list" and "flush"
commands only.
Fixes: 872f373dc50f7 ("doc: Add JSON schema documentation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/libnftables-json.adoc | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index 643884d..049c325 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -200,6 +200,18 @@ Rename a chain. The new name is expected in a dedicated property named
== RULESET ELEMENTS
+=== RULESET
+[verse]
+____
+*{ "ruleset":* 'RULSET_PROPERTIES' *}*
+
+'RULESET_PROPERTIES' := *null* | *{ "family":* 'STRING' *}*
+____
+
+This is a special object for use with *list* and *flush* commands which will
+then operate on either the whole ruleset or the parts of it belonging to the
+given family.
+
=== TABLE
[verse]
____

View File

@ -0,0 +1,104 @@
From 26fc99ea52458477bfc2ad67f927f9d7f18454ca Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 27 Nov 2025 10:58:08 +0100
Subject: [PATCH] mnl: Support simple wildcards in netdev hooks
JIRA: https://issues.redhat.com/browse/RHEL-108861
Upstream Status: nftables commit c31e887504a90152e29c4a76a74c8a442f771917
commit c31e887504a90152e29c4a76a74c8a442f771917
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Aug 13 20:26:08 2024 +0200
mnl: Support simple wildcards in netdev hooks
When building NFTA_{FLOWTABLE_,}HOOK_DEVS attributes, detect trailing
asterisks in interface names and transmit the leading part in a
NFTA_DEVICE_PREFIX attribute.
Deserialization (i.e., appending asterisk to interface prefixes returned
in NFTA_DEVICE_PREFIX atributes happens in libnftnl.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/linux/netfilter/nf_tables.h | 2 ++
src/mnl.c | 26 +++++++++++++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f57963e..b38d478 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1774,10 +1774,12 @@ enum nft_synproxy_attributes {
* enum nft_device_attributes - nf_tables device netlink attributes
*
* @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
+ * @NFTA_DEVICE_PREFIX: device name prefix, a simple wildcard (NLA_STRING)
*/
enum nft_devices_attributes {
NFTA_DEVICE_UNSPEC,
NFTA_DEVICE_NAME,
+ NFTA_DEVICE_PREFIX,
__NFTA_DEVICE_MAX
};
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
diff --git a/src/mnl.c b/src/mnl.c
index 25cd872..ccf4ca5 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -801,6 +801,26 @@ static void nft_dev_array_free(const struct nft_dev *dev_array)
free_const(dev_array);
}
+static bool is_wildcard_str(const char *str)
+{
+ size_t len = strlen(str);
+
+ if (len < 1 || str[len - 1] != '*')
+ return false;
+ if (len < 2 || str[len - 2] != '\\')
+ return true;
+ /* XXX: ignore backslash escaping for now */
+ return false;
+}
+
+static void mnl_nft_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname)
+{
+ uint16_t attr = is_wildcard_str(ifname) ?
+ NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME;
+
+ mnl_attr_put_strz(nlh, attr, ifname);
+}
+
static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
{
const struct expr *dev_expr = cmd->chain->dev_expr;
@@ -809,14 +829,14 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
int i, num_devs = 0;
dev_array = nft_dev_array(dev_expr, &num_devs);
- if (num_devs == 1) {
+ if (num_devs == 1 && !is_wildcard_str(dev_array[0].ifname)) {
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, dev_array[i].location);
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+ mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
}
mnl_attr_nest_end(nlh, nest_dev);
}
@@ -2108,7 +2128,7 @@ static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
for (i = 0; i < num_devs; i++) {
cmd_add_loc(cmd, nlh, dev_array[i].location);
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+ mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
}
mnl_attr_nest_end(nlh, nest_dev);

View File

@ -0,0 +1,128 @@
From 66a04c194d09808b9feff3093bf321cc489c2def Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 27 Nov 2025 10:58:08 +0100
Subject: [PATCH] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
JIRA: https://issues.redhat.com/browse/RHEL-108861
Upstream Status: nftables commit 796de697f662064d256e628bc5c703b6d14ae391
commit 796de697f662064d256e628bc5c703b6d14ae391
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Aug 13 20:36:36 2024 +0200
parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
All clauses are identical, so instead of adding a third one for
ASTERISK_STRING, use a single one for 'string' (which combines all three
variants).
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
doc/nft.txt | 30 ++++++++++++++++++++++++++----
src/parser_bison.y | 11 +----------
2 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/doc/nft.txt b/doc/nft.txt
index 8712981..42cdd38 100644
--- a/doc/nft.txt
+++ b/doc/nft.txt
@@ -387,13 +387,19 @@ add table inet mytable
CHAINS
------
[verse]
-{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' [*device* 'device'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
+____
+{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' ['DEVICE'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
{*delete* | *destroy* | *list* | *flush*} *chain* ['family'] 'table' 'chain'
*list chains* ['family']
*delete chain* ['family'] 'table' *handle* 'handle'
*destroy chain* ['family'] 'table' *handle* 'handle'
*rename chain* ['family'] 'table' 'chain' 'newname'
+'DEVICE' := {*device* 'DEVICE_NAME' | *devices = {* 'DEVICE_LIST' *}*}
+'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
+'DEVICE_NAME' := 'string' | 'string'***
+____
+
Chains are containers for rules. They exist in two kinds, base chains and
regular chains. A base chain is an entry point for packets from the networking
stack, a regular chain may be used as jump target and is used for better rule
@@ -436,7 +442,7 @@ further quirks worth noticing:
* The netdev family supports merely two combinations, namely *filter* type with
*ingress* hook and *filter* type with *egress* hook. Base chains in this
- family also require the *device* parameter to be present since they exist per
+ family also require the 'DEVICE' parameter to be present since they exist per
interface only.
* The arp family supports only the *input* and *output* hooks, both in chains of type
*filter*.
@@ -449,7 +455,13 @@ further quirks worth noticing:
The *device* parameter accepts a network interface name as a string, and is
required when adding a base chain that filters traffic on the ingress or
egress hooks. Any ingress or egress chains will only filter traffic from the
-interface specified in the *device* parameter.
+interface specified in the *device* parameter. The same base chain may be used
+for multiple devices by using the *devices* parameter instead.
+
+With newer kernels there is also basic support for wildcards in 'DEVICE_NAME'
+by specifying an asterisk suffix. The chain will apply to all interfaces
+matching the given prefix. Use the *list hooks* command to see the current
+status.
The *priority* parameter accepts a signed integer value or a standard priority
name which specifies the order in which chains with the same *hook* value are
@@ -763,11 +775,16 @@ per element comment field
FLOWTABLES
-----------
[verse]
-{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'device'[*,* ...] *} ; }*
+____
+{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'DEVICE_LIST' *} ; }*
*list flowtables* ['family'] ['table']
{*delete* | *destroy* | *list*} *flowtable* ['family'] 'table' 'flowtable'
*delete* *flowtable* ['family'] 'table' *handle* 'handle'
+'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
+'DEVICE_NAME' := 'string' | 'string'***
+____
+
Flowtables allow you to accelerate packet forwarding in software. Flowtables
entries are represented through a tuple that is composed of the input interface,
source and destination address, source and destination port; and layer 3/4
@@ -786,6 +803,11 @@ The *priority* can be a signed integer or *filter* which stands for 0. Addition
and subtraction can be used to set relative priority, e.g. filter + 5 equals to
5.
+With newer kernels there is basic support for wildcards in 'DEVICE_LIST' by
+specifying an asterisk suffix. The flowtable will apply to all interfaces
+matching the given prefix. Use the *list hooks* command to see the current
+status.
+
[horizontal]
*add*:: Add a new flowtable for the given family with the given name.
*delete*:: Delete the specified flowtable.
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 9ac1ca3..936372f 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2473,16 +2473,7 @@ flowtable_list_expr : flowtable_expr_member
| flowtable_list_expr COMMA opt_newline
;
-flowtable_expr_member : QUOTED_STRING
- {
- struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);
-
- if (!expr)
- YYERROR;
-
- $$ = expr;
- }
- | STRING
+flowtable_expr_member : string
{
struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);

View File

@ -0,0 +1,257 @@
From 22b7438f93073a76836a571b42e78df7638e117e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 27 Nov 2025 10:58:08 +0100
Subject: [PATCH] tests: shell: Test ifname-based hooks
JIRA: https://issues.redhat.com/browse/RHEL-108861
Upstream Status: nftables commit 12c31bc2a822437d026b0cd83143d45808971404
commit 12c31bc2a822437d026b0cd83143d45808971404
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Jul 15 15:26:33 2025 +0200
tests: shell: Test ifname-based hooks
Assert that:
- Non-matching interface specs are accepted
- Existing interfaces are hooked into upon flowtable/chain creation
- A new device matching the spec is hooked into immediately
- No stale hooks remain in 'nft list hooks' output
- Wildcard hooks basically work
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
.../features/list_hooks_flowtable_info.sh | 7 +++
.../netdev_chain_name_based_hook_0.json-nft | 34 ++++++++++++++
.../dumps/netdev_chain_name_based_hook_0.nft | 5 +++
.../chains/netdev_chain_name_based_hook_0 | 44 ++++++++++++++++++
.../testcases/flowtable/0016name_based_hook_0 | 45 +++++++++++++++++++
.../dumps/0016name_based_hook_0.json-nft | 32 +++++++++++++
.../flowtable/dumps/0016name_based_hook_0.nft | 6 +++
7 files changed, 173 insertions(+)
create mode 100755 tests/shell/features/list_hooks_flowtable_info.sh
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
create mode 100755 tests/shell/testcases/chains/netdev_chain_name_based_hook_0
create mode 100755 tests/shell/testcases/flowtable/0016name_based_hook_0
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
diff --git a/tests/shell/features/list_hooks_flowtable_info.sh b/tests/shell/features/list_hooks_flowtable_info.sh
new file mode 100755
index 0000000..58bc57e
--- /dev/null
+++ b/tests/shell/features/list_hooks_flowtable_info.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# check for flowtable info in 'list hooks' output
+
+unshare -n bash -c " \
+$NFT \"table inet t { flowtable ft { hook ingress priority 0; devices = { lo }; }; }\"; \
+$NFT list hooks netdev device lo | grep -q flowtable\ inet\ t\ ft"
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
new file mode 100644
index 0000000..0070627
--- /dev/null
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
@@ -0,0 +1,34 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "netdev",
+ "name": "t",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "netdev",
+ "table": "t",
+ "name": "c",
+ "handle": 0,
+ "dev": [
+ "foo*",
+ "lo"
+ ],
+ "type": "filter",
+ "hook": "ingress",
+ "prio": 0,
+ "policy": "accept"
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
new file mode 100644
index 0000000..ac5acac
--- /dev/null
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
@@ -0,0 +1,5 @@
+table netdev t {
+ chain c {
+ type filter hook ingress devices = { "foo*", "lo" } priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/chains/netdev_chain_name_based_hook_0 b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
new file mode 100755
index 0000000..8a8a601
--- /dev/null
+++ b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
+
+cspec=' chain netdev t c '
+$NFT add table netdev t
+$NFT add $cspec '{ type filter hook ingress priority 0; devices = { lo, foo* }; }'
+$NFT list hooks netdev device lo | grep -q "$cspec" || {
+ echo "Existing device lo not hooked into chain as expected"
+ exit 1
+}
+
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
+ echo "Chain hooks into more than just lo"
+ exit 2
+}
+
+ip link add foo1 type dummy
+$NFT list hooks netdev device foo1 | grep -q "$cspec" || {
+ echo "Chain did not hook into new device foo1"
+ exit 3
+}
+[[ $($NFT list hooks | grep -c "$cspec") -eq 2 ]] || {
+ echo "Chain expected to hook into exactly two devices"
+ exit 4
+}
+
+ip link del foo1
+$NFT list hooks netdev device foo1 | grep -q "$cspec" && {
+ echo "Chain still hooks into removed device foo1"
+ exit 5
+}
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
+ echo "Chain expected to hook into just lo"
+ exit 6
+}
+
+for ((i = 0; i < 100; i++)); do
+ ip link add foo$i type dummy
+done
+[[ $($NFT list hooks | grep -c "$cspec") -eq 101 ]] || {
+ echo "Chain did not hook into all 100 new devices"
+ exit 7
+}
diff --git a/tests/shell/testcases/flowtable/0016name_based_hook_0 b/tests/shell/testcases/flowtable/0016name_based_hook_0
new file mode 100755
index 0000000..9a55596
--- /dev/null
+++ b/tests/shell/testcases/flowtable/0016name_based_hook_0
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_list_hooks_flowtable_info)
+
+ftspec=' flowtable ip t ft '
+$NFT add table t
+$NFT add $ftspec '{ hook ingress priority 0; devices = { lo, foo* }; }'
+$NFT list hooks netdev device lo | grep -q "$ftspec" || {
+ echo "Existing device lo not hooked into flowtable as expected"
+ exit 1
+}
+
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
+ echo "Flowtable hooks into more than just lo"
+ exit 2
+}
+
+ip link add foo1 type dummy
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" || {
+ echo "Flowtable did not hook into new device foo1"
+ exit 3
+}
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 2 ]] || {
+ echo "Flowtable expected to hook into exactly two devices"
+ exit 4
+}
+
+ip link del foo1
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" && {
+ echo "Flowtable still hooks into removed device foo1"
+ exit 5
+}
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
+ echo "Flowtable expected to hook into just lo"
+ exit 6
+}
+
+for ((i = 0; i < 100; i++)); do
+ ip link add foo$i type dummy
+done
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 101 ]] || {
+ echo "Flowtable did not hook into all 100 new devices"
+ exit 7
+}
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
new file mode 100644
index 0000000..93e2633
--- /dev/null
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
@@ -0,0 +1,32 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "ip",
+ "name": "t",
+ "handle": 0
+ }
+ },
+ {
+ "flowtable": {
+ "family": "ip",
+ "name": "ft",
+ "table": "t",
+ "handle": 0,
+ "hook": "ingress",
+ "prio": 0,
+ "dev": [
+ "foo*",
+ "lo"
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
new file mode 100644
index 0000000..b481066
--- /dev/null
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
@@ -0,0 +1,6 @@
+table ip t {
+ flowtable ft {
+ hook ingress priority filter
+ devices = { "foo*", "lo" }
+ }
+}

View File

@ -0,0 +1,50 @@
From 34146c80ea9418fc96fe7bd6246ed88a517ccd23 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 27 Nov 2025 10:58:08 +0100
Subject: [PATCH] mnl: Drop asterisk from end of NFTA_DEVICE_PREFIX strings
JIRA: https://issues.redhat.com/browse/RHEL-108861
Upstream Status: nftables commit 11b9415fd63d245b1a3230aa4f7cd1e2b0639ddd
commit 11b9415fd63d245b1a3230aa4f7cd1e2b0639ddd
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Oct 7 17:51:32 2025 +0200
mnl: Drop asterisk from end of NFTA_DEVICE_PREFIX strings
The asterisk left in place becomes part of the prefix by accident and is thus
both included when matching interface names as well as dumped back to user
space.
Fixes: c31e887504a90 ("mnl: Support simple wildcards in netdev hooks")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/mnl.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/mnl.c b/src/mnl.c
index ccf4ca5..bd5d95e 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -815,9 +815,16 @@ static bool is_wildcard_str(const char *str)
static void mnl_nft_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname)
{
- uint16_t attr = is_wildcard_str(ifname) ?
- NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME;
+ uint16_t attr = NFTA_DEVICE_NAME;
+ char pfx[IFNAMSIZ];
+ if (is_wildcard_str(ifname)) {
+ snprintf(pfx, IFNAMSIZ, "%s", ifname);
+ pfx[strlen(pfx) - 1] = '\0';
+
+ attr = NFTA_DEVICE_PREFIX;
+ ifname = pfx;
+ }
mnl_attr_put_strz(nlh, attr, ifname);
}

View File

@ -0,0 +1,51 @@
From 61fe7eb2b5acbacc8105d08172c19476af4d7dfc Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 16 Dec 2025 16:35:49 +0100
Subject: [PATCH] tests: monitor: Fix for out-of-path call
JIRA: https://issues.redhat.com/browse/RHEL-121194
Upstream Status: nftables commit 1ac69c4de8ff7b472c3a5f2cf1d9442642e9047c
Conflicts: Fix manually applied, upstream refactored the problematic
code in commit 48550e8e9359c ("tests: monitor: Excercise all
syntaxes and variants by default").
commit 1ac69c4de8ff7b472c3a5f2cf1d9442642e9047c
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Dec 16 15:36:23 2025 +0100
tests: monitor: Fix for out-of-path call
When called from another directory without specifying test cases, an
incorrect regexp was used to glob all tests and no test was run at all:
| # ./tests/monitor/run-tests.sh
| echo: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| monitor: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| json-echo: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| json-monitor: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
Fixes: 83eaf50c36fe8 ("tests: monitor: Become $PWD agnostic")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/monitor/run-tests.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh
index 76355e8..bf10c16 100755
--- a/tests/monitor/run-tests.sh
+++ b/tests/monitor/run-tests.sh
@@ -170,7 +170,7 @@ for variant in $variants; do
run_test=${variant}_run_test
output_append=${variant}_output_append
- for testcase in ${testcases:-testcases/*.t}; do
+ for testcase in ${testcases:-$(dirname $0)/testcases/*.t}; do
filename=$(basename $testcase)
echo "$variant: running tests from file $filename"
rc_start=$rc

View File

@ -0,0 +1 @@
monitor: 1 tests from file flowtable-simple.t failed

View File

@ -1,788 +1,5 @@
any/objects.t: ERROR: line 3: I cannot create the chain 'egress'
any/objects.t: ERROR: line 16: The chain egress does not exist in netdev test-netdev. I cannot delete it.
any/rawpayload.t: ERROR: line 3: I cannot create the chain 'egress'
any/rawpayload.t: ERROR: line 8: add rule netdev test-netdev egress meta l4proto { tcp, udp, sctp} @th,16,16 { 22, 23, 80 }: This rule should not have failed.
any/rawpayload.t: ERROR: line 9: add rule netdev test-netdev egress meta l4proto tcp @th,16,16 { 22, 23, 80}: This rule should not have failed.
any/rawpayload.t: ERROR: line 10: add rule netdev test-netdev egress @nh,8,8 0xff: This rule should not have failed.
any/rawpayload.t: ERROR: line 11: add rule netdev test-netdev egress @nh,8,16 0x0: This rule should not have failed.
any/rawpayload.t: ERROR: line 18: add rule netdev test-netdev egress @ll,0,1 1: This rule should not have failed.
any/rawpayload.t: ERROR: line 19: add rule netdev test-netdev egress @ll,0,8 & 0x80 == 0x80: This rule should not have failed.
any/rawpayload.t: ERROR: line 20: add rule netdev test-netdev egress @ll,0,128 0xfedcba987654321001234567890abcde: This rule should not have failed.
any/rawpayload.t: ERROR: line 22: add rule inet test-inet input @ih,32,32 0x14000000: This rule should not have failed.
any/rawpayload.t: ERROR: line 22: The chain egress does not exist in netdev test-netdev. I cannot delete it.
any/quota.t: ERROR: line 3: I cannot create the chain 'egress'
any/quota.t: ERROR: line 12: add rule netdev test-netdev egress quota 1025 bytes: This rule should not have failed.
any/quota.t: ERROR: line 13: add rule netdev test-netdev egress quota 1 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 14: add rule netdev test-netdev egress quota 2 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 15: add rule netdev test-netdev egress quota 1025 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 16: add rule netdev test-netdev egress quota 1023 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 17: add rule netdev test-netdev egress quota 10230 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 18: add rule netdev test-netdev egress quota 1023000 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 20: add rule netdev test-netdev egress quota over 1 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 21: add rule netdev test-netdev egress quota over 2 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 22: add rule netdev test-netdev egress quota over 1025 kbytes: This rule should not have failed.
any/quota.t: ERROR: line 23: add rule netdev test-netdev egress quota over 1023 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 24: add rule netdev test-netdev egress quota over 10230 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 25: add rule netdev test-netdev egress quota over 1023000 mbytes: This rule should not have failed.
any/quota.t: ERROR: line 25: The chain egress does not exist in netdev test-netdev. I cannot delete it.
any/tcpopt.t: ERROR: line 58: add rule ip test-ip4 input reset tcp option mptcp: This rule should not have failed.
any/tcpopt.t: ERROR: line 59: add rule ip test-ip4 input reset tcp option 2: This rule should not have failed.
any/tcpopt.t: ERROR: line 60: add rule ip test-ip4 input reset tcp option 123: This rule should not have failed.
any/meta.t: ERROR: line 3: I cannot create the chain 'egress'
any/meta.t: ERROR: line 12: add rule netdev test-netdev egress meta length 1000: This rule should not have failed.
any/meta.t: ERROR: line 13: add rule netdev test-netdev egress meta length 22: This rule should not have failed.
any/meta.t: ERROR: line 14: add rule netdev test-netdev egress meta length != 233: This rule should not have failed.
any/meta.t: ERROR: line 15: add rule netdev test-netdev egress meta length 33-45: This rule should not have failed.
any/meta.t: ERROR: line 16: add rule netdev test-netdev egress meta length != 33-45: This rule should not have failed.
any/meta.t: ERROR: line 17: add rule netdev test-netdev egress meta length { 33, 55, 67, 88}: This rule should not have failed.
any/meta.t: ERROR: line 18: add rule netdev test-netdev egress meta length { 33-55, 67-88}: This rule should not have failed.
any/meta.t: ERROR: line 19: add rule netdev test-netdev egress meta length { 33-55, 56-88, 100-120}: This rule should not have failed.
any/meta.t: ERROR: line 20: add rule netdev test-netdev egress meta length != { 33, 55, 67, 88}: This rule should not have failed.
any/meta.t: ERROR: line 21: add rule netdev test-netdev egress meta length { 33-55, 66-88}: This rule should not have failed.
any/meta.t: ERROR: line 22: add rule netdev test-netdev egress meta length != { 33-55, 66-88}: This rule should not have failed.
any/meta.t: ERROR: line 24: add rule netdev test-netdev egress meta protocol { ip, arp, ip6, vlan }: This rule should not have failed.
any/meta.t: ERROR: line 25: add rule netdev test-netdev egress meta protocol != {ip, arp, ip6, 8021q}: This rule should not have failed.
any/meta.t: ERROR: line 26: add rule netdev test-netdev egress meta protocol ip: This rule should not have failed.
any/meta.t: ERROR: line 27: add rule netdev test-netdev egress meta protocol != ip: This rule should not have failed.
any/meta.t: ERROR: line 29: add rule netdev test-netdev egress meta l4proto 22: This rule should not have failed.
any/meta.t: ERROR: line 30: add rule netdev test-netdev egress meta l4proto != 233: This rule should not have failed.
any/meta.t: ERROR: line 31: add rule netdev test-netdev egress meta l4proto 33-45: This rule should not have failed.
any/meta.t: ERROR: line 32: add rule netdev test-netdev egress meta l4proto != 33-45: This rule should not have failed.
any/meta.t: ERROR: line 33: add rule netdev test-netdev egress meta l4proto { 33, 55, 67, 88}: This rule should not have failed.
any/meta.t: ERROR: line 34: add rule netdev test-netdev egress meta l4proto != { 33, 55, 67, 88}: This rule should not have failed.
any/meta.t: ERROR: line 35: add rule netdev test-netdev egress meta l4proto { 33-55, 66-88}: This rule should not have failed.
any/meta.t: ERROR: line 36: add rule netdev test-netdev egress meta l4proto != { 33-55, 66-88}: This rule should not have failed.
any/meta.t: ERROR: line 38: add rule netdev test-netdev egress meta priority root: This rule should not have failed.
any/meta.t: ERROR: line 39: add rule netdev test-netdev egress meta priority none: This rule should not have failed.
any/meta.t: ERROR: line 40: add rule netdev test-netdev egress meta priority 0x87654321: This rule should not have failed.
any/meta.t: ERROR: line 41: add rule netdev test-netdev egress meta priority 2271560481: This rule should not have failed.
any/meta.t: ERROR: line 42: add rule netdev test-netdev egress meta priority 1:1234: This rule should not have failed.
any/meta.t: ERROR: line 43: add rule netdev test-netdev egress meta priority bcad:dadc: This rule should not have failed.
any/meta.t: ERROR: line 44: add rule netdev test-netdev egress meta priority aabb:0: This rule should not have failed.
any/meta.t: ERROR: line 45: add rule netdev test-netdev egress meta priority != bcad:dadc: This rule should not have failed.
any/meta.t: ERROR: line 46: add rule netdev test-netdev egress meta priority != aabb:0: This rule should not have failed.
any/meta.t: ERROR: line 47: add rule netdev test-netdev egress meta priority bcad:dada-bcad:dadc: This rule should not have failed.
any/meta.t: ERROR: line 48: add rule netdev test-netdev egress meta priority != bcad:dada-bcad:dadc: This rule should not have failed.
any/meta.t: ERROR: line 49: add rule netdev test-netdev egress meta priority {bcad:dada, bcad:dadc, aaaa:bbbb}: This rule should not have failed.
any/meta.t: ERROR: line 50: add rule netdev test-netdev egress meta priority set cafe:beef: This rule should not have failed.
any/meta.t: ERROR: line 51: add rule netdev test-netdev egress meta priority != {bcad:dada, bcad:dadc, aaaa:bbbb}: This rule should not have failed.
any/meta.t: ERROR: line 53: add rule netdev test-netdev egress meta mark 0x4: This rule should not have failed.
any/meta.t: ERROR: line 54: add rule netdev test-netdev egress meta mark 0x32: This rule should not have failed.
any/meta.t: ERROR: line 55: add rule netdev test-netdev egress meta mark and 0x03 == 0x01: This rule should not have failed.
any/meta.t: ERROR: line 56: add rule netdev test-netdev egress meta mark and 0x03 != 0x01: This rule should not have failed.
any/meta.t: ERROR: line 57: add rule netdev test-netdev egress meta mark 0x10: This rule should not have failed.
any/meta.t: ERROR: line 58: add rule netdev test-netdev egress meta mark != 0x10: This rule should not have failed.
any/meta.t: ERROR: line 59: add rule netdev test-netdev egress meta mark 0xffffff00/24: This rule should not have failed.
any/meta.t: ERROR: line 61: add rule netdev test-netdev egress meta mark or 0x03 == 0x01: This rule should not have failed.
any/meta.t: ERROR: line 62: add rule netdev test-netdev egress meta mark or 0x03 != 0x01: This rule should not have failed.
any/meta.t: ERROR: line 63: add rule netdev test-netdev egress meta mark xor 0x03 == 0x01: This rule should not have failed.
any/meta.t: ERROR: line 64: add rule netdev test-netdev egress meta mark xor 0x03 != 0x01: This rule should not have failed.
any/meta.t: ERROR: line 66: add rule netdev test-netdev egress meta iif "lo" accept: This rule should not have failed.
any/meta.t: ERROR: line 67: add rule netdev test-netdev egress meta iif != "lo" accept: This rule should not have failed.
any/meta.t: ERROR: line 69: add rule netdev test-netdev egress meta iifname "dummy0": This rule should not have failed.
any/meta.t: ERROR: line 70: add rule netdev test-netdev egress meta iifname != "dummy0": This rule should not have failed.
any/meta.t: ERROR: line 71: add rule netdev test-netdev egress meta iifname {"dummy0", "lo"}: This rule should not have failed.
any/meta.t: ERROR: line 72: add rule netdev test-netdev egress meta iifname != {"dummy0", "lo"}: This rule should not have failed.
any/meta.t: ERROR: line 73: add rule netdev test-netdev egress meta iifname "dummy*": This rule should not have failed.
any/meta.t: ERROR: line 74: add rule netdev test-netdev egress meta iifname "dummy\*": This rule should not have failed.
any/meta.t: ERROR: line 77: add rule netdev test-netdev egress meta iiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre}: This rule should not have failed.
any/meta.t: ERROR: line 78: add rule netdev test-netdev egress meta iiftype != {ether, ppp, ipip, ipip6, loopback, sit, ipgre}: This rule should not have failed.
any/meta.t: ERROR: line 79: add rule netdev test-netdev egress meta iiftype != ether: This rule should not have failed.
any/meta.t: ERROR: line 80: add rule netdev test-netdev egress meta iiftype ether: This rule should not have failed.
any/meta.t: ERROR: line 81: add rule netdev test-netdev egress meta iiftype != ppp: This rule should not have failed.
any/meta.t: ERROR: line 82: add rule netdev test-netdev egress meta iiftype ppp: This rule should not have failed.
any/meta.t: ERROR: line 84: add rule netdev test-netdev egress meta oif "lo" accept: This rule should not have failed.
any/meta.t: ERROR: line 85: add rule netdev test-netdev egress meta oif != "lo" accept: This rule should not have failed.
any/meta.t: ERROR: line 87: add rule netdev test-netdev egress meta oifname "dummy0": This rule should not have failed.
any/meta.t: ERROR: line 88: add rule netdev test-netdev egress meta oifname != "dummy0": This rule should not have failed.
any/meta.t: ERROR: line 89: add rule netdev test-netdev egress meta oifname { "dummy0", "lo"}: This rule should not have failed.
any/meta.t: ERROR: line 90: add rule netdev test-netdev egress meta oifname "dummy*": This rule should not have failed.
any/meta.t: ERROR: line 91: add rule netdev test-netdev egress meta oifname "dummy\*": This rule should not have failed.
any/meta.t: ERROR: line 94: add rule netdev test-netdev egress meta oiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre}: This rule should not have failed.
any/meta.t: ERROR: line 95: add rule netdev test-netdev egress meta oiftype != {ether, ppp, ipip, ipip6, loopback, sit, ipgre}: This rule should not have failed.
any/meta.t: ERROR: line 96: add rule netdev test-netdev egress meta oiftype != ether: This rule should not have failed.
any/meta.t: ERROR: line 97: add rule netdev test-netdev egress meta oiftype ether: This rule should not have failed.
any/meta.t: ERROR: line 99: add rule netdev test-netdev egress meta skuid {"bin", "root", "daemon"} accept: This rule should not have failed.
any/meta.t: ERROR: line 100: add rule netdev test-netdev egress meta skuid != {"bin", "root", "daemon"} accept: This rule should not have failed.
any/meta.t: ERROR: line 101: add rule netdev test-netdev egress meta skuid "root": This rule should not have failed.
any/meta.t: ERROR: line 102: add rule netdev test-netdev egress meta skuid != "root": This rule should not have failed.
any/meta.t: ERROR: line 103: add rule netdev test-netdev egress meta skuid lt 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 104: add rule netdev test-netdev egress meta skuid gt 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 105: add rule netdev test-netdev egress meta skuid eq 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 106: add rule netdev test-netdev egress meta skuid 3001-3005 accept: This rule should not have failed.
any/meta.t: ERROR: line 107: add rule netdev test-netdev egress meta skuid != 2001-2005 accept: This rule should not have failed.
any/meta.t: ERROR: line 108: add rule netdev test-netdev egress meta skuid { 2001-2005, 3001-3005} accept: This rule should not have failed.
any/meta.t: ERROR: line 109: add rule netdev test-netdev egress meta skuid != { 2001-2005, 3001-3005} accept: This rule should not have failed.
any/meta.t: ERROR: line 111: add rule netdev test-netdev egress meta skgid {"bin", "root", "daemon"} accept: This rule should not have failed.
any/meta.t: ERROR: line 112: add rule netdev test-netdev egress meta skgid != {"bin", "root", "daemon"} accept: This rule should not have failed.
any/meta.t: ERROR: line 113: add rule netdev test-netdev egress meta skgid "root": This rule should not have failed.
any/meta.t: ERROR: line 114: add rule netdev test-netdev egress meta skgid != "root": This rule should not have failed.
any/meta.t: ERROR: line 115: add rule netdev test-netdev egress meta skgid lt 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 116: add rule netdev test-netdev egress meta skgid gt 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 117: add rule netdev test-netdev egress meta skgid eq 3000 accept: This rule should not have failed.
any/meta.t: ERROR: line 118: add rule netdev test-netdev egress meta skgid 2001-2005 accept: This rule should not have failed.
any/meta.t: ERROR: line 119: add rule netdev test-netdev egress meta skgid != 2001-2005 accept: This rule should not have failed.
any/meta.t: ERROR: line 131: add rule netdev test-netdev egress meta mark set 0xffffffc8 xor 0x16: This rule should not have failed.
any/meta.t: ERROR: line 132: add rule netdev test-netdev egress meta mark set 0x16 and 0x16: This rule should not have failed.
any/meta.t: ERROR: line 133: add rule netdev test-netdev egress meta mark set 0xffffffe9 or 0x16: This rule should not have failed.
any/meta.t: ERROR: line 134: add rule netdev test-netdev egress meta mark set 0xffffffde and 0x16: This rule should not have failed.
any/meta.t: ERROR: line 135: add rule netdev test-netdev egress meta mark set 0xf045ffde or 0x10: This rule should not have failed.
any/meta.t: ERROR: line 136: add rule netdev test-netdev egress meta mark set 0xffffffde or 0x16: This rule should not have failed.
any/meta.t: ERROR: line 137: add rule netdev test-netdev egress meta mark set 0x32 or 0xfffff: This rule should not have failed.
any/meta.t: ERROR: line 138: add rule netdev test-netdev egress meta mark set 0xfffe xor 0x16: This rule should not have failed.
any/meta.t: ERROR: line 143: add rule netdev test-netdev egress meta iif "lo": This rule should not have failed.
any/meta.t: ERROR: line 144: add rule netdev test-netdev egress meta oif "lo": This rule should not have failed.
any/meta.t: ERROR: line 145: add rule netdev test-netdev egress meta oifname "dummy2" accept: This rule should not have failed.
any/meta.t: ERROR: line 146: add rule netdev test-netdev egress meta skuid 3000: This rule should not have failed.
any/meta.t: ERROR: line 147: add rule netdev test-netdev egress meta skgid 3000: This rule should not have failed.
any/meta.t: ERROR: line 151: add rule netdev test-netdev egress meta rtclassid "cosmos": This rule should not have failed.
any/meta.t: ERROR: line 153: add rule netdev test-netdev egress meta pkttype broadcast: This rule should not have failed.
any/meta.t: ERROR: line 154: add rule netdev test-netdev egress meta pkttype host: This rule should not have failed.
any/meta.t: ERROR: line 155: add rule netdev test-netdev egress meta pkttype multicast: This rule should not have failed.
any/meta.t: ERROR: line 156: add rule netdev test-netdev egress meta pkttype != broadcast: This rule should not have failed.
any/meta.t: ERROR: line 157: add rule netdev test-netdev egress meta pkttype != host: This rule should not have failed.
any/meta.t: ERROR: line 158: add rule netdev test-netdev egress meta pkttype != multicast: This rule should not have failed.
any/meta.t: ERROR: line 160: add rule netdev test-netdev egress pkttype { broadcast, multicast} accept: This rule should not have failed.
any/meta.t: ERROR: line 162: add rule netdev test-netdev egress meta cpu 1: This rule should not have failed.
any/meta.t: ERROR: line 163: add rule netdev test-netdev egress meta cpu != 1: This rule should not have failed.
any/meta.t: ERROR: line 164: add rule netdev test-netdev egress meta cpu 1-3: This rule should not have failed.
any/meta.t: ERROR: line 165: add rule netdev test-netdev egress meta cpu != 1-2: This rule should not have failed.
any/meta.t: ERROR: line 166: add rule netdev test-netdev egress meta cpu { 2,3}: This rule should not have failed.
any/meta.t: ERROR: line 167: add rule netdev test-netdev egress meta cpu { 2-3, 5-7}: This rule should not have failed.
any/meta.t: ERROR: line 168: add rule netdev test-netdev egress meta cpu != { 2,3}: This rule should not have failed.
any/meta.t: ERROR: line 170: add rule netdev test-netdev egress meta iifgroup 0: This rule should not have failed.
any/meta.t: ERROR: line 171: add rule netdev test-netdev egress meta iifgroup != 0: This rule should not have failed.
any/meta.t: ERROR: line 172: add rule netdev test-netdev egress meta iifgroup "default": This rule should not have failed.
any/meta.t: ERROR: line 173: add rule netdev test-netdev egress meta iifgroup != "default": This rule should not have failed.
any/meta.t: ERROR: line 174: add rule netdev test-netdev egress meta iifgroup {"default", 11}: This rule should not have failed.
any/meta.t: ERROR: line 175: add rule netdev test-netdev egress meta iifgroup != {"default", 11}: This rule should not have failed.
any/meta.t: ERROR: line 176: add rule netdev test-netdev egress meta iifgroup { 11,33}: This rule should not have failed.
any/meta.t: ERROR: line 177: add rule netdev test-netdev egress meta iifgroup {11-33, 44-55}: This rule should not have failed.
any/meta.t: ERROR: line 178: add rule netdev test-netdev egress meta iifgroup != { 11,33}: This rule should not have failed.
any/meta.t: ERROR: line 179: add rule netdev test-netdev egress meta iifgroup != {11-33, 44-55}: This rule should not have failed.
any/meta.t: ERROR: line 180: add rule netdev test-netdev egress meta oifgroup 0: This rule should not have failed.
any/meta.t: ERROR: line 181: add rule netdev test-netdev egress meta oifgroup != 0: This rule should not have failed.
any/meta.t: ERROR: line 182: add rule netdev test-netdev egress meta oifgroup "default": This rule should not have failed.
any/meta.t: ERROR: line 183: add rule netdev test-netdev egress meta oifgroup != "default": This rule should not have failed.
any/meta.t: ERROR: line 184: add rule netdev test-netdev egress meta oifgroup {"default", 11}: This rule should not have failed.
any/meta.t: ERROR: line 185: add rule netdev test-netdev egress meta oifgroup != {"default", 11}: This rule should not have failed.
any/meta.t: ERROR: line 186: add rule netdev test-netdev egress meta oifgroup { 11,33}: This rule should not have failed.
any/meta.t: ERROR: line 187: add rule netdev test-netdev egress meta oifgroup {11-33, 44-55}: This rule should not have failed.
any/meta.t: ERROR: line 188: add rule netdev test-netdev egress meta oifgroup != { 11,33}: This rule should not have failed.
any/meta.t: ERROR: line 189: add rule netdev test-netdev egress meta oifgroup != {11-33, 44-55}: This rule should not have failed.
any/meta.t: ERROR: line 191: add rule netdev test-netdev egress meta cgroup 1048577: This rule should not have failed.
any/meta.t: ERROR: line 192: add rule netdev test-netdev egress meta cgroup != 1048577: This rule should not have failed.
any/meta.t: ERROR: line 193: add rule netdev test-netdev egress meta cgroup { 1048577, 1048578 }: This rule should not have failed.
any/meta.t: ERROR: line 194: add rule netdev test-netdev egress meta cgroup != { 1048577, 1048578}: This rule should not have failed.
any/meta.t: ERROR: line 195: add rule netdev test-netdev egress meta cgroup 1048577-1048578: This rule should not have failed.
any/meta.t: ERROR: line 196: add rule netdev test-netdev egress meta cgroup != 1048577-1048578: This rule should not have failed.
any/meta.t: ERROR: line 198: add rule netdev test-netdev egress meta iif . meta oif { "lo" . "lo" }: This rule should not have failed.
any/meta.t: ERROR: line 199: add rule netdev test-netdev egress meta iif . meta oif . meta mark { "lo" . "lo" . 0x0000000a }: This rule should not have failed.
any/meta.t: ERROR: line 200: add rule netdev test-netdev egress meta iif . meta oif vmap { "lo" . "lo" : drop }: This rule should not have failed.
any/meta.t: ERROR: line 202: add rule netdev test-netdev egress meta random eq 1: This rule should not have failed.
any/meta.t: ERROR: line 203: add rule netdev test-netdev egress meta random gt 1000000: This rule should not have failed.
any/meta.t: ERROR: line 205: add rule netdev test-netdev egress meta time "1970-05-23 21:07:14" drop: This rule should not have failed.
any/meta.t: ERROR: line 206: add rule netdev test-netdev egress meta time 12341234 drop: This rule should not have failed.
any/meta.t: ERROR: line 207: add rule netdev test-netdev egress meta time "2019-06-21 17:00:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 208: add rule netdev test-netdev egress meta time "2019-07-01 00:00:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 209: add rule netdev test-netdev egress meta time "2019-07-01 00:01:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 210: add rule netdev test-netdev egress meta time "2019-07-01 00:00:01" drop: This rule should not have failed.
any/meta.t: ERROR: line 211: add rule netdev test-netdev egress meta time < "2022-07-01 11:00:00" accept: This rule should not have failed.
any/meta.t: ERROR: line 212: add rule netdev test-netdev egress meta time > "2022-07-01 11:00:00" accept: This rule should not have failed.
any/meta.t: ERROR: line 213: add rule netdev test-netdev egress meta day "Saturday" drop: This rule should not have failed.
any/meta.t: ERROR: line 214: add rule netdev test-netdev egress meta day 6 drop: This rule should not have failed.
any/meta.t: ERROR: line 216: add rule netdev test-netdev egress meta hour "17:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 217: add rule netdev test-netdev egress meta hour "17:00:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 218: add rule netdev test-netdev egress meta hour "17:00:01" drop: This rule should not have failed.
any/meta.t: ERROR: line 219: add rule netdev test-netdev egress meta hour "00:00" drop: This rule should not have failed.
any/meta.t: ERROR: line 220: add rule netdev test-netdev egress meta hour "00:01" drop: This rule should not have failed.
any/meta.t: ERROR: line 221: add rule netdev test-netdev egress time < "2022-07-01 11:00:00" accept: This rule should not have failed.
any/meta.t: ERROR: line 222: add rule netdev test-netdev egress time > "2022-07-01 11:00:00" accept: This rule should not have failed.
any/meta.t: ERROR: line 226: The chain egress does not exist in netdev test-netdev. I cannot delete it.
any/limit.t: ERROR: line 3: I cannot create the chain 'egress'
any/limit.t: ERROR: line 12: add rule netdev test-netdev egress limit rate 400/minute: This rule should not have failed.
any/limit.t: ERROR: line 13: add rule netdev test-netdev egress limit rate 20/second: This rule should not have failed.
any/limit.t: ERROR: line 14: add rule netdev test-netdev egress limit rate 400/hour: This rule should not have failed.
any/limit.t: ERROR: line 15: add rule netdev test-netdev egress limit rate 40/day: This rule should not have failed.
any/limit.t: ERROR: line 16: add rule netdev test-netdev egress limit rate 400/week: This rule should not have failed.
any/limit.t: ERROR: line 17: add rule netdev test-netdev egress limit rate 1023/second burst 10 packets: This rule should not have failed.
any/limit.t: ERROR: line 20: add rule netdev test-netdev egress limit rate 1 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 21: add rule netdev test-netdev egress limit rate 2 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 22: add rule netdev test-netdev egress limit rate 1025 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 23: add rule netdev test-netdev egress limit rate 1023 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 24: add rule netdev test-netdev egress limit rate 10230 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 25: add rule netdev test-netdev egress limit rate 1023000 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 28: add rule netdev test-netdev egress limit rate 1 bytes / second: This rule should not have failed.
any/limit.t: ERROR: line 29: add rule netdev test-netdev egress limit rate 1 kbytes / second: This rule should not have failed.
any/limit.t: ERROR: line 30: add rule netdev test-netdev egress limit rate 1 mbytes / second: This rule should not have failed.
any/limit.t: ERROR: line 33: add rule netdev test-netdev egress limit rate 1025 bytes/second burst 512 bytes: This rule should not have failed.
any/limit.t: ERROR: line 34: add rule netdev test-netdev egress limit rate 1025 kbytes/second burst 1023 kbytes: This rule should not have failed.
any/limit.t: ERROR: line 35: add rule netdev test-netdev egress limit rate 1025 mbytes/second burst 1025 kbytes: This rule should not have failed.
any/limit.t: ERROR: line 36: add rule netdev test-netdev egress limit rate 1025000 mbytes/second burst 1023 mbytes: This rule should not have failed.
any/limit.t: ERROR: line 38: add rule netdev test-netdev egress limit rate over 400/minute: This rule should not have failed.
any/limit.t: ERROR: line 39: add rule netdev test-netdev egress limit rate over 20/second: This rule should not have failed.
any/limit.t: ERROR: line 40: add rule netdev test-netdev egress limit rate over 400/hour: This rule should not have failed.
any/limit.t: ERROR: line 41: add rule netdev test-netdev egress limit rate over 40/day: This rule should not have failed.
any/limit.t: ERROR: line 42: add rule netdev test-netdev egress limit rate over 400/week: This rule should not have failed.
any/limit.t: ERROR: line 43: add rule netdev test-netdev egress limit rate over 1023/second burst 10 packets: This rule should not have failed.
any/limit.t: ERROR: line 45: add rule netdev test-netdev egress limit rate over 1 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 46: add rule netdev test-netdev egress limit rate over 2 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 47: add rule netdev test-netdev egress limit rate over 1025 kbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 48: add rule netdev test-netdev egress limit rate over 1023 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 49: add rule netdev test-netdev egress limit rate over 10230 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 50: add rule netdev test-netdev egress limit rate over 1023000 mbytes/second: This rule should not have failed.
any/limit.t: ERROR: line 52: add rule netdev test-netdev egress limit rate over 1025 bytes/second burst 512 bytes: This rule should not have failed.
any/limit.t: ERROR: line 53: add rule netdev test-netdev egress limit rate over 1025 kbytes/second burst 1023 kbytes: This rule should not have failed.
any/limit.t: ERROR: line 54: add rule netdev test-netdev egress limit rate over 1025 mbytes/second burst 1025 kbytes: This rule should not have failed.
any/limit.t: ERROR: line 55: add rule netdev test-netdev egress limit rate over 1025000 mbytes/second burst 1023 mbytes: This rule should not have failed.
any/limit.t: ERROR: line 55: The chain egress does not exist in netdev test-netdev. I cannot delete it.
arp/arp.t: ERROR: line 4: I cannot create the chain 'egress'
arp/arp.t: ERROR: line 9: add rule netdev test-netdev egress arp htype 1: This rule should not have failed.
arp/arp.t: ERROR: line 10: add rule netdev test-netdev egress arp htype != 1: This rule should not have failed.
arp/arp.t: ERROR: line 11: add rule netdev test-netdev egress arp htype 22: This rule should not have failed.
arp/arp.t: ERROR: line 12: add rule netdev test-netdev egress arp htype != 233: This rule should not have failed.
arp/arp.t: ERROR: line 13: add rule netdev test-netdev egress arp htype 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 14: add rule netdev test-netdev egress arp htype != 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 15: add rule netdev test-netdev egress arp htype { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 16: add rule netdev test-netdev egress arp htype != { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 18: add rule netdev test-netdev egress arp ptype 0x0800: This rule should not have failed.
arp/arp.t: ERROR: line 20: add rule netdev test-netdev egress arp hlen 22: This rule should not have failed.
arp/arp.t: ERROR: line 21: add rule netdev test-netdev egress arp hlen != 233: This rule should not have failed.
arp/arp.t: ERROR: line 22: add rule netdev test-netdev egress arp hlen 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 23: add rule netdev test-netdev egress arp hlen != 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 24: add rule netdev test-netdev egress arp hlen { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 25: add rule netdev test-netdev egress arp hlen != { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 27: add rule netdev test-netdev egress arp plen 22: This rule should not have failed.
arp/arp.t: ERROR: line 28: add rule netdev test-netdev egress arp plen != 233: This rule should not have failed.
arp/arp.t: ERROR: line 29: add rule netdev test-netdev egress arp plen 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 30: add rule netdev test-netdev egress arp plen != 33-45: This rule should not have failed.
arp/arp.t: ERROR: line 31: add rule netdev test-netdev egress arp plen { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 32: add rule netdev test-netdev egress arp plen != { 33, 55, 67, 88}: This rule should not have failed.
arp/arp.t: ERROR: line 34: add rule netdev test-netdev egress arp operation {nak, inreply, inrequest, rreply, rrequest, reply, request}: This rule should not have failed.
arp/arp.t: ERROR: line 35: add rule netdev test-netdev egress arp operation != {nak, inreply, inrequest, rreply, rrequest, reply, request}: This rule should not have failed.
arp/arp.t: ERROR: line 36: add rule netdev test-netdev egress arp operation 1-2: This rule should not have failed.
arp/arp.t: ERROR: line 37: add rule netdev test-netdev egress arp operation request: This rule should not have failed.
arp/arp.t: ERROR: line 38: add rule netdev test-netdev egress arp operation reply: This rule should not have failed.
arp/arp.t: ERROR: line 39: add rule netdev test-netdev egress arp operation rrequest: This rule should not have failed.
arp/arp.t: ERROR: line 40: add rule netdev test-netdev egress arp operation rreply: This rule should not have failed.
arp/arp.t: ERROR: line 41: add rule netdev test-netdev egress arp operation inrequest: This rule should not have failed.
arp/arp.t: ERROR: line 42: add rule netdev test-netdev egress arp operation inreply: This rule should not have failed.
arp/arp.t: ERROR: line 43: add rule netdev test-netdev egress arp operation nak: This rule should not have failed.
arp/arp.t: ERROR: line 44: add rule netdev test-netdev egress arp operation != request: This rule should not have failed.
arp/arp.t: ERROR: line 45: add rule netdev test-netdev egress arp operation != reply: This rule should not have failed.
arp/arp.t: ERROR: line 46: add rule netdev test-netdev egress arp operation != rrequest: This rule should not have failed.
arp/arp.t: ERROR: line 47: add rule netdev test-netdev egress arp operation != rreply: This rule should not have failed.
arp/arp.t: ERROR: line 48: add rule netdev test-netdev egress arp operation != inrequest: This rule should not have failed.
arp/arp.t: ERROR: line 49: add rule netdev test-netdev egress arp operation != inreply: This rule should not have failed.
arp/arp.t: ERROR: line 50: add rule netdev test-netdev egress arp operation != nak: This rule should not have failed.
arp/arp.t: ERROR: line 52: add rule netdev test-netdev egress arp saddr ip 1.2.3.4: This rule should not have failed.
arp/arp.t: ERROR: line 53: add rule netdev test-netdev egress arp daddr ip 4.3.2.1: This rule should not have failed.
arp/arp.t: ERROR: line 54: add rule netdev test-netdev egress arp saddr ether aa:bb:cc:aa:bb:cc: This rule should not have failed.
arp/arp.t: ERROR: line 55: add rule netdev test-netdev egress arp daddr ether aa:bb:cc:aa:bb:cc: This rule should not have failed.
arp/arp.t: ERROR: line 57: add rule netdev test-netdev egress arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee: This rule should not have failed.
arp/arp.t: ERROR: line 58: add rule netdev test-netdev egress arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1: This rule should not have failed.
arp/arp.t: ERROR: line 60: add rule netdev test-netdev egress meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566: This rule should not have failed.
arp/arp.t: ERROR: line 60: The chain egress does not exist in netdev test-netdev. I cannot delete it.
bridge/vlan.t: ERROR: line 3: I cannot create the chain 'egress'
bridge/vlan.t: ERROR: line 8: add rule netdev test-netdev egress vlan id 4094: This rule should not have failed.
bridge/vlan.t: ERROR: line 9: add rule netdev test-netdev egress vlan id 0: This rule should not have failed.
bridge/vlan.t: ERROR: line 12: add rule netdev test-netdev egress vlan id 4094 vlan dei 0: This rule should not have failed.
bridge/vlan.t: ERROR: line 13: add rule netdev test-netdev egress vlan id 4094 vlan dei 1: This rule should not have failed.
bridge/vlan.t: ERROR: line 14: add rule netdev test-netdev egress vlan id 4094 vlan dei != 1: This rule should not have failed.
bridge/vlan.t: ERROR: line 15: add rule netdev test-netdev egress vlan id 4094 vlan cfi 1: This rule should not have failed.
bridge/vlan.t: ERROR: line 19: add rule netdev test-netdev egress vlan id 4094 vlan dei 1 vlan pcp 7: This rule should not have failed.
bridge/vlan.t: ERROR: line 20: add rule netdev test-netdev egress vlan id 4094 vlan dei 1 vlan pcp 3: This rule should not have failed.
bridge/vlan.t: ERROR: line 22: add rule netdev test-netdev egress ether type vlan vlan id 4094: This rule should not have failed.
bridge/vlan.t: ERROR: line 23: add rule netdev test-netdev egress ether type vlan vlan id 0: This rule should not have failed.
bridge/vlan.t: ERROR: line 24: add rule netdev test-netdev egress ether type vlan vlan id 4094 vlan dei 0: This rule should not have failed.
bridge/vlan.t: ERROR: line 25: add rule netdev test-netdev egress ether type vlan vlan id 4094 vlan dei 1: This rule should not have failed.
bridge/vlan.t: ERROR: line 28: add rule netdev test-netdev egress vlan id 4094 tcp dport 22: This rule should not have failed.
bridge/vlan.t: ERROR: line 29: add rule netdev test-netdev egress vlan id 1 ip saddr 10.0.0.1: This rule should not have failed.
bridge/vlan.t: ERROR: line 30: add rule netdev test-netdev egress vlan id 1 ip saddr 10.0.0.0/23: This rule should not have failed.
bridge/vlan.t: ERROR: line 31: add rule netdev test-netdev egress vlan id 1 ip saddr 10.0.0.0/23 udp dport 53: This rule should not have failed.
bridge/vlan.t: ERROR: line 32: add rule netdev test-netdev egress ether type vlan vlan id 1 ip saddr 10.0.0.0/23 udp dport 53: This rule should not have failed.
bridge/vlan.t: ERROR: line 34: add rule netdev test-netdev egress vlan id { 1, 2, 4, 100, 4095 } vlan pcp 1-3: This rule should not have failed.
bridge/vlan.t: ERROR: line 37: add rule netdev test-netdev egress ether type vlan ip protocol 1 accept: This rule should not have failed.
bridge/vlan.t: ERROR: line 40: add rule netdev test-netdev egress ether type 8021ad vlan id 1 ip protocol 6 accept: This rule should not have failed.
bridge/vlan.t: ERROR: line 41: add rule netdev test-netdev egress ether type 8021ad vlan id 1 vlan type 8021q vlan id 2 vlan type ip counter: This rule should not have failed.
bridge/vlan.t: ERROR: line 42: add rule netdev test-netdev egress ether type 8021ad vlan id 1 vlan type 8021q vlan id 2 vlan type ip ip protocol 6: This rule should not have failed.
bridge/vlan.t: ERROR: line 49: add rule netdev test-netdev egress vlan id 1 vlan id set 2: This rule should not have failed.
bridge/vlan.t: ERROR: line 51: add rule netdev test-netdev egress ether saddr 00:01:02:03:04:05 vlan id 1: This rule should not have failed.
bridge/vlan.t: ERROR: line 52: add rule netdev test-netdev egress vlan id 2 ether saddr 0:1:2:3:4:6: This rule should not have failed.
bridge/vlan.t: ERROR: line 54: add rule netdev test-netdev egress ether saddr . vlan id { 0a:0b:0c:0d:0e:0f . 42, 0a:0b:0c:0d:0e:0f . 4095 }: This rule should not have failed.
bridge/vlan.t: ERROR: line 54: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/dccp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/dccp.t: ERROR: line 10: add rule netdev test-netdev egress dccp sport 21-35: This rule should not have failed.
inet/dccp.t: ERROR: line 11: add rule netdev test-netdev egress dccp sport != 21-35: This rule should not have failed.
inet/dccp.t: ERROR: line 12: add rule netdev test-netdev egress dccp sport {23, 24, 25}: This rule should not have failed.
inet/dccp.t: ERROR: line 13: add rule netdev test-netdev egress dccp sport != {23, 24, 25}: This rule should not have failed.
inet/dccp.t: ERROR: line 15: add rule netdev test-netdev egress dccp sport 20-50: This rule should not have failed.
inet/dccp.t: ERROR: line 19: add rule netdev test-netdev egress dccp dport {23, 24, 25}: This rule should not have failed.
inet/dccp.t: ERROR: line 20: add rule netdev test-netdev egress dccp dport != {23, 24, 25}: This rule should not have failed.
inet/dccp.t: ERROR: line 22: add rule netdev test-netdev egress dccp type {request, response, data, ack, dataack, closereq, close, reset, sync, syncack}: This rule should not have failed.
inet/dccp.t: ERROR: line 23: add rule netdev test-netdev egress dccp type != {request, response, data, ack, dataack, closereq, close, reset, sync, syncack}: This rule should not have failed.
inet/dccp.t: ERROR: line 24: add rule netdev test-netdev egress dccp type request: This rule should not have failed.
inet/dccp.t: ERROR: line 25: add rule netdev test-netdev egress dccp type != request: This rule should not have failed.
inet/dccp.t: ERROR: line 25: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/map.t: ERROR: line 3: I cannot create the chain 'egress'
inet/map.t: ERROR: line 9: add rule netdev test-netdev egress mark set ip saddr map { 10.2.3.2 : 0x0000002a, 10.2.3.1 : 0x00000017}: This rule should not have failed.
inet/map.t: ERROR: line 10: add rule netdev test-netdev egress mark set ip hdrlength map { 5 : 0x00000017, 4 : 0x00000001}: This rule should not have failed.
inet/map.t: ERROR: line 10: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/sets.t: ERROR: line 3: I cannot create the chain 'egress'
inet/sets.t: ERROR: line 15: add rule netdev test-netdev egress ip saddr @set1 drop: This rule should not have failed.
inet/sets.t: ERROR: line 18: add rule netdev test-netdev egress ip6 daddr != @set2 accept: This rule should not have failed.
inet/sets.t: ERROR: line 24: add rule netdev test-netdev egress ip saddr . ip daddr . tcp dport @set3 accept: This rule should not have failed.
inet/sets.t: ERROR: line 25: add rule netdev test-netdev egress ip daddr . tcp dport { 10.0.0.0/8 . 10-23, 192.168.1.1-192.168.3.8 . 80-443 } accept: This rule should not have failed.
inet/sets.t: ERROR: line 25: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/ip.t: ERROR: line 3: I cannot create the chain 'egress'
inet/ip.t: ERROR: line 10: add rule netdev test-netdev egress ip saddr . ip daddr . ether saddr { 1.1.1.1 . 2.2.2.2 . ca:fe:ca:fe:ca:fe }: This rule should not have failed.
inet/ip.t: ERROR: line 12: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/udp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/udp.t: ERROR: line 10: add rule netdev test-netdev egress udp sport 80 accept: This rule should not have failed.
inet/udp.t: ERROR: line 11: add rule netdev test-netdev egress udp sport != 60 accept: This rule should not have failed.
inet/udp.t: ERROR: line 12: add rule netdev test-netdev egress udp sport 50-70 accept: This rule should not have failed.
inet/udp.t: ERROR: line 13: add rule netdev test-netdev egress udp sport != 50-60 accept: This rule should not have failed.
inet/udp.t: ERROR: line 14: add rule netdev test-netdev egress udp sport { 49, 50} drop: This rule should not have failed.
inet/udp.t: ERROR: line 15: add rule netdev test-netdev egress udp sport != { 50, 60} accept: This rule should not have failed.
inet/udp.t: ERROR: line 19: add rule netdev test-netdev egress udp dport 80 accept: This rule should not have failed.
inet/udp.t: ERROR: line 20: add rule netdev test-netdev egress udp dport != 60 accept: This rule should not have failed.
inet/udp.t: ERROR: line 21: add rule netdev test-netdev egress udp dport 70-75 accept: This rule should not have failed.
inet/udp.t: ERROR: line 22: add rule netdev test-netdev egress udp dport != 50-60 accept: This rule should not have failed.
inet/udp.t: ERROR: line 23: add rule netdev test-netdev egress udp dport { 49, 50} drop: This rule should not have failed.
inet/udp.t: ERROR: line 24: add rule netdev test-netdev egress udp dport != { 50, 60} accept: This rule should not have failed.
inet/udp.t: ERROR: line 26: add rule netdev test-netdev egress udp length 6666: This rule should not have failed.
inet/udp.t: ERROR: line 27: add rule netdev test-netdev egress udp length != 6666: This rule should not have failed.
inet/udp.t: ERROR: line 28: add rule netdev test-netdev egress udp length 50-65 accept: This rule should not have failed.
inet/udp.t: ERROR: line 29: add rule netdev test-netdev egress udp length != 50-65 accept: This rule should not have failed.
inet/udp.t: ERROR: line 30: add rule netdev test-netdev egress udp length { 50, 65} accept: This rule should not have failed.
inet/udp.t: ERROR: line 31: add rule netdev test-netdev egress udp length != { 50, 65} accept: This rule should not have failed.
inet/udp.t: ERROR: line 33: add rule netdev test-netdev egress udp checksum 6666 drop: This rule should not have failed.
inet/udp.t: ERROR: line 34: add rule netdev test-netdev egress udp checksum != { 444, 555} accept: This rule should not have failed.
inet/udp.t: ERROR: line 36: add rule netdev test-netdev egress udp checksum 22: This rule should not have failed.
inet/udp.t: ERROR: line 37: add rule netdev test-netdev egress udp checksum != 233: This rule should not have failed.
inet/udp.t: ERROR: line 38: add rule netdev test-netdev egress udp checksum 33-45: This rule should not have failed.
inet/udp.t: ERROR: line 39: add rule netdev test-netdev egress udp checksum != 33-45: This rule should not have failed.
inet/udp.t: ERROR: line 40: add rule netdev test-netdev egress udp checksum { 33, 55, 67, 88}: This rule should not have failed.
inet/udp.t: ERROR: line 41: add rule netdev test-netdev egress udp checksum != { 33, 55, 67, 88}: This rule should not have failed.
inet/udp.t: ERROR: line 44: add rule netdev test-netdev egress iif "lo" udp checksum set 0: This rule should not have failed.
inet/udp.t: ERROR: line 45: add rule netdev test-netdev egress iif "lo" udp dport set 65535: This rule should not have failed.
inet/udp.t: ERROR: line 45: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/ether.t: ERROR: line 3: I cannot create the chain 'egress'
inet/ether.t: ERROR: line 11: add rule netdev test-netdev egress tcp dport 22 iiftype ether ether saddr 00:0f:54:0c:11:4 accept: This rule should not have failed.
inet/ether.t: ERROR: line 12: add rule netdev test-netdev egress tcp dport 22 ether saddr 00:0f:54:0c:11:04 accept: This rule should not have failed.
inet/ether.t: ERROR: line 14: add rule netdev test-netdev egress ether saddr 00:0f:54:0c:11:04 accept: This rule should not have failed.
inet/ether.t: ERROR: line 14: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/comp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/comp.t: ERROR: line 12: add rule netdev test-netdev egress comp nexthdr != esp: This rule should not have failed.
inet/comp.t: ERROR: line 18: add rule netdev test-netdev egress comp flags 0x0: This rule should not have failed.
inet/comp.t: ERROR: line 19: add rule netdev test-netdev egress comp flags != 0x23: This rule should not have failed.
inet/comp.t: ERROR: line 20: add rule netdev test-netdev egress comp flags 0x33-0x45: This rule should not have failed.
inet/comp.t: ERROR: line 21: add rule netdev test-netdev egress comp flags != 0x33-0x45: This rule should not have failed.
inet/comp.t: ERROR: line 22: add rule netdev test-netdev egress comp flags {0x33, 0x55, 0x67, 0x88}: This rule should not have failed.
inet/comp.t: ERROR: line 23: add rule netdev test-netdev egress comp flags != {0x33, 0x55, 0x67, 0x88}: This rule should not have failed.
inet/comp.t: ERROR: line 25: add rule netdev test-netdev egress comp cpi 22: This rule should not have failed.
inet/comp.t: ERROR: line 26: add rule netdev test-netdev egress comp cpi != 233: This rule should not have failed.
inet/comp.t: ERROR: line 27: add rule netdev test-netdev egress comp cpi 33-45: This rule should not have failed.
inet/comp.t: ERROR: line 28: add rule netdev test-netdev egress comp cpi != 33-45: This rule should not have failed.
inet/comp.t: ERROR: line 29: add rule netdev test-netdev egress comp cpi {33, 55, 67, 88}: This rule should not have failed.
inet/comp.t: ERROR: line 30: add rule netdev test-netdev egress comp cpi != {33, 55, 67, 88}: This rule should not have failed.
inet/comp.t: ERROR: line 30: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/udplite.t: ERROR: line 3: I cannot create the chain 'egress'
inet/udplite.t: ERROR: line 10: add rule netdev test-netdev egress udplite sport 80 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 11: add rule netdev test-netdev egress udplite sport != 60 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 12: add rule netdev test-netdev egress udplite sport 50-70 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 13: add rule netdev test-netdev egress udplite sport != 50-60 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 14: add rule netdev test-netdev egress udplite sport { 49, 50} drop: This rule should not have failed.
inet/udplite.t: ERROR: line 15: add rule netdev test-netdev egress udplite sport != { 49, 50} accept: This rule should not have failed.
inet/udplite.t: ERROR: line 17: add rule netdev test-netdev egress udplite dport 80 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 18: add rule netdev test-netdev egress udplite dport != 60 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 19: add rule netdev test-netdev egress udplite dport 70-75 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 20: add rule netdev test-netdev egress udplite dport != 50-60 accept: This rule should not have failed.
inet/udplite.t: ERROR: line 21: add rule netdev test-netdev egress udplite dport { 49, 50} drop: This rule should not have failed.
inet/udplite.t: ERROR: line 22: add rule netdev test-netdev egress udplite dport != { 49, 50} accept: This rule should not have failed.
inet/udplite.t: ERROR: line 31: add rule netdev test-netdev egress udplite checksum 6666 drop: This rule should not have failed.
inet/udplite.t: ERROR: line 32: add rule netdev test-netdev egress udplite checksum != { 444, 555} accept: This rule should not have failed.
inet/udplite.t: ERROR: line 33: add rule netdev test-netdev egress udplite checksum 22: This rule should not have failed.
inet/udplite.t: ERROR: line 34: add rule netdev test-netdev egress udplite checksum != 233: This rule should not have failed.
inet/udplite.t: ERROR: line 35: add rule netdev test-netdev egress udplite checksum 33-45: This rule should not have failed.
inet/udplite.t: ERROR: line 36: add rule netdev test-netdev egress udplite checksum != 33-45: This rule should not have failed.
inet/udplite.t: ERROR: line 37: add rule netdev test-netdev egress udplite checksum { 33, 55, 67, 88}: This rule should not have failed.
inet/udplite.t: ERROR: line 38: add rule netdev test-netdev egress udplite checksum != { 33, 55, 67, 88}: This rule should not have failed.
inet/udplite.t: ERROR: line 38: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/tcp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/tcp.t: ERROR: line 12: add rule netdev test-netdev egress tcp dport 22: This rule should not have failed.
inet/tcp.t: ERROR: line 13: add rule netdev test-netdev egress tcp dport != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 14: add rule netdev test-netdev egress tcp dport 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 15: add rule netdev test-netdev egress tcp dport != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 16: add rule netdev test-netdev egress tcp dport { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 17: add rule netdev test-netdev egress tcp dport != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 18: add rule netdev test-netdev egress tcp dport {telnet, http, https} accept: This rule should not have failed.
inet/tcp.t: ERROR: line 19: add rule netdev test-netdev egress tcp dport vmap { 22 : accept, 23 : drop }: This rule should not have failed.
inet/tcp.t: ERROR: line 20: add rule netdev test-netdev egress tcp dport vmap { 25:accept, 28:drop }: This rule should not have failed.
inet/tcp.t: ERROR: line 21: add rule netdev test-netdev egress tcp dport { 22, 53, 80, 110 }: This rule should not have failed.
inet/tcp.t: ERROR: line 22: add rule netdev test-netdev egress tcp dport != { 22, 53, 80, 110 }: This rule should not have failed.
inet/tcp.t: ERROR: line 26: add rule netdev test-netdev egress tcp sport 22: This rule should not have failed.
inet/tcp.t: ERROR: line 27: add rule netdev test-netdev egress tcp sport != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 28: add rule netdev test-netdev egress tcp sport 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 29: add rule netdev test-netdev egress tcp sport != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 30: add rule netdev test-netdev egress tcp sport { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 31: add rule netdev test-netdev egress tcp sport != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 32: add rule netdev test-netdev egress tcp sport vmap { 25:accept, 28:drop }: This rule should not have failed.
inet/tcp.t: ERROR: line 34: add rule netdev test-netdev egress tcp sport 8080 drop: This rule should not have failed.
inet/tcp.t: ERROR: line 35: add rule netdev test-netdev egress tcp sport 1024 tcp dport 22: This rule should not have failed.
inet/tcp.t: ERROR: line 36: add rule netdev test-netdev egress tcp sport 1024 tcp dport 22 tcp sequence 0: This rule should not have failed.
inet/tcp.t: ERROR: line 38: add rule netdev test-netdev egress tcp sequence 0 tcp sport 1024 tcp dport 22: This rule should not have failed.
inet/tcp.t: ERROR: line 39: add rule netdev test-netdev egress tcp sequence 0 tcp sport { 1024, 1022} tcp dport 22: This rule should not have failed.
inet/tcp.t: ERROR: line 41: add rule netdev test-netdev egress tcp sequence 22: This rule should not have failed.
inet/tcp.t: ERROR: line 42: add rule netdev test-netdev egress tcp sequence != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 43: add rule netdev test-netdev egress tcp sequence 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 44: add rule netdev test-netdev egress tcp sequence != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 45: add rule netdev test-netdev egress tcp sequence { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 46: add rule netdev test-netdev egress tcp sequence != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 48: add rule netdev test-netdev egress tcp ackseq 42949672 drop: This rule should not have failed.
inet/tcp.t: ERROR: line 49: add rule netdev test-netdev egress tcp ackseq 22: This rule should not have failed.
inet/tcp.t: ERROR: line 50: add rule netdev test-netdev egress tcp ackseq != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 51: add rule netdev test-netdev egress tcp ackseq 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 52: add rule netdev test-netdev egress tcp ackseq != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 53: add rule netdev test-netdev egress tcp ackseq { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 54: add rule netdev test-netdev egress tcp ackseq != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 66: add rule netdev test-netdev egress tcp flags { fin, syn, rst, psh, ack, urg, ecn, cwr} drop: This rule should not have failed.
inet/tcp.t: ERROR: line 67: add rule netdev test-netdev egress tcp flags != { fin, urg, ecn, cwr} drop: This rule should not have failed.
inet/tcp.t: ERROR: line 68: add rule netdev test-netdev egress tcp flags cwr: This rule should not have failed.
inet/tcp.t: ERROR: line 69: add rule netdev test-netdev egress tcp flags != cwr: This rule should not have failed.
inet/tcp.t: ERROR: line 70: add rule netdev test-netdev egress tcp flags == syn: This rule should not have failed.
inet/tcp.t: ERROR: line 71: add rule netdev test-netdev egress tcp flags fin,syn / fin,syn: This rule should not have failed.
inet/tcp.t: ERROR: line 72: add rule netdev test-netdev egress tcp flags != syn / fin,syn: This rule should not have failed.
inet/tcp.t: ERROR: line 73: add rule netdev test-netdev egress tcp flags & syn != 0: This rule should not have failed.
inet/tcp.t: ERROR: line 74: add rule netdev test-netdev egress tcp flags & syn == 0: This rule should not have failed.
inet/tcp.t: ERROR: line 75: add rule netdev test-netdev egress tcp flags & (syn | ack) != 0: This rule should not have failed.
inet/tcp.t: ERROR: line 76: add rule netdev test-netdev egress tcp flags & (syn | ack) == 0: This rule should not have failed.
inet/tcp.t: ERROR: line 78: add rule netdev test-netdev egress tcp flags & syn == syn: This rule should not have failed.
inet/tcp.t: ERROR: line 79: add rule netdev test-netdev egress tcp flags & syn != syn: This rule should not have failed.
inet/tcp.t: ERROR: line 80: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | ack) syn: This rule should not have failed.
inet/tcp.t: ERROR: line 81: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | ack) == syn: This rule should not have failed.
inet/tcp.t: ERROR: line 82: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | ack) != syn: This rule should not have failed.
inet/tcp.t: ERROR: line 83: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | ack) == (syn | ack): This rule should not have failed.
inet/tcp.t: ERROR: line 84: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | ack) != (syn | ack): This rule should not have failed.
inet/tcp.t: ERROR: line 85: add rule netdev test-netdev egress tcp flags & (syn | ack) == (syn | ack): This rule should not have failed.
inet/tcp.t: ERROR: line 86: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr: This rule should not have failed.
inet/tcp.t: ERROR: line 87: add rule netdev test-netdev egress tcp flags { syn, syn | ack }: This rule should not have failed.
inet/tcp.t: ERROR: line 88: add rule netdev test-netdev egress tcp flags & (fin | syn | rst | psh | ack | urg) == { fin, ack, psh | ack, fin | psh | ack }: This rule should not have failed.
inet/tcp.t: ERROR: line 89: add rule netdev test-netdev egress tcp flags ! fin,rst: This rule should not have failed.
inet/tcp.t: ERROR: line 92: add rule netdev test-netdev egress tcp window 22222: This rule should not have failed.
inet/tcp.t: ERROR: line 93: add rule netdev test-netdev egress tcp window 22: This rule should not have failed.
inet/tcp.t: ERROR: line 94: add rule netdev test-netdev egress tcp window != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 95: add rule netdev test-netdev egress tcp window 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 96: add rule netdev test-netdev egress tcp window != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 97: add rule netdev test-netdev egress tcp window { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 98: add rule netdev test-netdev egress tcp window != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 100: add rule netdev test-netdev egress tcp checksum 22: This rule should not have failed.
inet/tcp.t: ERROR: line 101: add rule netdev test-netdev egress tcp checksum != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 102: add rule netdev test-netdev egress tcp checksum 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 103: add rule netdev test-netdev egress tcp checksum != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 104: add rule netdev test-netdev egress tcp checksum { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 105: add rule netdev test-netdev egress tcp checksum != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 107: add rule netdev test-netdev egress tcp urgptr 1234 accept: This rule should not have failed.
inet/tcp.t: ERROR: line 108: add rule netdev test-netdev egress tcp urgptr 22: This rule should not have failed.
inet/tcp.t: ERROR: line 109: add rule netdev test-netdev egress tcp urgptr != 233: This rule should not have failed.
inet/tcp.t: ERROR: line 110: add rule netdev test-netdev egress tcp urgptr 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 111: add rule netdev test-netdev egress tcp urgptr != 33-45: This rule should not have failed.
inet/tcp.t: ERROR: line 112: add rule netdev test-netdev egress tcp urgptr { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 113: add rule netdev test-netdev egress tcp urgptr != { 33, 55, 67, 88}: This rule should not have failed.
inet/tcp.t: ERROR: line 115: add rule netdev test-netdev egress tcp doff 8: This rule should not have failed.
inet/tcp.t: ERROR: line 115: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/ip_tcp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/ip_tcp.t: ERROR: line 10: add rule netdev test-netdev egress ip protocol tcp tcp dport 22: This rule should not have failed.
inet/ip_tcp.t: ERROR: line 13: add rule netdev test-netdev egress ip protocol tcp ip saddr 1.2.3.4 tcp dport 22: This rule should not have failed.
inet/ip_tcp.t: ERROR: line 16: add rule netdev test-netdev egress ip protocol tcp counter ip saddr 1.2.3.4 tcp dport 22: This rule should not have failed.
inet/ip_tcp.t: ERROR: line 19: add rule netdev test-netdev egress ip protocol tcp counter tcp dport 22: This rule should not have failed.
inet/ip_tcp.t: ERROR: line 21: add rule netdev test-netdev egress ether type ip tcp dport 22: This rule should not have failed.
inet/ip_tcp.t: ERROR: line 21: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/ah.t: ERROR: line 3: I cannot create the chain 'egress'
inet/ah.t: ERROR: line 22: add rule netdev test-netdev egress ah hdrlength 11-23: This rule should not have failed.
inet/ah.t: ERROR: line 23: add rule netdev test-netdev egress ah hdrlength != 11-23: This rule should not have failed.
inet/ah.t: ERROR: line 24: add rule netdev test-netdev egress ah hdrlength {11, 23, 44 }: This rule should not have failed.
inet/ah.t: ERROR: line 25: add rule netdev test-netdev egress ah hdrlength != {11, 23, 44 }: This rule should not have failed.
inet/ah.t: ERROR: line 27: add rule netdev test-netdev egress ah reserved 22: This rule should not have failed.
inet/ah.t: ERROR: line 28: add rule netdev test-netdev egress ah reserved != 233: This rule should not have failed.
inet/ah.t: ERROR: line 29: add rule netdev test-netdev egress ah reserved 33-45: This rule should not have failed.
inet/ah.t: ERROR: line 30: add rule netdev test-netdev egress ah reserved != 33-45: This rule should not have failed.
inet/ah.t: ERROR: line 31: add rule netdev test-netdev egress ah reserved {23, 100}: This rule should not have failed.
inet/ah.t: ERROR: line 32: add rule netdev test-netdev egress ah reserved != {23, 100}: This rule should not have failed.
inet/ah.t: ERROR: line 34: add rule netdev test-netdev egress ah spi 111: This rule should not have failed.
inet/ah.t: ERROR: line 35: add rule netdev test-netdev egress ah spi != 111: This rule should not have failed.
inet/ah.t: ERROR: line 36: add rule netdev test-netdev egress ah spi 111-222: This rule should not have failed.
inet/ah.t: ERROR: line 37: add rule netdev test-netdev egress ah spi != 111-222: This rule should not have failed.
inet/ah.t: ERROR: line 38: add rule netdev test-netdev egress ah spi {111, 122}: This rule should not have failed.
inet/ah.t: ERROR: line 39: add rule netdev test-netdev egress ah spi != {111, 122}: This rule should not have failed.
inet/ah.t: ERROR: line 42: add rule netdev test-netdev egress ah sequence 123: This rule should not have failed.
inet/ah.t: ERROR: line 43: add rule netdev test-netdev egress ah sequence != 123: This rule should not have failed.
inet/ah.t: ERROR: line 44: add rule netdev test-netdev egress ah sequence {23, 25, 33}: This rule should not have failed.
inet/ah.t: ERROR: line 45: add rule netdev test-netdev egress ah sequence != {23, 25, 33}: This rule should not have failed.
inet/ah.t: ERROR: line 46: add rule netdev test-netdev egress ah sequence 23-33: This rule should not have failed.
inet/ah.t: ERROR: line 47: add rule netdev test-netdev egress ah sequence != 23-33: This rule should not have failed.
inet/ah.t: ERROR: line 47: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/vmap.t: ERROR: line 3: I cannot create the chain 'egress'
inet/vmap.t: ERROR: line 8: add rule netdev test-netdev egress iifname . ip protocol . th dport vmap { "eth0" . tcp . 22 : accept, "eth1" . udp . 67 : drop }: This rule should not have failed.
inet/vmap.t: ERROR: line 9: add rule inet test-inet input ip saddr . @ih,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }: This rule should not have failed.
inet/vmap.t: ERROR: line 10: add rule netdev test-netdev egress udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : accept }: This rule should not have failed.
inet/vmap.t: ERROR: line 10: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/ether-ip.t: ERROR: line 3: I cannot create the chain 'egress'
inet/ether-ip.t: ERROR: line 8: add rule netdev test-netdev egress tcp dport 22 iiftype ether ip daddr 1.2.3.4 ether saddr 00:0f:54:0c:11:4 accept: This rule should not have failed.
inet/ether-ip.t: ERROR: line 9: add rule netdev test-netdev egress tcp dport 22 ip daddr 1.2.3.4 ether saddr 00:0f:54:0c:11:04: This rule should not have failed.
inet/ether-ip.t: ERROR: line 9: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/esp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/esp.t: ERROR: line 10: add rule netdev test-netdev egress esp spi 100: This rule should not have failed.
inet/esp.t: ERROR: line 11: add rule netdev test-netdev egress esp spi != 100: This rule should not have failed.
inet/esp.t: ERROR: line 12: add rule netdev test-netdev egress esp spi 111-222: This rule should not have failed.
inet/esp.t: ERROR: line 13: add rule netdev test-netdev egress esp spi != 111-222: This rule should not have failed.
inet/esp.t: ERROR: line 14: add rule netdev test-netdev egress esp spi { 100, 102}: This rule should not have failed.
inet/esp.t: ERROR: line 15: add rule netdev test-netdev egress esp spi != { 100, 102}: This rule should not have failed.
inet/esp.t: ERROR: line 17: add rule netdev test-netdev egress esp sequence 22: This rule should not have failed.
inet/esp.t: ERROR: line 18: add rule netdev test-netdev egress esp sequence 22-24: This rule should not have failed.
inet/esp.t: ERROR: line 19: add rule netdev test-netdev egress esp sequence != 22-24: This rule should not have failed.
inet/esp.t: ERROR: line 20: add rule netdev test-netdev egress esp sequence { 22, 24}: This rule should not have failed.
inet/esp.t: ERROR: line 21: add rule netdev test-netdev egress esp sequence != { 22, 24}: This rule should not have failed.
inet/esp.t: ERROR: line 21: The chain egress does not exist in netdev test-netdev. I cannot delete it.
inet/sctp.t: ERROR: line 3: I cannot create the chain 'egress'
inet/sctp.t: ERROR: line 10: add rule netdev test-netdev egress sctp sport 23: This rule should not have failed.
inet/sctp.t: ERROR: line 11: add rule netdev test-netdev egress sctp sport != 23: This rule should not have failed.
inet/sctp.t: ERROR: line 12: add rule netdev test-netdev egress sctp sport 23-44: This rule should not have failed.
inet/sctp.t: ERROR: line 13: add rule netdev test-netdev egress sctp sport != 23-44: This rule should not have failed.
inet/sctp.t: ERROR: line 14: add rule netdev test-netdev egress sctp sport { 23, 24, 25}: This rule should not have failed.
inet/sctp.t: ERROR: line 15: add rule netdev test-netdev egress sctp sport != { 23, 24, 25}: This rule should not have failed.
inet/sctp.t: ERROR: line 17: add rule netdev test-netdev egress sctp dport 23: This rule should not have failed.
inet/sctp.t: ERROR: line 18: add rule netdev test-netdev egress sctp dport != 23: This rule should not have failed.
inet/sctp.t: ERROR: line 19: add rule netdev test-netdev egress sctp dport 23-44: This rule should not have failed.
inet/sctp.t: ERROR: line 20: add rule netdev test-netdev egress sctp dport != 23-44: This rule should not have failed.
inet/sctp.t: ERROR: line 21: add rule netdev test-netdev egress sctp dport { 23, 24, 25}: This rule should not have failed.
inet/sctp.t: ERROR: line 22: add rule netdev test-netdev egress sctp dport != { 23, 24, 25}: This rule should not have failed.
inet/sctp.t: ERROR: line 24: add rule netdev test-netdev egress sctp checksum 1111: This rule should not have failed.
inet/sctp.t: ERROR: line 25: add rule netdev test-netdev egress sctp checksum != 11: This rule should not have failed.
inet/sctp.t: ERROR: line 26: add rule netdev test-netdev egress sctp checksum 21-333: This rule should not have failed.
inet/sctp.t: ERROR: line 27: add rule netdev test-netdev egress sctp checksum != 32-111: This rule should not have failed.
inet/sctp.t: ERROR: line 28: add rule netdev test-netdev egress sctp checksum { 22, 33, 44}: This rule should not have failed.
inet/sctp.t: ERROR: line 29: add rule netdev test-netdev egress sctp checksum != { 22, 33, 44}: This rule should not have failed.
inet/sctp.t: ERROR: line 31: add rule netdev test-netdev egress sctp vtag 22: This rule should not have failed.
inet/sctp.t: ERROR: line 32: add rule netdev test-netdev egress sctp vtag != 233: This rule should not have failed.
inet/sctp.t: ERROR: line 33: add rule netdev test-netdev egress sctp vtag 33-45: This rule should not have failed.
inet/sctp.t: ERROR: line 34: add rule netdev test-netdev egress sctp vtag != 33-45: This rule should not have failed.
inet/sctp.t: ERROR: line 35: add rule netdev test-netdev egress sctp vtag {33, 55, 67, 88}: This rule should not have failed.
inet/sctp.t: ERROR: line 36: add rule netdev test-netdev egress sctp vtag != {33, 55, 67, 88}: This rule should not have failed.
inet/sctp.t: ERROR: line 39: add rule netdev test-netdev egress sctp chunk data exists: This rule should not have failed.
inet/sctp.t: ERROR: line 40: add rule netdev test-netdev egress sctp chunk init exists: This rule should not have failed.
inet/sctp.t: ERROR: line 41: add rule netdev test-netdev egress sctp chunk init-ack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 42: add rule netdev test-netdev egress sctp chunk sack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 43: add rule netdev test-netdev egress sctp chunk heartbeat exists: This rule should not have failed.
inet/sctp.t: ERROR: line 44: add rule netdev test-netdev egress sctp chunk heartbeat-ack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 45: add rule netdev test-netdev egress sctp chunk abort exists: This rule should not have failed.
inet/sctp.t: ERROR: line 46: add rule netdev test-netdev egress sctp chunk shutdown exists: This rule should not have failed.
inet/sctp.t: ERROR: line 47: add rule netdev test-netdev egress sctp chunk shutdown-ack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 48: add rule netdev test-netdev egress sctp chunk error exists: This rule should not have failed.
inet/sctp.t: ERROR: line 49: add rule netdev test-netdev egress sctp chunk cookie-echo exists: This rule should not have failed.
inet/sctp.t: ERROR: line 50: add rule netdev test-netdev egress sctp chunk cookie-ack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 51: add rule netdev test-netdev egress sctp chunk ecne exists: This rule should not have failed.
inet/sctp.t: ERROR: line 52: add rule netdev test-netdev egress sctp chunk cwr exists: This rule should not have failed.
inet/sctp.t: ERROR: line 53: add rule netdev test-netdev egress sctp chunk shutdown-complete exists: This rule should not have failed.
inet/sctp.t: ERROR: line 54: add rule netdev test-netdev egress sctp chunk asconf-ack exists: This rule should not have failed.
inet/sctp.t: ERROR: line 55: add rule netdev test-netdev egress sctp chunk forward-tsn exists: This rule should not have failed.
inet/sctp.t: ERROR: line 56: add rule netdev test-netdev egress sctp chunk asconf exists: This rule should not have failed.
inet/sctp.t: ERROR: line 59: add rule netdev test-netdev egress sctp chunk data type 0: This rule should not have failed.
inet/sctp.t: ERROR: line 60: add rule netdev test-netdev egress sctp chunk init flags 23: This rule should not have failed.
inet/sctp.t: ERROR: line 61: add rule netdev test-netdev egress sctp chunk init-ack length 42: This rule should not have failed.
inet/sctp.t: ERROR: line 64: add rule netdev test-netdev egress sctp chunk data stream 1337: This rule should not have failed.
inet/sctp.t: ERROR: line 65: add rule netdev test-netdev egress sctp chunk init initial-tsn 5: This rule should not have failed.
inet/sctp.t: ERROR: line 66: add rule netdev test-netdev egress sctp chunk init-ack num-outbound-streams 3: This rule should not have failed.
inet/sctp.t: ERROR: line 67: add rule netdev test-netdev egress sctp chunk sack a-rwnd 1: This rule should not have failed.
inet/sctp.t: ERROR: line 68: add rule netdev test-netdev egress sctp chunk shutdown cum-tsn-ack 65535: This rule should not have failed.
inet/sctp.t: ERROR: line 69: add rule netdev test-netdev egress sctp chunk ecne lowest-tsn 5: This rule should not have failed.
inet/sctp.t: ERROR: line 70: add rule netdev test-netdev egress sctp chunk cwr lowest-tsn 8: This rule should not have failed.
inet/sctp.t: ERROR: line 71: add rule netdev test-netdev egress sctp chunk asconf-ack seqno 12345: This rule should not have failed.
inet/sctp.t: ERROR: line 72: add rule netdev test-netdev egress sctp chunk forward-tsn new-cum-tsn 31337: This rule should not have failed.
inet/sctp.t: ERROR: line 73: add rule netdev test-netdev egress sctp chunk asconf seqno 12345: This rule should not have failed.
inet/sctp.t: ERROR: line 73: The chain egress does not exist in netdev test-netdev. I cannot delete it.
ip/sets.t: ERROR: line 3: I cannot create the chain 'egress'
ip/sets.t: ERROR: line 32: add rule netdev test-netdev egress ip saddr @set1 drop: This rule should not have failed.
ip/sets.t: ERROR: line 33: add rule netdev test-netdev egress ip saddr != @set1 drop: This rule should not have failed.
ip/sets.t: ERROR: line 34: add rule netdev test-netdev egress ip saddr @set2 drop: This rule should not have failed.
ip/sets.t: ERROR: line 35: add rule netdev test-netdev egress ip saddr != @set2 drop: This rule should not have failed.
ip/sets.t: ERROR: line 52: add rule netdev test-netdev egress ip saddr . ip daddr @set5 drop: This rule should not have failed.
ip/sets.t: ERROR: line 53: add rule netdev test-netdev egress add @set5 { ip saddr . ip daddr }: This rule should not have failed.
ip/sets.t: ERROR: line 56: add rule netdev test-netdev egress ip saddr { { 1.1.1.0, 3.3.3.0 }, 2.2.2.0 }: This rule should not have failed.
ip/sets.t: ERROR: line 57: add rule netdev test-netdev egress ip saddr { { 1.1.1.0/24, 3.3.3.0/24 }, 2.2.2.0/24 }: This rule should not have failed.
ip/sets.t: ERROR: line 61: add rule netdev test-netdev egress ip saddr @set6 drop: This rule should not have failed.
ip/sets.t: ERROR: line 63: add rule netdev test-netdev egress ip saddr vmap { 1.1.1.1 : drop, * : accept }: This rule should not have failed.
ip/sets.t: ERROR: line 64: add rule netdev test-netdev egress meta mark set ip saddr map { 1.1.1.1 : 0x00000001, * : 0x00000002 }: This rule should not have failed.
ip/sets.t: ERROR: line 65: The chain egress does not exist in netdev test-netdev. I cannot delete it.
ip/ip.t: ERROR: line 3: I cannot create the chain 'egress'
ip/ip.t: ERROR: line 28: add rule netdev test-netdev egress ip dscp cs1: This rule should not have failed.
ip/ip.t: ERROR: line 29: add rule netdev test-netdev egress ip dscp != cs1: This rule should not have failed.
ip/ip.t: ERROR: line 30: add rule netdev test-netdev egress ip dscp 0x38: This rule should not have failed.
ip/ip.t: ERROR: line 31: add rule netdev test-netdev egress ip dscp != 0x20: This rule should not have failed.
ip/ip.t: ERROR: line 32: add rule netdev test-netdev egress ip dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef}: This rule should not have failed.
ip/ip.t: ERROR: line 34: add rule netdev test-netdev egress ip dscp != {cs0, cs3}: This rule should not have failed.
ip/ip.t: ERROR: line 35: add rule netdev test-netdev egress ip dscp vmap { cs1 : continue , cs4 : accept } counter: This rule should not have failed.
ip/ip.t: ERROR: line 37: add rule netdev test-netdev egress ip length 232: This rule should not have failed.
ip/ip.t: ERROR: line 38: add rule netdev test-netdev egress ip length != 233: This rule should not have failed.
ip/ip.t: ERROR: line 39: add rule netdev test-netdev egress ip length 333-435: This rule should not have failed.
ip/ip.t: ERROR: line 40: add rule netdev test-netdev egress ip length != 333-453: This rule should not have failed.
ip/ip.t: ERROR: line 41: add rule netdev test-netdev egress ip length { 333, 553, 673, 838}: This rule should not have failed.
ip/ip.t: ERROR: line 42: add rule netdev test-netdev egress ip length != { 333, 553, 673, 838}: This rule should not have failed.
ip/ip.t: ERROR: line 44: add rule netdev test-netdev egress ip id 22: This rule should not have failed.
ip/ip.t: ERROR: line 45: add rule netdev test-netdev egress ip id != 233: This rule should not have failed.
ip/ip.t: ERROR: line 46: add rule netdev test-netdev egress ip id 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 47: add rule netdev test-netdev egress ip id != 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 48: add rule netdev test-netdev egress ip id { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 49: add rule netdev test-netdev egress ip id != { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 51: add rule netdev test-netdev egress ip frag-off 222 accept: This rule should not have failed.
ip/ip.t: ERROR: line 52: add rule netdev test-netdev egress ip frag-off != 233: This rule should not have failed.
ip/ip.t: ERROR: line 53: add rule netdev test-netdev egress ip frag-off 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 54: add rule netdev test-netdev egress ip frag-off != 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 55: add rule netdev test-netdev egress ip frag-off { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 56: add rule netdev test-netdev egress ip frag-off != { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 58: add rule netdev test-netdev egress ip ttl 0 drop: This rule should not have failed.
ip/ip.t: ERROR: line 59: add rule netdev test-netdev egress ip ttl 233: This rule should not have failed.
ip/ip.t: ERROR: line 60: add rule netdev test-netdev egress ip ttl 33-55: This rule should not have failed.
ip/ip.t: ERROR: line 61: add rule netdev test-netdev egress ip ttl != 45-50: This rule should not have failed.
ip/ip.t: ERROR: line 62: add rule netdev test-netdev egress ip ttl {43, 53, 45 }: This rule should not have failed.
ip/ip.t: ERROR: line 63: add rule netdev test-netdev egress ip ttl != {43, 53, 45 }: This rule should not have failed.
ip/ip.t: ERROR: line 65: add rule netdev test-netdev egress ip protocol tcp: This rule should not have failed.
ip/ip.t: ERROR: line 66: add rule netdev test-netdev egress ip protocol != tcp: This rule should not have failed.
ip/ip.t: ERROR: line 67: add rule netdev test-netdev egress ip protocol { icmp, esp, ah, comp, udp, udplite, tcp, dccp, sctp} accept: This rule should not have failed.
ip/ip.t: ERROR: line 68: add rule netdev test-netdev egress ip protocol != { icmp, esp, ah, comp, udp, udplite, tcp, dccp, sctp} accept: This rule should not have failed.
ip/ip.t: ERROR: line 70: add rule netdev test-netdev egress ip protocol 255: This rule should not have failed.
ip/ip.t: ERROR: line 73: add rule netdev test-netdev egress ip checksum 13172 drop: This rule should not have failed.
ip/ip.t: ERROR: line 74: add rule netdev test-netdev egress ip checksum 22: This rule should not have failed.
ip/ip.t: ERROR: line 75: add rule netdev test-netdev egress ip checksum != 233: This rule should not have failed.
ip/ip.t: ERROR: line 76: add rule netdev test-netdev egress ip checksum 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 77: add rule netdev test-netdev egress ip checksum != 33-45: This rule should not have failed.
ip/ip.t: ERROR: line 78: add rule netdev test-netdev egress ip checksum { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 79: add rule netdev test-netdev egress ip checksum != { 33, 55, 67, 88}: This rule should not have failed.
ip/ip.t: ERROR: line 83: add rule netdev test-netdev egress ip saddr 192.168.2.0/24: This rule should not have failed.
ip/ip.t: ERROR: line 84: add rule netdev test-netdev egress ip saddr != 192.168.2.0/24: This rule should not have failed.
ip/ip.t: ERROR: line 85: add rule netdev test-netdev egress ip saddr 192.168.3.1 ip daddr 192.168.3.100: This rule should not have failed.
ip/ip.t: ERROR: line 86: add rule netdev test-netdev egress ip saddr != 1.1.1.1: This rule should not have failed.
ip/ip.t: ERROR: line 87: add rule netdev test-netdev egress ip saddr 1.1.1.1: This rule should not have failed.
ip/ip.t: ERROR: line 88: add rule netdev test-netdev egress ip daddr 192.168.0.1-192.168.0.250: This rule should not have failed.
ip/ip.t: ERROR: line 89: add rule netdev test-netdev egress ip daddr 10.0.0.0-10.255.255.255: This rule should not have failed.
ip/ip.t: ERROR: line 90: add rule netdev test-netdev egress ip daddr 172.16.0.0-172.31.255.255: This rule should not have failed.
ip/ip.t: ERROR: line 91: add rule netdev test-netdev egress ip daddr 192.168.3.1-192.168.4.250: This rule should not have failed.
ip/ip.t: ERROR: line 92: add rule netdev test-netdev egress ip daddr != 192.168.0.1-192.168.0.250: This rule should not have failed.
ip/ip.t: ERROR: line 93: add rule netdev test-netdev egress ip daddr { 192.168.5.1, 192.168.5.2, 192.168.5.3 } accept: This rule should not have failed.
ip/ip.t: ERROR: line 94: add rule netdev test-netdev egress ip daddr != { 192.168.5.1, 192.168.5.2, 192.168.5.3 } accept: This rule should not have failed.
ip/ip.t: ERROR: line 96: add rule netdev test-netdev egress ip daddr 192.168.1.2-192.168.1.55: This rule should not have failed.
ip/ip.t: ERROR: line 97: add rule netdev test-netdev egress ip daddr != 192.168.1.2-192.168.1.55: This rule should not have failed.
ip/ip.t: ERROR: line 98: add rule netdev test-netdev egress ip saddr 192.168.1.3-192.168.33.55: This rule should not have failed.
ip/ip.t: ERROR: line 99: add rule netdev test-netdev egress ip saddr != 192.168.1.3-192.168.33.55: This rule should not have failed.
ip/ip.t: ERROR: line 101: add rule netdev test-netdev egress ip daddr 192.168.0.1: This rule should not have failed.
ip/ip.t: ERROR: line 102: add rule netdev test-netdev egress ip daddr 192.168.0.1 drop: This rule should not have failed.
ip/ip.t: ERROR: line 103: add rule netdev test-netdev egress ip daddr 192.168.0.2: This rule should not have failed.
ip/ip.t: ERROR: line 105: add rule netdev test-netdev egress ip saddr & 0xff == 1: This rule should not have failed.
ip/ip.t: ERROR: line 106: add rule netdev test-netdev egress ip saddr & 0.0.0.255 < 0.0.0.127: This rule should not have failed.
ip/ip.t: ERROR: line 108: add rule netdev test-netdev egress ip saddr & 0xffff0000 == 0xffff0000: This rule should not have failed.
ip/ip.t: ERROR: line 110: add rule netdev test-netdev egress ip version 4 ip hdrlength 5: This rule should not have failed.
ip/ip.t: ERROR: line 111: add rule netdev test-netdev egress ip hdrlength 0: This rule should not have failed.
ip/ip.t: ERROR: line 112: add rule netdev test-netdev egress ip hdrlength 15: This rule should not have failed.
ip/ip.t: ERROR: line 113: add rule netdev test-netdev egress ip hdrlength vmap { 0-4 : drop, 5 : accept, 6 : continue } counter: This rule should not have failed.
ip/ip.t: ERROR: line 117: add rule netdev test-netdev egress iif "lo" ip daddr set 127.0.0.1: This rule should not have failed.
ip/ip.t: ERROR: line 118: add rule netdev test-netdev egress iif "lo" ip checksum set 0: This rule should not have failed.
ip/ip.t: ERROR: line 119: add rule netdev test-netdev egress iif "lo" ip id set 0: This rule should not have failed.
ip/ip.t: ERROR: line 120: add rule netdev test-netdev egress iif "lo" ip ecn set 1: This rule should not have failed.
ip/ip.t: ERROR: line 121: add rule netdev test-netdev egress iif "lo" ip ecn set ce: This rule should not have failed.
ip/ip.t: ERROR: line 122: add rule netdev test-netdev egress iif "lo" ip ttl set 23: This rule should not have failed.
ip/ip.t: ERROR: line 123: add rule netdev test-netdev egress iif "lo" ip protocol set 1: This rule should not have failed.
ip/ip.t: ERROR: line 125: add rule netdev test-netdev egress iif "lo" ip dscp set af23: This rule should not have failed.
ip/ip.t: ERROR: line 126: add rule netdev test-netdev egress iif "lo" ip dscp set cs0: This rule should not have failed.
ip/ip.t: ERROR: line 128: add rule netdev test-netdev egress ip saddr . ip daddr { 192.0.2.1 . 10.0.0.1-10.0.0.2 }: This rule should not have failed.
ip/ip.t: ERROR: line 129: add rule netdev test-netdev egress ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept }: This rule should not have failed.
ip/ip.t: ERROR: line 129: The chain egress does not exist in netdev test-netdev. I cannot delete it.
ip6/sets.t: ERROR: line 3: I cannot create the chain 'egress'
ip6/sets.t: ERROR: line 25: add rule netdev test-netdev egress ip6 saddr @set2 drop: This rule should not have failed.
ip6/sets.t: ERROR: line 26: add rule netdev test-netdev egress ip6 saddr != @set2 drop: This rule should not have failed.
ip6/sets.t: ERROR: line 42: add rule netdev test-netdev egress ip6 saddr . ip6 daddr @set5 drop: This rule should not have failed.
ip6/sets.t: ERROR: line 43: add rule netdev test-netdev egress add @set5 { ip6 saddr . ip6 daddr }: This rule should not have failed.
ip6/sets.t: ERROR: line 44: add rule netdev test-netdev egress delete @set5 { ip6 saddr . ip6 daddr }: This rule should not have failed.
ip6/sets.t: ERROR: line 44: The chain egress does not exist in netdev test-netdev. I cannot delete it.
ip6/frag.t: ERROR: line 3: I cannot create the chain 'egress'
ip6/frag.t: ERROR: line 9: add rule netdev test-netdev egress frag nexthdr tcp: This rule should not have failed.
ip6/frag.t: ERROR: line 10: add rule netdev test-netdev egress frag nexthdr != icmp: This rule should not have failed.
ip6/frag.t: ERROR: line 11: add rule netdev test-netdev egress frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp}: This rule should not have failed.
ip6/frag.t: ERROR: line 12: add rule netdev test-netdev egress frag nexthdr != {esp, ah, comp, udp, udplite, tcp, dccp, sctp}: This rule should not have failed.
ip6/frag.t: ERROR: line 13: add rule netdev test-netdev egress frag nexthdr esp: This rule should not have failed.
ip6/frag.t: ERROR: line 14: add rule netdev test-netdev egress frag nexthdr ah: This rule should not have failed.
ip6/frag.t: ERROR: line 16: add rule netdev test-netdev egress frag reserved 22: This rule should not have failed.
ip6/frag.t: ERROR: line 17: add rule netdev test-netdev egress frag reserved != 233: This rule should not have failed.
ip6/frag.t: ERROR: line 18: add rule netdev test-netdev egress frag reserved 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 19: add rule netdev test-netdev egress frag reserved != 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 20: add rule netdev test-netdev egress frag reserved { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 21: add rule netdev test-netdev egress frag reserved != { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 23: add rule netdev test-netdev egress frag frag-off 22: This rule should not have failed.
ip6/frag.t: ERROR: line 24: add rule netdev test-netdev egress frag frag-off != 233: This rule should not have failed.
ip6/frag.t: ERROR: line 25: add rule netdev test-netdev egress frag frag-off 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 26: add rule netdev test-netdev egress frag frag-off != 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 27: add rule netdev test-netdev egress frag frag-off { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 28: add rule netdev test-netdev egress frag frag-off != { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 30: add rule netdev test-netdev egress frag reserved2 1: This rule should not have failed.
ip6/frag.t: ERROR: line 31: add rule netdev test-netdev egress frag more-fragments 0: This rule should not have failed.
ip6/frag.t: ERROR: line 32: add rule netdev test-netdev egress frag more-fragments 1: This rule should not have failed.
ip6/frag.t: ERROR: line 34: add rule netdev test-netdev egress frag id 1: This rule should not have failed.
ip6/frag.t: ERROR: line 35: add rule netdev test-netdev egress frag id 22: This rule should not have failed.
ip6/frag.t: ERROR: line 36: add rule netdev test-netdev egress frag id != 33: This rule should not have failed.
ip6/frag.t: ERROR: line 37: add rule netdev test-netdev egress frag id 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 38: add rule netdev test-netdev egress frag id != 33-45: This rule should not have failed.
ip6/frag.t: ERROR: line 39: add rule netdev test-netdev egress frag id { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 40: add rule netdev test-netdev egress frag id != { 33, 55, 67, 88}: This rule should not have failed.
ip6/frag.t: ERROR: line 40: The chain egress does not exist in netdev test-netdev. I cannot delete it.
ip6/vmap.t: ERROR: line 3: I cannot create the chain 'egress'
ip6/vmap.t: ERROR: line 9: add rule netdev test-netdev egress ip6 saddr vmap { abcd::3 : accept }: This rule should not have failed.
ip6/vmap.t: ERROR: line 14: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 15: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234:1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 16: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234:1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 17: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234::1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 18: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234::1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 19: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234::1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 20: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 21: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234:1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 22: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234:1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 23: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 24: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 25: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234::1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 26: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234::1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 27: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 28: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 29: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 30: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 31: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 32: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234::1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 33: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 34: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 35: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 36: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 37: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 38: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 39: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 40: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 41: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 42: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 43: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 44: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 45: add rule netdev test-netdev egress ip6 saddr vmap { ::1234:1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 46: add rule netdev test-netdev egress ip6 saddr vmap { 1234::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 47: add rule netdev test-netdev egress ip6 saddr vmap { 1234:1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 48: add rule netdev test-netdev egress ip6 saddr vmap { ::1234 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 49: add rule netdev test-netdev egress ip6 saddr vmap { 1234:: : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 50: add rule netdev test-netdev egress ip6 saddr vmap { ::/64 : accept}: This rule should not have failed.
ip6/vmap.t: ERROR: line 52: add rule netdev test-netdev egress ip6 saddr vmap {1234:1234:1234:1234:1234:1234:aaaa:: : accept, ::aaaa : drop}: This rule should not have failed.
ip6/vmap.t: ERROR: line 53: add rule netdev test-netdev egress ip6 saddr vmap {1234:1234:1234:1234:1234:1234:aaaa:::accept, ::bbbb : drop}: This rule should not have failed.
ip6/vmap.t: ERROR: line 54: add rule netdev test-netdev egress ip6 saddr vmap {1234:1234:1234:1234:1234:1234:aaaa:::accept,::cccc : drop}: This rule should not have failed.
ip6/vmap.t: ERROR: line 55: add rule netdev test-netdev egress ip6 saddr vmap {1234:1234:1234:1234:1234:1234:aaaa:::accept,::dddd: drop}: This rule should not have failed.
ip6/vmap.t: ERROR: line 58: The chain egress does not exist in netdev test-netdev. I cannot delete it.
netdev/fwd.t: ERROR: line 2: I cannot create the chain 'egress'
netdev/fwd.t: ERROR: line 6: add rule netdev test-netdev egress fwd to "lo": This rule should not have failed.
netdev/fwd.t: ERROR: line 7: add rule netdev test-netdev egress fwd to meta mark map { 0x00000001 : "lo", 0x00000002 : "lo"}: This rule should not have failed.
netdev/fwd.t: ERROR: line 9: add rule netdev test-netdev egress fwd ip to 192.168.2.200 device "lo": This rule should not have failed.
netdev/fwd.t: ERROR: line 9: The chain egress does not exist in netdev test-netdev. I cannot delete it.
netdev/dup.t: ERROR: line 2: I cannot create the chain 'egress'
netdev/dup.t: ERROR: line 6: add rule netdev test-netdev egress dup to "lo": This rule should not have failed.
netdev/dup.t: ERROR: line 7: add rule netdev test-netdev egress dup to meta mark map { 0x00000001 : "lo", 0x00000002 : "lo"}: This rule should not have failed.
netdev/dup.t: ERROR: line 8: The chain egress does not exist in netdev test-netdev. I cannot delete it.
any/meta.t: ERROR: line 240: add rule ip test-ip4 input meta mark set meta mark | iif | meta cpu: This rule should not have failed.
any/ct.t: ERROR: line 66: add rule ip test-ip4 output ct mark set ct mark and 0xffff0000 or meta mark and 0xffff: This rule should not have failed.
inet/meta.t: ERROR: line 35: add rule inet test-inet input meta mark set ct mark and 0xffff0000 or meta mark and 0xffff: This rule should not have failed.
ip/ct.t: ERROR: line 38: add rule ip test-ip4 output ct mark set ct mark | ip dscp | 0x200 counter: This rule should not have failed.
ip6/ct.t: ERROR: line 10: add rule ip6 test-ip6 output ct mark set ct mark | ip6 dscp | 0x200 counter: This rule should not have failed.

View File

@ -1,6 +1,6 @@
Name: nftables
Version: 1.1.1
Release: 9%{?dist}
Version: 1.1.5
Release: 3%{?dist}
# Upstream released a 0.100 version, then 0.4. Need Epoch to get back on track.
Epoch: 1
Summary: Netfilter Tables userspace utilities
@ -15,28 +15,34 @@ Source4: router.nft
Source5: nat.nft
Source6: nft-test.stderr.expect
Source7: run-tests.stderr.expect
Source8: monitor_run-tests.stderr.expect
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
Patch14: 0014-evaluate-allow-to-re-use-existing-metered-set.patch
Patch15: 0015-src-split-monitor-trace-code-into-new-trace.c.patch
Patch16: 0016-src-add-conntrack-information-to-trace-monitor-mode.patch
Patch17: 0017-trace-Fix-for-memleak-in-trace_alloc_list-error-path.patch
Patch18: 0018-doc-nft.8-Minor-NAT-STATEMENTS-section-review.patch
Patch19: 0019-table-Embed-creating-nft-version-into-userdata.patch
Patch20: 0020-Makefile-Fix-for-make-CFLAGS.patch
Patch21: 0021-fib-Fix-for-existence-check-on-Big-Endian.patch
Patch1: 0001-table-Embed-creating-nft-version-into-userdata.patch
Patch2: 0002-Makefile-Fix-for-make-CFLAGS.patch
Patch3: 0003-fib-Fix-for-existence-check-on-Big-Endian.patch
Patch4: 0004-parser_bison-remove-leftover-utf-8-character-in-erro.patch
Patch5: 0005-tools-gitignore-nftables.service-file.patch
Patch6: 0006-monitor-Quote-device-names-in-chain-declarations-too.patch
Patch7: 0007-tests-monitor-Fix-regex-collecting-expected-echo-out.patch
Patch8: 0008-tests-shell-skip-two-bitwise-tests-if-multi-register.patch
Patch9: 0009-monitor-Inform-JSON-printer-when-reporting-an-object.patch
Patch10: 0010-libnftables-do-not-re-add-default-include-directory-.patch
Patch11: 0011-doc-fix-tcpdump-example.patch
Patch12: 0012-src-parser_json-fix-format-string-bugs.patch
Patch13: 0013-datatype-Fix-boolean-type-on-Big-Endian.patch
Patch14: 0014-optimize-Fix-verdict-expression-comparison.patch
Patch15: 0015-tests-py-any-tcpopt.t.json-Fix-JSON-equivalent.patch
Patch16: 0016-tests-py-any-ct.t.json.output-Drop-leftover-entry.patch
Patch17: 0017-tests-py-inet-osf.t-Fix-element-ordering-in-JSON-equ.patch
Patch18: 0018-tests-shell-fix-typo-in-vmap_timeout-test-script.patch
Patch19: 0019-build-don-t-install-ancillary-files-without-systemd-.patch
Patch20: 0020-doc-don-t-suggest-to-disable-GSO.patch
Patch21: 0021-doc-libnftables-json-Describe-RULESET-object.patch
Patch22: 0022-mnl-Support-simple-wildcards-in-netdev-hooks.patch
Patch23: 0023-parser_bison-Accept-ASTERISK_STRING-in-flowtable_exp.patch
Patch24: 0024-tests-shell-Test-ifname-based-hooks.patch
Patch25: 0025-mnl-Drop-asterisk-from-end-of-NFTA_DEVICE_PREFIX-str.patch
Patch26: 0026-tests-monitor-Fix-for-out-of-path-call.patch
BuildRequires: autoconf
BuildRequires: automake
@ -47,7 +53,7 @@ BuildRequires: flex
BuildRequires: bison
BuildRequires: pkgconfig(libmnl) >= 1.0.4
BuildRequires: gmp-devel
BuildRequires: libnftnl-devel >= 1.2.8-4
BuildRequires: libnftnl-devel >= 1.3.0-1
BuildRequires: systemd
BuildRequires: asciidoc
BuildRequires: pkgconfig(xtables) >= 1.6.1
@ -55,6 +61,8 @@ BuildRequires: jansson-devel
BuildRequires: python3-devel
BuildRequires: readline-devel
Requires: libnftnl >= 1.3.0-2
%generate_buildrequires
cd py/
%pyproject_buildrequires
@ -82,6 +90,7 @@ The nftables python module provides an interface to libnftables via ctypes.
%autosetup -p1
cp -a %{SOURCE6} ./tests/py/
cp -a %{SOURCE7} ./tests/shell/
cp -a %{SOURCE8} ./tests/monitor/run-tests.stderr.expect
%build
autoreconf -fi
@ -151,6 +160,38 @@ cd py/
%files -n python3-nftables -f %{pyproject_files}
%changelog
* Tue Dec 16 2025 Phil Sutter <psutter@redhat.com> [1.1.5-3.el10]
- Update expected test suite results (Phil Sutter) [RHEL-121194]
- tests: monitor: Fix for out-of-path call (Phil Sutter) [RHEL-121194]
* Thu Nov 27 2025 Phil Sutter <psutter@redhat.com> [1.1.5-2.el10]
- spec: Require libnftnl >= 1.3.0-2 for NFTA_DEVICE_PREFIX handling (Phil Sutter) [RHEL-108861]
- mnl: Drop asterisk from end of NFTA_DEVICE_PREFIX strings (Phil Sutter) [RHEL-108861]
- tests: shell: Test ifname-based hooks (Phil Sutter) [RHEL-108861]
- parser_bison: Accept ASTERISK_STRING in flowtable_expr_member (Phil Sutter) [RHEL-108861]
- mnl: Support simple wildcards in netdev hooks (Phil Sutter) [RHEL-108861]
* Thu Nov 20 2025 Phil Sutter <psutter@redhat.com> [1.1.5-1.el10]
- doc: libnftables-json: Describe RULESET object (Phil Sutter) [RHEL-121194]
- doc: don't suggest to disable GSO (Phil Sutter) [RHEL-121194]
- build: don't install ancillary files without systemd service file (Phil Sutter) [RHEL-121194]
- tests: shell: fix typo in vmap_timeout test script (Phil Sutter) [RHEL-121194]
- tests: py: inet/osf.t: Fix element ordering in JSON equivalents (Phil Sutter) [RHEL-121194]
- tests: py: any/ct.t.json.output: Drop leftover entry (Phil Sutter) [RHEL-121194]
- tests: py: any/tcpopt.t.json: Fix JSON equivalent (Phil Sutter) [RHEL-121194]
- optimize: Fix verdict expression comparison (Phil Sutter) [RHEL-121194]
- datatype: Fix boolean type on Big Endian (Phil Sutter) [RHEL-121194]
- src: parser_json: fix format string bugs (Phil Sutter) [RHEL-121194]
- doc: fix tcpdump example (Phil Sutter) [RHEL-121194]
- libnftables: do not re-add default include directory in include search path (Phil Sutter) [RHEL-121194]
- monitor: Inform JSON printer when reporting an object delete event (Phil Sutter) [RHEL-121194]
- tests: shell: skip two bitwise tests if multi-register support isn't available (Phil Sutter) [RHEL-121194]
- tests: monitor: Fix regex collecting expected echo output (Phil Sutter) [RHEL-121194]
- monitor: Quote device names in chain declarations, too (Phil Sutter) [RHEL-121194]
- tools: gitignore nftables.service file (Phil Sutter) [RHEL-121194]
- parser_bison: remove leftover utf-8 character in error (Phil Sutter) [RHEL-121194]
- Rebase onto version 1.1.5 (Phil Sutter) [RHEL-121194]
* Tue Nov 04 2025 Phil Sutter <psutter@redhat.com> [1.1.1-9.el10]
- fib: Fix for existence check on Big Endian (Phil Sutter) [RHEL-113851]

View File

@ -1,6 +0,0 @@
W: [FAILED] ././tests/shell/testcases/cache/0010_implicit_chain_0
W: [FAILED] ././tests/shell/testcases/chains/0021prio_0
W: [FAILED] ././tests/shell/testcases/chains/0041chain_binding_0
W: [FAILED] ././tests/shell/testcases/maps/typeof_integer_0
W: [FAILED] ././tests/shell/testcases/maps/typeof_raw_0
W: [FAILED] ././tests/shell/testcases/sets/typeof_raw_0

View File

@ -1 +1 @@
SHA512 (nftables-1.1.1.tar.xz) = 676413d4adadffb15d52c1f8f6432636cab83a7bcda1a18d9f0e6b58819a2c027a49922588c02bd9ad386de930eaa697bfe74c0938b595bf1ee485bfa7cf2e50
SHA512 (nftables-1.1.5.tar.xz) = 01fbbea43fd01250b0176a200dfdb6b84d3d51156cc2350acb25a5e66960e1908c3d17a0363baddb32897ea8bea0569b67500a94f708c8587b0e29402f51cbb6