netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH nft 3/5] evaluate: handle binop adjustment recursively
Date: Thu, 11 Jan 2018 16:30:22 +0100	[thread overview]
Message-ID: <20180111153024.25198-5-fw@strlen.de> (raw)
In-Reply-To: <20180111153024.25198-1-fw@strlen.de>

currently this is fine, but a followup commit will add
EXPR_SET_ELEM handling.

And unlike RANGE we cannot assume the key is a value.
Therefore make binop_can_transfer and binop_transfer_one handle
right hand recursively if needed.  For RANGE, call it again with
from/to.

For future SET_ELEM, we can then just call the function recursively
again with right->key as new RHS.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/evaluate.c | 55 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 7fe738d8d590..cc32f74bd95e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1408,6 +1408,21 @@ static int expr_evaluate_hash(struct eval_ctx *ctx, struct expr **exprp)
 static int binop_can_transfer(struct eval_ctx *ctx,
 			      struct expr *left, struct expr *right)
 {
+	int err;
+
+	switch (right->ops->type) {
+	case EXPR_VALUE:
+		break;
+	case EXPR_RANGE:
+		err = binop_can_transfer(ctx, left, right->left);
+		if (err <= 0)
+			return err;
+		return binop_can_transfer(ctx, left, right->right);
+	default:
+		fprintf(stderr, "ERR: UNHANDLED %s\n", right->ops->name);
+		return 0;
+	}
+
 	switch (left->op) {
 	case OP_LSHIFT:
 		if (mpz_scan1(right->value, 0) < mpz_get_uint32(left->right->value))
@@ -1428,6 +1443,21 @@ static int binop_can_transfer(struct eval_ctx *ctx,
 static int binop_transfer_one(struct eval_ctx *ctx,
 			      const struct expr *left, struct expr **right)
 {
+	int err;
+
+	switch ((*right)->ops->type) {
+	case EXPR_VALUE:
+		break;
+	case EXPR_RANGE:
+		err = binop_transfer_one(ctx, left, &(*right)->left);
+		if (err < 0)
+			return err;
+		return binop_transfer_one(ctx, left, &(*right)->right);
+	default:
+		fprintf(stderr, "ERR2: UNHANDLED %s\n", (*right)->ops->name);
+		return 0;
+	}
+
 	expr_get(*right);
 
 	switch (left->op) {
@@ -1468,15 +1498,10 @@ static int binop_transfer(struct eval_ctx *ctx, struct expr **expr)
 			return -1;
 		break;
 	case EXPR_RANGE:
-		err = binop_can_transfer(ctx, left, (*expr)->right->left);
-		if (err <= 0)
-			return err;
-		err = binop_can_transfer(ctx, left, (*expr)->right->right);
+		err = binop_can_transfer(ctx, left, (*expr)->right);
 		if (err <= 0)
 			return err;
-		if (binop_transfer_one(ctx, left, &(*expr)->right->left) < 0)
-			return -1;
-		if (binop_transfer_one(ctx, left, &(*expr)->right->right) < 0)
+		if (binop_transfer_one(ctx, left, &(*expr)->right) < 0)
 			return -1;
 		break;
 	case EXPR_SET:
@@ -1497,15 +1522,8 @@ static int binop_transfer(struct eval_ctx *ctx, struct expr **expr)
 		list_for_each_entry(i, &(*expr)->right->set->init->expressions, list) {
 			switch (i->key->ops->type) {
 			case EXPR_VALUE:
-				err = binop_can_transfer(ctx, left, i->key);
-				if (err <= 0)
-					return err;
-				break;
 			case EXPR_RANGE:
-				err = binop_can_transfer(ctx, left, i->key->left);
-				if (err <= 0)
-					return err;
-				err = binop_can_transfer(ctx, left, i->key->right);
+				err = binop_can_transfer(ctx, left, i->key);
 				if (err <= 0)
 					return err;
 				break;
@@ -1518,13 +1536,8 @@ static int binop_transfer(struct eval_ctx *ctx, struct expr **expr)
 			list_del(&i->list);
 			switch (i->key->ops->type) {
 			case EXPR_VALUE:
-				if (binop_transfer_one(ctx, left, &i->key) < 0)
-					return -1;
-				break;
 			case EXPR_RANGE:
-				if (binop_transfer_one(ctx, left, &i->key->left) < 0)
-					return -1;
-				if (binop_transfer_one(ctx, left, &i->key->right) < 0)
+				if (binop_transfer_one(ctx, left, &i->key) < 0)
 					return -1;
 				break;
 			default:
-- 
2.13.6


  parent reply	other threads:[~2018-01-11 15:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-11 15:30 [nftables] vmap and bit-sized headers Florian Westphal
2018-01-11 15:30 ` [PATCH nft] netlink_linearize: exthdr op must be u32 Florian Westphal
2018-01-15 11:00   ` Pablo Neira Ayuso
2018-01-11 15:30 ` [PATCH nft 1/5] src: segtree: use value expression length Florian Westphal
2018-01-11 15:30 ` [PATCH nft 2/5] src: netlink_delinearize: don't assume element contains a value Florian Westphal
2018-01-11 15:30 ` Florian Westphal [this message]
2018-01-11 15:30 ` [PATCH nft 4/5] src: evaluate: add binop transfer support for vmaps Florian Westphal
2018-01-11 15:30 ` [PATCH nft 5/5] tests: add test cases for vmap binop transfer Florian Westphal

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=20180111153024.25198-5-fw@strlen.de \
    --to=fw@strlen.de \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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