netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [iptables PATCH] nft: Optimize class-based IP prefix matches
Date: Fri,  2 Oct 2020 11:03:34 +0200	[thread overview]
Message-ID: <20201002090334.29788-1-phil@nwl.cc> (raw)

Payload expression works on byte-boundaries, leverage this with suitable
prefix lengths.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft-ipv4.c   |  6 ++++--
 iptables/nft-ipv6.c   |  6 ++++--
 iptables/nft-shared.c | 14 ++++++++++----
 iptables/nft-shared.h |  4 ++++
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index afdecf9711e64..ce702041af0f4 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -199,7 +199,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
 			parse_mask_ipv4(ctx, &cs->fw.ip.smsk);
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
 		} else {
-			cs->fw.ip.smsk.s_addr = 0xffffffff;
+			memset(&cs->fw.ip.smsk, 0xff,
+			       min(ctx->payload.len, sizeof(struct in_addr)));
 		}
 
 		if (inv)
@@ -212,7 +213,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
 			parse_mask_ipv4(ctx, &cs->fw.ip.dmsk);
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
 		} else {
-			cs->fw.ip.dmsk.s_addr = 0xffffffff;
+			memset(&cs->fw.ip.dmsk, 0xff,
+			       min(ctx->payload.len, sizeof(struct in_addr)));
 		}
 
 		if (inv)
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 4008b7eab4f2a..c877ec6d10887 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -146,7 +146,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
 			parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk);
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
 		} else {
-			memset(&cs->fw6.ipv6.smsk, 0xff, sizeof(struct in6_addr));
+			memset(&cs->fw6.ipv6.smsk, 0xff,
+			       min(ctx->payload.len, sizeof(struct in6_addr)));
 		}
 
 		if (inv)
@@ -159,7 +160,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
 			parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk);
 			ctx->flags &= ~NFT_XT_CTX_BITWISE;
 		} else {
-			memset(&cs->fw6.ipv6.dmsk, 0xff, sizeof(struct in6_addr));
+			memset(&cs->fw6.ipv6.dmsk, 0xff,
+			       min(ctx->payload.len, sizeof(struct in6_addr)));
 		}
 
 		if (inv)
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 7741d23befc5a..545e9c60fa015 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -166,16 +166,22 @@ void add_addr(struct nftnl_rule *r, int offset,
 	      void *data, void *mask, size_t len, uint32_t op)
 {
 	const unsigned char *m = mask;
+	bool bitwise = false;
 	int i;
 
-	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
-
 	for (i = 0; i < len; i++) {
-		if (m[i] != 0xff)
+		if (m[i] != 0xff) {
+			bitwise = m[i] != 0;
 			break;
+		}
 	}
 
-	if (i != len)
+	if (!bitwise)
+		len = i;
+
+	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
+
+	if (bitwise)
 		add_bitwise(r, mask, len);
 
 	add_cmp_ptr(r, op, data, len);
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 4440fd17bfeac..a52463342b30a 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -247,4 +247,8 @@ void xtables_restore_parse(struct nft_handle *h,
 			   const struct nft_xt_restore_parse *p);
 
 void nft_check_xt_legacy(int family, bool is_ipt_save);
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
 #endif
-- 
2.28.0


             reply	other threads:[~2020-10-02  8:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-02  9:03 Phil Sutter [this message]
2020-10-02 11:25 ` [iptables PATCH] nft: Optimize class-based IP prefix matches Arturo Borrero Gonzalez
2020-10-02 11:34   ` Phil Sutter
2020-10-06  8:56 ` Pablo Neira Ayuso
2020-10-06  9:37   ` Phil Sutter
2020-10-06  9:41     ` Pablo Neira Ayuso
2020-10-06 11:48       ` Phil Sutter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201002090334.29788-1-phil@nwl.cc \
    --to=phil@nwl.cc \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).