]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: handle binop adjustment recursively
authorFlorian Westphal <fw@strlen.de>
Thu, 11 Jan 2018 15:30:22 +0000 (16:30 +0100)
committerFlorian Westphal <fw@strlen.de>
Sat, 17 Mar 2018 00:47:17 +0000 (01:47 +0100)
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

index 114c831f5379c7152692c10f0f07de823ede7d70..46ac9e43a37a86e6094607fca1d3a296caf3f875 100644 (file)
@@ -1403,6 +1403,20 @@ 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:
+               return 0;
+       }
+
        switch (left->op) {
        case OP_LSHIFT:
                if (mpz_scan1(right->value, 0) < mpz_get_uint32(left->right->value))
@@ -1423,6 +1437,20 @@ 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:
+               return 0;
+       }
+
        expr_get(*right);
 
        switch (left->op) {
@@ -1463,15 +1491,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:
@@ -1492,15 +1515,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;
@@ -1513,13 +1529,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: