[PATCH nft 3/4] src: transform flag match expression to binop expression from parser

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Transform flagcmp expression to a relational with binop on the left hand
side, ie.

         relational
          /      \
       binop    value
       /   \
 payload  mask

Add list_expr_to_binop() to make this transformation.

Goal is two-fold:

- Allow -o/--optimize to pick up on this representation.
- Remove the flagcmp expression in a follow up patch.

This prepare for the removal of the flagcmp expression added by:

  c3d57114f119 ("parser_bison: add shortcut syntax for matching flags without binary operations")

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 include/expression.h |  1 +
 src/expression.c     | 23 +++++++++++++++++++++++
 src/parser_bison.y   | 22 ++++++++++++++++++----
 3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 8472748621ef..818d7a7dc74b 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -519,6 +519,7 @@ extern void list_splice_sorted(struct list_head *list, struct list_head *head);
 extern struct expr *concat_expr_alloc(const struct location *loc);
 
 extern struct expr *list_expr_alloc(const struct location *loc);
+struct expr *list_expr_to_binop(struct expr *expr);
 
 extern struct expr *set_expr_alloc(const struct location *loc,
 				   const struct set *set);
diff --git a/src/expression.c b/src/expression.c
index 156a66eb37f0..2a30d5af92a4 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1263,6 +1263,29 @@ struct expr *list_expr_alloc(const struct location *loc)
 	return compound_expr_alloc(loc, EXPR_LIST);
 }
 
+/* list is assumed to have two items at least, otherwise extend this! */
+struct expr *list_expr_to_binop(struct expr *expr)
+{
+	struct expr *first, *last, *i;
+
+	first = list_first_entry(&expr->expressions, struct expr, list);
+	i = first;
+
+	list_for_each_entry_continue(i, &expr->expressions, list) {
+		if (first) {
+			last = binop_expr_alloc(&expr->location, OP_OR, first, i);
+			first = NULL;
+		} else {
+			last = binop_expr_alloc(&expr->location, OP_OR, i, last);
+		}
+	}
+	/* zap list expressions, they have been moved to binop expression. */
+	init_list_head(&expr->expressions);
+	expr_free(expr);
+
+	return last;
+}
+
 static const char *calculate_delim(const struct expr *expr, int *count,
 				   struct output_ctx *octx)
 {
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 5760ba479fc9..4b2b51d4275c 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4917,19 +4917,33 @@ relational_expr		:	expr	/* implicit */	rhs_expr
 			}
 			|	expr	/* implicit */	basic_rhs_expr	SLASH	list_rhs_expr
 			{
-				$$ = flagcmp_expr_alloc(&@$, OP_EQ, $1, $4, $2);
+				struct expr *mask = list_expr_to_binop($4);
+				struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask);
+
+				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, binop, $2);
 			}
 			|	expr	/* implicit */	list_rhs_expr	SLASH	list_rhs_expr
 			{
-				$$ = flagcmp_expr_alloc(&@$, OP_EQ, $1, $4, $2);
+				struct expr *value = list_expr_to_binop($2);
+				struct expr *mask = list_expr_to_binop($4);
+				struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask);
+
+				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, binop, value);
 			}
 			|	expr	relational_op	basic_rhs_expr	SLASH	list_rhs_expr
 			{
-				$$ = flagcmp_expr_alloc(&@$, $2, $1, $5, $3);
+				struct expr *mask = list_expr_to_binop($5);
+				struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask);
+
+				$$ = relational_expr_alloc(&@$, $2, binop, $3);
 			}
 			|	expr	relational_op	list_rhs_expr	SLASH	list_rhs_expr
 			{
-				$$ = flagcmp_expr_alloc(&@$, $2, $1, $5, $3);
+				struct expr *value = list_expr_to_binop($3);
+				struct expr *mask = list_expr_to_binop($5);
+				struct expr *binop = binop_expr_alloc(&@$, OP_AND, $1, mask);
+
+				$$ = relational_expr_alloc(&@$, $2, binop, value);
 			}
 			|	expr	relational_op	rhs_expr
 			{
-- 
2.30.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux