From: Pablo Neira Ayuso Date: Wed, 26 Mar 2025 20:54:08 +0000 (+0100) Subject: src: transform flag match expression to binop expression from parser X-Git-Tag: v1.1.2~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d5990c92c830e695c3173b72f33ffb94b8cac05;p=thirdparty%2Fnftables.git src: transform flag match expression to binop expression from parser 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 --- diff --git a/include/expression.h b/include/expression.h index 6e8675b0..d48d8ed8 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 52e4c7d1..ecdb8846 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 5760ba47..4b2b51d4 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 {