import UBI nftables-1.1.5-5.el10_2

This commit is contained in:
AlmaLinux RelEng Bot 2026-06-23 20:43:57 -04:00
parent 36b5c1e31d
commit b006d85ccf
14 changed files with 25334 additions and 3 deletions

View File

@ -0,0 +1,69 @@
From 212f623b375694c58357719c95929457c93ab218 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:22 +0100
Subject: [PATCH] segtree: Fix range aggregation on Big Endian
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit e8b17865833b8c2b9f31a4dfb98069651572494d
commit e8b17865833b8c2b9f31a4dfb98069651572494d
Author: Phil Sutter <phil@nwl.cc>
Date: Tue Oct 21 18:36:10 2025 +0200
segtree: Fix range aggregation on Big Endian
Interface name wildcards are received as ranges from prefix with zero
padding to prefix with ones padding. E.g. with "abcd*" (in hex):
61626364000000000000000000000000 - 61626364ffffffffffffffffffffffff
The faulty code tries to export the prefix from the lower boundary (r1)
into a buffer, append "*" and allocate a constant expression from the
resulting string. This does not work on Big Endian though:
mpz_export_data() seems to zero-pad data upon export and not necessarily
respect the passed length value. Moreover, this padding appears in the
first bytes of the buffer. The amount of padding seems illogical, too:
While a 6B prefix causes 2B padding and 8B prefix no padding, 10B prefix
causes 4B padding and 12B prefix even 8B padding.
Work around the odd behaviour by exporting the full data into a larger
buffer.
A similar issue is caused by increasing the constant expression's length
to match the upper boundary data length: Data export when printing puts
the padding upfront, so the resulting string starts with NUL-chars.
Since this length adjustment seems not to have any effect in practice,
just drop it.
Fixes: 88b2345a215ef ("segtree: add pretty-print support for wildcard strings in concatenated sets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/segtree.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/segtree.c b/src/segtree.c
index fd77e03..bf9d7b1 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -409,16 +409,16 @@ void concat_range_aggregate(struct expr *set)
if (prefix_len >= 0 &&
(prefix_len % BITS_PER_BYTE) == 0 &&
string_type) {
+ unsigned int r1len = div_round_up(r1->len, BITS_PER_BYTE);
unsigned int str_len = prefix_len / BITS_PER_BYTE;
- char data[str_len + 2];
+ char data[r1len + 1] = {};
- mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, str_len);
+ mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, r1len);
data[str_len] = '*';
tmp = constant_expr_alloc(&r1->location, r1->dtype,
BYTEORDER_HOST_ENDIAN,
(str_len + 1) * BITS_PER_BYTE, data);
- tmp->len = r2->len;
list_replace(&r2->list, &tmp->list);
r2_next = tmp->list.next;
expr_free(r2);

View File

@ -0,0 +1,345 @@
From f120f2c4a4a4c95c66ba1a90647b146cdf2aca57 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:22 +0100
Subject: [PATCH] mergesort: Fix sorting of string values
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 340d904a974ed206fcc4d8ca32540762fd8e59e0
commit 340d904a974ed206fcc4d8ca32540762fd8e59e0
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 13 00:03:37 2025 +0100
mergesort: Fix sorting of string values
Sorting order was obviously wrong, e.g. "ppp0" ordered before "eth1".
Moreover, this happened on Little Endian only so sorting order actually
depended on host's byteorder. By reimporting string values as Big
Endian, both issues are fixed: On one hand, GMP-internal byteorder no
longer depends on host's byteorder, on the other comparing strings
really starts with the first character, not the last.
Fixes: 14ee0a979b622 ("src: sort set elements in netlink_get_setelems()")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/mergesort.c | 7 +++
tests/py/any/meta.t.json.output | 54 -------------------
tests/py/any/queue.t.json.output | 4 +-
tests/py/inet/osf.t.json.output | 54 +++++++++++++++++++
.../testcases/maps/dumps/0012map_0.json-nft | 20 +++----
.../shell/testcases/maps/dumps/0012map_0.nft | 8 +--
.../maps/dumps/named_ct_objects.json-nft | 4 +-
.../testcases/maps/dumps/named_ct_objects.nft | 4 +-
.../sets/dumps/sets_with_ifnames.json-nft | 4 +-
.../sets/dumps/sets_with_ifnames.nft | 2 +-
10 files changed, 84 insertions(+), 77 deletions(-)
diff --git a/src/mergesort.c b/src/mergesort.c
index bd1c218..4e15a8b 100644
--- a/src/mergesort.c
+++ b/src/mergesort.c
@@ -37,6 +37,13 @@ static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
case EXPR_RANGE:
return expr_msort_value(expr->left, value);
case EXPR_VALUE:
+ if (expr_basetype(expr)->type == TYPE_STRING) {
+ char buf[expr->len];
+
+ mpz_export_data(buf, expr->value, BYTEORDER_HOST_ENDIAN, expr->len);
+ mpz_import_data(value, buf, BYTEORDER_BIG_ENDIAN, expr->len);
+ return value;
+ }
return expr->value;
case EXPR_RANGE_VALUE:
return expr->range.low;
diff --git a/tests/py/any/meta.t.json.output b/tests/py/any/meta.t.json.output
index 8f4d597..4454bb9 100644
--- a/tests/py/any/meta.t.json.output
+++ b/tests/py/any/meta.t.json.output
@@ -233,60 +233,6 @@
}
]
-# meta iifname {"dummy0", "lo"}
-[
- {
- "match": {
- "left": {
- "meta": { "key": "iifname" }
- },
- "op": "==",
- "right": {
- "set": [
- "lo",
- "dummy0"
- ]
- }
- }
- }
-]
-
-# meta iifname != {"dummy0", "lo"}
-[
- {
- "match": {
- "left": {
- "meta": { "key": "iifname" }
- },
- "op": "!=",
- "right": {
- "set": [
- "lo",
- "dummy0"
- ]
- }
- }
- }
-]
-
-# meta oifname { "dummy0", "lo"}
-[
- {
- "match": {
- "left": {
- "meta": { "key": "oifname" }
- },
- "op": "==",
- "right": {
- "set": [
- "lo",
- "dummy0"
- ]
- }
- }
- }
-]
-
# meta skuid {"bin", "root", "daemon"} accept
[
{
diff --git a/tests/py/any/queue.t.json.output b/tests/py/any/queue.t.json.output
index ea37223..90670cc 100644
--- a/tests/py/any/queue.t.json.output
+++ b/tests/py/any/queue.t.json.output
@@ -104,11 +104,11 @@
0
],
[
- "ppp0",
+ "eth1",
2
],
[
- "eth1",
+ "ppp0",
2
]
]
diff --git a/tests/py/inet/osf.t.json.output b/tests/py/inet/osf.t.json.output
index 922e395..77ca7e3 100644
--- a/tests/py/inet/osf.t.json.output
+++ b/tests/py/inet/osf.t.json.output
@@ -18,6 +18,26 @@
}
]
+# osf version { "Windows:XP", "MacOs:Sierra" }
+[
+ {
+ "match": {
+ "left": {
+ "osf": {
+ "key": "version"
+ }
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ "MacOs:Sierra",
+ "Windows:XP"
+ ]
+ }
+ }
+ }
+]
+
# ct mark set osf name map { "Windows" : 0x00000001, "MacOs" : 0x00000002 }
[
{
@@ -51,3 +71,37 @@
}
}
]
+
+# ct mark set osf version map { "Windows:XP" : 0x00000003, "MacOs:Sierra" : 0x00000004 }
+[
+ {
+ "mangle": {
+ "key": {
+ "ct": {
+ "key": "mark"
+ }
+ },
+ "value": {
+ "map": {
+ "data": {
+ "set": [
+ [
+ "MacOs:Sierra",
+ 4
+ ],
+ [
+ "Windows:XP",
+ 3
+ ]
+ ]
+ },
+ "key": {
+ "osf": {
+ "key": "version"
+ }
+ }
+ }
+ }
+ }
+ }
+]
diff --git a/tests/shell/testcases/maps/dumps/0012map_0.json-nft b/tests/shell/testcases/maps/dumps/0012map_0.json-nft
index 2892e11..6c88570 100644
--- a/tests/shell/testcases/maps/dumps/0012map_0.json-nft
+++ b/tests/shell/testcases/maps/dumps/0012map_0.json-nft
@@ -32,21 +32,21 @@
"map": "verdict",
"elem": [
[
- "lo",
+ "eth0",
{
- "accept": null
+ "drop": null
}
],
[
- "eth0",
+ "eth1",
{
"drop": null
}
],
[
- "eth1",
+ "lo",
{
- "drop": null
+ "accept": null
}
]
]
@@ -69,21 +69,21 @@
"data": {
"set": [
[
- "lo",
+ "eth0",
{
- "accept": null
+ "drop": null
}
],
[
- "eth0",
+ "eth1",
{
"drop": null
}
],
[
- "eth1",
+ "lo",
{
- "drop": null
+ "accept": null
}
]
]
diff --git a/tests/shell/testcases/maps/dumps/0012map_0.nft b/tests/shell/testcases/maps/dumps/0012map_0.nft
index e734fc1..0df329a 100644
--- a/tests/shell/testcases/maps/dumps/0012map_0.nft
+++ b/tests/shell/testcases/maps/dumps/0012map_0.nft
@@ -1,12 +1,12 @@
table ip x {
map z {
type ifname : verdict
- elements = { "lo" : accept,
- "eth0" : drop,
- "eth1" : drop }
+ elements = { "eth0" : drop,
+ "eth1" : drop,
+ "lo" : accept }
}
chain y {
- iifname vmap { "lo" : accept, "eth0" : drop, "eth1" : drop }
+ iifname vmap { "eth0" : drop, "eth1" : drop, "lo" : accept }
}
}
diff --git a/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft b/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
index c0f270e..34c8798 100644
--- a/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
+++ b/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
@@ -195,8 +195,8 @@
},
"handle": 0,
"elem": [
- "sip",
- "ftp"
+ "ftp",
+ "sip"
]
}
},
diff --git a/tests/shell/testcases/maps/dumps/named_ct_objects.nft b/tests/shell/testcases/maps/dumps/named_ct_objects.nft
index 59f1893..dab683b 100644
--- a/tests/shell/testcases/maps/dumps/named_ct_objects.nft
+++ b/tests/shell/testcases/maps/dumps/named_ct_objects.nft
@@ -50,8 +50,8 @@ table inet t {
set helpname {
typeof ct helper
- elements = { "sip",
- "ftp" }
+ elements = { "ftp",
+ "sip" }
}
chain y {
diff --git a/tests/shell/testcases/sets/dumps/sets_with_ifnames.json-nft b/tests/shell/testcases/sets/dumps/sets_with_ifnames.json-nft
index ac42842..7b4849e 100644
--- a/tests/shell/testcases/sets/dumps/sets_with_ifnames.json-nft
+++ b/tests/shell/testcases/sets/dumps/sets_with_ifnames.json-nft
@@ -260,8 +260,8 @@
},
"right": {
"set": [
- "eth0",
- "abcdef0"
+ "abcdef0",
+ "eth0"
]
}
}
diff --git a/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
index 77a8baf..8abca03 100644
--- a/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
+++ b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
@@ -39,7 +39,7 @@ table inet testifsets {
chain v4icmp {
iifname @simple counter packets 0 bytes 0
iifname @simple_wild counter packets 0 bytes 0
- iifname { "eth0", "abcdef0" } counter packets 0 bytes 0
+ iifname { "abcdef0", "eth0" } counter packets 0 bytes 0
iifname { "abcdef*", "eth0" } counter packets 0 bytes 0
iifname vmap @map_wild
}

View File

@ -0,0 +1,728 @@
From 4a28adfce9f43e547e14d9a8a02042ef0c4ebfab Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] mergesort: Align concatenation sort order with Big Endian
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 0d819bcbbf36d324b5344ac29bd82a5017098c4b
commit 0d819bcbbf36d324b5344ac29bd82a5017098c4b
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 13 00:14:43 2025 +0100
mergesort: Align concatenation sort order with Big Endian
By exporting all concat components in a way independent from host
byteorder and importing that blob of data in the same way aligns sort
order between hosts of different Endianness.
Fixes: 741a06ac15d2b ("mergesort: find base value expression type via recursion")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/mergesort.c | 4 +-
tests/py/any/ct.t.json.output | 20 ++---
tests/py/any/tcpopt.t.json.output | 77 -------------------
.../maps/dumps/named_ct_objects.json-nft | 8 +-
.../testcases/maps/dumps/named_ct_objects.nft | 2 +-
.../maps/dumps/typeof_integer_0.json-nft | 12 +--
.../testcases/maps/dumps/typeof_integer_0.nft | 4 +-
.../dumps/0012different_defines_0.json-nft | 8 +-
.../nft-f/dumps/0012different_defines_0.nft | 2 +-
.../dumps/merge_nat_inet.json-nft | 12 +--
.../optimizations/dumps/merge_nat_inet.nft | 2 +-
.../optimizations/dumps/merge_reject.json-nft | 16 ++--
.../optimizations/dumps/merge_reject.nft | 4 +-
.../dumps/merge_stmts_concat.json-nft | 42 +++++-----
.../dumps/merge_stmts_concat.nft | 8 +-
.../dumps/merge_stmts_concat_vmap.json-nft | 4 +-
.../dumps/merge_stmts_concat_vmap.nft | 2 +-
.../sets/dumps/0029named_ifname_dtype_0.nft | 4 +-
.../0037_set_with_inet_service_0.json-nft | 12 +--
.../dumps/0037_set_with_inet_service_0.nft | 8 +-
.../testcases/sets/dumps/typeof_sets_0.nft | 4 +-
tests/shell/testcases/sets/typeof_sets_0 | 4 +-
22 files changed, 91 insertions(+), 168 deletions(-)
diff --git a/src/mergesort.c b/src/mergesort.c
index 4e15a8b..51cde10 100644
--- a/src/mergesort.c
+++ b/src/mergesort.c
@@ -20,11 +20,11 @@ static void concat_expr_msort_value(const struct expr *expr, mpz_t value)
list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
ilen = div_round_up(i->len, BITS_PER_BYTE);
- mpz_export_data(data + len, i->value, i->byteorder, ilen);
+ mpz_export_data(data + len, i->value, BYTEORDER_BIG_ENDIAN, ilen);
len += ilen;
}
- mpz_import_data(value, data, BYTEORDER_HOST_ENDIAN, len);
+ mpz_import_data(value, data, BYTEORDER_BIG_ENDIAN, len);
}
static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
diff --git a/tests/py/any/ct.t.json.output b/tests/py/any/ct.t.json.output
index 82634c2..3f79593 100644
--- a/tests/py/any/ct.t.json.output
+++ b/tests/py/any/ct.t.json.output
@@ -494,14 +494,14 @@
"set": [
{
"concat": [
- "new",
- 305419896
+ "established",
+ 309876276
]
},
{
"concat": [
- "established",
- 309876276
+ "new",
+ 305419896
]
},
{
@@ -578,23 +578,23 @@
[
{
"concat": [
- "new",
- 305419896
+ "established",
+ 2271560481
]
},
{
- "drop": null
+ "accept": null
}
],
[
{
"concat": [
- "established",
- 2271560481
+ "new",
+ 305419896
]
},
{
- "accept": null
+ "drop": null
}
]
]
diff --git a/tests/py/any/tcpopt.t.json.output b/tests/py/any/tcpopt.t.json.output
index ae979e7..4f170cf 100644
--- a/tests/py/any/tcpopt.t.json.output
+++ b/tests/py/any/tcpopt.t.json.output
@@ -29,80 +29,3 @@
}
}
]
-
-# 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
- ]
- }
- ]
- }
- }
- }
-]
diff --git a/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft b/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
index 34c8798..21ab056 100644
--- a/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
+++ b/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
@@ -318,8 +318,8 @@
[
{
"concat": [
- "feed::17",
- 512
+ "dead::beef",
+ 123
]
},
"exp2"
@@ -327,8 +327,8 @@
[
{
"concat": [
- "dead::beef",
- 123
+ "feed::17",
+ 512
]
},
"exp2"
diff --git a/tests/shell/testcases/maps/dumps/named_ct_objects.nft b/tests/shell/testcases/maps/dumps/named_ct_objects.nft
index dab683b..18b52eb 100644
--- a/tests/shell/testcases/maps/dumps/named_ct_objects.nft
+++ b/tests/shell/testcases/maps/dumps/named_ct_objects.nft
@@ -58,7 +58,7 @@ table inet t {
ct expectation set ip saddr map @exp
ct expectation set ip6 saddr map { dead::beef : "exp2" }
ct expectation set ip6 daddr map { dead::beef : "exp2", feed::17 : "exp2" }
- ct expectation set ip6 daddr . tcp dport map { feed::17 . 512 : "exp2", dead::beef . 123 : "exp2" }
+ ct expectation set ip6 daddr . tcp dport map { dead::beef . 123 : "exp2", feed::17 . 512 : "exp2" }
ct helper set ip6 saddr map { 1c3::c01d : "myftp", dead::beef : "myftp" }
ct helper set ip6 saddr map @helpobj
ct timeout set ip daddr map @timeoutmap
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft
index 1df729b..65474c9 100644
--- a/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft
+++ b/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft
@@ -117,23 +117,23 @@
[
{
"concat": [
- 30,
- 30
+ 20,
+ 36
]
},
{
- "drop": null
+ "accept": null
}
],
[
{
"concat": [
- 20,
- 36
+ 30,
+ 30
]
},
{
- "accept": null
+ "drop": null
}
]
]
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
index 19c24fe..7bd7daa 100644
--- a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
+++ b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
@@ -8,8 +8,8 @@ table inet t {
map m2 {
typeof udp length . @ih,32,32 : verdict
- elements = { 30 . 0x1e : drop,
- 20 . 0x24 : accept }
+ elements = { 20 . 0x24 : accept,
+ 30 . 0x1e : drop }
}
chain c {
diff --git a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.json-nft b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.json-nft
index 0e7ea22..e266bf4 100644
--- a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.json-nft
+++ b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.json-nft
@@ -361,14 +361,14 @@
"set": [
{
"concat": [
- "fe0::2",
- "tcp"
+ "fe0::1",
+ "udp"
]
},
{
"concat": [
- "fe0::1",
- "udp"
+ "fe0::2",
+ "tcp"
]
}
]
diff --git a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
index 4734b2f..a6e16e7 100644
--- a/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
+++ b/tests/shell/testcases/nft-f/dumps/0012different_defines_0.nft
@@ -8,7 +8,7 @@ table inet t {
ip6 daddr fe0::1 ip6 saddr fe0::2
ip saddr vmap { 10.0.0.0 : drop, 10.0.0.2 : accept }
ip6 daddr vmap { fe0::1 : drop, fe0::2 : accept }
- ip6 saddr . ip6 nexthdr { fe0::2 . tcp, fe0::1 . udp }
+ ip6 saddr . ip6 nexthdr { fe0::1 . udp, fe0::2 . tcp }
ip daddr . iif vmap { 10.0.0.0 . "lo" : accept }
tcp dport 100-222
udp dport vmap { 100-222 : accept }
diff --git a/tests/shell/testcases/optimizations/dumps/merge_nat_inet.json-nft b/tests/shell/testcases/optimizations/dumps/merge_nat_inet.json-nft
index 99930f1..7df802e 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_nat_inet.json-nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_nat_inet.json-nft
@@ -93,14 +93,14 @@
{
"concat": [
"enp2s0",
- "72.2.3.70",
- 80
+ "72.2.3.66",
+ 443
]
},
{
"concat": [
"10.1.1.52",
- 80
+ 443
]
}
],
@@ -123,14 +123,14 @@
{
"concat": [
"enp2s0",
- "72.2.3.66",
- 443
+ "72.2.3.70",
+ 80
]
},
{
"concat": [
"10.1.1.52",
- 443
+ 80
]
}
]
diff --git a/tests/shell/testcases/optimizations/dumps/merge_nat_inet.nft b/tests/shell/testcases/optimizations/dumps/merge_nat_inet.nft
index a1a1135..1e08d5a 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_nat_inet.nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_nat_inet.nft
@@ -1,7 +1,7 @@
table inet nat {
chain prerouting {
oif "lo" accept
- dnat ip to iifname . ip daddr . tcp dport map { "enp2s0" . 72.2.3.70 . 80 : 10.1.1.52 . 80, "enp2s0" . 72.2.3.66 . 53122 : 10.1.1.10 . 22, "enp2s0" . 72.2.3.66 . 443 : 10.1.1.52 . 443 }
+ dnat ip to iifname . ip daddr . tcp dport map { "enp2s0" . 72.2.3.66 . 443 : 10.1.1.52 . 443, "enp2s0" . 72.2.3.66 . 53122 : 10.1.1.10 . 22, "enp2s0" . 72.2.3.70 . 80 : 10.1.1.52 . 80 }
}
chain postrouting {
diff --git a/tests/shell/testcases/optimizations/dumps/merge_reject.json-nft b/tests/shell/testcases/optimizations/dumps/merge_reject.json-nft
index 46ed067..8f468e0 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_reject.json-nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_reject.json-nft
@@ -101,15 +101,15 @@
{
"concat": [
"tcp",
- "172.30.238.117",
- 8080
+ "172.30.33.71",
+ 3306
]
},
{
"concat": [
"tcp",
- "172.30.33.71",
- 3306
+ "172.30.238.117",
+ 8080
]
},
{
@@ -234,15 +234,15 @@
{
"concat": [
"tcp",
- "aaaa::3",
- 8080
+ "aaaa::2",
+ 3306
]
},
{
"concat": [
"tcp",
- "aaaa::2",
- 3306
+ "aaaa::3",
+ 8080
]
},
{
diff --git a/tests/shell/testcases/optimizations/dumps/merge_reject.nft b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
index c29ad6d..1727d02 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_reject.nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
@@ -1,13 +1,13 @@
table ip x {
chain y {
ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
- meta l4proto . ip daddr . tcp dport { tcp . 172.30.238.117 . 8080, tcp . 172.30.33.71 . 3306, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
+ meta l4proto . ip daddr . tcp dport { tcp . 172.30.33.71 . 3306, tcp . 172.30.238.117 . 8080, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
}
}
table ip6 x {
chain y {
- meta l4proto . ip6 daddr . tcp dport { tcp . aaaa::3 . 8080, tcp . aaaa::2 . 3306, tcp . aaaa::4 . 3306 } counter packets 0 bytes 0 reject
+ meta l4proto . ip6 daddr . tcp dport { tcp . aaaa::2 . 3306, tcp . aaaa::3 . 8080, tcp . aaaa::4 . 3306 } counter packets 0 bytes 0 reject
ip6 daddr aaaa::5 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
}
}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.json-nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.json-nft
index 46e740a..b70ee97 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.json-nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.json-nft
@@ -216,14 +216,14 @@
},
{
"concat": [
- 138,
- "new"
+ 137,
+ "untracked"
]
},
{
"concat": [
- 137,
- "untracked"
+ 138,
+ "new"
]
},
{
@@ -271,8 +271,8 @@
"set": [
{
"concat": [
- 51820,
- "foo"
+ 67,
+ "bar"
]
},
{
@@ -283,8 +283,8 @@
},
{
"concat": [
- 67,
- "bar"
+ 51820,
+ "foo"
]
}
]
@@ -326,13 +326,13 @@
"set": [
{
"concat": [
- 100,
- "foo"
+ 67,
+ "bar"
]
},
{
"concat": [
- 51820,
+ 100,
"foo"
]
},
@@ -344,8 +344,8 @@
},
{
"concat": [
- 67,
- "bar"
+ 51820,
+ "foo"
]
}
]
@@ -387,32 +387,32 @@
"set": [
{
"concat": [
- 100,
- "foo"
+ 67,
+ "bar"
]
},
{
"concat": [
- 51820,
+ 100,
"foo"
]
},
{
"concat": [
- 514,
- "bar"
+ 100,
+ "test"
]
},
{
"concat": [
- 67,
+ 514,
"bar"
]
},
{
"concat": [
- 100,
- "test"
+ 51820,
+ "foo"
]
},
{
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
index d00ac41..6150258 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
@@ -2,18 +2,18 @@ table ip x {
chain y {
iifname . ip saddr . ip daddr { "eth1" . 1.1.1.1 . 2.2.2.3, "eth1" . 1.1.1.2 . 2.2.2.4, "eth1" . 1.1.1.2 . 2.2.3.0/24, "eth1" . 1.1.1.2 . 2.2.4.0-2.2.4.10, "eth2" . 1.1.1.3 . 2.2.2.5 } accept
ip protocol . th dport { tcp . 22, udp . 67 }
- udp dport . ct state { 137 . new, 138 . new, 137 . untracked, 138 . untracked } accept
+ udp dport . ct state { 137 . new, 137 . untracked, 138 . new, 138 . untracked } accept
}
chain c1 {
- udp dport . iifname { 51820 . "foo", 514 . "bar", 67 . "bar" } accept
+ udp dport . iifname { 67 . "bar", 514 . "bar", 51820 . "foo" } accept
}
chain c2 {
- udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar" } accept
+ udp dport . iifname { 67 . "bar", 100 . "foo", 514 . "bar", 51820 . "foo" } accept
}
chain c3 {
- udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar", 100 . "test", 51820 . "test" } accept
+ udp dport . iifname { 67 . "bar", 100 . "foo", 100 . "test", 514 . "bar", 51820 . "foo", 51820 . "test" } accept
}
}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.json-nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.json-nft
index 5dfa40a..5259e56 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.json-nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.json-nft
@@ -60,7 +60,7 @@
{
"concat": [
"broadcast",
- 547
+ 67
]
},
{
@@ -71,7 +71,7 @@
{
"concat": [
"broadcast",
- 67
+ 547
]
},
{
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
index 780aa09..81abb99 100644
--- a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
@@ -1,6 +1,6 @@
table ip x {
chain x {
- meta pkttype . udp dport vmap { broadcast . 547 : accept, broadcast . 67 : accept, multicast . 1900 : drop }
+ meta pkttype . udp dport vmap { broadcast . 67 : accept, broadcast . 547 : accept, multicast . 1900 : drop }
}
chain y {
diff --git a/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
index 6f9832a..e75d8a9 100644
--- a/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
+++ b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
@@ -12,8 +12,8 @@ table inet t {
type inet_service . ifname
elements = { 22 . "eth0",
80 . "eth0",
- 81 . "eth0",
- 80 . "eth1" }
+ 80 . "eth1",
+ 81 . "eth0" }
}
set nv {
diff --git a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.json-nft b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.json-nft
index 1c3b559..cf1c1cc 100644
--- a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.json-nft
+++ b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.json-nft
@@ -40,16 +40,16 @@
"elem": [
{
"concat": [
- "192.168.0.113",
+ "192.168.0.12",
"tcp",
- 22
+ 53
]
},
{
"concat": [
"192.168.0.12",
"tcp",
- 53
+ 80
]
},
{
@@ -61,16 +61,16 @@
},
{
"concat": [
- "192.168.0.12",
+ "192.168.0.13",
"tcp",
80
]
},
{
"concat": [
- "192.168.0.13",
+ "192.168.0.113",
"tcp",
- 80
+ 22
]
}
]
diff --git a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
index 68b1f7b..0e85f7c 100644
--- a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
+++ b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
@@ -1,11 +1,11 @@
table inet filter {
set myset {
type ipv4_addr . inet_proto . inet_service
- elements = { 192.168.0.113 . tcp . 22,
- 192.168.0.12 . tcp . 53,
- 192.168.0.12 . udp . 53,
+ elements = { 192.168.0.12 . tcp . 53,
192.168.0.12 . tcp . 80,
- 192.168.0.13 . tcp . 80 }
+ 192.168.0.12 . udp . 53,
+ 192.168.0.13 . tcp . 80,
+ 192.168.0.113 . tcp . 22 }
}
chain forward {
diff --git a/tests/shell/testcases/sets/dumps/typeof_sets_0.nft b/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
index 34aaab6..1ceddfc 100644
--- a/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
+++ b/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
@@ -67,8 +67,8 @@ table inet t {
set s14 {
typeof tcp option mptcp subtype . ip daddr
- elements = { remove-addr . 10.1.1.1,
- mp-join . 10.1.1.2 }
+ elements = { mp-join . 10.1.1.2,
+ remove-addr . 10.1.1.1 }
}
chain c1 {
diff --git a/tests/shell/testcases/sets/typeof_sets_0 b/tests/shell/testcases/sets/typeof_sets_0
index 28e39b4..8850e9a 100755
--- a/tests/shell/testcases/sets/typeof_sets_0
+++ b/tests/shell/testcases/sets/typeof_sets_0
@@ -223,8 +223,8 @@ $INPUT_VERSION_SET
set s14 {
typeof tcp option mptcp subtype . ip daddr
- elements = { remove-addr . 10.1.1.1,
- mp-join . 10.1.1.2 }
+ elements = { mp-join . 10.1.1.2,
+ remove-addr . 10.1.1.1 }
}
$INPUT_OSF_CHAIN
chain c2 {

View File

@ -0,0 +1,65 @@
From 06ba89ac8e3a57d54b581f9ff234d6f67b232306 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] intervals: Convert byte order implicitly
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 56107b766e1d886be4f6bf25c54f49b90c1b858b
commit 56107b766e1d886be4f6bf25c54f49b90c1b858b
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 13 16:36:01 2025 +0100
intervals: Convert byte order implicitly
When converting ranges to intervals, the latter's high and low values
must be in network byte order. Instead of creating the low/high constant
expressions with host byte order and converting the value, create them
with Big Endian and keep the value as is. Upon export, Little Endian MPZ
values will be byte-swapped by mpz_export_data() if BYTEORDER_BIG_ENDIAN
is passed.
The benefit of this is that value's byteorder may be communicated to
libnftnl later by looking at struct expr::byteorder field. By the time
this information is required during netlink serialization, there is no
other indicator for data byte order available.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/intervals.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/intervals.c b/src/intervals.c
index 8c8ce8c..d8c61ef 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -798,11 +798,8 @@ int setelem_to_interval(const struct set *set, struct expr *elem,
}
low = constant_expr_alloc(&key->location, set->key->dtype,
- set->key->byteorder, set->key->len, NULL);
-
+ BYTEORDER_BIG_ENDIAN, set->key->len, NULL);
mpz_set(low->value, key->range.low);
- if (set->key->byteorder == BYTEORDER_HOST_ENDIAN)
- mpz_switch_byteorder(low->value, set->key->len / BITS_PER_BYTE);
low = set_elem_expr_alloc(&key->location, low);
set_elem_expr_copy(low, interval_expr_key(elem));
@@ -824,12 +821,11 @@ int setelem_to_interval(const struct set *set, struct expr *elem,
}
high = constant_expr_alloc(&key->location, set->key->dtype,
- set->key->byteorder, set->key->len,
+ BYTEORDER_BIG_ENDIAN, set->key->len,
NULL);
mpz_set(high->value, key->range.high);
mpz_add_ui(high->value, high->value, 1);
- if (set->key->byteorder == BYTEORDER_HOST_ENDIAN)
- mpz_switch_byteorder(high->value, set->key->len / BITS_PER_BYTE);
+ high->byteorder = BYTEORDER_BIG_ENDIAN;
high = set_elem_expr_alloc(&key->location, high);

View File

@ -0,0 +1,56 @@
From f675eaad15472cd84fae5f51a0ecac188e1b7e66 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] expression: Set range expression 'len' field
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit b74a108432510b8cef62c4d0de1cef754ee70ab1
commit b74a108432510b8cef62c4d0de1cef754ee70ab1
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Oct 16 18:57:20 2025 +0200
expression: Set range expression 'len' field
The length value is needed for netlink debug output of concatenated
ranges. Set it to one of the inner elements' lengths (which should be
identical).
Since the inner element length may not be set initially, set it in
eval phase again. This covers at least all cases in tests/py.
Without this, netlink_gen_concat_key() et al. would have to inspect
element types and extract lengths accordingly, this is much easier.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/evaluate.c | 1 +
src/expression.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/evaluate.c b/src/evaluate.c
index 9125d5f..0831d2c 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1337,6 +1337,7 @@ static int expr_evaluate_range(struct eval_ctx *ctx, struct expr **exprp)
datatype_set(range, left->dtype);
range->flags |= EXPR_F_CONSTANT;
+ range->len = left->len;
return 0;
}
diff --git a/src/expression.c b/src/expression.c
index 8cb6397..6e0941a 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1013,6 +1013,7 @@ struct expr *range_expr_alloc(const struct location *loc,
BYTEORDER_INVALID, 0);
expr->left = left;
expr->right = right;
+ expr->len = left->len;
return expr;
}

View File

@ -0,0 +1,218 @@
From 1f034c281e4e41eb260f7ad5667f9d8df638ed70 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] netlink: Introduce struct nft_data_linearize::byteorder
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit c06b480ea54bbdc997e69f047360541d141b00e1
commit c06b480ea54bbdc997e69f047360541d141b00e1
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Nov 13 17:11:15 2025 +0100
netlink: Introduce struct nft_data_linearize::byteorder
Bits in this field indicate data is in host byte order and thus may need
conversion when being printed "byte-by-byte" in libnftnl.
With regular immediate values, this field's value has boolean properties
(if non-zero, data is in host byte order). Concatenations may contain
components in different byte order, so with them each bit (at index N)
indicates whether a component (at the same index) is in host byte order.
Communicate a possible byte order conversion in
__netlink_gen_concat_key() back to caller since this has to be respected
when setting 'byteorder' field in struct nft_data_linearize.
String-based values are special: While defined as being in host byte
order in nftables, libnftnl shall print them without prior conversion
like Big Endian values.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/netlink.h | 1 +
src/netlink.c | 60 +++++++++++++++++++++++++++++++++++++++--------
2 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/include/netlink.h b/include/netlink.h
index 2737d57..a762cb4 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -106,6 +106,7 @@ struct nft_data_linearize {
char chain[NFT_CHAIN_MAXNAMELEN];
uint32_t chain_id;
int verdict;
+ uint32_t byteorder;
};
struct nft_data_delinearize {
diff --git a/src/netlink.c b/src/netlink.c
index b5da33e..939552a 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -248,6 +248,7 @@ void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder,
assert(len > 0);
mpz_export_data(data->value, value, byteorder, len);
data->len = len;
+ data->byteorder = byteorder == BYTEORDER_HOST_ENDIAN ? UINT32_MAX : 0;
}
static int netlink_export_pad(unsigned char *data, const mpz_t v,
@@ -265,12 +266,15 @@ static void byteorder_switch_expr_value(mpz_t v, const struct expr *e)
}
static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
- unsigned char *data)
+ unsigned char *data,
+ enum byteorder *byteorder)
{
struct expr *expr;
mpz_t value;
int ret;
+ *byteorder = i->byteorder;
+
switch (i->etype) {
case EXPR_RANGE:
if (flags & EXPR_F_INTERVAL_END)
@@ -281,8 +285,10 @@ static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
mpz_init_set(value, expr->value);
if (expr_basetype(expr)->type == TYPE_INTEGER &&
- expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ expr->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, expr);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
i = expr;
break;
@@ -293,8 +299,10 @@ static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
mpz_init_set(value, i->range.low);
if (expr_basetype(i)->type == TYPE_INTEGER &&
- i->byteorder == BYTEORDER_HOST_ENDIAN)
+ i->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, i);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
break;
case EXPR_PREFIX:
@@ -304,8 +312,10 @@ static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
mpz_init_bitmask(v, i->len - i->prefix_len);
- if (i->byteorder == BYTEORDER_HOST_ENDIAN)
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(v, i);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
mpz_add(v, i->prefix->value, v);
count = netlink_export_pad(data, v, i);
@@ -323,9 +333,12 @@ static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
break;
expr = (struct expr *)i;
+
if (expr_basetype(expr)->type == TYPE_INTEGER &&
- expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ expr->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, expr);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
break;
default:
BUG("invalid expression type '%s' in set", expr_ops(i)->name);
@@ -352,16 +365,24 @@ static void netlink_gen_concat_key(const struct expr *expr,
{
unsigned int len = netlink_padded_len(expr->len) / BITS_PER_BYTE;
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
+ enum byteorder byteorder;
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
- offset += __netlink_gen_concat_key(expr->flags, i, data + offset);
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
+ offset += __netlink_gen_concat_key(expr->flags, i,
+ data + offset, &byteorder);
+ if (byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
@@ -418,17 +439,28 @@ static void __netlink_gen_concat_expand(const struct expr *expr,
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(false, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(true, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
@@ -440,14 +472,20 @@ static void __netlink_gen_concat(const struct expr *expr,
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(expr->flags, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
@@ -467,6 +505,8 @@ static void netlink_gen_constant_data(const struct expr *expr,
assert(expr->etype == EXPR_VALUE);
netlink_gen_raw_data(expr->value, expr->byteorder,
div_round_up(expr->len, BITS_PER_BYTE), data);
+ if (expr_basetype(expr)->type == TYPE_STRING)
+ data->byteorder = 0;
}
static void netlink_gen_chain(const struct expr *expr,

View File

@ -0,0 +1,108 @@
From 3dbc8914f61700ab156fc9851e45a21c184391f3 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] netlink: Introduce struct nft_data_linearize::sizes
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 3d5937f52b7d7675a8f9b446a336317b0f36560a
commit 3d5937f52b7d7675a8f9b446a336317b0f36560a
Author: Phil Sutter <phil@nwl.cc>
Date: Fri Oct 17 17:06:10 2025 +0200
netlink: Introduce struct nft_data_linearize::sizes
This array holds each concat component's actual length in bytes. It is
crucial because component data is padded to match register lengths and
if libnftnl has to print data "in reverse" (to print Little Endian
values byte-by-byte), it will print extra leading zeroes with odd data
lengths and thus indicate number of printed bytes does no longer
correctly reflect actual data length.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/netlink.h | 1 +
src/netlink.c | 14 ++++++++++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/netlink.h b/include/netlink.h
index a762cb4..aa25094 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -107,6 +107,7 @@ struct nft_data_linearize {
uint32_t chain_id;
int verdict;
uint32_t byteorder;
+ uint8_t sizes[NFT_REG32_COUNT];
};
struct nft_data_delinearize {
diff --git a/src/netlink.c b/src/netlink.c
index 939552a..4523d0a 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -381,7 +381,7 @@ static void netlink_gen_concat_key(const struct expr *expr,
if (byteorder == BYTEORDER_HOST_ENDIAN &&
expr_basetype(i)->type != TYPE_STRING)
nld->byteorder |= 1 << n;
- n++;
+ nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE);
}
nft_data_memcpy(nld, data, len);
@@ -451,7 +451,7 @@ static void __netlink_gen_concat_expand(const struct expr *expr,
if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
expr_basetype(i)->type != TYPE_STRING)
nld->byteorder |= 1 << n;
- n++;
+ nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE);
}
list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
@@ -459,7 +459,7 @@ static void __netlink_gen_concat_expand(const struct expr *expr,
if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
expr_basetype(i)->type != TYPE_STRING)
nld->byteorder |= 1 << n;
- n++;
+ nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE);
}
nft_data_memcpy(nld, data, len);
@@ -484,7 +484,7 @@ static void __netlink_gen_concat(const struct expr *expr,
if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
expr_basetype(i)->type != TYPE_STRING)
nld->byteorder |= 1 << n;
- n++;
+ nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE);
}
nft_data_memcpy(nld, data, len);
@@ -562,6 +562,8 @@ static void netlink_gen_range(const struct expr *expr,
offset = netlink_export_pad(data, expr->left->value, expr->left);
netlink_export_pad(data + offset, expr->right->value, expr->right);
nft_data_memcpy(nld, data, len);
+ nld->sizes[0] = div_round_up(expr->left->len, BITS_PER_BYTE);
+ nld->sizes[1] = div_round_up(expr->right->len, BITS_PER_BYTE);
}
static void netlink_gen_range_value(const struct expr *expr,
@@ -578,6 +580,8 @@ static void netlink_gen_range_value(const struct expr *expr,
offset = netlink_export_pad(data, expr->range.low, expr);
netlink_export_pad(data + offset, expr->range.high, expr);
nft_data_memcpy(nld, data, len);
+ nld->sizes[0] = div_round_up(expr->len, BITS_PER_BYTE);
+ nld->sizes[1] = nld->sizes[0];
}
static void netlink_gen_prefix(const struct expr *expr,
@@ -598,6 +602,8 @@ static void netlink_gen_prefix(const struct expr *expr,
mpz_clear(v);
nft_data_memcpy(nld, data, len);
+ nld->sizes[0] = div_round_up(expr->prefix->len, BITS_PER_BYTE);
+ nld->sizes[1] = nld->sizes[0];
}
static void netlink_gen_key(const struct expr *expr,

View File

@ -0,0 +1,76 @@
From 3097a93fcfa42b6460cd9ba37577e647c754eae3 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] netlink: No need to reference array when passing as pointer
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 134b50e5d3f185219e09c613d98d6bf9494b1248
commit 134b50e5d3f185219e09c613d98d6bf9494b1248
Author: Phil Sutter <phil@nwl.cc>
Date: Fri Oct 17 16:11:14 2025 +0200
netlink: No need to reference array when passing as pointer
Struct nft_data_linearize::value is an array, drop the reference
operator.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/netlink.c | 6 +++---
src/netlink_linearize.c | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/netlink.c b/src/netlink.c
index 4523d0a..49655f2 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -139,17 +139,17 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
netlink_gen_key(key, &nld);
key->flags &= ~EXPR_F_INTERVAL;
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, &nld.value, nld.len);
+ nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, nld.value, nld.len);
key->flags |= EXPR_F_INTERVAL_END;
netlink_gen_key(key, &nld);
key->flags &= ~EXPR_F_INTERVAL_END;
nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY_END,
- &nld.value, nld.len);
+ nld.value, nld.len);
} else {
netlink_gen_key(key, &nld);
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, &nld.value, nld.len);
+ nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, nld.value, nld.len);
}
break;
}
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 8ac33d3..9af7333 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -470,8 +470,8 @@ static struct expr *netlink_gen_prefix(struct netlink_linearize_ctx *ctx,
netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg);
netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, nld.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, &nld.value, nld.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, &zero.value, zero.len);
+ nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, nld.value, nld.len);
+ nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, zero.value, zero.len);
nft_rule_add_expr(ctx, nle, &expr->location);
return expr->right->prefix;
@@ -546,8 +546,8 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg);
netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, &nld2.value, nld2.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, &nld.value, nld.len);
+ nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, nld2.value, nld2.len);
+ nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, nld.value, nld.len);
nft_rule_add_expr(ctx, nle, &expr->location);
nle = alloc_nft_expr("cmp");

View File

@ -0,0 +1,162 @@
From 855f8ec6c185de220b7e31a35418d977997aaa53 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] netlink: Make use of nftnl_{expr,set_elem}_set_imm()
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 0041f7189a2b9e649c3a58dcc2005eaa713bdac4
commit 0041f7189a2b9e649c3a58dcc2005eaa713bdac4
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Oct 8 22:15:15 2025 +0200
netlink: Make use of nftnl_{expr,set_elem}_set_imm()
Pass the previously collected byteorder (and sizes) to libnftnl for
improved netlink debug output.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/netlink.c | 18 ++++++++++++------
src/netlink_linearize.c | 34 ++++++++++++++++++++++------------
2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/src/netlink.c b/src/netlink.c
index 49655f2..22961f1 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -139,17 +139,22 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
netlink_gen_key(key, &nld);
key->flags &= ~EXPR_F_INTERVAL;
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, nld.value, nld.len);
+ nftnl_set_elem_set_imm(nlse, NFTNL_SET_ELEM_KEY,
+ nld.value, nld.len,
+ nld.byteorder, nld.sizes);
key->flags |= EXPR_F_INTERVAL_END;
netlink_gen_key(key, &nld);
key->flags &= ~EXPR_F_INTERVAL_END;
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY_END,
- nld.value, nld.len);
+ nftnl_set_elem_set_imm(nlse, NFTNL_SET_ELEM_KEY_END,
+ nld.value, nld.len,
+ nld.byteorder, nld.sizes);
} else {
netlink_gen_key(key, &nld);
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, nld.value, nld.len);
+ nftnl_set_elem_set_imm(nlse, NFTNL_SET_ELEM_KEY,
+ nld.value, nld.len,
+ nld.byteorder, nld.sizes);
}
break;
}
@@ -217,8 +222,9 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
case EXPR_RANGE:
case EXPR_RANGE_VALUE:
case EXPR_PREFIX:
- nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_DATA,
- nld.value, nld.len);
+ nftnl_set_elem_set_imm(nlse, NFTNL_SET_ELEM_DATA,
+ nld.value, nld.len,
+ nld.byteorder, nld.sizes);
break;
default:
BUG("unexpected set element expression\n");
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 9af7333..2ac1fd4 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -470,8 +470,10 @@ static struct expr *netlink_gen_prefix(struct netlink_linearize_ctx *ctx,
netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg);
netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, nld.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, nld.value, nld.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, zero.value, zero.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_MASK,
+ nld.value, nld.len, nld.byteorder);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_XOR,
+ zero.value, zero.len, zero.byteorder);
nft_rule_add_expr(ctx, nle, &expr->location);
return expr->right->prefix;
@@ -539,15 +541,18 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
nle = alloc_nft_expr("cmp");
netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_EQ);
- nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld2.value, nld2.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_CMP_DATA,
+ nld2.value, nld2.len, nld2.byteorder);
nft_rule_add_expr(ctx, nle, &expr->location);
} else {
nle = alloc_nft_expr("bitwise");
netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, sreg);
netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, sreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, nld2.value, nld2.len);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, nld.value, nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_MASK,
+ nld2.value, nld2.len, nld2.byteorder);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_XOR,
+ nld.value, nld.len, nld.byteorder);
nft_rule_add_expr(ctx, nle, &expr->location);
nle = alloc_nft_expr("cmp");
@@ -557,7 +562,8 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
else
nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_NEQ);
- nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_CMP_DATA,
+ nld.value, nld.len, nld.byteorder);
nft_rule_add_expr(ctx, nle, &expr->location);
}
@@ -633,7 +639,8 @@ static void netlink_gen_relational(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP,
netlink_gen_cmp_op(expr->op));
netlink_gen_data(right, &nld);
- nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_CMP_DATA,
+ nld.value, len, nld.byteorder);
release_register(ctx, expr->left);
nft_rule_add_expr(ctx, nle, &expr->location);
@@ -669,8 +676,8 @@ static void netlink_gen_bitwise_shift(struct netlink_linearize_ctx *ctx,
netlink_gen_raw_data(expr->right->value, expr->right->byteorder,
sizeof(uint32_t), &nld);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_DATA, nld.value,
- nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_DATA,
+ nld.value, nld.len, nld.byteorder);
nft_rule_add_expr(ctx, nle, &expr->location);
}
@@ -735,9 +742,11 @@ static void netlink_gen_bitwise_mask_xor(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len);
netlink_gen_raw_data(mask, expr->byteorder, len, &nld);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_MASK, nld.value, nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_MASK,
+ nld.value, nld.len, nld.byteorder);
netlink_gen_raw_data(xor, expr->byteorder, len, &nld);
- nftnl_expr_set(nle, NFTNL_EXPR_BITWISE_XOR, nld.value, nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_BITWISE_XOR,
+ nld.value, nld.len, nld.byteorder);
mpz_clear(tmp);
mpz_clear(val);
@@ -859,7 +868,8 @@ static void netlink_gen_immediate(struct netlink_linearize_ctx *ctx,
netlink_gen_data(expr, &nld);
switch (expr->etype) {
case EXPR_VALUE:
- nftnl_expr_set(nle, NFTNL_EXPR_IMM_DATA, nld.value, nld.len);
+ nftnl_expr_set_imm(nle, NFTNL_EXPR_IMM_DATA,
+ nld.value, nld.len, nld.byteorder);
break;
case EXPR_VERDICT:
if (expr->chain) {

View File

@ -0,0 +1,104 @@
From 9ef04720b6513392d8aa2164b97c3a24e39c7965 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] tests: py: tools: Add regen_payloads.sh
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit db82466117b8bfc93923eec49114d47200f7f913
commit db82466117b8bfc93923eec49114d47200f7f913
Author: Phil Sutter <phil@nwl.cc>
Date: Wed Nov 24 17:29:04 2021 +0100
tests: py: tools: Add regen_payloads.sh
Use this script to recreate all payload records.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/tools/regen_payloads.sh | 74 ++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100755 tests/py/tools/regen_payloads.sh
diff --git a/tests/py/tools/regen_payloads.sh b/tests/py/tools/regen_payloads.sh
new file mode 100755
index 0000000..9fcbc2c
--- /dev/null
+++ b/tests/py/tools/regen_payloads.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+# update payload records in an automated fashion, trying to reduce diff sizes
+
+
+# scan payloadfile and print record for cmd (if found)
+find_payload() { # (payloadfile, cmd)
+ local found=false
+
+ readarray -t pl <"$1"
+ for l in "${pl[@]}"; do
+ if [[ "$l" == "# "* ]]; then
+ $found && return
+ [[ "$l" == "$2" ]] && found=true
+ fi
+ $found && echo "$l"
+ done
+ $found || echo "Warning: Command '$2' not found in '$1'" >&2
+}
+
+cd $(dirname $0)/../
+
+# make sure no stray output files get in the way
+rm -f */*.got */*.gotgot
+
+# store payload records for later
+# clear payload files to force regenerating (but leave them in place)
+for pl in */*.payload*; do
+ [[ $pl == *.bak ]] && continue # ignore leftover .bak files
+ cp "$pl" "${pl}.bak"
+ echo >"$pl"
+done
+
+# run the testsuite to create .got files
+# pass -f to keep going despite missing payloads
+./nft-test.py -f
+
+# restore old payload records
+for plbak in */*.bak; do
+ mv "$plbak" "${plbak%.bak}"
+done
+
+# sort created got files to match order in old payload records
+for g in ${@:-*/*.payload*.got}; do
+ pl=${g%.got}
+
+ [[ -f $g ]] || continue
+ [[ -f $pl ]] || continue
+
+ readarray -t ploads <"$g"
+ readarray -t cmds <<< $(grep '^# ' $pl)
+ for cmd in "${cmds[@]}"; do
+ found=false
+ for l in "${ploads[@]}"; do
+ if [[ "$l" == "# "* ]]; then
+ $found && break
+ [[ "$l" == "$cmd" ]] && found=true
+ fi
+ $found && [[ "$l" != "" ]] && echo "$l"
+ done
+ if ! $found; then
+ echo "Warning: Command '$cmd' not found in '$g'" >&2
+ else
+ echo ""
+ fi
+ done | head -n -1 >${g}got
+
+ mv "${g}got" "${g}"
+done
+
+# overwrite old payload records with new ones
+for got in */*.payload*.got; do
+ mv "${got}" "${got%.got}"
+done

View File

@ -0,0 +1,137 @@
From c67e2fa3f2e7edf6bcf6a4b3331960105727ee4f Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:53:23 +0100
Subject: [PATCH] tests: py: objects.t: must use input, not output
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 6b71d114912cd269416f232c0f0ec2fcc42eb58f
commit 6b71d114912cd269416f232c0f0ec2fcc42eb58f
Author: Florian Westphal <fw@strlen.de>
Date: Tue Oct 7 12:48:49 2025 +0200
tests: py: objects.t: must use input, not output
synproxy must never be used in output rules, doing so results in kernel
crash due to infinite recursive calls back to nf_hook_slow() for the
emitted reply packet.
Up until recently kernel lacked this validation, and now that the kernel
rejects this the test fails. Use input to make this pass again.
A new test to ensure we reject synproxy in ouput should be added
in the near future.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/ip/objects.t | 4 ++--
tests/py/ip/objects.t.payload | 22 +++++++++++-----------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tests/py/ip/objects.t b/tests/py/ip/objects.t
index 4fcde7c..71d5ffe 100644
--- a/tests/py/ip/objects.t
+++ b/tests/py/ip/objects.t
@@ -1,6 +1,6 @@
-:output;type filter hook output priority 0
+:input;type filter hook input priority 0
-*ip;test-ip4;output
+*ip;test-ip4;input
# counter
%cnt1 type counter;ok
diff --git a/tests/py/ip/objects.t.payload b/tests/py/ip/objects.t.payload
index 5252724..3da4b28 100644
--- a/tests/py/ip/objects.t.payload
+++ b/tests/py/ip/objects.t.payload
@@ -1,5 +1,5 @@
# ip saddr 192.168.1.3 counter name "cnt2"
-ip test-ip4 output
+ip test-ip4 input
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x0301a8c0 ]
[ objref type 1 name cnt2 ]
@@ -8,14 +8,14 @@ ip test-ip4 output
__objmap%d test-ip4 43
__objmap%d test-ip4 0
element 0000bb01 : 0 [end] element 00005000 : 0 [end] element 00001600 : 0 [end]
-ip test-ip4 output
+ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ objref sreg 1 set __objmap%d ]
# ip saddr 192.168.1.3 quota name "qt1"
-ip test-ip4 output
+ip test-ip4 input
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x0301a8c0 ]
[ objref type 2 name qt1 ]
@@ -24,28 +24,28 @@ ip test-ip4 output
__objmap%d test-ip4 43
__objmap%d test-ip4 0
element 0000bb01 : 0 [end] element 00005000 : 0 [end] element 00001600 : 0 [end]
-ip test-ip4 output
+ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ objref sreg 1 set __objmap%d ]
# ct helper set "cthelp1"
-ip test-ip4 output
+ip test-ip4 input
[ objref type 3 name cthelp1 ]
# ct helper set tcp dport map {21 : "cthelp1", 2121 : "cthelp1" }
__objmap%d test-ip4 43
__objmap%d test-ip4 0
element 00001500 : 0 [end] element 00004908 : 0 [end]
-ip test-ip4 output
+ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ objref sreg 1 set __objmap%d ]
# ip saddr 192.168.1.3 limit name "lim1"
-ip test-ip4 output
+ip test-ip4 input
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x0301a8c0 ]
[ objref type 4 name lim1 ]
@@ -54,25 +54,25 @@ ip test-ip4 output
__objmap%d test-ip4 43 size 3
__objmap%d test-ip4 0
element 0000bb01 : 0 [end] element 00005000 : 0 [end] element 00001600 : 0 [end]
-ip test-ip4 output
+ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ objref sreg 1 set __objmap%d ]
# ct timeout set "cttime1"
-ip test-ip4 output
+ip test-ip4 input
[ objref type 7 name cttime1 ]
# ct expectation set "ctexpect1"
-ip test-ip4 output
+ip test-ip4 input
[ objref type 9 name ctexpect1 ]
# synproxy name tcp dport map {443 : "synproxy1", 80 : "synproxy2"}
__objmap%d test-ip4 43 size 2
__objmap%d test-ip4 0
element 0000bb01 : 0 [end] element 00005000 : 0 [end]
-ip test-ip4 output
+ip test-ip4 input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 2b @ transport header + 2 => reg 1 ]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
From 1ed7838c2a122c5c73992b9734bf27d5c1998d18 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 24 Feb 2026 15:56:22 +0100
Subject: [PATCH] tests: py: Adjust payloads to changed userdata printing
JIRA: https://issues.redhat.com/browse/RHEL-128553
Upstream Status: nftables commit 471224bd15106fd94a182eaa9b794c484487f53f
commit 471224bd15106fd94a182eaa9b794c484487f53f
Author: Phil Sutter <phil@nwl.cc>
Date: Thu Jan 29 14:49:17 2026 +0100
tests: py: Adjust payloads to changed userdata printing
libnftnl no longer prints userdata content but merely its size and a sum
of all bytes.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
tests/py/ip6/srh.t.payload | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/py/ip6/srh.t.payload b/tests/py/ip6/srh.t.payload
index 5c3031f..54fdd0e 100644
--- a/tests/py/ip6/srh.t.payload
+++ b/tests/py/ip6/srh.t.payload
@@ -11,7 +11,7 @@ ip6 test-ip6 input
# srh last-entry { 0, 4-127, 255 }
__set%d test-ip6 7 size 5
__set%d test-ip6 0
- element 00 element 01 flags 1 element 04 element 80 flags 1 element ff userdata = { \x01\x04\x00\x00\x00\x01 }
+ element 00 element 01 flags 1 element 04 element 80 flags 1 element ff userdata len 6 sum 0x6
ip6 test-ip6 input
[ exthdr load ipv6 1b @ 43 + 4 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -29,7 +29,7 @@ ip6 test-ip6 input
# srh flags { 0, 4-127, 255 }
__set%d test-ip6 7 size 5
__set%d test-ip6 0
- element 00 element 01 flags 1 element 04 element 80 flags 1 element ff userdata = { \x01\x04\x00\x00\x00\x01 }
+ element 00 element 01 flags 1 element 04 element 80 flags 1 element ff userdata len 6 sum 0x6
ip6 test-ip6 input
[ exthdr load ipv6 1b @ 43 + 5 => reg 1 ]
[ lookup reg 1 set __set%d ]
@@ -47,7 +47,7 @@ ip6 test-ip6 input
# srh tag { 0, 4-127, 0xffff }
__set%d test-ip6 7 size 5
__set%d test-ip6 0
- element 0000 element 0001 flags 1 element 0004 element 0080 flags 1 element ffff userdata = { \x01\x04\x00\x00\x00\x01 }
+ element 0000 element 0001 flags 1 element 0004 element 0080 flags 1 element ffff userdata len 6 sum 0x6
ip6 test-ip6 input
[ exthdr load ipv6 2b @ 43 + 6 => reg 1 ]
[ lookup reg 1 set __set%d ]

View File

@ -1,6 +1,6 @@
Name: nftables
Version: 1.1.5
Release: 3%{?dist}
Release: 5%{?dist}
# Upstream released a 0.100 version, then 0.4. Need Epoch to get back on track.
Epoch: 1
Summary: Netfilter Tables userspace utilities
@ -43,6 +43,19 @@ Patch23: 0023-parser_bison-Accept-ASTERISK_STRING-in-flowtable_exp.pa
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
Patch27: 0027-segtree-Fix-range-aggregation-on-Big-Endian.patch
Patch28: 0028-mergesort-Fix-sorting-of-string-values.patch
Patch29: 0029-mergesort-Align-concatenation-sort-order-with-Big-En.patch
Patch30: 0030-intervals-Convert-byte-order-implicitly.patch
Patch31: 0031-expression-Set-range-expression-len-field.patch
Patch32: 0032-netlink-Introduce-struct-nft_data_linearize-byteorde.patch
Patch33: 0033-netlink-Introduce-struct-nft_data_linearize-sizes.patch
Patch34: 0034-netlink-No-need-to-reference-array-when-passing-as-p.patch
Patch35: 0035-netlink-Make-use-of-nftnl_-expr-set_elem-_set_imm.patch
Patch36: 0036-tests-py-tools-Add-regen_payloads.sh.patch
Patch37: 0037-tests-py-objects.t-must-use-input-not-output.patch
Patch38: 0038-tests-py-Update-payload-records.patch
Patch39: 0039-tests-py-Adjust-payloads-to-changed-userdata-printin.patch
BuildRequires: autoconf
BuildRequires: automake
@ -53,7 +66,7 @@ BuildRequires: flex
BuildRequires: bison
BuildRequires: pkgconfig(libmnl) >= 1.0.4
BuildRequires: gmp-devel
BuildRequires: libnftnl-devel >= 1.3.0-1
BuildRequires: libnftnl-devel >= 1.3.0-3
BuildRequires: systemd
BuildRequires: asciidoc
BuildRequires: pkgconfig(xtables) >= 1.6.1
@ -61,7 +74,7 @@ BuildRequires: jansson-devel
BuildRequires: python3-devel
BuildRequires: readline-devel
Requires: libnftnl >= 1.3.0-2
Requires: libnftnl >= 1.3.0-3
%generate_buildrequires
cd py/
@ -160,6 +173,25 @@ cd py/
%files -n python3-nftables -f %{pyproject_files}
%changelog
* Thu May 21 2026 Phil Sutter <psutter@redhat.com> [1.1.5-5.el10]
- Bump revision to overcome pipeline issues (Phil Sutter) [RHEL-128553]
* Tue Feb 24 2026 Phil Sutter <psutter@redhat.com> [1.1.5-4.el10]
- spec: Require libnftnl-1.3.0-3 for nftnl_{expr,set_elem}_set_imm() (Phil Sutter) [RHEL-128553]
- tests: py: Adjust payloads to changed userdata printing (Phil Sutter) [RHEL-128553]
- tests: py: Update payload records (Phil Sutter) [RHEL-128553]
- tests: py: objects.t: must use input, not output (Phil Sutter) [RHEL-128553]
- tests: py: tools: Add regen_payloads.sh (Phil Sutter) [RHEL-128553]
- netlink: Make use of nftnl_{expr,set_elem}_set_imm() (Phil Sutter) [RHEL-128553]
- netlink: No need to reference array when passing as pointer (Phil Sutter) [RHEL-128553]
- netlink: Introduce struct nft_data_linearize::sizes (Phil Sutter) [RHEL-128553]
- netlink: Introduce struct nft_data_linearize::byteorder (Phil Sutter) [RHEL-128553]
- expression: Set range expression 'len' field (Phil Sutter) [RHEL-128553]
- intervals: Convert byte order implicitly (Phil Sutter) [RHEL-128553]
- mergesort: Align concatenation sort order with Big Endian (Phil Sutter) [RHEL-128553]
- mergesort: Fix sorting of string values (Phil Sutter) [RHEL-128553]
- segtree: Fix range aggregation on Big Endian (Phil Sutter) [RHEL-128553]
* 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]