All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Sowden <jeremy@azazel.net>
To: Pablo Neira Ayuso <pablo@netfilter.org>, Florian Westphal <fw@strlen.de>
Cc: Netfilter Devel <netfilter-devel@vger.kernel.org>
Subject: [PATCH nft v3 14/18] netlink_delinearize: add support for processing variable payload statement arguments.
Date: Tue,  3 Mar 2020 09:48:40 +0000	[thread overview]
Message-ID: <20200303094844.26694-15-jeremy@azazel.net> (raw)
In-Reply-To: <20200303094844.26694-1-jeremy@azazel.net>

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 <jeremy@azazel.net>
---
 src/netlink_delinearize.c | 74 +++++++++++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 6 deletions(-)

diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index e8e9e5719ee8..571cab1d932b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2514,7 +2514,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;
@@ -2568,6 +2568,56 @@ 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 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;
+
+	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, &ctx->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;
@@ -2634,21 +2684,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)
@@ -2671,7 +2730,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;
 	case EXPR_PAYLOAD: /* II? */
-- 
2.25.1


  parent reply	other threads:[~2020-03-03 10:14 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-03  9:48 [PATCH nft v3 00/18] Support for boolean binops with variable RHS operands Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 01/18] evaluate: add separate variables for lshift and xor binops Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 02/18] evaluate: simplify calculation of payload size Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 03/18] evaluate: don't evaluate payloads twice Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 04/18] evaluate: convert the byte-order of payload statement arguments Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 05/18] evaluate: no need to swap byte-order for values of fewer than 16 bits Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 06/18] netlink_delinearize: set shift RHS byte-order Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 07/18] src: fix leaks Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 08/18] include: update nf_tables.h Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 09/18] src: support (de)linearization of bitwise op's with variable right operands Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 10/18] evaluate: allow boolean binop expressions with variable righthand arguments Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 11/18] evaluate: don't clobber binop bitmask lengths Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 12/18] netlink_delinearize: fix typo Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 13/18] netlink_delinearize: refactor stmt_payload_binop_postprocess Jeremy Sowden
2020-03-03  9:48 ` Jeremy Sowden [this message]
2020-03-03  9:48 ` [PATCH nft v3 15/18] netlink_delinearize: add postprocessing for payload binops Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 16/18] tests: shell: remove stray debug flag Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 17/18] tests: shell: add variable binop RHS tests Jeremy Sowden
2020-03-03  9:48 ` [PATCH nft v3 18/18] tests: py: " Jeremy Sowden
2020-03-10  2:39   ` Pablo Neira Ayuso
2020-03-10  9:30     ` Jeremy Sowden
2020-03-11 13:26       ` Pablo Neira Ayuso
2020-03-11 14:35         ` Jeremy Sowden
2020-03-11 17:17           ` Pablo Neira Ayuso
2020-03-11 20:54             ` Jeremy Sowden
2020-03-05 10:53 ` [PATCH nft v3 00/18] Support for boolean binops with variable RHS operands Florian Westphal
2020-03-05 11:36   ` Jeremy Sowden

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20200303094844.26694-15-jeremy@azazel.net \
    --to=jeremy@azazel.net \
    --cc=fw@strlen.de \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.