210 lines
6.6 KiB
Diff
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 ]
|
|
+
|