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

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