Blame SOURCES/0032-nft-Optimize-class-based-IP-prefix-matches.patch

9c35a8
From 87a2128fcfd4c5b0847a8c611652ade8c54d8185 Mon Sep 17 00:00:00 2001
9c35a8
From: Phil Sutter <phil@nwl.cc>
9c35a8
Date: Fri, 2 Oct 2020 09:44:38 +0200
9c35a8
Subject: [PATCH] nft: Optimize class-based IP prefix matches
9c35a8
9c35a8
Payload expression works on byte-boundaries, leverage this with suitable
9c35a8
prefix lengths.
9c35a8
9c35a8
Signed-off-by: Phil Sutter <phil@nwl.cc>
9c35a8
(cherry picked from commit 323259001d617ae359430a03ee3d3e7f107684e0)
9c35a8
Signed-off-by: Phil Sutter <psutter@redhat.com>
9c35a8
---
9c35a8
 iptables/nft-arp.c    | 11 ++++++++---
9c35a8
 iptables/nft-ipv4.c   |  6 ++++--
9c35a8
 iptables/nft-ipv6.c   |  6 ++++--
9c35a8
 iptables/nft-shared.c | 14 ++++++++++----
9c35a8
 iptables/nft-shared.h |  4 ++++
9c35a8
 5 files changed, 30 insertions(+), 11 deletions(-)
9c35a8
9c35a8
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
9c35a8
index d4a86610ec217..ac400e484a4fa 100644
9c35a8
--- a/iptables/nft-arp.c
9c35a8
+++ b/iptables/nft-arp.c
9c35a8
@@ -303,7 +303,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx,
9c35a8
 		memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
9c35a8
 		ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 	} else {
9c35a8
-		memset(info->mask, 0xff, ETH_ALEN);
9c35a8
+		memset(info->mask, 0xff,
9c35a8
+		       min(ctx->payload.len, ETH_ALEN));
9c35a8
 	}
9c35a8
 
9c35a8
 	return inv;
9c35a8
@@ -360,7 +361,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 				parse_mask_ipv4(ctx, &fw->arp.smsk);
9c35a8
 				ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 			} else {
9c35a8
-				fw->arp.smsk.s_addr = 0xffffffff;
9c35a8
+				memset(&fw->arp.smsk, 0xff,
9c35a8
+				       min(ctx->payload.len,
9c35a8
+					   sizeof(struct in_addr)));
9c35a8
 			}
9c35a8
 
9c35a8
 			if (inv)
9c35a8
@@ -380,7 +383,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 				parse_mask_ipv4(ctx, &fw->arp.tmsk);
9c35a8
 				ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 			} else {
9c35a8
-				fw->arp.tmsk.s_addr = 0xffffffff;
9c35a8
+				memset(&fw->arp.tmsk, 0xff,
9c35a8
+				       min(ctx->payload.len,
9c35a8
+					   sizeof(struct in_addr)));
9c35a8
 			}
9c35a8
 
9c35a8
 			if (inv)
9c35a8
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
9c35a8
index 70634f8fad84d..c84af2df90da7 100644
9c35a8
--- a/iptables/nft-ipv4.c
9c35a8
+++ b/iptables/nft-ipv4.c
9c35a8
@@ -199,7 +199,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 			parse_mask_ipv4(ctx, &cs->fw.ip.smsk);
9c35a8
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 		} else {
9c35a8
-			cs->fw.ip.smsk.s_addr = 0xffffffff;
9c35a8
+			memset(&cs->fw.ip.smsk, 0xff,
9c35a8
+			       min(ctx->payload.len, sizeof(struct in_addr)));
9c35a8
 		}
9c35a8
 
9c35a8
 		if (inv)
9c35a8
@@ -212,7 +213,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 			parse_mask_ipv4(ctx, &cs->fw.ip.dmsk);
9c35a8
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 		} else {
9c35a8
-			cs->fw.ip.dmsk.s_addr = 0xffffffff;
9c35a8
+			memset(&cs->fw.ip.dmsk, 0xff,
9c35a8
+			       min(ctx->payload.len, sizeof(struct in_addr)));
9c35a8
 		}
9c35a8
 
9c35a8
 		if (inv)
9c35a8
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
9c35a8
index d01491bfdb689..cfced245a781c 100644
9c35a8
--- a/iptables/nft-ipv6.c
9c35a8
+++ b/iptables/nft-ipv6.c
9c35a8
@@ -146,7 +146,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 			parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk);
9c35a8
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 		} else {
9c35a8
-			memset(&cs->fw6.ipv6.smsk, 0xff, sizeof(struct in6_addr));
9c35a8
+			memset(&cs->fw6.ipv6.smsk, 0xff,
9c35a8
+			       min(ctx->payload.len, sizeof(struct in6_addr)));
9c35a8
 		}
9c35a8
 
9c35a8
 		if (inv)
9c35a8
@@ -159,7 +160,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
9c35a8
 			parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk);
9c35a8
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
9c35a8
 		} else {
9c35a8
-			memset(&cs->fw6.ipv6.dmsk, 0xff, sizeof(struct in6_addr));
9c35a8
+			memset(&cs->fw6.ipv6.dmsk, 0xff,
9c35a8
+			       min(ctx->payload.len, sizeof(struct in6_addr)));
9c35a8
 		}
9c35a8
 
9c35a8
 		if (inv)
9c35a8
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
9c35a8
index f60f5df97fb86..b1237049d0a34 100644
9c35a8
--- a/iptables/nft-shared.c
9c35a8
+++ b/iptables/nft-shared.c
9c35a8
@@ -166,16 +166,22 @@ void add_addr(struct nftnl_rule *r, int offset,
9c35a8
 	      void *data, void *mask, size_t len, uint32_t op)
9c35a8
 {
9c35a8
 	const unsigned char *m = mask;
9c35a8
+	bool bitwise = false;
9c35a8
 	int i;
9c35a8
 
9c35a8
-	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
9c35a8
-
9c35a8
 	for (i = 0; i < len; i++) {
9c35a8
-		if (m[i] != 0xff)
9c35a8
+		if (m[i] != 0xff) {
9c35a8
+			bitwise = m[i] != 0;
9c35a8
 			break;
9c35a8
+		}
9c35a8
 	}
9c35a8
 
9c35a8
-	if (i != len)
9c35a8
+	if (!bitwise)
9c35a8
+		len = i;
9c35a8
+
9c35a8
+	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
9c35a8
+
9c35a8
+	if (bitwise)
9c35a8
 		add_bitwise(r, mask, len);
9c35a8
 
9c35a8
 	add_cmp_ptr(r, op, data, len);
9c35a8
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
9c35a8
index bee99a7dd0c93..c7f1e366b75ee 100644
9c35a8
--- a/iptables/nft-shared.h
9c35a8
+++ b/iptables/nft-shared.h
9c35a8
@@ -252,4 +252,8 @@ void xtables_restore_parse(struct nft_handle *h,
9c35a8
 			   const struct nft_xt_restore_parse *p);
9c35a8
 
9c35a8
 void nft_check_xt_legacy(int family, bool is_ipt_save);
9c35a8
+
9c35a8
+#define min(x, y) ((x) < (y) ? (x) : (y))
9c35a8
+#define max(x, y) ((x) > (y) ? (x) : (y))
9c35a8
+
9c35a8
 #endif
9c35a8
-- 
9c35a8
2.28.0
9c35a8