diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2025-07-09 00:51:24 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2025-07-10 00:13:04 +0200 |
commit | e0d92243be1cf1a485450a56d845e7bf2d1c6051 (patch) | |
tree | f4617c607751577a635ed4c9ce4a386c19bd8add | |
parent | 01fdd7c7f445337c460738aa872cbdaabb5316ea (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>
-rw-r--r-- | include/expression.h | 22 | ||||
-rw-r--r-- | src/cmd.c | 5 | ||||
-rw-r--r-- | src/evaluate.c | 124 | ||||
-rw-r--r-- | src/expression.c | 41 | ||||
-rw-r--r-- | src/intervals.c | 80 | ||||
-rw-r--r-- | src/json.c | 10 | ||||
-rw-r--r-- | src/mergesort.c | 2 | ||||
-rw-r--r-- | src/mnl.c | 12 | ||||
-rw-r--r-- | src/monitor.c | 2 | ||||
-rw-r--r-- | src/netlink.c | 26 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 14 | ||||
-rw-r--r-- | src/netlink_linearize.c | 2 | ||||
-rw-r--r-- | src/optimize.c | 22 | ||||
-rw-r--r-- | src/parser_bison.y | 2 | ||||
-rw-r--r-- | src/parser_json.c | 5 | ||||
-rw-r--r-- | src/rule.c | 4 | ||||
-rw-r--r-- | src/segtree.c | 22 |
17 files changed, 207 insertions, 188 deletions
diff --git a/include/expression.h b/include/expression.h index f42a0c2b..5b60c1b0 100644 --- a/include/expression.h +++ b/include/expression.h @@ -293,14 +293,24 @@ struct expr { struct expr *prefix; unsigned int prefix_len; }; - struct { - /* EXPR_CONCAT, EXPR_LIST, EXPR_SET */ + struct expr_concat { + /* EXPR_CONCAT */ struct list_head expressions; unsigned int size; - uint32_t set_flags; uint8_t field_len[NFT_REG32_COUNT]; uint8_t field_count; - }; + } expr_concat; + struct expr_set { + /* EXPR_SET */ + struct list_head expressions; + unsigned int size; + uint32_t set_flags; + } expr_set; + struct expr_list { + /* EXPR_LIST */ + struct list_head expressions; + unsigned int size; + } expr_list; struct { /* EXPR_SET_REF */ struct set *set; @@ -403,6 +413,10 @@ struct expr { }; }; +#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) + extern struct expr *expr_alloc(const struct location *loc, enum expr_types etype, const struct datatype *dtype, @@ -398,8 +398,9 @@ bool nft_cmd_collapse_elems(enum cmd_ops op, struct list_head *cmds, strcmp(last_cmd->handle.set.name, handle->set.name)) return false; - list_splice_tail_init(&init->expressions, &last_cmd->expr->expressions); - last_cmd->expr->size += init->size; + list_splice_tail_init(&expr_set(init)->expressions, + &expr_set(last_cmd->expr)->expressions); + expr_set(last_cmd->expr)->size += expr_set(init)->size; return true; } diff --git a/src/evaluate.c b/src/evaluate.c index fb6c4e06..1fa4cb78 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -191,7 +191,7 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr, if ((*expr)->etype == EXPR_CONCAT) { struct expr *i, *next, *unary; - list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { + list_for_each_entry_safe(i, next, &expr_concat(*expr)->expressions, list) { if (i->byteorder == BYTEORDER_BIG_ENDIAN) continue; @@ -1669,12 +1669,12 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) if (ctx->ectx.key && ctx->ectx.key->etype == EXPR_CONCAT) { key_ctx = ctx->ectx.key; - assert(!list_empty(&ctx->ectx.key->expressions)); - key = list_first_entry(&ctx->ectx.key->expressions, struct expr, list); - expressions = &ctx->ectx.key->expressions; + assert(!list_empty(&expr_concat(ctx->ectx.key)->expressions)); + key = list_first_entry(&expr_concat(ctx->ectx.key)->expressions, struct expr, list); + expressions = &expr_concat(ctx->ectx.key)->expressions; } - list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { + list_for_each_entry_safe(i, next, &expr_concat(*expr)->expressions, list) { enum byteorder bo = BYTEORDER_INVALID; unsigned dsize_bytes, dsize = 0; @@ -1798,7 +1798,7 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) ntype = concat_subtype_add(ntype, i->dtype->type); dsize_bytes = div_round_up(dsize, BITS_PER_BYTE); - (*expr)->field_len[(*expr)->field_count++] = dsize_bytes; + expr_concat(*expr)->field_len[expr_concat(*expr)->field_count++] = dsize_bytes; size += netlink_padded_len(dsize); if (key && expressions) { if (list_is_last(&key->list, expressions)) @@ -1839,7 +1839,7 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr) mpz_t val; mpz_init_set_ui(val, 0); - list_for_each_entry_safe(i, next, &list->expressions, list) { + list_for_each_entry_safe(i, next, &expr_list(list)->expressions, list) { if (list_member_evaluate(ctx, &i) < 0) { mpz_clear(val); return -1; @@ -1943,7 +1943,7 @@ static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr) key = elem->key; goto err_missing_flag; case EXPR_CONCAT: - list_for_each_entry(key, &elem->key->expressions, list) { + list_for_each_entry(key, &expr_concat(elem->key)->expressions, list) { switch (key->etype) { case EXPR_PREFIX: case EXPR_RANGE: @@ -2039,7 +2039,7 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) struct expr *set = *expr, *i, *next; const struct expr *elem; - list_for_each_entry_safe(i, next, &set->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(set)->expressions, list) { if (list_member_evaluate(ctx, &i) < 0) return -1; @@ -2048,12 +2048,12 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) i->left->key->etype == EXPR_SET) { struct expr *new, *j; - list_for_each_entry(j, &i->left->key->expressions, list) { + list_for_each_entry(j, &expr_set(i->left->key)->expressions, list) { new = mapping_expr_alloc(&i->location, expr_get(j), expr_get(i->right)); - list_add_tail(&new->list, &set->expressions); - set->size++; + list_add_tail(&new->list, &expr_set(set)->expressions); + expr_set(set)->size++; } list_del(&i->list); expr_free(i); @@ -2071,7 +2071,7 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) elem->key->etype == EXPR_SET) { struct expr *new = expr_get(elem->key); - set->set_flags |= elem->key->set_flags; + expr_set(set)->set_flags |= expr_set(elem->key)->set_flags; list_replace(&i->list, &new->list); expr_free(i); i = new; @@ -2084,24 +2084,24 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) if (i->etype == EXPR_SET) { /* Merge recursive set definitions */ - list_splice_tail_init(&i->expressions, &i->list); + list_splice_tail_init(&expr_set(i)->expressions, &i->list); list_del(&i->list); - set->size += i->size - 1; - set->set_flags |= i->set_flags; + expr_set(set)->size += expr_set(i)->size - 1; + expr_set(set)->set_flags |= expr_set(i)->set_flags; expr_free(i); } else if (!expr_is_singleton(i)) { - set->set_flags |= NFT_SET_INTERVAL; + expr_set(set)->set_flags |= NFT_SET_INTERVAL; if (elem->key->etype == EXPR_CONCAT) - set->set_flags |= NFT_SET_CONCAT; + expr_set(set)->set_flags |= NFT_SET_CONCAT; } } if (ctx->set) { if (ctx->set->flags & NFT_SET_CONCAT) - set->set_flags |= NFT_SET_CONCAT; + expr_set(set)->set_flags |= NFT_SET_CONCAT; } - set->set_flags |= NFT_SET_CONSTANT; + expr_set(set)->set_flags |= NFT_SET_CONSTANT; datatype_set(set, ctx->ectx.dtype); set->len = ctx->ectx.len; @@ -2114,13 +2114,15 @@ static int binop_transfer(struct eval_ctx *ctx, struct expr **expr); static void map_set_concat_info(struct expr *map) { - map->mappings->set->flags |= map->mappings->set->init->set_flags; + map->mappings->set->flags |= expr_set(map->mappings->set->init)->set_flags; if (map->mappings->set->flags & NFT_SET_INTERVAL && map->map->etype == EXPR_CONCAT) { - memcpy(&map->mappings->set->desc.field_len, &map->map->field_len, + memcpy(&map->mappings->set->desc.field_len, + &expr_concat(map->map)->field_len, sizeof(map->mappings->set->desc.field_len)); - map->mappings->set->desc.field_count = map->map->field_count; + map->mappings->set->desc.field_count = + expr_concat(map->map)->field_count; map->mappings->flags |= NFT_SET_CONCAT; } } @@ -2137,7 +2139,7 @@ static void __mapping_expr_expand(struct expr *i) i->right = range; break; case EXPR_CONCAT: - list_for_each_entry_safe(j, next, &i->right->expressions, list) { + list_for_each_entry_safe(j, next, &expr_concat(i->right)->expressions, list) { if (j->etype != EXPR_VALUE) continue; @@ -2159,7 +2161,7 @@ static int mapping_expr_expand(struct eval_ctx *ctx) if (!set_is_anonymous(ctx->set->flags)) return 0; - list_for_each_entry(i, &ctx->set->init->expressions, list) { + list_for_each_entry(i, &expr_set(ctx->set->init)->expressions, list) { if (i->etype != EXPR_MAPPING) return expr_error(ctx->msgs, i, "expected mapping, not %s", expr_name(i)); @@ -2191,7 +2193,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) else if (map->map->etype == EXPR_CONCAT) { struct expr *i; - list_for_each_entry(i, &map->map->expressions, list) { + list_for_each_entry(i, &expr_concat(map->map)->expressions, list) { if (i->etype == EXPR_CT && (i->ct.key == NFT_CT_SRC || i->ct.key == NFT_CT_DST)) @@ -2212,7 +2214,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) switch (map->mappings->etype) { case EXPR_SET: - set_flags |= mappings->set_flags; + set_flags |= expr_set(mappings)->set_flags; /* fallthrough */ case EXPR_VARIABLE: if (ctx->ectx.key && ctx->ectx.key->etype == EXPR_CONCAT) { @@ -2262,8 +2264,8 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) "Expression is not a map"); } - if (set_is_interval(map->mappings->set->init->set_flags) && - !(map->mappings->set->init->set_flags & NFT_SET_CONCAT) && + if (set_is_interval(expr_set(map->mappings->set->init)->set_flags) && + !(expr_set(map->mappings->set->init)->set_flags & NFT_SET_CONCAT) && interval_set_eval(ctx, ctx->set, map->mappings->set->init) < 0) return -1; @@ -2333,7 +2335,7 @@ static bool data_mapping_has_interval(struct expr *data) if (data->etype != EXPR_CONCAT) return false; - list_for_each_entry(i, &data->expressions, list) { + list_for_each_entry(i, &expr_concat(data)->expressions, list) { if (i->etype == EXPR_RANGE || i->etype == EXPR_RANGE_VALUE || i->etype == EXPR_PREFIX) @@ -2639,12 +2641,12 @@ static int __binop_transfer(struct eval_ctx *ctx, return -1; break; case EXPR_SET: - list_for_each_entry(i, &(*right)->expressions, list) { + list_for_each_entry(i, &expr_set(*right)->expressions, list) { err = binop_can_transfer(ctx, left, i); if (err <= 0) return err; } - list_for_each_entry_safe(i, next, &(*right)->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(*right)->expressions, list) { list_del(&i->list); err = binop_transfer_one(ctx, left, &i); list_add_tail(&i->list, &next->list); @@ -2710,7 +2712,7 @@ static void optimize_singleton_set(struct expr *rel, struct expr **expr) { struct expr *set = rel->right, *i; - i = list_first_entry(&set->expressions, struct expr, list); + i = list_first_entry(&expr_set(set)->expressions, struct expr, list); if (i->etype == EXPR_SET_ELEM && list_empty(&i->stmt_list)) { @@ -2819,7 +2821,7 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) case OP_EQ: case OP_IMPLICIT: case OP_NEQ: - if (right->etype == EXPR_SET && right->size == 1) + if (right->etype == EXPR_SET && expr_set(right)->size == 1) optimize_singleton_set(rel, &right); break; default: @@ -2868,14 +2870,14 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) return -1; break; case EXPR_SET: - if (right->size == 0) + if (expr_set(right)->size == 0) return expr_error(ctx->msgs, right, "Set is empty"); right = rel->right = implicit_set_declaration(ctx, "__set%d", expr_get(left), NULL, right, - right->set_flags | NFT_SET_ANONYMOUS); + expr_set(right)->set_flags | NFT_SET_ANONYMOUS); if (!right) return -1; @@ -3633,12 +3635,12 @@ static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt) set = set_expr_alloc(&key->location, existing_set); if (key->timeout) - set->set_flags |= NFT_SET_TIMEOUT; + expr_set(set)->set_flags |= NFT_SET_TIMEOUT; - set->set_flags |= NFT_SET_EVAL; + expr_set(set)->set_flags |= NFT_SET_EVAL; setref = implicit_set_declaration(ctx, stmt->meter.name, expr_get(key), NULL, set, - NFT_SET_EVAL | set->set_flags); + NFT_SET_EVAL | expr_set(set)->set_flags); if (setref) setref->set->desc.size = stmt->meter.size; } @@ -4168,7 +4170,7 @@ static bool nat_evaluate_addr_has_th_expr(const struct expr *map) if (concat ->etype != EXPR_CONCAT) return false; - list_for_each_entry(i, &concat->expressions, list) { + list_for_each_entry(i, &expr_concat(concat)->expressions, list) { enum proto_bases base; if (i->etype == EXPR_PAYLOAD && @@ -4245,7 +4247,7 @@ static void expr_family_infer(struct proto_ctx *pctx, const struct expr *expr, if (expr->etype == EXPR_MAP) { switch (expr->map->etype) { case EXPR_CONCAT: - list_for_each_entry(i, &expr->map->expressions, list) { + list_for_each_entry(i, &expr_concat(expr->map)->expressions, list) { if (i->etype == EXPR_PAYLOAD) { if (i->payload.desc == &proto_ip) *family = NFPROTO_IPV4; @@ -4356,10 +4358,10 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt) goto out; } - one = list_first_entry(&data->expressions, struct expr, list); + one = list_first_entry(&expr_concat(data)->expressions, struct expr, list); two = list_entry(one->list.next, struct expr, list); - if (one == two || !list_is_last(&two->list, &data->expressions)) { + if (one == two || !list_is_last(&two->list, &expr_concat(data)->expressions)) { err = __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size, BYTEORDER_BIG_ENDIAN, &stmt->nat.addr); @@ -4397,7 +4399,7 @@ static bool nat_concat_map(struct eval_ctx *ctx, struct stmt *stmt) switch (stmt->nat.addr->mappings->etype) { case EXPR_SET: - list_for_each_entry(i, &stmt->nat.addr->mappings->expressions, list) { + list_for_each_entry(i, &expr_set(stmt->nat.addr->mappings)->expressions, list) { if (i->etype == EXPR_MAPPING && i->right->etype == EXPR_CONCAT) { stmt->nat.type_flags |= STMT_NAT_F_CONCAT; @@ -4867,7 +4869,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) switch (map->mappings->etype) { case EXPR_SET: - set_flags |= mappings->set_flags; + set_flags |= expr_set(mappings)->set_flags; /* fallthrough */ case EXPR_VARIABLE: key = constant_expr_alloc(&stmt->location, @@ -4893,8 +4895,8 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) "Expression is not a map"); } - if (set_is_interval(map->mappings->set->init->set_flags) && - !(map->mappings->set->init->set_flags & NFT_SET_CONCAT) && + if (set_is_interval(expr_set(map->mappings->set->init)->set_flags) && + !(expr_set(map->mappings->set->init)->set_flags & NFT_SET_CONCAT) && interval_set_eval(ctx, ctx->set, map->mappings->set->init) < 0) return -1; @@ -5054,7 +5056,7 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct cmd *cmd) return -1; assert(cmd->expr->etype == EXPR_SET); - cmd->expr->set_flags |= NFT_SET_INTERVAL; + expr_set(cmd->expr)->set_flags |= NFT_SET_INTERVAL; } ctx->set = NULL; @@ -5082,7 +5084,7 @@ static int set_expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) uint32_t ntype = 0, size = 0; struct expr *i, *next; - list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { + list_for_each_entry_safe(i, next, &expr_concat(*expr)->expressions, list) { unsigned dsize_bytes; if (i->etype == EXPR_CT && @@ -5117,7 +5119,7 @@ static int set_expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) if (i->dtype->size) assert(dsize_bytes == div_round_up(i->dtype->size, BITS_PER_BYTE)); - (*expr)->field_len[(*expr)->field_count++] = dsize_bytes; + expr_concat(*expr)->field_len[expr_concat(*expr)->field_count++] = dsize_bytes; size += netlink_padded_len(i->len); if (size > NFT_MAX_EXPR_LEN_BITS) @@ -5228,9 +5230,9 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) } if (set->flags & NFT_SET_INTERVAL && set->key->etype == EXPR_CONCAT) { - memcpy(&set->desc.field_len, &set->key->field_len, + memcpy(&set->desc.field_len, &expr_concat(set->key)->field_len, sizeof(set->desc.field_len)); - set->desc.field_count = set->key->field_count; + set->desc.field_count = expr_concat(set->key)->field_count; set->flags |= NFT_SET_CONCAT; if (set->automerge) @@ -5240,7 +5242,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) if (set_is_anonymous(set->flags) && set->key->etype == EXPR_CONCAT) { struct expr *i; - list_for_each_entry(i, &set->init->expressions, list) { + list_for_each_entry(i, &expr_set(set->init)->expressions, list) { if ((i->etype == EXPR_SET_ELEM && i->key->etype != EXPR_CONCAT && i->key->etype != EXPR_SET_ELEM_CATCHALL) || @@ -5291,8 +5293,8 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) if (set_is_anonymous(set->flags)) { if (set->init->etype == EXPR_SET && - set_is_interval(set->init->set_flags) && - !(set->init->set_flags & NFT_SET_CONCAT) && + set_is_interval(expr_set(set->init)->set_flags) && + !(expr_set(set->init)->set_flags & NFT_SET_CONCAT) && interval_set_eval(ctx, set, set->init) < 0) return -1; @@ -5399,7 +5401,7 @@ static struct expr *expr_set_to_list(struct eval_ctx *ctx, struct expr *dev_expr struct location loc; LIST_HEAD(tmp); - list_for_each_entry_safe(expr, next, &dev_expr->expressions, list) { + list_for_each_entry_safe(expr, next, &expr_set(dev_expr)->expressions, list) { list_del(&expr->list); switch (expr->etype) { @@ -5411,7 +5413,7 @@ static struct expr *expr_set_to_list(struct eval_ctx *ctx, struct expr *dev_expr if (expr->etype == EXPR_SET) { expr = expr_set_to_list(ctx, expr); - list_splice_init(&expr->expressions, &tmp); + list_splice_init(&expr_list(expr)->expressions, &tmp); expr_free(expr); continue; } @@ -5433,7 +5435,7 @@ static struct expr *expr_set_to_list(struct eval_ctx *ctx, struct expr *dev_expr loc = dev_expr->location; expr_free(dev_expr); dev_expr = compound_expr_alloc(&loc, EXPR_LIST); - list_splice_init(&tmp, &dev_expr->expressions); + list_splice_init(&tmp, &expr_list(dev_expr)->expressions); return dev_expr; } @@ -5455,7 +5457,7 @@ static bool evaluate_device_expr(struct eval_ctx *ctx, struct expr **dev_expr) assert((*dev_expr)->etype == EXPR_LIST); - list_for_each_entry_safe(expr, next, &(*dev_expr)->expressions, list) { + list_for_each_entry_safe(expr, next, &expr_list(*dev_expr)->expressions, list) { list_del(&expr->list); switch (expr->etype) { @@ -5467,7 +5469,7 @@ static bool evaluate_device_expr(struct eval_ctx *ctx, struct expr **dev_expr) if (expr->etype == EXPR_SET) { expr = expr_set_to_list(ctx, expr); - list_splice_init(&expr->expressions, &tmp); + list_splice_init(&expr_list(expr)->expressions, &tmp); expr_free(expr); continue; } @@ -5481,7 +5483,7 @@ static bool evaluate_device_expr(struct eval_ctx *ctx, struct expr **dev_expr) list_add(&expr->list, &tmp); } - list_splice_init(&tmp, &(*dev_expr)->expressions); + list_splice_init(&tmp, &expr_list(*dev_expr)->expressions); return true; } diff --git a/src/expression.c b/src/expression.c index aa97413d..8cb63979 100644 --- a/src/expression.c +++ b/src/expression.c @@ -940,7 +940,7 @@ void relational_expr_pctx_update(struct proto_ctx *ctx, if (expr_is_singleton(right)) ops->pctx_update(ctx, &expr->location, left, right); else if (right->etype == EXPR_SET) { - list_for_each_entry(i, &right->expressions, list) { + list_for_each_entry(i, &expr_set(right)->expressions, list) { if (i->etype == EXPR_SET_ELEM && i->key->etype == EXPR_VALUE) ops->pctx_update(ctx, &expr->location, left, i->key); @@ -1022,7 +1022,8 @@ struct expr *compound_expr_alloc(const struct location *loc, struct expr *expr; expr = expr_alloc(loc, etype, &invalid_type, BYTEORDER_INVALID, 0); - init_list_head(&expr->expressions); + /* same layout for EXPR_CONCAT, EXPR_SET and EXPR_LIST. */ + init_list_head(&expr->expr_set.expressions); return expr; } @@ -1030,8 +1031,8 @@ static void compound_expr_clone(struct expr *new, const struct expr *expr) { struct expr *i; - init_list_head(&new->expressions); - list_for_each_entry(i, &expr->expressions, list) + init_list_head(&new->expr_set.expressions); + list_for_each_entry(i, &expr->expr_set.expressions, list) compound_expr_add(new, expr_clone(i)); } @@ -1039,7 +1040,7 @@ static void compound_expr_destroy(struct expr *expr) { struct expr *i, *next; - list_for_each_entry_safe(i, next, &expr->expressions, list) + list_for_each_entry_safe(i, next, &expr->expr_set.expressions, list) expr_free(i); } @@ -1049,7 +1050,7 @@ static void compound_expr_print(const struct expr *expr, const char *delim, const struct expr *i; const char *d = ""; - list_for_each_entry(i, &expr->expressions, list) { + list_for_each_entry(i, &expr->expr_set.expressions, list) { nft_print(octx, "%s", d); expr_print(i, octx); d = delim; @@ -1058,13 +1059,13 @@ static void compound_expr_print(const struct expr *expr, const char *delim, void compound_expr_add(struct expr *compound, struct expr *expr) { - list_add_tail(&expr->list, &compound->expressions); - compound->size++; + list_add_tail(&expr->list, &compound->expr_set.expressions); + compound->expr_set.size++; } void compound_expr_remove(struct expr *compound, struct expr *expr) { - compound->size--; + compound->expr_set.size--; list_del(&expr->list); } @@ -1104,7 +1105,7 @@ static int concat_expr_build_udata(struct nftnl_udata_buf *udbuf, struct expr *expr, *tmp; unsigned int i = 0; - list_for_each_entry_safe(expr, tmp, &concat_expr->expressions, list) { + list_for_each_entry_safe(expr, tmp, &expr_concat(concat_expr)->expressions, list) { struct nftnl_udata *nest_expr; int err; @@ -1268,12 +1269,12 @@ struct expr *list_expr_to_binop(struct expr *expr) { struct expr *first, *last = NULL, *i; - assert(!list_empty(&expr->expressions)); + assert(!list_empty(&expr_list(expr)->expressions)); - first = list_first_entry(&expr->expressions, struct expr, list); + first = list_first_entry(&expr_list(expr)->expressions, struct expr, list); i = first; - list_for_each_entry_continue(i, &expr->expressions, list) { + list_for_each_entry_continue(i, &expr_list(expr)->expressions, list) { if (first) { last = binop_expr_alloc(&expr->location, OP_OR, first, i); first = NULL; @@ -1285,7 +1286,7 @@ struct expr *list_expr_to_binop(struct expr *expr) assert(!first); /* zap list expressions, they have been moved to binop expression. */ - init_list_head(&expr->expressions); + init_list_head(&expr_list(expr)->expressions); expr_free(expr); return last; @@ -1300,7 +1301,7 @@ static const char *calculate_delim(const struct expr *expr, int *count, if (octx->force_newline) return newline; - if (set_is_anonymous(expr->set_flags)) + if (set_is_anonymous(expr_set(expr)->set_flags)) return singleline; if (!expr->dtype) @@ -1348,7 +1349,7 @@ static void set_expr_print(const struct expr *expr, struct output_ctx *octx) nft_print(octx, "{ "); - list_for_each_entry(i, &expr->expressions, list) { + list_for_each_entry(i, &expr_set(expr)->expressions, list) { nft_print(octx, "%s", d); expr_print(i, octx); count++; @@ -1364,7 +1365,7 @@ static void set_expr_set_type(const struct expr *expr, { struct expr *i; - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_set(expr)->expressions, list) expr_set_type(i, dtype, byteorder); } @@ -1385,7 +1386,7 @@ struct expr *set_expr_alloc(const struct location *loc, const struct set *set) if (!set) return set_expr; - set_expr->set_flags = set->flags; + expr_set(set_expr)->set_flags = set->flags; datatype_set(set_expr, set->key->dtype); return set_expr; @@ -1443,10 +1444,10 @@ static bool __set_expr_is_vmap(const struct expr *mappings) { const struct expr *mapping; - if (list_empty(&mappings->expressions)) + if (list_empty(&expr_set(mappings)->expressions)) return false; - mapping = list_first_entry(&mappings->expressions, struct expr, list); + mapping = list_first_entry(&expr_set(mappings)->expressions, struct expr, list); if (mapping->etype == EXPR_MAPPING && mapping->right->etype == EXPR_VERDICT) return true; diff --git a/src/intervals.c b/src/intervals.c index e5bbb038..8c8ce8c8 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -88,7 +88,7 @@ static void purge_elem(struct set_automerge_ctx *ctx, struct expr *i) i->key->range.low, i->key->range.high); } - list_move_tail(&i->list, &ctx->purge->expressions); + list_move_tail(&i->list, &expr_set(ctx->purge)->expressions); } static void remove_overlapping_range(struct set_automerge_ctx *ctx, @@ -101,7 +101,7 @@ static void remove_overlapping_range(struct set_automerge_ctx *ctx, } list_del(&i->list); expr_free(i); - ctx->init->size--; + expr_set(ctx->init)->size--; } struct range { @@ -129,7 +129,7 @@ static bool merge_ranges(struct set_automerge_ctx *ctx, mpz_set(prev_range->high, range->high); list_del(&i->list); expr_free(i); - ctx->init->size--; + expr_set(ctx->init)->size--; } return false; } @@ -139,16 +139,16 @@ static void set_sort_splice(struct expr *init, struct set *set) struct set *existing_set = set->existing_set; set_to_range(init); - list_expr_sort(&init->expressions); + list_expr_sort(&expr_set(init)->expressions); if (!existing_set || existing_set->errors) return; if (existing_set->init) { set_to_range(existing_set->init); - list_splice_sorted(&existing_set->init->expressions, - &init->expressions); - init_list_head(&existing_set->init->expressions); + list_splice_sorted(&expr_set(existing_set->init)->expressions, + &expr_set(init)->expressions); + init_list_head(&expr_set(existing_set->init)->expressions); } else { existing_set->init = set_expr_alloc(&internal_location, set); } @@ -174,7 +174,7 @@ static void setelem_automerge(struct set_automerge_ctx *ctx) mpz_init(range.high); mpz_init(rop); - list_for_each_entry_safe(i, next, &ctx->init->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(ctx->init)->expressions, list) { if (i->key->etype == EXPR_SET_ELEM_CATCHALL) continue; @@ -237,7 +237,7 @@ static void set_to_range(struct expr *init) { struct expr *i, *elem; - list_for_each_entry(i, &init->expressions, list) { + list_for_each_entry(i, &expr_set(init)->expressions, list) { elem = interval_expr_key(i); setelem_expr_to_range(elem); } @@ -258,7 +258,7 @@ int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set, if (set->flags & NFT_SET_MAP) { set_to_range(init); - list_expr_sort(&init->expressions); + list_expr_sort(&expr_set(init)->expressions); return 0; } @@ -268,9 +268,9 @@ int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set, setelem_automerge(&ctx); - list_for_each_entry_safe(i, next, &init->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(init)->expressions, list) { if (i->flags & EXPR_F_KERNEL) { - list_move_tail(&i->list, &existing_set->init->expressions); + list_move_tail(&i->list, &expr_set(existing_set->init)->expressions); } else if (existing_set) { if (debug_mask & NFT_DEBUG_SEGTREE) { pr_gmp_debug("add: [%Zx-%Zx]\n", @@ -278,11 +278,11 @@ int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set, } clone = expr_clone(i); clone->flags |= EXPR_F_KERNEL; - list_add_tail(&clone->list, &existing_set->init->expressions); + list_add_tail(&clone->list, &expr_set(existing_set->init)->expressions); } } - if (list_empty(&ctx.purge->expressions)) { + if (list_empty(&expr_set(ctx.purge)->expressions)) { expr_free(ctx.purge); return 0; } @@ -301,7 +301,7 @@ static void remove_elem(struct expr *prev, struct set *set, struct expr *purge) if (prev->flags & EXPR_F_KERNEL) { clone = expr_clone(prev); - list_move_tail(&clone->list, &purge->expressions); + list_move_tail(&clone->list, &expr_set(purge)->expressions); } } @@ -310,7 +310,7 @@ static void __adjust_elem_left(struct set *set, struct expr *prev, struct expr * prev->flags &= ~EXPR_F_KERNEL; mpz_set(prev->key->range.low, i->key->range.high); mpz_add_ui(prev->key->range.low, prev->key->range.low, 1); - list_move(&prev->list, &set->existing_set->init->expressions); + list_move(&prev->list, &expr_set(set->existing_set->init)->expressions); } static void adjust_elem_left(struct set *set, struct expr *prev, struct expr *i, @@ -329,7 +329,7 @@ static void __adjust_elem_right(struct set *set, struct expr *prev, struct expr prev->flags &= ~EXPR_F_KERNEL; mpz_set(prev->key->range.high, i->key->range.low); mpz_sub_ui(prev->key->range.high, prev->key->range.high, 1); - list_move(&prev->list, &set->existing_set->init->expressions); + list_move(&prev->list, &expr_set(set->existing_set->init)->expressions); } static void adjust_elem_right(struct set *set, struct expr *prev, struct expr *i, @@ -352,18 +352,18 @@ static void split_range(struct set *set, struct expr *prev, struct expr *i, if (prev->flags & EXPR_F_KERNEL) { clone = expr_clone(prev); - list_move_tail(&clone->list, &purge->expressions); + list_move_tail(&clone->list, &expr_set(purge)->expressions); } prev->flags &= ~EXPR_F_KERNEL; clone = expr_clone(prev); mpz_set(clone->key->range.low, i->key->range.high); mpz_add_ui(clone->key->range.low, i->key->range.high, 1); - list_add_tail(&clone->list, &set->existing_set->init->expressions); + list_add_tail(&clone->list, &expr_set(set->existing_set->init)->expressions); mpz_set(prev->key->range.high, i->key->range.low); mpz_sub_ui(prev->key->range.high, i->key->range.low, 1); - list_move(&prev->list, &set->existing_set->init->expressions); + list_move(&prev->list, &expr_set(set->existing_set->init)->expressions); list_del(&i->list); expr_free(i); @@ -407,7 +407,7 @@ static int setelem_delete(struct list_head *msgs, struct set *set, mpz_init(range.high); mpz_init(rop); - list_for_each_entry_safe(elem, next, &elems->expressions, list) { + list_for_each_entry_safe(elem, next, &expr_set(elems)->expressions, list) { i = interval_expr_key(elem); if (i->key->etype == EXPR_SET_ELEM_CATCHALL) { @@ -437,7 +437,7 @@ static int setelem_delete(struct list_head *msgs, struct set *set, if (elem->flags & EXPR_F_REMOVE) { if (prev->flags & EXPR_F_KERNEL) { prev->location = elem->location; - list_move_tail(&prev->list, &purge->expressions); + list_move_tail(&prev->list, &expr_set(purge)->expressions); } list_del(&elem->list); @@ -476,7 +476,7 @@ static void automerge_delete(struct list_head *msgs, struct set *set, }; ctx.purge = set_expr_alloc(&internal_location, set); - list_expr_sort(&init->expressions); + list_expr_sort(&expr_set(init)->expressions); setelem_automerge(&ctx); expr_free(ctx.purge); } @@ -486,8 +486,8 @@ static int __set_delete(struct list_head *msgs, struct expr *i, struct set *set, unsigned int debug_mask) { i->flags |= EXPR_F_REMOVE; - list_move_tail(&i->list, &existing_set->init->expressions); - list_expr_sort(&existing_set->init->expressions); + list_move_tail(&i->list, &expr_set(existing_set->init)->expressions); + list_expr_sort(&expr_set(existing_set->init)->expressions); return setelem_delete(msgs, set, init, existing_set->init, debug_mask); } @@ -513,38 +513,38 @@ int set_delete(struct list_head *msgs, struct cmd *cmd, struct set *set, existing_set->init = set_expr_alloc(&internal_location, set); } - list_splice_init(&init->expressions, &del_list); + list_splice_init(&expr_set(init)->expressions, &del_list); list_for_each_entry_safe(i, next, &del_list, list) { err = __set_delete(msgs, i, set, init, existing_set, debug_mask); if (err < 0) { - list_splice(&del_list, &init->expressions); + list_splice(&del_list, &expr_set(init)->expressions); return err; } } add = set_expr_alloc(&internal_location, set); - list_for_each_entry(i, &existing_set->init->expressions, list) { + list_for_each_entry(i, &expr_set(existing_set->init)->expressions, list) { if (!(i->flags & EXPR_F_KERNEL)) { clone = expr_clone(i); - list_add_tail(&clone->list, &add->expressions); + list_add_tail(&clone->list, &expr_set(add)->expressions); i->flags |= EXPR_F_KERNEL; } } if (debug_mask & NFT_DEBUG_SEGTREE) { - list_for_each_entry(i, &init->expressions, list) + list_for_each_entry(i, &expr_set(init)->expressions, list) pr_gmp_debug("remove: [%Zx-%Zx]\n", i->key->range.low, i->key->range.high); - list_for_each_entry(i, &add->expressions, list) + list_for_each_entry(i, &expr_set(add)->expressions, list) pr_gmp_debug("add: [%Zx-%Zx]\n", i->key->range.low, i->key->range.high); - list_for_each_entry(i, &existing_set->init->expressions, list) + list_for_each_entry(i, &expr_set(existing_set->init)->expressions, list) pr_gmp_debug("existing: [%Zx-%Zx]\n", i->key->range.low, i->key->range.high); } - if (list_empty(&add->expressions)) { + if (list_empty(&expr_set(add)->expressions)) { expr_free(add); return 0; } @@ -571,7 +571,7 @@ static int setelem_overlap(struct list_head *msgs, struct set *set, mpz_init(range.high); mpz_init(rop); - list_for_each_entry_safe(elem, next, &init->expressions, list) { + list_for_each_entry_safe(elem, next, &expr_set(init)->expressions, list) { i = interval_expr_key(elem); if (i->key->etype == EXPR_SET_ELEM_CATCHALL) @@ -640,13 +640,13 @@ int set_overlap(struct list_head *msgs, struct set *set, struct expr *init) err = setelem_overlap(msgs, set, init); - list_for_each_entry_safe(i, n, &init->expressions, list) { + list_for_each_entry_safe(i, n, &expr_set(init)->expressions, list) { if (i->flags & EXPR_F_KERNEL) - list_move_tail(&i->list, &existing_set->init->expressions); + list_move_tail(&i->list, &expr_set(existing_set->init)->expressions); else if (existing_set) { clone = expr_clone(i); clone->flags |= EXPR_F_KERNEL; - list_add_tail(&clone->list, &existing_set->init->expressions); + list_add_tail(&clone->list, &expr_set(existing_set->init)->expressions); } } @@ -665,7 +665,7 @@ static bool segtree_needs_first_segment(const struct set *set, * 4) This set is created with a number of initial elements. */ if ((set_is_anonymous(set->flags)) || - (set->init && set->init->size == 0) || + (set->init && expr_set(set->init)->size == 0) || (set->init == NULL && init) || (set->init == init)) { return true; @@ -683,7 +683,7 @@ int set_to_intervals(const struct set *set, struct expr *init, bool add) LIST_HEAD(intervals); mpz_t p; - list_for_each_entry_safe(i, n, &init->expressions, list) { + list_for_each_entry_safe(i, n, &expr_set(init)->expressions, list) { elem = interval_expr_key(i); if (elem->key->etype == EXPR_SET_ELEM_CATCHALL) @@ -715,7 +715,7 @@ int set_to_intervals(const struct set *set, struct expr *init, bool add) prev = i; } - list_splice_init(&intervals, &init->expressions); + list_splice_init(&intervals, &expr_set(init)->expressions); return 0; } @@ -232,11 +232,11 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set) if (set->automerge) json_object_set_new(root, "auto-merge", json_true()); - if (!nft_output_terse(octx) && set->init && set->init->size > 0) { + if (!nft_output_terse(octx) && set->init && expr_set(set->init)->size > 0) { json_t *array = json_array(); const struct expr *i; - list_for_each_entry(i, &set->init->expressions, list) + list_for_each_entry(i, &expr_set(set->init)->expressions, list) json_array_append_new(array, expr_print_json(i, octx)); json_object_set_new(root, "elem", array); @@ -658,7 +658,7 @@ json_t *concat_expr_json(const struct expr *expr, struct output_ctx *octx) json_t *array = json_array(); const struct expr *i; - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) json_array_append_new(array, expr_print_json(i, octx)); return nft_json_pack("{s:o}", "concat", array); @@ -669,7 +669,7 @@ json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx) json_t *array = json_array(); const struct expr *i; - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_set(expr)->expressions, list) json_array_append_new(array, expr_print_json(i, octx)); return nft_json_pack("{s:o}", "set", array); @@ -738,7 +738,7 @@ json_t *list_expr_json(const struct expr *expr, struct output_ctx *octx) json_t *array = json_array(); const struct expr *i; - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_list(expr)->expressions, list) json_array_append_new(array, expr_print_json(i, octx)); //return nft_json_pack("{s:s, s:o}", "type", "list", "val", array); diff --git a/src/mergesort.c b/src/mergesort.c index 0452d60a..bd1c2187 100644 --- a/src/mergesort.c +++ b/src/mergesort.c @@ -18,7 +18,7 @@ static void concat_expr_msort_value(const struct expr *expr, mpz_t value) const struct expr *i; char data[512]; - list_for_each_entry(i, &expr->expressions, list) { + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { ilen = div_round_up(i->len, BITS_PER_BYTE); mpz_export_data(data + len, i->value, i->byteorder, ilen); len += ilen; @@ -758,12 +758,12 @@ static struct nft_dev *nft_dev_array(const struct expr *dev_expr, int *num_devs) switch (dev_expr->etype) { case EXPR_LIST: - list_for_each_entry(expr, &dev_expr->expressions, list) + list_for_each_entry(expr, &expr_list(dev_expr)->expressions, list) len++; dev_array = xmalloc(sizeof(struct nft_dev) * len); - list_for_each_entry(expr, &dev_expr->expressions, list) { + list_for_each_entry(expr, &expr_list(dev_expr)->expressions, list) { nft_dev_add(dev_array, expr, i); i++; } @@ -1793,7 +1793,7 @@ static int mnl_nft_setelem_batch(const struct nftnl_set *nls, struct cmd *cmd, flags |= NLM_F_CREATE; if (init) - expr = list_first_entry(&init->expressions, struct expr, list); + expr = list_first_entry(&expr_set(init)->expressions, struct expr, list); next: nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(batch), msg_type, @@ -1813,16 +1813,16 @@ next: htonl(nftnl_set_get_u32(nls, NFTNL_SET_ID))); } - if (!init || list_empty(&init->expressions)) + if (!init || list_empty(&expr_set(init)->expressions)) return 0; assert(expr); nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS); - list_for_each_entry_from(expr, &init->expressions, list) { + list_for_each_entry_from(expr, &expr_set(init)->expressions, list) { if (set_is_non_concat_range(set)) { if (set_is_anonymous(set->flags) && - !list_is_last(&expr->list, &init->expressions)) + !list_is_last(&expr->list, &expr_set(init)->expressions)) next = list_next_entry(expr, list); else next = NULL; diff --git a/src/monitor.c b/src/monitor.c index 83977907..e0f97b4a 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -402,7 +402,7 @@ static bool netlink_event_range_cache(struct set *cached_set, } /* don't cache half-open range elements */ - elem = list_entry(dummyset->init->expressions.prev, struct expr, list); + elem = list_entry(expr_set(dummyset->init)->expressions.prev, struct expr, list); if (!set_elem_is_open_interval(elem) && dummyset->desc.field_count <= 1) { cached_set->rg_cache = expr_clone(elem); diff --git a/src/netlink.c b/src/netlink.c index e01cb56c..f2f4c5ea 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -132,8 +132,8 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, case EXPR_SET_ELEM_CATCHALL: break; default: - if (set->set_flags & NFT_SET_INTERVAL && - key->etype == EXPR_CONCAT && key->field_count > 1) { + if (expr_set(set)->set_flags & NFT_SET_INTERVAL && + key->etype == EXPR_CONCAT && expr_concat(key)->field_count > 1) { key->flags |= EXPR_F_INTERVAL; netlink_gen_key(key, &nld); key->flags &= ~EXPR_F_INTERVAL; @@ -199,7 +199,7 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, nftnl_udata_buf_len(udbuf)); nftnl_udata_buf_free(udbuf); } - if (set_is_datamap(set->set_flags) && data != NULL) { + if (set_is_datamap(expr_set(set)->set_flags) && data != NULL) { __netlink_gen_data(data, &nld, !(data->flags & EXPR_F_SINGLETON)); switch (data->etype) { case EXPR_VERDICT: @@ -224,7 +224,7 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, break; } } - if (set_is_objmap(set->set_flags) && data != NULL) { + if (set_is_objmap(expr_set(set)->set_flags) && data != NULL) { netlink_gen_data(data, &nld); nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_OBJREF, nld.value, nld.len); @@ -359,7 +359,7 @@ static void netlink_gen_concat_key(const struct expr *expr, memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) offset += __netlink_gen_concat_key(expr->flags, i, data + offset); nft_data_memcpy(nld, data, len); @@ -423,10 +423,10 @@ static void __netlink_gen_concat_expand(const struct expr *expr, memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) offset += __netlink_gen_concat_data(false, i, data + offset); - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) offset += __netlink_gen_concat_data(true, i, data + offset); nft_data_memcpy(nld, data, len); @@ -445,7 +445,7 @@ static void __netlink_gen_concat(const struct expr *expr, memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) offset += __netlink_gen_concat_data(expr->flags, i, data + offset); nft_data_memcpy(nld, data, len); @@ -1213,7 +1213,7 @@ void alloc_setelem_cache(const struct expr *set, struct nftnl_set *nls) struct nftnl_set_elem *nlse; const struct expr *expr; - list_for_each_entry(expr, &set->expressions, list) { + list_for_each_entry(expr, &expr_set(set)->expressions, list) { nlse = alloc_nftnl_setelem(set, expr); nftnl_set_elem_add(nls, nlse); } @@ -1360,7 +1360,7 @@ static struct expr *netlink_parse_concat_elem_key(const struct set *set, int off = dtype->subtypes; if (set->key->etype == EXPR_CONCAT) - n = list_first_entry(&set->key->expressions, struct expr, list); + n = list_first_entry(&expr_concat(set->key)->expressions, struct expr, list); concat = concat_expr_alloc(&data->location); while (off > 0) { @@ -1408,7 +1408,7 @@ static struct expr *netlink_parse_concat_elem(const struct set *set, } assert(list_empty(&expressions)); } else { - list_splice_tail(&expressions, &concat->expressions); + list_splice_tail(&expressions, &expr_concat(concat)->expressions); } expr_free(data); @@ -1679,7 +1679,7 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, else if (set->flags & NFT_SET_INTERVAL) interval_map_decompose(set->init); else - list_expr_sort(&ctx->set->init->expressions); + list_expr_sort(&expr_set(ctx->set->init)->expressions); nftnl_set_free(nls); ctx->set = NULL; @@ -1723,7 +1723,7 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, else if (set->flags & NFT_SET_INTERVAL) err = get_set_decompose(cache_set, set); else - list_expr_sort(&ctx->set->init->expressions); + list_expr_sort(&expr_set(ctx->set->init)->expressions); nftnl_set_free(nls); nftnl_set_free(nls_out); diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 48a3e33a..b4d4a3da 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2186,10 +2186,10 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, if (set_is_anonymous(set->flags) && set->init && - !list_empty(&set->init->expressions)) { + !list_empty(&expr_set(set->init)->expressions)) { struct expr *elem; - elem = list_first_entry(&set->init->expressions, struct expr, list); + elem = list_first_entry(&expr_set(set->init)->expressions, struct expr, list); if (elem->etype == EXPR_SET_ELEM && elem->key->etype == EXPR_VALUE) @@ -2476,7 +2476,7 @@ static void binop_adjust(const struct expr *binop, struct expr *right, if (!set_is_anonymous(right->set->flags)) break; - list_for_each_entry(i, &right->set->init->expressions, list) { + list_for_each_entry(i, &expr_set(right->set->init)->expressions, list) { switch (i->key->etype) { case EXPR_VALUE: binop_adjust_one(binop, i->key, shift); @@ -2822,7 +2822,7 @@ static void expr_postprocess_concat(struct rule_pp_ctx *ctx, struct expr **exprp assert(expr->etype == EXPR_CONCAT); ctx->flags |= RULE_PP_IN_CONCATENATION; - list_for_each_entry_safe(i, n, &expr->expressions, list) { + list_for_each_entry_safe(i, n, &expr_concat(expr)->expressions, list) { if (type) { dtype = concat_subtype_lookup(type, --off); expr_set_type(i, dtype, dtype->byteorder); @@ -2834,7 +2834,7 @@ static void expr_postprocess_concat(struct rule_pp_ctx *ctx, struct expr **exprp ntype = concat_subtype_add(ntype, i->dtype->type); } ctx->flags &= ~RULE_PP_IN_CONCATENATION; - list_splice(&tmp, &expr->expressions); + list_splice(&tmp, &expr_concat(expr)->expressions); __datatype_set(expr, concat_type_alloc(ntype)); } @@ -2861,7 +2861,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) expr_postprocess(ctx, &expr->right); break; case EXPR_SET: - list_for_each_entry(i, &expr->expressions, list) + list_for_each_entry(i, &expr_set(expr)->expressions, list) expr_postprocess(ctx, &i); break; case EXPR_CONCAT: @@ -3432,7 +3432,7 @@ static bool has_inner_desc(const struct expr *expr) case EXPR_BINOP: return has_inner_desc(expr->left); case EXPR_CONCAT: - list_for_each_entry(i, &expr->expressions, list) { + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { if (has_inner_desc(i)) return true; } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 5f73183b..8ac33d34 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -123,7 +123,7 @@ static void netlink_gen_concat(struct netlink_linearize_ctx *ctx, { const struct expr *i; - list_for_each_entry(i, &expr->expressions, list) { + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { netlink_gen_expr(ctx, i, dreg); dreg += netlink_register_space(i->len); } 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++) { diff --git a/src/parser_bison.y b/src/parser_bison.y index f9cc9098..5b84331f 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -2073,7 +2073,7 @@ chain_block : /* empty */ { $$ = $<chain>-1; } | chain_block DEVICES '=' flowtable_expr stmt_separator { if ($$->dev_expr) { - list_splice_init(&$4->expressions, &$$->dev_expr->expressions); + list_splice_init(&expr_list($4)->expressions, &expr_list($$->dev_expr)->expressions); expr_free($4); break; } diff --git a/src/parser_json.c b/src/parser_json.c index 08657f28..bd865de5 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1286,10 +1286,11 @@ static struct expr *json_parse_binop_expr(struct json_ctx *ctx, static struct expr *json_check_concat_expr(struct json_ctx *ctx, struct expr *e) { - if (e->size >= 2) + if (expr_concat(e)->size >= 2) return e; - json_error(ctx, "Concatenation with %d elements is illegal", e->size); + json_error(ctx, "Concatenation with %d elements is illegal", + expr_concat(e)->size); expr_free(e); return NULL; } @@ -424,7 +424,7 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts, return; } - if (set->init != NULL && set->init->size > 0) { + if (set->init != NULL && expr_set(set->init)->size > 0) { nft_print(octx, "%s%selements = ", opts->tab, opts->tab); if (set->timeout || set->elem_has_comment || @@ -1459,7 +1459,7 @@ void cmd_free(struct cmd *cmd) static int __do_add_elements(struct netlink_ctx *ctx, struct cmd *cmd, struct set *set, struct expr *expr, uint32_t flags) { - expr->set_flags |= set->flags; + expr_set(expr)->set_flags |= set->flags; if (mnl_nft_setelem_add(ctx, cmd, set, expr, flags) < 0) return -1; diff --git a/src/segtree.c b/src/segtree.c index 00db8810..70b4416c 100644 --- a/src/segtree.c +++ b/src/segtree.c @@ -77,9 +77,9 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init) mpz_init2(low, set->key->len); mpz_init2(high, set->key->len); - new_init = list_expr_alloc(&internal_location); + new_init = set_expr_alloc(&internal_location, NULL); - list_for_each_entry(i, &init->expressions, list) { + list_for_each_entry(i, &expr_set(init)->expressions, list) { switch (i->key->etype) { case EXPR_VALUE: set_elem_add(set, new_init, i->key->value, @@ -135,7 +135,7 @@ static struct expr *get_set_interval_find(const struct set *cache_set, mpz_init2(val, set->key->len); - list_for_each_entry(i, &set->init->expressions, list) { + list_for_each_entry(i, &expr_set(set->init)->expressions, list) { key = expr_value(i); switch (key->etype) { case EXPR_VALUE: @@ -236,7 +236,7 @@ int get_set_decompose(struct set *cache_set, struct set *set) new_init = set_expr_alloc(&internal_location, set); - list_for_each_entry_safe(i, next, &set->init->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(set->init)->expressions, list) { if (i->flags & EXPR_F_INTERVAL_END && left) { list_del(&left->list); list_del(&i->list); @@ -354,7 +354,7 @@ void concat_range_aggregate(struct expr *set) int prefix_len, free_r1; mpz_t range, p; - list_for_each_entry_safe(i, next, &set->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(set)->expressions, list) { if (!start) { start = i; continue; @@ -366,10 +366,10 @@ void concat_range_aggregate(struct expr *set) * store them by replacing r2 expressions, and free r1 * expressions. */ - r2 = list_first_entry(&expr_value(end)->expressions, + r2 = list_first_entry(&expr_concat(expr_value(end))->expressions, struct expr, list); list_for_each_entry_safe(r1, r1_next, - &expr_value(start)->expressions, + &expr_concat(expr_value(start))->expressions, list) { bool string_type = false; @@ -564,15 +564,15 @@ void interval_map_decompose(struct expr *set) unsigned int n, m, size; bool interval; - if (set->size == 0) + if (expr_set(set)->size == 0) return; - elements = xmalloc_array(set->size, sizeof(struct expr *)); - ranges = xmalloc_array(set->size * 2, sizeof(struct expr *)); + elements = xmalloc_array(expr_set(set)->size, sizeof(struct expr *)); + ranges = xmalloc_array(expr_set(set)->size * 2, sizeof(struct expr *)); /* Sort elements */ n = 0; - list_for_each_entry_safe(i, next, &set->expressions, list) { + list_for_each_entry_safe(i, next, &expr_set(set)->expressions, list) { key = NULL; if (i->etype == EXPR_SET_ELEM) key = i->key; |