summaryrefslogtreecommitdiffstats
path: root/src/optimize.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2025-07-09 00:51:24 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2025-07-10 00:13:04 +0200
commite0d92243be1cf1a485450a56d845e7bf2d1c6051 (patch)
treef4617c607751577a635ed4c9ce4a386c19bd8add /src/optimize.c
parent01fdd7c7f445337c460738aa872cbdaabb5316ea (diff)
src: detach set, list and concatenation expression layout
These three expressions use the same layout, but they have a different purpose. Several fields are specific of a given expression: - set_flags is only required by set expressions. - field_len and field_count are only used by concatenation expressions. Add accessors to validate the expression type before accessing the union fields: #define expr_set(__expr) (assert((__expr)->etype == EXPR_SET), &(__expr)->expr_set) #define expr_concat(__expr) (assert((__expr)->etype == EXPR_CONCAT), &(__expr)->expr_concat) #define expr_list(__expr) (assert((__expr)->etype == EXPR_LIST), &(__expr)->expr_list) This should help catch subtle bugs due to type confusion. assert() could be later enabled only in debugging builds to run tests, keep it by now. compound_expr_*() still works and it needs the same initial layout for all of these expressions: struct list_head expressions; unsigned int size; This is implicitly reducing the size of one of the largest structs in the union area of struct expr, still EXPR_SET_ELEM remains the largest so no gain is achieved in this iteration. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/optimize.c')
-rw-r--r--src/optimize.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/optimize.c b/src/optimize.c
index 89ba0d9d..40756cec 100644
--- a/src/optimize.c
+++ b/src/optimize.c
@@ -565,7 +565,7 @@ static void merge_expr_stmts(const struct optimize_ctx *ctx,
uint32_t i;
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
expr_a = stmt_a->expr->right;
elem = set_elem_expr_alloc(&internal_location, expr_get(expr_a));
@@ -588,7 +588,7 @@ static void merge_vmap(const struct optimize_ctx *ctx,
struct expr *mappings, *mapping, *expr;
mappings = stmt_b->expr->mappings;
- list_for_each_entry(expr, &mappings->expressions, list) {
+ list_for_each_entry(expr, &expr_set(mappings)->expressions, list) {
mapping = expr_clone(expr);
compound_expr_add(stmt_a->expr->mappings, mapping);
}
@@ -654,7 +654,7 @@ static void __merge_concat(const struct optimize_ctx *ctx, uint32_t i,
stmt_a = ctx->stmt_matrix[i][merge->stmt[k]];
switch (stmt_a->expr->right->etype) {
case EXPR_SET:
- list_for_each_entry(expr, &stmt_a->expr->right->expressions, list) {
+ list_for_each_entry(expr, &expr_set(stmt_a->expr->right)->expressions, list) {
concat_clone = expr_clone(concat);
clone = expr_clone(expr->key);
compound_expr_add(concat_clone, clone);
@@ -673,7 +673,7 @@ static void __merge_concat(const struct optimize_ctx *ctx, uint32_t i,
compound_expr_add(concat, clone);
break;
case EXPR_LIST:
- list_for_each_entry(expr, &stmt_a->expr->right->expressions, list) {
+ list_for_each_entry(expr, &expr_list(stmt_a->expr->right)->expressions, list) {
concat_clone = expr_clone(concat);
clone = expr_clone(expr);
compound_expr_add(concat_clone, clone);
@@ -727,7 +727,7 @@ static void merge_concat_stmts(const struct optimize_ctx *ctx,
/* build set data contenation, eg. { eth0 . 1.1.1.1 . 22 } */
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
for (i = from; i <= to; i++)
__merge_concat_stmts(ctx, i, merge, set);
@@ -750,7 +750,7 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict,
switch (expr->etype) {
case EXPR_LIST:
- list_for_each_entry(item, &expr->expressions, list) {
+ list_for_each_entry(item, &expr_list(expr)->expressions, list) {
elem = set_elem_expr_alloc(&internal_location, expr_get(item));
if (counter) {
counter_elem = counter_stmt_alloc(&counter->location);
@@ -764,7 +764,7 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict,
stmt_free(counter);
break;
case EXPR_SET:
- list_for_each_entry(item, &expr->expressions, list) {
+ list_for_each_entry(item, &expr_set(expr)->expressions, list) {
elem = set_elem_expr_alloc(&internal_location, expr_get(item->key));
if (counter) {
counter_elem = counter_stmt_alloc(&counter->location);
@@ -851,7 +851,7 @@ static void merge_stmts_vmap(const struct optimize_ctx *ctx,
assert(k >= 0);
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
expr_a = stmt_a->expr->right;
verdict_a = ctx->stmt_matrix[from][k];
@@ -925,7 +925,7 @@ static void merge_concat_stmts_vmap(const struct optimize_ctx *ctx,
/* build set data contenation, eg. { eth0 . 1.1.1.1 . 22 : accept } */
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
for (i = from; i <= to; i++) {
verdict = ctx->stmt_matrix[i][k];
@@ -1050,7 +1050,7 @@ static void merge_nat(const struct optimize_ctx *ctx,
assert(k >= 0);
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
for (i = from; i <= to; i++) {
stmt = ctx->stmt_matrix[i][merge->stmt[0]];
@@ -1102,7 +1102,7 @@ static void merge_concat_nat(const struct optimize_ctx *ctx,
assert(k >= 0);
set = set_expr_alloc(&internal_location, NULL);
- set->set_flags |= NFT_SET_ANONYMOUS;
+ expr_set(set)->set_flags |= NFT_SET_ANONYMOUS;
for (i = from; i <= to; i++) {