Blame SOURCES/0037-proto-Fix-ARP-header-field-ordering.patch

19e5f4
From 70dc225b23708c6ac96e2895488f3c6dea9e201d Mon Sep 17 00:00:00 2001
19e5f4
From: Phil Sutter <psutter@redhat.com>
19e5f4
Date: Mon, 7 Dec 2020 18:28:27 +0100
19e5f4
Subject: [PATCH] proto: Fix ARP header field ordering
19e5f4
19e5f4
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1896334
19e5f4
Upstream Status: nftables commit f751753f92ea7
19e5f4
19e5f4
commit f751753f92ea76f582f7d5d1fef8b4d5677ba589
19e5f4
Author: Phil Sutter <phil@nwl.cc>
19e5f4
Date:   Tue Nov 10 13:07:49 2020 +0100
19e5f4
19e5f4
    proto: Fix ARP header field ordering
19e5f4
19e5f4
    In ARP header, destination ether address sits between source IP and
19e5f4
    destination IP addresses. Enum arp_hdr_fields had this wrong, which
19e5f4
    in turn caused wrong ordering of entries in proto_arp->templates. When
19e5f4
    expanding a combined payload expression, code assumes that template
19e5f4
    entries are ordered by header offset, therefore the destination ether
19e5f4
    address match was printed as raw if an earlier field was matched as
19e5f4
    well:
19e5f4
19e5f4
    | arp saddr ip 192.168.1.1 arp daddr ether 3e:d1:3f:d6:12:0b
19e5f4
19e5f4
    was printed as:
19e5f4
19e5f4
    | arp saddr ip 192.168.1.1 @nh,144,48 69068440080907
19e5f4
19e5f4
    Note: Although strictly not necessary, reorder fields in
19e5f4
    proto_arp->templates as well to match their actual ordering, just to
19e5f4
    avoid confusion.
19e5f4
19e5f4
    Fixes: 4b0f2a712b579 ("src: support for arp sender and target ethernet and IPv4 addresses")
19e5f4
    Signed-off-by: Phil Sutter <phil@nwl.cc>
19e5f4
---
19e5f4
 include/proto.h                   |  2 +-
19e5f4
 src/proto.c                       |  2 +-
19e5f4
 tests/py/arp/arp.t                |  3 +++
19e5f4
 tests/py/arp/arp.t.json           | 56 +++++++++++++++++++++++++++++++++++++++
19e5f4
 tests/py/arp/arp.t.json.output    | 28 ++++++++++++++++++++
19e5f4
 tests/py/arp/arp.t.payload        | 10 +++++++
19e5f4
 tests/py/arp/arp.t.payload.netdev | 14 ++++++++++
19e5f4
 7 files changed, 113 insertions(+), 2 deletions(-)
19e5f4
19e5f4
diff --git a/include/proto.h b/include/proto.h
19e5f4
index 436cbe3..5a50059 100644
19e5f4
--- a/include/proto.h
19e5f4
+++ b/include/proto.h
19e5f4
@@ -184,8 +184,8 @@ enum arp_hdr_fields {
19e5f4
 	ARPHDR_PLN,
19e5f4
 	ARPHDR_OP,
19e5f4
 	ARPHDR_SADDR_ETHER,
19e5f4
-	ARPHDR_DADDR_ETHER,
19e5f4
 	ARPHDR_SADDR_IP,
19e5f4
+	ARPHDR_DADDR_ETHER,
19e5f4
 	ARPHDR_DADDR_IP,
19e5f4
 };
19e5f4
 
19e5f4
diff --git a/src/proto.c b/src/proto.c
19e5f4
index 8360abf..49c8c92 100644
19e5f4
--- a/src/proto.c
19e5f4
+++ b/src/proto.c
19e5f4
@@ -908,8 +908,8 @@ const struct proto_desc proto_arp = {
19e5f4
 		[ARPHDR_PLN]		= ARPHDR_FIELD("plen", plen),
19e5f4
 		[ARPHDR_OP]		= ARPHDR_TYPE("operation", &arpop_type, oper),
19e5f4
 		[ARPHDR_SADDR_ETHER]	= ARPHDR_TYPE("saddr ether", &etheraddr_type, sha),
19e5f4
-		[ARPHDR_DADDR_ETHER]	= ARPHDR_TYPE("daddr ether", &etheraddr_type, tha),
19e5f4
 		[ARPHDR_SADDR_IP]	= ARPHDR_TYPE("saddr ip", &ipaddr_type, spa),
19e5f4
+		[ARPHDR_DADDR_ETHER]	= ARPHDR_TYPE("daddr ether", &etheraddr_type, tha),
19e5f4
 		[ARPHDR_DADDR_IP]	= ARPHDR_TYPE("daddr ip", &ipaddr_type, tpa),
19e5f4
 	},
19e5f4
 	.format		= {
19e5f4
diff --git a/tests/py/arp/arp.t b/tests/py/arp/arp.t
19e5f4
index 2540c0a..109d01d 100644
19e5f4
--- a/tests/py/arp/arp.t
19e5f4
+++ b/tests/py/arp/arp.t
19e5f4
@@ -61,4 +61,7 @@ arp daddr ip 4.3.2.1;ok
19e5f4
 arp saddr ether aa:bb:cc:aa:bb:cc;ok
19e5f4
 arp daddr ether aa:bb:cc:aa:bb:cc;ok
19e5f4
 
19e5f4
+arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee;ok
19e5f4
+arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1;ok;arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
19e5f4
+
19e5f4
 meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566;ok;iifname "invalid" arp htype 1 arp ptype ip arp hlen 6 arp plen 4 arp daddr ip 192.168.143.16 arp daddr ether set 11:22:33:44:55:66
19e5f4
diff --git a/tests/py/arp/arp.t.json b/tests/py/arp/arp.t.json
19e5f4
index 5f2f6cd..8508c17 100644
19e5f4
--- a/tests/py/arp/arp.t.json
19e5f4
+++ b/tests/py/arp/arp.t.json
19e5f4
@@ -901,6 +901,62 @@
19e5f4
     }
19e5f4
 ]
19e5f4
 
19e5f4
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
19e5f4
+[
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "saddr ip",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "192.168.1.1"
19e5f4
+        }
19e5f4
+    },
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "daddr ether",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "fe:ed:00:c0:ff:ee"
19e5f4
+        }
19e5f4
+    }
19e5f4
+]
19e5f4
+
19e5f4
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
19e5f4
+[
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "daddr ether",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "fe:ed:00:c0:ff:ee"
19e5f4
+        }
19e5f4
+    },
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "saddr ip",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "192.168.1.1"
19e5f4
+        }
19e5f4
+    }
19e5f4
+]
19e5f4
+
19e5f4
 # meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566
19e5f4
 [
19e5f4
     {
19e5f4
diff --git a/tests/py/arp/arp.t.json.output b/tests/py/arp/arp.t.json.output
19e5f4
index b8507bf..afa75b2 100644
19e5f4
--- a/tests/py/arp/arp.t.json.output
19e5f4
+++ b/tests/py/arp/arp.t.json.output
19e5f4
@@ -66,6 +66,34 @@
19e5f4
     }
19e5f4
 ]
19e5f4
 
19e5f4
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
19e5f4
+[
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "saddr ip",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "192.168.1.1"
19e5f4
+        }
19e5f4
+    },
19e5f4
+    {
19e5f4
+        "match": {
19e5f4
+            "left": {
19e5f4
+                "payload": {
19e5f4
+                    "field": "daddr ether",
19e5f4
+                    "protocol": "arp"
19e5f4
+                }
19e5f4
+            },
19e5f4
+            "op": "==",
19e5f4
+            "right": "fe:ed:00:c0:ff:ee"
19e5f4
+        }
19e5f4
+    }
19e5f4
+]
19e5f4
+
19e5f4
 # meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566
19e5f4
 [
19e5f4
     {
19e5f4
diff --git a/tests/py/arp/arp.t.payload b/tests/py/arp/arp.t.payload
19e5f4
index 52c9932..f819853 100644
19e5f4
--- a/tests/py/arp/arp.t.payload
19e5f4
+++ b/tests/py/arp/arp.t.payload
19e5f4
@@ -307,3 +307,13 @@ arp test-arp input
19e5f4
   [ payload load 6b @ network header + 18 => reg 1 ]
19e5f4
   [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
19e5f4
 
19e5f4
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
19e5f4
+arp 
19e5f4
+  [ payload load 10b @ network header + 14 => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
19e5f4
+
19e5f4
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
19e5f4
+arp 
19e5f4
+  [ payload load 10b @ network header + 14 => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
19e5f4
+
19e5f4
diff --git a/tests/py/arp/arp.t.payload.netdev b/tests/py/arp/arp.t.payload.netdev
19e5f4
index 667691f..f57610c 100644
19e5f4
--- a/tests/py/arp/arp.t.payload.netdev
19e5f4
+++ b/tests/py/arp/arp.t.payload.netdev
19e5f4
@@ -409,3 +409,17 @@ netdev test-netdev ingress
19e5f4
   [ payload load 6b @ network header + 18 => reg 1 ]
19e5f4
   [ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
19e5f4
 
19e5f4
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
19e5f4
+netdev 
19e5f4
+  [ meta load protocol => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x00000608 ]
19e5f4
+  [ payload load 10b @ network header + 14 => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
19e5f4
+
19e5f4
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
19e5f4
+netdev 
19e5f4
+  [ meta load protocol => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x00000608 ]
19e5f4
+  [ payload load 10b @ network header + 14 => reg 1 ]
19e5f4
+  [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
19e5f4
+
19e5f4
-- 
19e5f4
1.8.3.1
19e5f4