nftables/SOURCES/0070-evaluate-skip-byteorder-conversion-for-selector-smal.patch
2026-08-26 08:03:54 -04:00

210 lines
6.6 KiB
Diff

From ff07e944ab10459c7fa9b6beac5c622e48eaa2f5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Fri, 17 Jul 2026 11:08:42 +0200
Subject: [PATCH] evaluate: skip byteorder conversion for selector smaller than
2 bytes
JIRA: https://issues.redhat.com/browse/RHEL-190549
Upstream Status: nftables commit 9fe58952c45a1643dc7df1a0b1f5d88e8ae1a978
commit 9fe58952c45a1643dc7df1a0b1f5d88e8ae1a978
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed Feb 7 23:53:32 2024 +0100
evaluate: skip byteorder conversion for selector smaller than 2 bytes
Add unary expression to trigger byteorder conversion for host byteorder
selectors only if selectors length is larger or equal than 2 bytes.
# cat test.nft
table ip x {
set test {
type ipv4_addr . ether_addr . inet_proto
flags interval
}
chain y {
ip saddr . ether saddr . meta l4proto @test counter
}
}
# nft -f test.nft
ip x y
[ meta load iiftype => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ payload load 4b @ network header + 12 => reg 1 ]
[ payload load 6b @ link header + 6 => reg 9 ]
[ meta load l4proto => reg 11 ]
[ byteorder reg 11 = hton(reg 11, 2, 1) ] <--- should not be here
[ lookup reg 1 set test ]
[ counter pkts 0 bytes 0 ]
Fixes: 1017d323cafa ("src: support for selectors with different byteorder with interval concatenations")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
src/evaluate.c | 12 ++++++----
tests/py/inet/meta.t | 1 +
tests/py/inet/meta.t.json | 41 ++++++++++++++++++++++++++++++++
tests/py/inet/meta.t.json.output | 41 ++++++++++++++++++++++++++++++++
tests/py/inet/meta.t.payload | 14 +++++++++++
5 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 20950fd..e64bc91 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -194,12 +194,14 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
assert(basetype == TYPE_INTEGER);
- op = byteorder_conversion_op(i, byteorder);
- unary = unary_expr_alloc(&i->location, op, i);
- if (expr_evaluate(ctx, &unary) < 0)
- return -1;
+ if (div_round_up(i->len, BITS_PER_BYTE) >= 2) {
+ op = byteorder_conversion_op(i, byteorder);
+ unary = unary_expr_alloc(&i->location, op, i);
+ if (expr_evaluate(ctx, &unary) < 0)
+ return -1;
- list_replace(&i->list, &unary->list);
+ list_replace(&i->list, &unary->list);
+ }
}
return 0;
diff --git a/tests/py/inet/meta.t b/tests/py/inet/meta.t
index 5c062b3..7d2515c 100644
--- a/tests/py/inet/meta.t
+++ b/tests/py/inet/meta.t
@@ -25,6 +25,7 @@ meta mark set ct mark >> 8;ok
meta mark . tcp dport { 0x0000000a-0x00000014 . 80-90, 0x00100000-0x00100123 . 100-120 };ok
ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 1.2.3.6-1.2.3.8 . 0x00000200-0x00000300 };ok
ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 5.6.7.8 . 0x00000200 };ok
+ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 };ok
meta mark set ip dscp;ok
meta mark set ip dscp | 0x40;ok
diff --git a/tests/py/inet/meta.t.json b/tests/py/inet/meta.t.json
index 3ba0fd1..0fee165 100644
--- a/tests/py/inet/meta.t.json
+++ b/tests/py/inet/meta.t.json
@@ -526,3 +526,44 @@
}
]
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+[
+ {
+ "match": {
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "field": "saddr",
+ "protocol": "ip"
+ }
+ },
+ {
+ "payload": {
+ "field": "saddr",
+ "protocol": "ether"
+ }
+ },
+ {
+ "meta": {
+ "key": "l4proto"
+ }
+ }
+ ]
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ {
+ "concat": [
+ "1.2.3.4",
+ "aa:bb:cc:dd:ee:ff",
+ "tcp"
+ ]
+ }
+ ]
+ }
+ }
+ }
+]
+
diff --git a/tests/py/inet/meta.t.json.output b/tests/py/inet/meta.t.json.output
index 3e7dd21..8697d5a 100644
--- a/tests/py/inet/meta.t.json.output
+++ b/tests/py/inet/meta.t.json.output
@@ -51,3 +51,44 @@
}
]
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+[
+ {
+ "match": {
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "field": "saddr",
+ "protocol": "ip"
+ }
+ },
+ {
+ "payload": {
+ "field": "saddr",
+ "protocol": "ether"
+ }
+ },
+ {
+ "meta": {
+ "key": "l4proto"
+ }
+ }
+ ]
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ {
+ "concat": [
+ "1.2.3.4",
+ "aa:bb:cc:dd:ee:ff",
+ 6
+ ]
+ }
+ ]
+ }
+ }
+ }
+]
+
diff --git a/tests/py/inet/meta.t.payload b/tests/py/inet/meta.t.payload
index c53b507..7184fa0 100644
--- a/tests/py/inet/meta.t.payload
+++ b/tests/py/inet/meta.t.payload
@@ -173,3 +173,17 @@ inet test-inet input
[ bitwise reg 1 = ( reg 1 & 0xffffffbf ) ^ 0x00000040 ]
[ meta set mark with reg 1 ]
+# ip saddr . ether saddr . meta l4proto { 1.2.3.4 . aa:bb:cc:dd:ee:ff . 6 }
+__set%d test-inet 3 size 1
+__set%d test-inet 0
+ element 04030201 ddccbbaa 0000ffee 00000006 : 0 [end]
+inet test-inet input
+ [ meta load nfproto => reg 1 ]
+ [ cmp eq reg 1 0x00000002 ]
+ [ meta load iiftype => reg 1 ]
+ [ cmp eq reg 1 0x00000001 ]
+ [ payload load 4b @ network header + 12 => reg 1 ]
+ [ payload load 6b @ link header + 6 => reg 9 ]
+ [ meta load l4proto => reg 11 ]
+ [ lookup reg 1 set __set%d ]
+