Blame SOURCES/0018-evaluate-search-stacked-header-list-for-matching-pay.patch

1d03cd
From 71fb4e3be07548216a831dda28f4aedfc37b2df1 Mon Sep 17 00:00:00 2001
1d03cd
From: Phil Sutter <psutter@redhat.com>
1d03cd
Date: Thu, 9 Feb 2023 10:27:58 +0100
1d03cd
Subject: [PATCH] evaluate: search stacked header list for matching payload dep
1d03cd
1d03cd
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2094887
1d03cd
Upstream Status: nftables commit 87c3041bfd244
1d03cd
1d03cd
commit 87c3041bfd244aaf39e644d33c0df4fe04079e1c
1d03cd
Author: Florian Westphal <fw@strlen.de>
1d03cd
Date:   Mon Jul 25 20:02:28 2022 +0200
1d03cd
1d03cd
    evaluate: search stacked header list for matching payload dep
1d03cd
1d03cd
    "ether saddr 0:1:2:3:4:6 vlan id 2" works, but reverse fails:
1d03cd
1d03cd
    "vlan id 2 ether saddr 0:1:2:3:4:6" will give
1d03cd
    Error: conflicting protocols specified: vlan vs. ether
1d03cd
1d03cd
    After "proto: track full stack of seen l2 protocols, not just cumulative offset",
1d03cd
    we have a list of all l2 headers, so search those to see if we had this
1d03cd
    proto base in the past before rejecting this.
1d03cd
1d03cd
    Reported-by: Eric Garver <eric@garver.life>
1d03cd
    Signed-off-by: Florian Westphal <fw@strlen.de>
1d03cd
1d03cd
Signed-off-by: Phil Sutter <psutter@redhat.com>
1d03cd
---
1d03cd
 src/evaluate.c                        | 21 +++++++---
1d03cd
 tests/py/bridge/vlan.t                |  3 ++
1d03cd
 tests/py/bridge/vlan.t.json           | 56 +++++++++++++++++++++++++++
1d03cd
 tests/py/bridge/vlan.t.payload        | 16 ++++++++
1d03cd
 tests/py/bridge/vlan.t.payload.netdev | 20 ++++++++++
1d03cd
 5 files changed, 110 insertions(+), 6 deletions(-)
1d03cd
1d03cd
diff --git a/src/evaluate.c b/src/evaluate.c
1d03cd
index 9246064..d67f915 100644
1d03cd
--- a/src/evaluate.c
1d03cd
+++ b/src/evaluate.c
1d03cd
@@ -659,13 +659,22 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
1d03cd
 	struct stmt *nstmt = NULL;
1d03cd
 	int link, err;
1d03cd
 
1d03cd
-	if (payload->payload.base == PROTO_BASE_LL_HDR &&
1d03cd
-	    proto_is_dummy(desc)) {
1d03cd
-		err = meta_iiftype_gen_dependency(ctx, payload, &nstmt);
1d03cd
-		if (err < 0)
1d03cd
-			return err;
1d03cd
+	if (payload->payload.base == PROTO_BASE_LL_HDR) {
1d03cd
+		if (proto_is_dummy(desc)) {
1d03cd
+			err = meta_iiftype_gen_dependency(ctx, payload, &nstmt);
1d03cd
+			if (err < 0)
1d03cd
+				return err;
1d03cd
 
1d03cd
-		rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
1d03cd
+			rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
1d03cd
+		} else {
1d03cd
+			unsigned int i;
1d03cd
+
1d03cd
+			/* payload desc stored in the L2 header stack? No conflict. */
1d03cd
+			for (i = 0; i < ctx->pctx.stacked_ll_count; i++) {
1d03cd
+				if (ctx->pctx.stacked_ll[i] == payload->payload.desc)
1d03cd
+					return 0;
1d03cd
+			}
1d03cd
+		}
1d03cd
 	}
1d03cd
 
1d03cd
 	assert(base <= PROTO_BASE_MAX);
1d03cd
diff --git a/tests/py/bridge/vlan.t b/tests/py/bridge/vlan.t
1d03cd
index 924ed4e..4920601 100644
1d03cd
--- a/tests/py/bridge/vlan.t
1d03cd
+++ b/tests/py/bridge/vlan.t
1d03cd
@@ -47,3 +47,6 @@ ether type ip vlan id 1 ip saddr 10.0.0.1;fail
1d03cd
 
1d03cd
 # mangling
1d03cd
 vlan id 1 vlan id set 2;ok
1d03cd
+
1d03cd
+ether saddr 00:01:02:03:04:05 vlan id 1;ok
1d03cd
+vlan id 2 ether saddr 0:1:2:3:4:6;ok;ether saddr 00:01:02:03:04:06 vlan id 2
1d03cd
diff --git a/tests/py/bridge/vlan.t.json b/tests/py/bridge/vlan.t.json
1d03cd
index e7640f9..58d4a40 100644
1d03cd
--- a/tests/py/bridge/vlan.t.json
1d03cd
+++ b/tests/py/bridge/vlan.t.json
1d03cd
@@ -761,3 +761,59 @@
1d03cd
         }
1d03cd
     }
1d03cd
 ]
1d03cd
+
1d03cd
+# ether saddr 00:01:02:03:04:05 vlan id 1
1d03cd
+[
1d03cd
+    {
1d03cd
+        "match": {
1d03cd
+            "left": {
1d03cd
+                "payload": {
1d03cd
+                    "field": "saddr",
1d03cd
+                    "protocol": "ether"
1d03cd
+                }
1d03cd
+            },
1d03cd
+            "op": "==",
1d03cd
+            "right": "00:01:02:03:04:05"
1d03cd
+        }
1d03cd
+    },
1d03cd
+    {
1d03cd
+        "match": {
1d03cd
+            "left": {
1d03cd
+                "payload": {
1d03cd
+                    "field": "id",
1d03cd
+                    "protocol": "vlan"
1d03cd
+                }
1d03cd
+            },
1d03cd
+            "op": "==",
1d03cd
+            "right": 1
1d03cd
+        }
1d03cd
+    }
1d03cd
+]
1d03cd
+
1d03cd
+# vlan id 2 ether saddr 0:1:2:3:4:6
1d03cd
+[
1d03cd
+    {
1d03cd
+        "match": {
1d03cd
+            "left": {
1d03cd
+                "payload": {
1d03cd
+                    "field": "saddr",
1d03cd
+                    "protocol": "ether"
1d03cd
+                }
1d03cd
+            },
1d03cd
+            "op": "==",
1d03cd
+            "right": "00:01:02:03:04:06"
1d03cd
+        }
1d03cd
+    },
1d03cd
+    {
1d03cd
+        "match": {
1d03cd
+            "left": {
1d03cd
+                "payload": {
1d03cd
+                    "field": "id",
1d03cd
+                    "protocol": "vlan"
1d03cd
+                }
1d03cd
+            },
1d03cd
+            "op": "==",
1d03cd
+            "right": 2
1d03cd
+        }
1d03cd
+    }
1d03cd
+]
1d03cd
diff --git a/tests/py/bridge/vlan.t.payload b/tests/py/bridge/vlan.t.payload
1d03cd
index 6c8d595..713670e 100644
1d03cd
--- a/tests/py/bridge/vlan.t.payload
1d03cd
+++ b/tests/py/bridge/vlan.t.payload
1d03cd
@@ -276,3 +276,19 @@ bridge
1d03cd
   [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
   [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000200 ]
1d03cd
   [ payload write reg 1 => 2b @ link header + 14 csum_type 0 csum_off 0 csum_flags 0x0 ]
1d03cd
+
1d03cd
+# ether saddr 00:01:02:03:04:05 vlan id 1
1d03cd
+bridge test-bridge input
1d03cd
+  [ payload load 8b @ link header + 6 => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x03020100 0x00810504 ]
1d03cd
+  [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
1d03cd
+  [ cmp eq reg 1 0x00000100 ]
1d03cd
+
1d03cd
+# vlan id 2 ether saddr 0:1:2:3:4:6
1d03cd
+bridge test-bridge input
1d03cd
+  [ payload load 8b @ link header + 6 => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x03020100 0x00810604 ]
1d03cd
+  [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
1d03cd
+  [ cmp eq reg 1 0x00000200 ]
1d03cd
diff --git a/tests/py/bridge/vlan.t.payload.netdev b/tests/py/bridge/vlan.t.payload.netdev
1d03cd
index d2c7d74..98a2a2b 100644
1d03cd
--- a/tests/py/bridge/vlan.t.payload.netdev
1d03cd
+++ b/tests/py/bridge/vlan.t.payload.netdev
1d03cd
@@ -322,3 +322,23 @@ netdev
1d03cd
   [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
   [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000200 ]
1d03cd
   [ payload write reg 1 => 2b @ link header + 14 csum_type 0 csum_off 0 csum_flags 0x0 ]
1d03cd
+
1d03cd
+# vlan id 2 ether saddr 0:1:2:3:4:6
1d03cd
+netdev test-netdev ingress
1d03cd
+  [ meta load iiftype => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x00000001 ]
1d03cd
+  [ payload load 8b @ link header + 6 => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x03020100 0x00810604 ]
1d03cd
+  [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
1d03cd
+  [ cmp eq reg 1 0x00000200 ]
1d03cd
+
1d03cd
+# ether saddr 00:01:02:03:04:05 vlan id 1
1d03cd
+netdev test-netdev ingress
1d03cd
+  [ meta load iiftype => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x00000001 ]
1d03cd
+  [ payload load 8b @ link header + 6 => reg 1 ]
1d03cd
+  [ cmp eq reg 1 0x03020100 0x00810504 ]
1d03cd
+  [ payload load 2b @ link header + 14 => reg 1 ]
1d03cd
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
1d03cd
+  [ cmp eq reg 1 0x00000100 ]
1d03cd
-- 
1d03cd
2.39.1
1d03cd