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

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