From patchwork Sun May 28 14:00:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786853 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=O9yBIXs1; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLs6VNcz20Q8 for ; Mon, 29 May 2023 00:01:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229448AbjE1OBk (ORCPT ); Sun, 28 May 2023 10:01:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229591AbjE1OBf (ORCPT ); Sun, 28 May 2023 10:01:35 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2635C9 for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=48yAVw3l8xbyZeODy+QjdKnhMuajWlNi2GSf/bI9TtQ=; b=O9yBIXs1hZPxSeXGTuXxXgRG4X AJ4Iw2J7LFYCc/EaEYnnut1hVnLCVA/ukWGqlI6RRNmvqvFVaadaQcMm16YVgIMOAqM+ql2CRiNoG pCFmmjkS6HZIlfaLJUh3QwEoIPMC2yPgFKWboTGzdfXqI+dXxZDt0ND+HWGrCvKgVOHMtVcm+jIFF 6M6XU5NjPsqc9LY+20i33TiGH3LNtwh9PnU6ZBaGL2uhxnHVdESLke/mUUXgCX86LTHEJAmcRQn+J DlavDsj75RZSCcH5HohGJDWjQRi/q013C05a09W3nxbYBUIpiD54Yv+gzVdyPQeJvmprYNUBZR6Hq LGp8g6rw==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-5m; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 1/8] netlink: support (de)linearization of new bitwise boolean operations Date: Sun, 28 May 2023 15:00:51 +0100 Message-Id: <20230528140058.1218669-2-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Hitherto, all boolean bitwise operationss have been converted to the form: dst = (src & mask) ^ xor and constant values have been required for `xor` and `mask`. This has meant that the right-hand operand of a boolean binop must be constant. The kernel now supports performing AND, OR and XOR operations directly, on one register and an immediate value or on two registers, so we need to be able to generate and parse bitwise boolean expressions of this form. If a boolean operation has a constant RHS, we continue to send a mask-and-xor expression to the kernel. Signed-off-by: Jeremy Sowden --- include/linux/netfilter/nf_tables.h | 19 +++++++-- src/netlink_delinearize.c | 64 ++++++++++++++++++++++------- src/netlink_linearize.c | 62 +++++++++++++++++++++++----- 3 files changed, 117 insertions(+), 28 deletions(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 9c6f02c26054..2e3a7ede6290 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -555,16 +555,27 @@ enum nft_immediate_attributes { /** * enum nft_bitwise_ops - nf_tables bitwise operations * - * @NFT_BITWISE_BOOL: mask-and-xor operation used to implement NOT, AND, OR and - * XOR boolean operations + * @NFT_BITWISE_MASK_XOR: mask-and-xor operation used to implement NOT, AND, OR + * and XOR boolean operations * @NFT_BITWISE_LSHIFT: left-shift operation * @NFT_BITWISE_RSHIFT: right-shift operation + * @NFT_BITWISE_AND: and operation + * @NFT_BITWISE_OR: or operation + * @NFT_BITWISE_XOR: xor operation */ enum nft_bitwise_ops { - NFT_BITWISE_BOOL, + NFT_BITWISE_MASK_XOR, NFT_BITWISE_LSHIFT, NFT_BITWISE_RSHIFT, + NFT_BITWISE_AND, + NFT_BITWISE_OR, + NFT_BITWISE_XOR, }; +/* + * Old name for NFT_BITWISE_MASK_XOR, predating the addition of NFT_BITWISE_AND, + * NFT_BITWISE_OR and NFT_BITWISE_XOR. Retained for backwards-compatibility. + */ +#define NFT_BITWISE_BOOL NFT_BITWISE_MASK_XOR /** * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes @@ -577,6 +588,7 @@ enum nft_bitwise_ops { * @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops) * @NFTA_BITWISE_DATA: argument for non-boolean operations * (NLA_NESTED: nft_data_attributes) + * @NFTA_BITWISE_SREG2: second source register (NLA_U32: nft_registers) * * The bitwise expression supports boolean and shift operations. It implements * the boolean operations by performing the following operation: @@ -600,6 +612,7 @@ enum nft_bitwise_attributes { NFTA_BITWISE_XOR, NFTA_BITWISE_OP, NFTA_BITWISE_DATA, + NFTA_BITWISE_SREG2, __NFTA_BITWISE_MAX }; #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 935a6667a1c7..bdd3242bf5ec 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -457,12 +457,12 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, ctx->stmt = expr_stmt_alloc(loc, expr); } -static struct expr *netlink_parse_bitwise_bool(struct netlink_parse_ctx *ctx, - const struct location *loc, - const struct nftnl_expr *nle, - enum nft_registers sreg, - struct expr *left) - +static struct expr * +netlink_parse_bitwise_mask_xor(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nftnl_expr *nle, + enum nft_registers sreg, + struct expr *left) { struct nft_data_delinearize nld; struct expr *expr, *mask, *xor, *or; @@ -522,10 +522,39 @@ static struct expr *netlink_parse_bitwise_bool(struct netlink_parse_ctx *ctx, return expr; } +static struct expr *netlink_parse_bitwise_bool(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nftnl_expr *nle, + enum nft_bitwise_ops op, + enum nft_registers sreg, + struct expr *left) +{ + enum nft_registers sreg2; + struct expr *right, *expr; + + sreg2 = netlink_parse_register(nle, NFTNL_EXPR_BITWISE_SREG2); + right = netlink_get_register(ctx, loc, sreg2); + if (right == NULL) { + netlink_error(ctx, loc, + "Bitwise expression has no right-hand expression"); + return NULL; + } + + expr = binop_expr_alloc(loc, + op == NFT_BITWISE_XOR ? OP_XOR : + op == NFT_BITWISE_AND ? OP_AND : OP_OR, + left, right); + + if (left->len > 0) + expr->len = left->len; + + return expr; +} + static struct expr *netlink_parse_bitwise_shift(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle, - enum ops op, + enum nft_bitwise_ops op, enum nft_registers sreg, struct expr *left) { @@ -536,7 +565,9 @@ static struct expr *netlink_parse_bitwise_shift(struct netlink_parse_ctx *ctx, right = netlink_alloc_value(loc, &nld); right->byteorder = BYTEORDER_HOST_ENDIAN; - expr = binop_expr_alloc(loc, op, left, right); + expr = binop_expr_alloc(loc, + op == NFT_BITWISE_LSHIFT ? OP_LSHIFT : OP_RSHIFT, + left, right); expr->len = nftnl_expr_get_u32(nle, NFTNL_EXPR_BITWISE_LEN) * BITS_PER_BYTE; return expr; @@ -560,16 +591,19 @@ static void netlink_parse_bitwise(struct netlink_parse_ctx *ctx, op = nftnl_expr_get_u32(nle, NFTNL_EXPR_BITWISE_OP); switch (op) { - case NFT_BITWISE_BOOL: - expr = netlink_parse_bitwise_bool(ctx, loc, nle, sreg, - left); + case NFT_BITWISE_MASK_XOR: + expr = netlink_parse_bitwise_mask_xor(ctx, loc, nle, sreg, + left); break; - case NFT_BITWISE_LSHIFT: - expr = netlink_parse_bitwise_shift(ctx, loc, nle, OP_LSHIFT, - sreg, left); + case NFT_BITWISE_XOR: + case NFT_BITWISE_AND: + case NFT_BITWISE_OR: + expr = netlink_parse_bitwise_bool(ctx, loc, nle, op, + sreg, left); break; + case NFT_BITWISE_LSHIFT: case NFT_BITWISE_RSHIFT: - expr = netlink_parse_bitwise_shift(ctx, loc, nle, OP_RSHIFT, + expr = netlink_parse_bitwise_shift(ctx, loc, nle, op, sreg, left); break; default: diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 11cf48a3f9d0..25cff75df585 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -662,9 +662,9 @@ static void combine_binop(mpz_t mask, mpz_t xor, const mpz_t m, const mpz_t x) mpz_and(mask, mask, m); } -static void netlink_gen_shift(struct netlink_linearize_ctx *ctx, - const struct expr *expr, - enum nft_registers dreg) +static void netlink_gen_bitwise_shift(struct netlink_linearize_ctx *ctx, + const struct expr *expr, + enum nft_registers dreg) { enum nft_bitwise_ops op = expr->op == OP_LSHIFT ? NFT_BITWISE_LSHIFT : NFT_BITWISE_RSHIFT; @@ -689,9 +689,9 @@ static void netlink_gen_shift(struct netlink_linearize_ctx *ctx, nft_rule_add_expr(ctx, nle, &expr->location); } -static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx, - const struct expr *expr, - enum nft_registers dreg) +static void netlink_gen_bitwise_mask_xor(struct netlink_linearize_ctx *ctx, + const struct expr *expr, + enum nft_registers dreg) { struct nftnl_expr *nle; struct nft_data_linearize nld; @@ -708,7 +708,8 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx, binops[n++] = left = (struct expr *) expr; while (left->etype == EXPR_BINOP && left->left != NULL && - (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR)) + (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR) && + expr_is_constant(left->right)) binops[n++] = left = left->left; n--; @@ -743,7 +744,7 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx, nle = alloc_nft_expr("bitwise"); netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, dreg); netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, dreg); - nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_BOOL); + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_MASK_XOR); nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len); netlink_gen_raw_data(mask, expr->byteorder, len, &nld); @@ -759,6 +760,44 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx, nft_rule_add_expr(ctx, nle, &expr->location); } +static void netlink_gen_bitwise_bool(struct netlink_linearize_ctx *ctx, + const struct expr *expr, + enum nft_registers dreg) +{ + enum nft_registers sreg2; + struct nftnl_expr *nle; + unsigned int len; + + nle = alloc_nft_expr("bitwise"); + + switch (expr->op) { + case OP_XOR: + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_XOR); + break; + case OP_AND: + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_AND); + break; + case OP_OR: + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_OR); + break; + default: + BUG("invalid binary operation %u\n", expr->op); + } + + netlink_gen_expr(ctx, expr->left, dreg); + netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG, dreg); + netlink_put_register(nle, NFTNL_EXPR_BITWISE_DREG, dreg); + + sreg2 = get_register(ctx, expr->right); + netlink_gen_expr(ctx, expr->right, sreg2); + netlink_put_register(nle, NFTNL_EXPR_BITWISE_SREG2, sreg2); + + len = div_round_up(expr->len, BITS_PER_BYTE); + nftnl_expr_set_u32(nle, NFTNL_EXPR_BITWISE_LEN, len); + + nftnl_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_binop(struct netlink_linearize_ctx *ctx, const struct expr *expr, enum nft_registers dreg) @@ -766,10 +805,13 @@ static void netlink_gen_binop(struct netlink_linearize_ctx *ctx, switch(expr->op) { case OP_LSHIFT: case OP_RSHIFT: - netlink_gen_shift(ctx, expr, dreg); + netlink_gen_bitwise_shift(ctx, expr, dreg); break; default: - netlink_gen_bitwise(ctx, expr, dreg); + if (expr_is_constant(expr->right)) + netlink_gen_bitwise_mask_xor(ctx, expr, dreg); + else + netlink_gen_bitwise_bool(ctx, expr, dreg); break; } } From patchwork Sun May 28 14:00:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786851 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=DRR2sF5g; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLs0CwGz20Q8 for ; Mon, 29 May 2023 00:01:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229587AbjE1OBi (ORCPT ); Sun, 28 May 2023 10:01:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229585AbjE1OBf (ORCPT ); Sun, 28 May 2023 10:01:35 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3075D8 for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=ueHrCm9ru1w4aRGbwNEd+G8hOxIoBkPGYE36QmlyGZU=; b=DRR2sF5gtL7CHDXS3q1v8gaYx2 pw7hnXAOxugajPGWZvMBqV9oDKbFzg0FJf416nkOJV/zxSjC1USgqVvtqgqIb+XqtCEcgC2o8MxX4 ZWCU+vvSTdRHayCva3ZAZFd5RCnuH+Pb1ziyn1eJ0Y3u/fgMvD8P7AkI3w9+x5vhItfEALwPfQGyC K73HNbHaEj1b9lOgBuA0Q4igESQESUV8rG0DODHYmWgRVaREYGkc9pNNZ7qKNP2k18JwtuXtFJXLL wWbXv0o7KGbLnsyqj91+m2KyNTl7pOFrrz/DszR6OiSP8wcptVWz/SsQqc8PafhIQROvV7dnpoc/k c3I7XGiA==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-7h; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 2/8] netlink_delinearize: refactor stmt_payload_binop_postprocess Date: Sun, 28 May 2023 15:00:52 +0100 Message-Id: <20230528140058.1218669-3-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org We are about to add support for a new payload binop that needs to be post-processed, so move the contents of the two major cases (I and II) into separate functions to keep the function size reasonable. Fix a typo in a comment while we're at it. Signed-off-by: Jeremy Sowden --- src/netlink_delinearize.c | 193 +++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 84 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index bdd3242bf5ec..d729fb85a3ed 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -3112,6 +3112,110 @@ static void stmt_payload_binop_pp(struct rule_pp_ctx *ctx, struct expr *binop) } } +static bool stmt_payload_binop_postprocess_i(struct rule_pp_ctx *ctx) +{ + struct expr *expr, *binop, *payload, *value, *mask; + struct stmt *stmt = ctx->stmt; + mpz_t tmp, bitmask; + + expr = stmt->payload.val; + + if (expr->op != OP_OR) + return false; + + value = expr->right; + if (value->etype != EXPR_VALUE) + return false; + + binop = expr->left; + if (binop->op != OP_AND) + return false; + + payload = binop->left; + if (payload->etype != EXPR_PAYLOAD) + return false; + + if (!payload_expr_cmp(stmt->payload.expr, payload)) + return false; + + mask = binop->right; + if (mask->etype != EXPR_VALUE) + return false; + + mpz_init(tmp); + mpz_set(tmp, mask->value); + + mpz_init_bitmask(bitmask, payload->len); + mpz_xor(bitmask, bitmask, mask->value); + mpz_xor(bitmask, bitmask, value->value); + mpz_set(mask->value, bitmask); + mpz_clear(bitmask); + + binop_postprocess(ctx, expr, &expr->left); + if (!payload_is_known(payload)) + mpz_set(mask->value, tmp); + else { + expr_free(stmt->payload.expr); + stmt->payload.expr = expr_get(payload); + stmt->payload.val = expr_get(expr->right); + expr_free(expr); + } + + mpz_clear(tmp); + + return true; +} + +static bool stmt_payload_binop_postprocess_ii(struct rule_pp_ctx *ctx) +{ + struct expr *expr, *payload, *value; + struct stmt *stmt = ctx->stmt; + mpz_t bitmask; + + expr = stmt->payload.val; + + value = expr->right; + if (value->etype != EXPR_VALUE) + return false; + + switch (expr->op) { + case OP_AND: /* IIa */ + payload = expr->left; + mpz_init_bitmask(bitmask, payload->len); + mpz_xor(bitmask, bitmask, value->value); + mpz_set(value->value, bitmask); + mpz_clear(bitmask); + break; + case OP_OR: /* IIb */ + break; + default: /* No idea */ + return false; + } + + stmt_payload_binop_pp(ctx, expr); + if (!payload_is_known(expr->left)) + return false; + + expr_free(stmt->payload.expr); + + switch (expr->op) { + case OP_AND: + /* Mask was used to match payload, i.e. + * user asked to set zero value. + */ + mpz_set_ui(value->value, 0); + break; + default: + break; + } + + stmt->payload.expr = expr_get(expr->left); + stmt->payload.val = expr_get(expr->right); + expr_free(expr); + + return true; +} + /** * stmt_payload_binop_postprocess - decode payload set binop * @@ -3128,7 +3232,7 @@ static void stmt_payload_binop_pp(struct rule_pp_ctx *ctx, struct expr *binop) * a binop expression with a munged payload expression on the left * and a mask to clear the real payload offset/length. * - * So chech if we have one of the following binops: + * So check if we have one of the following binops: * I) * binop (|) * binop(&) value/set @@ -3156,9 +3260,8 @@ static void stmt_payload_binop_pp(struct rule_pp_ctx *ctx, struct expr *binop) */ static void stmt_payload_binop_postprocess(struct rule_pp_ctx *ctx) { - struct expr *expr, *binop, *payload, *value, *mask; + struct expr *expr; struct stmt *stmt = ctx->stmt; - mpz_t bitmask; expr = stmt->payload.val; @@ -3166,93 +3269,15 @@ static void stmt_payload_binop_postprocess(struct rule_pp_ctx *ctx) return; switch (expr->left->etype) { - case EXPR_BINOP: {/* I? */ - mpz_t tmp; - - if (expr->op != OP_OR) - return; - - value = expr->right; - if (value->etype != EXPR_VALUE) - return; - - binop = expr->left; - if (binop->op != OP_AND) - return; - - payload = binop->left; - if (payload->etype != EXPR_PAYLOAD) - return; - - if (!payload_expr_cmp(stmt->payload.expr, payload)) - return; - - mask = binop->right; - if (mask->etype != EXPR_VALUE) - return; - - mpz_init(tmp); - mpz_set(tmp, mask->value); - - mpz_init_bitmask(bitmask, payload->len); - mpz_xor(bitmask, bitmask, mask->value); - mpz_xor(bitmask, bitmask, value->value); - mpz_set(mask->value, bitmask); - mpz_clear(bitmask); - - binop_postprocess(ctx, expr, &expr->left); - if (!payload_is_known(payload)) { - mpz_set(mask->value, tmp); - mpz_clear(tmp); + case EXPR_BINOP: /* I? */ + if (stmt_payload_binop_postprocess_i(ctx)) return; - } - mpz_clear(tmp); - expr_free(stmt->payload.expr); - stmt->payload.expr = expr_get(payload); - stmt->payload.val = expr_get(expr->right); - expr_free(expr); break; - } case EXPR_PAYLOAD: /* II? */ - value = expr->right; - if (value->etype != EXPR_VALUE) - return; - - switch (expr->op) { - case OP_AND: /* IIa */ - payload = expr->left; - mpz_init_bitmask(bitmask, payload->len); - mpz_xor(bitmask, bitmask, value->value); - mpz_set(value->value, bitmask); - mpz_clear(bitmask); - break; - case OP_OR: /* IIb */ - break; - default: /* No idea */ - return; - } - - stmt_payload_binop_pp(ctx, expr); - if (!payload_is_known(expr->left)) + if (stmt_payload_binop_postprocess_ii(ctx)) return; - expr_free(stmt->payload.expr); - - switch (expr->op) { - case OP_AND: - /* Mask was used to match payload, i.e. - * user asked to set zero value. - */ - mpz_set_ui(value->value, 0); - break; - default: - break; - } - - stmt->payload.expr = expr_get(expr->left); - stmt->payload.val = expr_get(expr->right); - expr_free(expr); break; default: /* No idea */ break; From patchwork Sun May 28 14:00:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786848 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=rTed2Ag4; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLq4vX3z20Pc for ; Mon, 29 May 2023 00:01:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229492AbjE1OBg (ORCPT ); Sun, 28 May 2023 10:01:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229510AbjE1OBe (ORCPT ); Sun, 28 May 2023 10:01:34 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91A9DBE for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=b9hQOEhXXcYfqfFFLTfwt5uzr9cPzLp69WgTS0CdMHA=; b=rTed2Ag4LUmC7R/Y32LrD95z3c qIpBochAs1VuD/gF75HQ4nOMSgcDxpirzrcOfvsnJklxdAyRCwc7HAjmYBODNwQ3U/9rvFFPbLxbH RoYiTLNoiXmbUnakunnP1OfGXUmTksPKkN34EtEh+oRxBLFwxSgoNhYQcLmo0C9p6Zi27sAArI1GG HZVyCSbfar9ZMxHI5vlfd3mZa+rdxjkDbphCboWD7rhH3V7BRZejVa3qEBnqFzlB/0qr37EcWOY9Z 7YFKRTA9sfjTRll+0io8KvsHt8LtBtcBgOAP7DbzxAYpkVRloSN8skwJ47i38KyhunmaVJ0mCsuV4 haldRDHg==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-9U; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 3/8] netlink_delinearize: add support for processing variable payload statement arguments Date: Sun, 28 May 2023 15:00:53 +0100 Message-Id: <20230528140058.1218669-4-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org If a user uses a variable payload expression in a payload statement, the structure of the statement value is not handled by the existing statement postprocessing function, so we need to extend it. Signed-off-by: Jeremy Sowden --- src/netlink_delinearize.c | 86 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index d729fb85a3ed..b36440e7c106 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -3112,7 +3112,7 @@ static void stmt_payload_binop_pp(struct rule_pp_ctx *ctx, struct expr *binop) } } -static bool stmt_payload_binop_postprocess_i(struct rule_pp_ctx *ctx) +static bool stmt_payload_binop_postprocess_i_a(struct rule_pp_ctx *ctx) { struct expr *expr, *binop, *payload, *value, *mask; struct stmt *stmt = ctx->stmt; @@ -3166,6 +3166,68 @@ static bool stmt_payload_binop_postprocess_i(struct rule_pp_ctx *ctx) return true; } +static bool stmt_payload_binop_postprocess_i_b(struct rule_pp_ctx *ctx) +{ + struct dl_proto_ctx *dl = dl_proto_ctx(ctx); + struct expr *expr, *payload, *mask, *xor; + struct stmt *stmt = ctx->stmt; + unsigned int shift; + mpz_t tmp, bitmask; + + expr = stmt->payload.val; + + if (expr->op != OP_XOR) + return false; + + if (expr->left->etype != EXPR_BINOP) + return false; + + if (expr->left->op != OP_AND) + return false; + + if (expr->right->etype == EXPR_UNARY) { + /* + * If the payload value was originally in a different byte-order + * from the payload expression, there will be a byte-order + * conversion to remove. + */ + xor = expr_get(expr->right->arg); + expr_free(expr->right); + expr->right = xor; + } else + xor = expr->right; + + mask = expr->left->right; + payload = expr->left->left; + + mpz_init(tmp); + mpz_set(tmp, mask->value); + + mpz_init_bitmask(bitmask, payload->len); + mpz_xor(bitmask, bitmask, mask->value); + mpz_set(mask->value, bitmask); + mpz_clear(bitmask); + + if (payload_expr_trim(payload, mask, &dl->pctx, &shift)) + payload_match_postprocess(ctx, expr->left, payload); + + if (!payload_is_known(payload)) { + mpz_set(mask->value, tmp); + } else { + if (shift) { + expr->right = expr_get(xor->left); + expr_free(xor); + } + expr_free(stmt->payload.expr); + stmt->payload.expr = expr_get(payload); + stmt->payload.val = expr_get(expr->right); + expr_free(expr); + } + + mpz_clear(tmp); + return true; +} + static bool stmt_payload_binop_postprocess_ii(struct rule_pp_ctx *ctx) { struct expr *expr, *payload, *value; @@ -3233,21 +3295,30 @@ static bool stmt_payload_binop_postprocess_ii(struct rule_pp_ctx *ctx) * and a mask to clear the real payload offset/length. * * So check if we have one of the following binops: - * I) + * + * Ia) * binop (|) * binop(&) value/set * payload value(mask) * - * This is the normal case, the | RHS is the value the user wants - * to set, the & RHS is the mask value that discards bits we need + * This is the normal constant case, the | RHS is the value the user + * wants to set, the & RHS is the mask value that discards bits we need * to clear but retains everything unrelated to the set operation. * + * Ib) + * binop (^) + * binop(&) value/set + * payload value(mask) + * + * The user wants to set a variable payload argument. The ^ RHS is the + * variable expression. The mask is as above. + * * IIa) * binop (&) * payload mask * * User specified a zero set value -- netlink bitwise decoding - * discarded the redundant "| 0" part. This is identical to I), + * discarded the redundant "| 0" part. This is identical to Ia), * we can just set value to 0 after we inferred the real payload size. * * IIb) @@ -3270,7 +3341,10 @@ static void stmt_payload_binop_postprocess(struct rule_pp_ctx *ctx) switch (expr->left->etype) { case EXPR_BINOP: /* I? */ - if (stmt_payload_binop_postprocess_i(ctx)) + if (stmt_payload_binop_postprocess_i_a(ctx)) + return; + + if (stmt_payload_binop_postprocess_i_b(ctx)) return; break; From patchwork Sun May 28 14:00:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786847 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=NV5gTTXJ; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLq1XFGz20Q8 for ; Mon, 29 May 2023 00:01:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229450AbjE1OBf (ORCPT ); Sun, 28 May 2023 10:01:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229492AbjE1OBe (ORCPT ); Sun, 28 May 2023 10:01:34 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91BB0C7 for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=ExHsRPHi8lRmIoEB6mUVHiBdbgkNAGYrJIqfPkOmyC0=; b=NV5gTTXJbqc0RsO76KKJYio0IY 7oQWlaM1Mibcq6ab6I10SRrxXRvQweBeh8a7Qg7iXaJAFBN/3tV4jM58itnXwCoMKoIDbwmTAml/k UEvUb5Gf2mgSWlyHwMcL++u/NjiaeA18bVJDOPYbsht8eHBFx9UBOZxKetN0ghV07EtDd/Vw/S0TQ gxOP4dG/UD7xpULjWWUx68slg/ZC0UU+InoLwjNXK5Jd95JtZk1i/rqtODtOhxNbT+gZp6Vr85Dvu Od40hz9vw8dfiOt0wmamH/CotNHVWJkSU9POjV3hu0BAxr2NDup3W3jGO44HVi3eEHCrwsoNyXgCM ymAmKRTw==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-BI; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 4/8] evaluate: prevent nested byte-order conversions Date: Sun, 28 May 2023 15:00:54 +0100 Message-Id: <20230528140058.1218669-5-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org There is a an assertion in `expr_evaluate_unary` that checks that the operand of the unary operation is not itself a unary expression. Add a check to `byteorder_conversion` to ensure that this is the case by removing an existing unary operation, rather than adding a second one. Signed-off-by: Jeremy Sowden --- src/evaluate.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/evaluate.c b/src/evaluate.c index 17a437bd6530..77781f0ec6de 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -195,7 +195,12 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr, if (expr_is_constant(*expr) || div_round_up((*expr)->len, BITS_PER_BYTE) < 2) (*expr)->byteorder = byteorder; - else { + else if ((*expr)->etype == EXPR_UNARY) { + /* Remove existing conversion */ + struct expr *unary = *expr; + *expr = expr_get((*expr)->arg); + expr_free(unary); + } else { op = byteorder_conversion_op(*expr, byteorder); *expr = unary_expr_alloc(&(*expr)->location, op, *expr); if (expr_evaluate(ctx, expr) < 0) From patchwork Sun May 28 14:00:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786849 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=HsMGKdU4; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLr0sg8z20Q8 for ; Mon, 29 May 2023 00:01:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229596AbjE1OBh (ORCPT ); Sun, 28 May 2023 10:01:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229551AbjE1OBe (ORCPT ); Sun, 28 May 2023 10:01:34 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A282BCF for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=/cvai6cbsVzloqQxr6zIxMWMSjb7kobvQEcBmhQRxUU=; b=HsMGKdU4A/x2XO2RcB6VfY/3gG sHOU0Z00l6VNRCwAmZbdkd38uY2eom8sxz4y2HTkUA+a5dIlgf2TTtLYmLdttJbKmFql/degZBm57 sX5iW7OkThRUZbZAB3au20ULdcWh6E14uASpRfPhDngor58KlCLrtkeraA4jcFR+41stcwmwMe0NO hAa0qKnCDTiPkGivUYqcbzIb92TPK0IvXQvbUm5IXN9Xvf1ZWipHhp0PZ9pV0YABp6+nNnHXcWCQt JPh4D8UMFSDxLXYrSX1ITAWf+8ac1Qa0cWpcfC169jYiIo3pvYlmB8Gv/fi/Kyzu/N7G/Ld68iHU+ E4/GQmoA==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-D4; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 5/8] evaluate: preserve existing binop properties Date: Sun, 28 May 2023 15:00:55 +0100 Message-Id: <20230528140058.1218669-6-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org In certain cases, such as evaluating payload statement arguments, we allocate new binop expressions and set properties such as length, data-type and byte-order. When the new expressions are themselves evaluated, these properties are overridden. Since the length of expression is set in all cases, check for this and preserve the length, data-type and byte-order for bitwise op's and the length for shifts. Remove a couple of superfluous assignments for a left-shift which were being correctly overridden. Signed-off-by: Jeremy Sowden --- src/evaluate.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/evaluate.c b/src/evaluate.c index 77781f0ec6de..136b4539e828 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1301,7 +1301,9 @@ static int expr_evaluate_shift(struct eval_ctx *ctx, struct expr **expr) unsigned int shift = mpz_get_uint32(right->value); unsigned int max_shift_len; - if (ctx->stmt_len > left->len) + if (op->len) + max_shift_len = op->len; + else if (ctx->stmt_len > left->len) max_shift_len = ctx->stmt_len; else max_shift_len = left->len; @@ -1335,7 +1337,16 @@ static int expr_evaluate_bitwise(struct eval_ctx *ctx, struct expr **expr) unsigned int max_len; int byteorder; - if (ctx->stmt_len > left->len) { + if (op->len) { + max_len = op->len; + byteorder = op->byteorder; + dtype = op->dtype; + + if (byteorder_conversion(ctx, &op->left, byteorder) < 0) + return -1; + + left = op->left; + } else if (ctx->stmt_len > left->len) { max_len = ctx->stmt_len; byteorder = BYTEORDER_HOST_ENDIAN; dtype = &integer_type; @@ -2962,8 +2973,6 @@ static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt) lshift = binop_expr_alloc(&payload->location, OP_LSHIFT, stmt->payload.val, off); - lshift->dtype = payload->dtype; - lshift->byteorder = payload->byteorder; stmt->payload.val = lshift; } From patchwork Sun May 28 14:00:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786852 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=iq16ZO9v; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLs3Kz1z20Pc for ; Mon, 29 May 2023 00:01:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229478AbjE1OBj (ORCPT ); Sun, 28 May 2023 10:01:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229589AbjE1OBf (ORCPT ); Sun, 28 May 2023 10:01:35 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C024BD9 for ; Sun, 28 May 2023 07:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Af6orlwf3TxdD+VuimQzl7U9OKtjkotPFDgchLIjpfI=; b=iq16ZO9vLQ3EbwaEu9ianLTtTU jkESS0FUTwykTRO1b2LU9cXrPd/pIRCxQgUtFrU10uIwAKUTwvlLamhCuvE0ljHbsAmo/Q1hVGF2/ qQU1mCLlsy1SxPd1CTlxPAbl4XdT0D6y/gKWGH4rAqnJ2bJXW9XEbs1XK/KurgvBseu4ZwT3xbe48 VfazUUeQJq5GCfWI9YSl2WheAYIygLoNmJKBB9rYZufHdttIgJs4DhQ8FE/U4fSSt5QHXFm33WnCF zEGEF5CODS8dTNXUg0jcgLQ8FUZ6AodLPMQP6KS06hFhQorN+iHEhpdGqNG250yGdXYRrcQiJO/7g 9R//92SA==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-Eq; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 6/8] evaluate: allow binop expressions with variable right-hand operands Date: Sun, 28 May 2023 15:00:56 +0100 Message-Id: <20230528140058.1218669-7-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Hitherto, the kernel has required constant values for the `xor` and `mask` attributes of boolean bitwise expressions. This has meant that the right-hand operand of a boolean binop must be constant. Now the kernel has support for AND, OR and XOR operations with right-hand operands passed via registers, we can relax this restriction. Allow non-constant right-hand operands if the left-hand operand is not constant, e.g.: ct mark & 0xffff0000 | meta mark & 0xffff Signed-off-by: Jeremy Sowden --- src/evaluate.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/evaluate.c b/src/evaluate.c index 136b4539e828..c98bd578f38b 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1369,16 +1369,18 @@ static int expr_evaluate_bitwise(struct eval_ctx *ctx, struct expr **expr) op->byteorder = byteorder; op->len = max_len; - if (expr_is_constant(left)) + if (expr_is_constant(left) && expr_is_constant(op->right)) return constant_binop_simplify(ctx, expr); return 0; } /* - * Binop expression: both sides must be of integer base type. The left - * hand side may be either constant or non-constant; in case its constant - * it must be a singleton. The ride hand side must always be a constant - * singleton. + * Binop expression: both sides must be of integer base type. The left-hand side + * may be either constant or non-constant; if it is constant, it must be a + * singleton. For bitwise operations, the right-hand side must be constant if + * the left-hand side is constant; the right-hand side may be constant or + * non-constant, if the left-hand side is non-constant; for shifts, the + * right-hand side must be constant; if it is constant, it must be a singleton. */ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr) { @@ -1419,27 +1421,36 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr) "for %s expressions", sym, expr_name(left)); - if (!expr_is_constant(right)) - return expr_binary_error(ctx->msgs, right, op, - "Right hand side of binary operation " - "(%s) must be constant", sym); - - if (!expr_is_singleton(right)) - return expr_binary_error(ctx->msgs, left, op, - "Binary operation (%s) is undefined " - "for %s expressions", - sym, expr_name(right)); - /* The grammar guarantees this */ assert(datatype_equal(expr_basetype(left), expr_basetype(right))); switch (op->op) { case OP_LSHIFT: case OP_RSHIFT: + if (!expr_is_constant(right)) + return expr_binary_error(ctx->msgs, right, op, + "Right hand side of binary operation " + "(%s) must be constant", sym); + + if (!expr_is_singleton(right)) + return expr_binary_error(ctx->msgs, left, op, + "Binary operation (%s) is undefined " + "for %s expressions", + sym, expr_name(right)); return expr_evaluate_shift(ctx, expr); case OP_AND: case OP_XOR: case OP_OR: + if (expr_is_constant(left) && !expr_is_constant(right)) + return expr_binary_error(ctx->msgs, right, op, + "Right hand side of binary operation " + "(%s) must be constant", sym); + + if (expr_is_constant(right) && !expr_is_singleton(right)) + return expr_binary_error(ctx->msgs, left, op, + "Binary operation (%s) is undefined " + "for %s expressions", + sym, expr_name(right)); return expr_evaluate_bitwise(ctx, expr); default: BUG("invalid binary operation %u\n", op->op); From patchwork Sun May 28 14:00:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=mKSoooXS; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLr3xLwz20Pc for ; Mon, 29 May 2023 00:01:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229551AbjE1OBi (ORCPT ); Sun, 28 May 2023 10:01:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbjE1OBf (ORCPT ); Sun, 28 May 2023 10:01:35 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1DF3DC for ; Sun, 28 May 2023 07:01:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=8DlbrMbCJacsHewu+hV6NLyfV8LWfuNyvK8qvCEvcOw=; b=mKSoooXSFFk7t6PDj7+vfUWPmH eAG1PjzljdRCI9JVmWRwETNNHGPpoMv+4uGUm3OpGgtlhNIjAKAYwyyxmipz+1R5EP2lzB5//xYvo DnQgGaZI7p32vjidg5etViQRfaSNMYFl6cvY/M0G/NGfm1HHib9TNJjVfFryy6lWt9OqZzdDmtiWT 2I+Ghuaat4gN1zLV41530L/GeBohlIKKsPeXOGN2n6Q9G8La+FRj/OtJeuRw5t4fB1yugyt7YddiA mwFXHJJxVdT1XqYb/pSbORJSVer78DgxjgPWV/inJyMHp7YRIsonSiTe2/NU2MZhoYj9FtX9jwTY8 9gVJ4pfg==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-Gb; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 7/8] parser_json: allow RHS mark and payload expressions Date: Sun, 28 May 2023 15:00:57 +0100 Message-Id: <20230528140058.1218669-8-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Support for binops with variable RHS's will make it possible to have ct and meta mark and payload expressions in the RHS. Relax the JSON parser accordingly. Fix a typo in an adjacent comment. Signed-off-by: Jeremy Sowden --- src/parser_json.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index ad31b4e0365f..c6abd42f8ebb 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1454,20 +1454,20 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "concat", json_parse_concat_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_DTYPE | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, { "set", json_parse_set_expr, CTX_F_RHS | CTX_F_STMT }, /* allow this as stmt expr because that allows set references */ { "map", json_parse_map_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS }, - /* below three are multiton_rhs_expr */ + /* below two are multiton_rhs_expr */ { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_SET_RHS | CTX_F_STMT | CTX_F_CONCAT }, { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_SET_RHS | CTX_F_STMT | CTX_F_CONCAT }, - { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, + { "payload", json_parse_payload_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, { "ip option", json_parse_ip_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, { "sctp chunk", json_parse_sctp_chunk_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, - { "meta", json_parse_meta_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, + { "meta", json_parse_meta_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "osf", json_parse_osf_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT }, { "ipsec", json_parse_xfrm_expr, CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT }, { "socket", json_parse_socket_expr, CTX_F_PRIMARY | CTX_F_CONCAT }, { "rt", json_parse_rt_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "ct", json_parse_ct_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, + { "ct", json_parse_ct_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "numgen", json_parse_numgen_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, /* below two are hash expr */ { "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, From patchwork Sun May 28 14:00:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Sowden X-Patchwork-Id: 1786854 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=azazel.net header.i=@azazel.net header.a=rsa-sha256 header.s=20220717 header.b=KuVGVdKE; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QTgLt6CFYz20Pc for ; Mon, 29 May 2023 00:01:42 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229585AbjE1OBl (ORCPT ); Sun, 28 May 2023 10:01:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229510AbjE1OBh (ORCPT ); Sun, 28 May 2023 10:01:37 -0400 Received: from taras.nevrast.org (unknown [IPv6:2a05:d01c:431:aa03:b7e1:333d:ea2a:b14e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0D91D2 for ; Sun, 28 May 2023 07:01:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=azazel.net; s=20220717; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=oGUzbso3ffeyjvDwqnniDOJJueWvCPEUxRk6dECgDmE=; b=KuVGVdKEt0J/I7BVAAqe0xtlLb zKapiOZypsitUcLef1P8AemWonNR2pSEe3Jpu+5V6wAzj1p56zXVNz7Y0TYe5QaWSArcgXT8KdG7Y Hcqn/PjT/1ey9UzncMVJwX855yrmPf8GNXtyyvJOOAWzkNZ6n/DA3uoe2xNCYFhQrJfmwB2rbo+8C oEzMFMgV7o2ABgr1ADB3IqJ7QkpAAqHGwztUMpvo672Lz9feRmA752CECZSHv2ygCUtYCe9GR0HDz z32rXnVazns559VR1uv8THOzsrmHsmM2XC/17etnlMYO4F79XyEpbfoP6zXtnWjfuhuJ87AaefBMx YRPPn0sQ==; Received: from [2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608] (helo=ulthar.dreamlands) by taras.nevrast.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1q3Gxe-008Xe1-IX; Sun, 28 May 2023 15:01:30 +0100 From: Jeremy Sowden To: Netfilter Devel Cc: Kevin Darbyshire-Bryant Subject: [PATCH nft v5 8/8] tests: add tests for binops with variable RHS operands Date: Sun, 28 May 2023 15:00:58 +0100 Message-Id: <20230528140058.1218669-9-jeremy@azazel.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230528140058.1218669-1-jeremy@azazel.net> References: <20230528140058.1218669-1-jeremy@azazel.net> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:8b0:135f:bcd1:e0cb:4eff:fedf:e608 X-SA-Exim-Mail-From: jeremy@azazel.net X-SA-Exim-Scanned: No (on taras.nevrast.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_FAIL, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add tests to validate setting marks and payloads with statement arguments that include binops with variable RHS operands. Signed-off-by: Jeremy Sowden --- tests/py/any/ct.t | 1 + tests/py/any/ct.t.json | 37 +++++++++ tests/py/any/ct.t.payload | 9 +++ tests/py/inet/meta.t | 2 + tests/py/inet/meta.t.json | 37 +++++++++ tests/py/inet/meta.t.payload | 9 +++ tests/py/ip/ct.t | 1 + tests/py/ip/ct.t.json | 36 +++++++++ tests/py/ip/ct.t.payload | 11 +++ tests/py/ip/ip.t | 2 + tests/py/ip/ip.t.json | 77 ++++++++++++++++++- tests/py/ip/ip.t.payload | 28 +++++++ tests/py/ip/ip.t.payload.bridge | 32 ++++++++ tests/py/ip/ip.t.payload.inet | 32 ++++++++ tests/py/ip/ip.t.payload.netdev | 32 ++++++++ tests/py/ip6/ct.t | 1 + tests/py/ip6/ct.t.json | 36 +++++++++ tests/py/ip6/ct.t.payload | 12 +++ tests/py/ip6/ip6.t | 2 + tests/py/ip6/ip6.t.json | 76 ++++++++++++++++++ tests/py/ip6/ip6.t.payload.inet | 36 +++++++++ tests/py/ip6/ip6.t.payload.ip6 | 32 ++++++++ .../shell/testcases/bitwise/0040mark_binop_10 | 11 +++ .../shell/testcases/bitwise/0040mark_binop_11 | 11 +++ .../shell/testcases/bitwise/0040mark_binop_12 | 11 +++ .../shell/testcases/bitwise/0040mark_binop_13 | 11 +++ .../testcases/bitwise/0044payload_binop_0 | 11 +++ .../testcases/bitwise/0044payload_binop_1 | 11 +++ .../testcases/bitwise/0044payload_binop_2 | 11 +++ .../testcases/bitwise/0044payload_binop_3 | 11 +++ .../testcases/bitwise/0044payload_binop_4 | 11 +++ .../testcases/bitwise/0044payload_binop_5 | 11 +++ .../bitwise/dumps/0040mark_binop_10.nft | 6 ++ .../bitwise/dumps/0040mark_binop_11.nft | 6 ++ .../bitwise/dumps/0040mark_binop_12.nft | 6 ++ .../bitwise/dumps/0040mark_binop_13.nft | 6 ++ .../bitwise/dumps/0044payload_binop_0.nft | 6 ++ .../bitwise/dumps/0044payload_binop_1.nft | 6 ++ .../bitwise/dumps/0044payload_binop_2.nft | 6 ++ .../bitwise/dumps/0044payload_binop_3.nft | 6 ++ .../bitwise/dumps/0044payload_binop_4.nft | 6 ++ .../bitwise/dumps/0044payload_binop_5.nft | 6 ++ 42 files changed, 710 insertions(+), 1 deletion(-) create mode 100755 tests/shell/testcases/bitwise/0040mark_binop_10 create mode 100755 tests/shell/testcases/bitwise/0040mark_binop_11 create mode 100755 tests/shell/testcases/bitwise/0040mark_binop_12 create mode 100755 tests/shell/testcases/bitwise/0040mark_binop_13 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_0 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_1 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_2 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_3 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_4 create mode 100755 tests/shell/testcases/bitwise/0044payload_binop_5 create mode 100644 tests/shell/testcases/bitwise/dumps/0040mark_binop_10.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0040mark_binop_11.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0040mark_binop_12.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0040mark_binop_13.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_0.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_1.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_2.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_3.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_4.nft create mode 100644 tests/shell/testcases/bitwise/dumps/0044payload_binop_5.nft diff --git a/tests/py/any/ct.t b/tests/py/any/ct.t index f73fa4e7aedb..3e0e473f55b7 100644 --- a/tests/py/any/ct.t +++ b/tests/py/any/ct.t @@ -61,6 +61,7 @@ ct mark set 0x11;ok;ct mark set 0x00000011 ct mark set mark;ok;ct mark set meta mark ct mark set (meta mark | 0x10) << 8;ok;ct mark set (meta mark | 0x00000010) << 8 ct mark set mark map { 1 : 10, 2 : 20, 3 : 30 };ok;ct mark set meta mark map { 0x00000003 : 0x0000001e, 0x00000002 : 0x00000014, 0x00000001 : 0x0000000a} +ct mark set ct mark and 0xffff0000 or meta mark and 0xffff;ok;ct mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff ct mark set {0x11333, 0x11};fail ct zone set {123, 127};fail diff --git a/tests/py/any/ct.t.json b/tests/py/any/ct.t.json index a2a06025992c..4d6043190201 100644 --- a/tests/py/any/ct.t.json +++ b/tests/py/any/ct.t.json @@ -817,6 +817,43 @@ } ] +# ct mark set ct mark and 0xffff0000 or meta mark and 0xffff +[ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": { + "|": [ + { + "&": [ + { + "ct": { + "key": "mark" + } + }, + 4294901760 + ] + }, + { + "&": [ + { + "meta": { + "key": "mark" + } + }, + 65535 + ] + } + ] + } + } + } +] + # ct expiration 30s [ { diff --git a/tests/py/any/ct.t.payload b/tests/py/any/ct.t.payload index ed868e53277d..1523e54d1307 100644 --- a/tests/py/any/ct.t.payload +++ b/tests/py/any/ct.t.payload @@ -336,6 +336,15 @@ ip test-ip4 output [ lookup reg 1 set __map%d dreg 1 ] [ ct set mark with reg 1 ] +# ct mark set ct mark and 0xffff0000 or meta mark and 0xffff +ip + [ ct load mark => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xffff0000 ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x0000ffff ) ^ 0x00000000 ] + [ bitwise reg 1 = ( reg 1 | reg 2 ) ] + [ ct set mark with reg 1 ] + # ct original bytes > 100000 ip test-ip4 output [ ct load bytes => reg 1 , dir original ] diff --git a/tests/py/inet/meta.t b/tests/py/inet/meta.t index 374738a701d6..1e582161caa1 100644 --- a/tests/py/inet/meta.t +++ b/tests/py/inet/meta.t @@ -25,3 +25,5 @@ meta mark set ct mark >> 8;ok meta mark . tcp dport { 0x0000000a-0x00000014 . 80-90, 0x00100000-0x00100123 . 100-120 };ok ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 1.2.3.6-1.2.3.8 . 0x00000200-0x00000300 };ok ip saddr . meta mark { 1.2.3.4 . 0x00000100 , 5.6.7.8 . 0x00000200 };ok + +meta mark set ct mark and 0xffff0000 or meta mark and 0xffff;ok;meta mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff diff --git a/tests/py/inet/meta.t.json b/tests/py/inet/meta.t.json index 92a1f9bff373..3b50efd646ad 100644 --- a/tests/py/inet/meta.t.json +++ b/tests/py/inet/meta.t.json @@ -236,6 +236,43 @@ } ] +# meta mark set ct mark and 0xffff0000 or meta mark and 0xffff +[ + { + "mangle": { + "key": { + "meta": { + "key": "mark" + } + }, + "value": { + "|": [ + { + "&": [ + { + "ct": { + "key": "mark" + } + }, + 4294901760 + ] + }, + { + "&": [ + { + "meta": { + "key": "mark" + } + }, + 65535 + ] + } + ] + } + } + } +] + # meta protocol ip udp dport 67 [ { diff --git a/tests/py/inet/meta.t.payload b/tests/py/inet/meta.t.payload index ea54090727fa..8dc1a7e7d151 100644 --- a/tests/py/inet/meta.t.payload +++ b/tests/py/inet/meta.t.payload @@ -80,6 +80,15 @@ inet test-inet input [ bitwise reg 1 = ( reg 1 >> 0x00000008 ) ] [ meta set mark with reg 1 ] +# meta mark set ct mark and 0xffff0000 or meta mark and 0xffff +inet test-inet input + [ ct load mark => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xffff0000 ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x0000ffff ) ^ 0x00000000 ] + [ bitwise reg 1 = ( reg 1 | reg 2 ) ] + [ meta set mark with reg 1 ] + # meta protocol ip udp dport 67 inet test-inet input [ meta load protocol => reg 1 ] diff --git a/tests/py/ip/ct.t b/tests/py/ip/ct.t index a0a222893dd0..8f62c00d134f 100644 --- a/tests/py/ip/ct.t +++ b/tests/py/ip/ct.t @@ -34,3 +34,4 @@ ct mark set ip dscp & 0x0f << 1;ok;ct mark set ip dscp & af33 ct mark set ip dscp & 0x0f << 2;ok;ct mark set ip dscp & 0x3c ct mark set ip dscp | 0x04;ok ct mark set ip dscp | 1 << 20;ok;ct mark set ip dscp | 0x100000 +ct mark set ct mark | ip dscp | 0x200 counter;ok;ct mark set ct mark | ip dscp | 0x00000200 counter diff --git a/tests/py/ip/ct.t.json b/tests/py/ip/ct.t.json index 915632aef076..0287d2dc44b0 100644 --- a/tests/py/ip/ct.t.json +++ b/tests/py/ip/ct.t.json @@ -479,3 +479,39 @@ } } ] + +# ct mark set ct mark | ip dscp | 0x200 counter +[ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": { + "|": [ + { + "|": [ + { + "ct": { + "key": "mark" + } + }, + { + "payload": { + "field": "dscp", + "protocol": "ip" + } + } + ] + }, + 512 + ] + } + } + }, + { + "counter": null + } +] diff --git a/tests/py/ip/ct.t.payload b/tests/py/ip/ct.t.payload index 692011d0f860..823de5974228 100644 --- a/tests/py/ip/ct.t.payload +++ b/tests/py/ip/ct.t.payload @@ -134,3 +134,14 @@ ip test-ip4 output [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ] [ bitwise reg 1 = ( reg 1 & 0xffefffff ) ^ 0x00100000 ] [ ct set mark with reg 1 ] + +# ct mark set ct mark | ip dscp | 0x200 counter +ip test-ip4 output + [ ct load mark => reg 1 ] + [ payload load 1b @ network header + 1 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x000000fc ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000002 ) ] + [ bitwise reg 1 = ( reg 1 | reg 2 ) ] + [ bitwise reg 1 = ( reg 1 & 0xfffffdff ) ^ 0x00000200 ] + [ ct set mark with reg 1 ] + [ counter pkts 0 bytes 0 ] diff --git a/tests/py/ip/ip.t b/tests/py/ip/ip.t index d5a4d8a5e46e..6ef1be3a8ddb 100644 --- a/tests/py/ip/ip.t +++ b/tests/py/ip/ip.t @@ -124,6 +124,8 @@ iif "lo" ip protocol set 1;ok iif "lo" ip dscp set af23;ok iif "lo" ip dscp set cs0;ok +iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26;ok +iif "lo" ip dscp set ip dscp & 0xc;ok;iif "lo" ip dscp set ip dscp & af12 ip saddr . ip daddr { 192.0.2.1 . 10.0.0.1-10.0.0.2 };ok ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept };ok diff --git a/tests/py/ip/ip.t.json b/tests/py/ip/ip.t.json index b1085035a000..1adbf9323b7a 100644 --- a/tests/py/ip/ip.t.json +++ b/tests/py/ip/ip.t.json @@ -1596,6 +1596,82 @@ } ] +# iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26 +[ + { + "match": { + "left": { + "meta": { + "key": "iif" + } + }, + "op": "==", + "right": "lo" + } + }, + { + "mangle": { + "key": { + "payload": { + "field": "dscp", + "protocol": "ip" + } + }, + "value": { + ">>": [ + { + "&": [ + { + "meta": { + "key": "mark" + } + }, + 4227858432 + ] + }, + 26 + ] + } + } + } +] + +# iif "lo" ip dscp set ip dscp & 0xc +[ + { + "match": { + "left": { + "meta": { + "key": "iif" + } + }, + "op": "==", + "right": "lo" + } + }, + { + "mangle": { + "key": { + "payload": { + "field": "dscp", + "protocol": "ip" + } + }, + "value": { + "&": [ + { + "payload": { + "field": "dscp", + "protocol": "ip" + } + }, + "af12" + ] + } + } + } +] + # ip saddr . ip daddr { 192.0.2.1 . 10.0.0.1-10.0.0.2 } [ { @@ -1684,4 +1760,3 @@ } } ] - diff --git a/tests/py/ip/ip.t.payload b/tests/py/ip/ip.t.payload index b9fcb5158e9d..7e955d07ebc9 100644 --- a/tests/py/ip/ip.t.payload +++ b/tests/py/ip/ip.t.payload @@ -490,6 +490,34 @@ ip test-ip4 input [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] +# iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26 +ip test-ip4 input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + +# iif "lo" ip dscp set ip dscp & 0xc +ip test-ip4 input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ payload load 1b @ network header + 1 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x000000fc ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000002 ) ] + [ bitwise reg 2 = ( reg 2 & 0x0000000c ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + # iif "lo" ip ttl set 23 ip test-ip4 input [ meta load iif => reg 1 ] diff --git a/tests/py/ip/ip.t.payload.bridge b/tests/py/ip/ip.t.payload.bridge index c6f8d4e5575b..fd3603a68e9b 100644 --- a/tests/py/ip/ip.t.payload.bridge +++ b/tests/py/ip/ip.t.payload.bridge @@ -662,6 +662,38 @@ bridge test-bridge input [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] +# iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26 +bridge test-bridge input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + +# iif "lo" ip dscp set ip dscp & 0xc +bridge test-bridge input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ payload load 1b @ network header + 1 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x000000fc ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000002 ) ] + [ bitwise reg 2 = ( reg 2 & 0x0000000c ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + # ip saddr . ip daddr { 192.0.2.1 . 10.0.0.1-10.0.0.2 } __set%d test-bridge 87 size 1 __set%d test-bridge 0 diff --git a/tests/py/ip/ip.t.payload.inet b/tests/py/ip/ip.t.payload.inet index e26d0dac47be..7f92423ab051 100644 --- a/tests/py/ip/ip.t.payload.inet +++ b/tests/py/ip/ip.t.payload.inet @@ -642,6 +642,38 @@ inet test-inet input [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] +# iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26 +inet test-inet input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load nfproto => reg 1 ] + [ cmp eq reg 1 0x00000002 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + +# iif "lo" ip dscp set ip dscp & 0xc +inet test-inet input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load nfproto => reg 1 ] + [ cmp eq reg 1 0x00000002 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ payload load 1b @ network header + 1 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x000000fc ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000002 ) ] + [ bitwise reg 2 = ( reg 2 & 0x0000000c ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + # iif "lo" ip ttl set 23 inet test-inet input [ meta load iif => reg 1 ] diff --git a/tests/py/ip/ip.t.payload.netdev b/tests/py/ip/ip.t.payload.netdev index de990f5bba12..74fc696f31fe 100644 --- a/tests/py/ip/ip.t.payload.netdev +++ b/tests/py/ip/ip.t.payload.netdev @@ -642,6 +642,38 @@ netdev test-netdev ingress [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] +# iif "lo" ip dscp set (meta mark & 0xfc000000) >> 26 +netdev test-netdev ingress + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ meta load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + +# iif "lo" ip dscp set ip dscp & 0xc +netdev test-netdev ingress + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x000003ff ) ^ 0x00000000 ] + [ payload load 1b @ network header + 1 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x000000fc ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000002 ) ] + [ bitwise reg 2 = ( reg 2 & 0x0000000c ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 << 0x00000002 ) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ] + # iif "lo" ip ttl set 23 netdev test-netdev ingress [ meta load iif => reg 1 ] diff --git a/tests/py/ip6/ct.t b/tests/py/ip6/ct.t index c06fd6a0441d..1617c68b6da2 100644 --- a/tests/py/ip6/ct.t +++ b/tests/py/ip6/ct.t @@ -7,3 +7,4 @@ ct mark set ip6 dscp << 26 | 0x10;ok ct mark set ip6 dscp | 0x04;ok ct mark set ip6 dscp | 0xff000000;ok ct mark set ip6 dscp & 0x0f << 2;ok;ct mark set ip6 dscp & 0x3c +ct mark set ct mark | ip6 dscp | 0x200 counter;ok;ct mark set ct mark | ip6 dscp | 0x00000200 counter diff --git a/tests/py/ip6/ct.t.json b/tests/py/ip6/ct.t.json index 7d8c88bb09cb..9fbcdc9f36e1 100644 --- a/tests/py/ip6/ct.t.json +++ b/tests/py/ip6/ct.t.json @@ -291,3 +291,39 @@ } } ] + +# ct mark set ct mark | ip6 dscp | 0x200 counter +[ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": { + "|": [ + { + "|": [ + { + "ct": { + "key": "mark" + } + }, + { + "payload": { + "field": "dscp", + "protocol": "ip6" + } + } + ] + }, + 512 + ] + } + } + }, + { + "counter": null + } +] diff --git a/tests/py/ip6/ct.t.payload b/tests/py/ip6/ct.t.payload index 164149e93d17..fc54e5df0235 100644 --- a/tests/py/ip6/ct.t.payload +++ b/tests/py/ip6/ct.t.payload @@ -44,3 +44,15 @@ ip6 test-ip6 output [ byteorder reg 1 = ntoh(reg 1, 2, 1) ] [ bitwise reg 1 = ( reg 1 & 0x0000003c ) ^ 0x00000000 ] [ ct set mark with reg 1 ] + +# ct mark set ct mark | ip6 dscp | 0x200 counter +ip6 test-ip6 output + [ ct load mark => reg 1 ] + [ payload load 2b @ network header + 0 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x0000c00f ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x00000006 ) ] + [ byteorder reg 2 = ntoh(reg 2, 2, 1) ] + [ bitwise reg 1 = ( reg 1 | reg 2 ) ] + [ bitwise reg 1 = ( reg 1 & 0xfffffdff ) ^ 0x00000200 ] + [ ct set mark with reg 1 ] + [ counter pkts 0 bytes 0 ] diff --git a/tests/py/ip6/ip6.t b/tests/py/ip6/ip6.t index 2ffe318e1e6d..bfa384ad1834 100644 --- a/tests/py/ip6/ip6.t +++ b/tests/py/ip6/ip6.t @@ -141,6 +141,8 @@ iif "lo" ip6 daddr set ::1;ok iif "lo" ip6 hoplimit set 1;ok iif "lo" ip6 dscp set af42;ok iif "lo" ip6 dscp set 63;ok;iif "lo" ip6 dscp set 0x3f +iif "lo" ip6 dscp set (ct mark & 0xfc000000) >> 26;ok +iif "lo" ip6 dscp set ip6 dscp & 0xc;ok;iif "lo" ip6 dscp set ip6 dscp & 0x0c iif "lo" ip6 ecn set ect0;ok iif "lo" ip6 ecn set ce;ok diff --git a/tests/py/ip6/ip6.t.json b/tests/py/ip6/ip6.t.json index cf802175b792..70faf735a37d 100644 --- a/tests/py/ip6/ip6.t.json +++ b/tests/py/ip6/ip6.t.json @@ -1437,6 +1437,82 @@ } ] +# iif "lo" ip6 dscp set (ct mark & 0xfc000000) >> 26 +[ + { + "match": { + "left": { + "meta": { + "key": "iif" + } + }, + "op": "==", + "right": "lo" + } + }, + { + "mangle": { + "key": { + "payload": { + "field": "dscp", + "protocol": "ip6" + } + }, + "value": { + ">>": [ + { + "&": [ + { + "ct": { + "key": "mark" + } + }, + 4227858432 + ] + }, + 26 + ] + } + } + } +] + +# iif "lo" ip6 dscp set ip6 dscp & 0xc +[ + { + "match": { + "left": { + "meta": { + "key": "iif" + } + }, + "op": "==", + "right": "lo" + } + }, + { + "mangle": { + "key": { + "payload": { + "field": "dscp", + "protocol": "ip6" + } + }, + "value": { + "&": [ + { + "payload": { + "field": "dscp", + "protocol": "ip6" + } + }, + 12 + ] + } + } + } +] + # iif "lo" ip6 ecn set ect0 [ { diff --git a/tests/py/ip6/ip6.t.payload.inet b/tests/py/ip6/ip6.t.payload.inet index 20dfe5497367..41fc81ace7fa 100644 --- a/tests/py/ip6/ip6.t.payload.inet +++ b/tests/py/ip6/ip6.t.payload.inet @@ -589,6 +589,42 @@ inet test-inet input [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x0000c00f ] [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] +# iif "lo" ip6 dscp set (ct mark & 0xfc000000) >> 26 +inet test-inet input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load nfproto => reg 1 ] + [ cmp eq reg 1 0x0000000a ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x00000000 ] + [ ct load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] + +# iif "lo" ip6 dscp set ip6 dscp & 0xc +inet test-inet input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ meta load nfproto => reg 1 ] + [ cmp eq reg 1 0x0000000a ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x00000000 ] + [ payload load 2b @ network header + 0 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x0000c00f ) ^ 0x00000000 ] + [ byteorder reg 2 = ntoh(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 >> 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 & 0x00000c00 ) ^ 0x00000000 ] + [ byteorder reg 2 = ntoh(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 << 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 2, 1) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] + # iif "lo" ip6 ecn set ect0 inet test-inet input [ meta load iif => reg 1 ] diff --git a/tests/py/ip6/ip6.t.payload.ip6 b/tests/py/ip6/ip6.t.payload.ip6 index f8e3ca3cb622..b7d2ab5aa4bb 100644 --- a/tests/py/ip6/ip6.t.payload.ip6 +++ b/tests/py/ip6/ip6.t.payload.ip6 @@ -439,6 +439,38 @@ ip6 test-ip6 input [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x0000c00f ] [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] +# iif "lo" ip6 dscp set (ct mark & 0xfc000000) >> 26 +ip6 test-ip6 input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x00000000 ] + [ ct load mark => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0xfc000000 ) ^ 0x00000000 ] + [ bitwise reg 2 = ( reg 2 >> 0x0000001a ) ] + [ bitwise reg 2 = ( reg 2 << 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 4, 4) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] + +# iif "lo" ip6 dscp set ip6 dscp & 0xc +ip6 test-ip6 input + [ meta load iif => reg 1 ] + [ cmp eq reg 1 0x00000001 ] + [ payload load 2b @ network header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0x00003ff0 ) ^ 0x00000000 ] + [ payload load 2b @ network header + 0 => reg 2 ] + [ bitwise reg 2 = ( reg 2 & 0x0000c00f ) ^ 0x00000000 ] + [ byteorder reg 2 = ntoh(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 >> 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 & 0x00000c00 ) ^ 0x00000000 ] + [ byteorder reg 2 = ntoh(reg 2, 2, 1) ] + [ bitwise reg 2 = ( reg 2 << 0x00000006 ) ] + [ byteorder reg 2 = hton(reg 2, 2, 1) ] + [ bitwise reg 1 = ( reg 1 ^ reg 2 ) ] + [ payload write reg 1 => 2b @ network header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ] + # iif "lo" ip6 ecn set ect0 ip6 test-ip6 input [ meta load iif => reg 1 ] diff --git a/tests/shell/testcases/bitwise/0040mark_binop_10 b/tests/shell/testcases/bitwise/0040mark_binop_10 new file mode 100755 index 000000000000..8e9bc6ad4329 --- /dev/null +++ b/tests/shell/testcases/bitwise/0040mark_binop_10 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table t + add chain t c { type filter hook output priority filter; } + add rule t c ct mark set ct mark and 0xffff0000 or meta mark and 0xffff +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0040mark_binop_11 b/tests/shell/testcases/bitwise/0040mark_binop_11 new file mode 100755 index 000000000000..7825b0827851 --- /dev/null +++ b/tests/shell/testcases/bitwise/0040mark_binop_11 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table t + add chain t c { type filter hook input priority filter; } + add rule t c meta mark set ct mark and 0xffff0000 or meta mark and 0xffff +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0040mark_binop_12 b/tests/shell/testcases/bitwise/0040mark_binop_12 new file mode 100755 index 000000000000..aa27cdc5303c --- /dev/null +++ b/tests/shell/testcases/bitwise/0040mark_binop_12 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table ip6 t + add chain ip6 t c { type filter hook output priority filter; } + add rule ip6 t c ct mark set ct mark and 0xffff0000 or meta mark and 0xffff +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0040mark_binop_13 b/tests/shell/testcases/bitwise/0040mark_binop_13 new file mode 100755 index 000000000000..53a7e2ec6c6f --- /dev/null +++ b/tests/shell/testcases/bitwise/0040mark_binop_13 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table ip6 t + add chain ip6 t c { type filter hook input priority filter; } + add rule ip6 t c meta mark set ct mark and 0xffff0000 or meta mark and 0xffff +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_0 b/tests/shell/testcases/bitwise/0044payload_binop_0 new file mode 100755 index 000000000000..81b8cbaa961f --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_0 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table t + add chain t c { type filter hook output priority filter; } + add rule t c ip dscp set (ct mark & 0xfc000000) >> 26 +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_1 b/tests/shell/testcases/bitwise/0044payload_binop_1 new file mode 100755 index 000000000000..1d69b6f78654 --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_1 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table t + add chain t c { type filter hook output priority filter; } + add rule t c ip dscp set ip dscp and 0xc +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_2 b/tests/shell/testcases/bitwise/0044payload_binop_2 new file mode 100755 index 000000000000..2d09d24479d0 --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_2 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table t + add chain t c { type filter hook output priority filter; } + add rule t c ct mark set ct mark | ip dscp | 0x200 counter +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_3 b/tests/shell/testcases/bitwise/0044payload_binop_3 new file mode 100755 index 000000000000..7752af238409 --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_3 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table ip6 t + add chain ip6 t c { type filter hook output priority filter; } + add rule ip6 t c ip6 dscp set (ct mark & 0xfc000000) >> 26 +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_4 b/tests/shell/testcases/bitwise/0044payload_binop_4 new file mode 100755 index 000000000000..2c7792e9f929 --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_4 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table ip6 t + add chain ip6 t c { type filter hook output priority filter; } + add rule ip6 t c ip6 dscp set ip6 dscp and 0xc +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/0044payload_binop_5 b/tests/shell/testcases/bitwise/0044payload_binop_5 new file mode 100755 index 000000000000..aa82cd1c299e --- /dev/null +++ b/tests/shell/testcases/bitwise/0044payload_binop_5 @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +RULESET=" + add table ip6 t + add chain ip6 t c { type filter hook output priority filter; } + add rule ip6 t c ct mark set ct mark | ip6 dscp | 0x200 counter +" + +$NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/bitwise/dumps/0040mark_binop_10.nft b/tests/shell/testcases/bitwise/dumps/0040mark_binop_10.nft new file mode 100644 index 000000000000..5566f7298461 --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0040mark_binop_10.nft @@ -0,0 +1,6 @@ +table ip t { + chain c { + type filter hook output priority filter; policy accept; + ct mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0040mark_binop_11.nft b/tests/shell/testcases/bitwise/dumps/0040mark_binop_11.nft new file mode 100644 index 000000000000..719980d55341 --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0040mark_binop_11.nft @@ -0,0 +1,6 @@ +table ip t { + chain c { + type filter hook input priority filter; policy accept; + meta mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0040mark_binop_12.nft b/tests/shell/testcases/bitwise/dumps/0040mark_binop_12.nft new file mode 100644 index 000000000000..bd589fe549f7 --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0040mark_binop_12.nft @@ -0,0 +1,6 @@ +table ip6 t { + chain c { + type filter hook output priority filter; policy accept; + ct mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0040mark_binop_13.nft b/tests/shell/testcases/bitwise/dumps/0040mark_binop_13.nft new file mode 100644 index 000000000000..2b046b128fb2 --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0040mark_binop_13.nft @@ -0,0 +1,6 @@ +table ip6 t { + chain c { + type filter hook input priority filter; policy accept; + meta mark set ct mark & 0xffff0000 | meta mark & 0x0000ffff + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_0.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_0.nft new file mode 100644 index 000000000000..5aaf1353bdc8 --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_0.nft @@ -0,0 +1,6 @@ +table ip t { + chain c { + type filter hook output priority filter; policy accept; + ip dscp set (ct mark & 0xfc000000) >> 26 + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_1.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_1.nft new file mode 100644 index 000000000000..54f744b54a3a --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_1.nft @@ -0,0 +1,6 @@ +table ip t { + chain c { + type filter hook output priority filter; policy accept; + ip dscp set ip dscp & af12 + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_2.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_2.nft new file mode 100644 index 000000000000..ed347bb2788a --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_2.nft @@ -0,0 +1,6 @@ +table ip t { + chain c { + type filter hook output priority filter; policy accept; + ct mark set ct mark | ip dscp | 0x00000200 counter packets 0 bytes 0 + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_3.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_3.nft new file mode 100644 index 000000000000..64da4a77cb5c --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_3.nft @@ -0,0 +1,6 @@ +table ip6 t { + chain c { + type filter hook output priority filter; policy accept; + ip6 dscp set (ct mark & 0xfc000000) >> 26 + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_4.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_4.nft new file mode 100644 index 000000000000..f5bd9789ce2f --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_4.nft @@ -0,0 +1,6 @@ +table ip6 t { + chain c { + type filter hook output priority filter; policy accept; + ip6 dscp set ip6 dscp & 0x0c + } +} diff --git a/tests/shell/testcases/bitwise/dumps/0044payload_binop_5.nft b/tests/shell/testcases/bitwise/dumps/0044payload_binop_5.nft new file mode 100644 index 000000000000..ccdb93d74a9a --- /dev/null +++ b/tests/shell/testcases/bitwise/dumps/0044payload_binop_5.nft @@ -0,0 +1,6 @@ +table ip6 t { + chain c { + type filter hook output priority filter; policy accept; + ct mark set ct mark | ip6 dscp | 0x00000200 counter packets 0 bytes 0 + } +}