From patchwork Fri Oct 2 09:03:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1375605 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4C2k8h00jYz9sSn for ; Fri, 2 Oct 2020 18:45:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726176AbgJBIpW (ORCPT ); Fri, 2 Oct 2020 04:45:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726017AbgJBIpW (ORCPT ); Fri, 2 Oct 2020 04:45:22 -0400 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76550C0613D0 for ; Fri, 2 Oct 2020 01:45:22 -0700 (PDT) Received: from localhost ([::1]:49680 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.94) (envelope-from ) id 1kOGgq-0005jZ-9l; Fri, 02 Oct 2020 10:45:20 +0200 From: Phil Sutter To: Pablo Neira Ayuso 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 Message-Id: <20201002090334.29788-1-phil@nwl.cc> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Payload expression works on byte-boundaries, leverage this with suitable prefix lengths. Signed-off-by: Phil Sutter --- 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