]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: search stacked header list for matching payload dep
authorFlorian Westphal <fw@strlen.de>
Mon, 25 Jul 2022 18:02:28 +0000 (20:02 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 4 Aug 2022 23:46:39 +0000 (01:46 +0200)
"ether saddr 0:1:2:3:4:6 vlan id 2" works, but reverse fails:

"vlan id 2 ether saddr 0:1:2:3:4:6" will give
Error: conflicting protocols specified: vlan vs. ether

After "proto: track full stack of seen l2 protocols, not just cumulative offset",
we have a list of all l2 headers, so search those to see if we had this
proto base in the past before rejecting this.

Reported-by: Eric Garver <eric@garver.life>
Signed-off-by: Florian Westphal <fw@strlen.de>
src/evaluate.c
tests/py/bridge/vlan.t
tests/py/bridge/vlan.t.json
tests/py/bridge/vlan.t.payload
tests/py/bridge/vlan.t.payload.netdev

index be9fcd5117fb3c43a01562074ce7c8b980f03d41..919c38c5604ee5b83aebc6fac118d230fb20c38d 100644 (file)
@@ -659,13 +659,22 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
        struct stmt *nstmt = NULL;
        int link, err;
 
-       if (payload->payload.base == PROTO_BASE_LL_HDR &&
-           proto_is_dummy(desc)) {
-               err = meta_iiftype_gen_dependency(ctx, payload, &nstmt);
-               if (err < 0)
-                       return err;
+       if (payload->payload.base == PROTO_BASE_LL_HDR) {
+               if (proto_is_dummy(desc)) {
+                       err = meta_iiftype_gen_dependency(ctx, payload, &nstmt);
+                       if (err < 0)
+                               return err;
 
-               rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
+                       rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
+               } else {
+                       unsigned int i;
+
+                       /* payload desc stored in the L2 header stack? No conflict. */
+                       for (i = 0; i < ctx->pctx.stacked_ll_count; i++) {
+                               if (ctx->pctx.stacked_ll[i] == payload->payload.desc)
+                                       return 0;
+                       }
+               }
        }
 
        assert(base <= PROTO_BASE_MAX);
index 924ed4ed3679b1abf70487cc15f1d7f07b3a2466..49206017fff283896cb3d73c39189edcc5791e6d 100644 (file)
@@ -47,3 +47,6 @@ ether type ip vlan id 1 ip saddr 10.0.0.1;fail
 
 # mangling
 vlan id 1 vlan id set 2;ok
+
+ether saddr 00:01:02:03:04:05 vlan id 1;ok
+vlan id 2 ether saddr 0:1:2:3:4:6;ok;ether saddr 00:01:02:03:04:06 vlan id 2
index e7640f9a6a379d53ed3748fc11b65c4afea22526..58d4a40f5bafc57df1b72fe029900b639505672d 100644 (file)
         }
     }
 ]
+
+# ether saddr 00:01:02:03:04:05 vlan id 1
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "saddr",
+                    "protocol": "ether"
+                }
+            },
+            "op": "==",
+            "right": "00:01:02:03:04:05"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "id",
+                    "protocol": "vlan"
+                }
+            },
+            "op": "==",
+            "right": 1
+        }
+    }
+]
+
+# vlan id 2 ether saddr 0:1:2:3:4:6
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "saddr",
+                    "protocol": "ether"
+                }
+            },
+            "op": "==",
+            "right": "00:01:02:03:04:06"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "id",
+                    "protocol": "vlan"
+                }
+            },
+            "op": "==",
+            "right": 2
+        }
+    }
+]
index 6c8d595a1aad0b021d31c9d78d26aeb7070bb76a..713670e9e721ecf1235d967878946953cb2a0971 100644 (file)
@@ -276,3 +276,19 @@ bridge
   [ payload load 2b @ link header + 14 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000200 ]
   [ payload write reg 1 => 2b @ link header + 14 csum_type 0 csum_off 0 csum_flags 0x0 ]
+
+# ether saddr 00:01:02:03:04:05 vlan id 1
+bridge test-bridge input
+  [ payload load 8b @ link header + 6 => reg 1 ]
+  [ cmp eq reg 1 0x03020100 0x00810504 ]
+  [ payload load 2b @ link header + 14 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000100 ]
+
+# vlan id 2 ether saddr 0:1:2:3:4:6
+bridge test-bridge input
+  [ payload load 8b @ link header + 6 => reg 1 ]
+  [ cmp eq reg 1 0x03020100 0x00810604 ]
+  [ payload load 2b @ link header + 14 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000200 ]
index d2c7d74a4e858748921d83353b784e12bd39de8d..98a2a2b0f3798c5c89b7bd1b8ab1cda1669df77f 100644 (file)
@@ -322,3 +322,23 @@ netdev
   [ payload load 2b @ link header + 14 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000200 ]
   [ payload write reg 1 => 2b @ link header + 14 csum_type 0 csum_off 0 csum_flags 0x0 ]
+
+# vlan id 2 ether saddr 0:1:2:3:4:6
+netdev test-netdev ingress
+  [ meta load iiftype => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
+  [ payload load 8b @ link header + 6 => reg 1 ]
+  [ cmp eq reg 1 0x03020100 0x00810604 ]
+  [ payload load 2b @ link header + 14 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000200 ]
+
+# ether saddr 00:01:02:03:04:05 vlan id 1
+netdev test-netdev ingress
+  [ meta load iiftype => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
+  [ payload load 8b @ link header + 6 => reg 1 ]
+  [ cmp eq reg 1 0x03020100 0x00810504 ]
+  [ payload load 2b @ link header + 14 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x0000ff0f ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000100 ]