diff options
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index a865902c..91d6b254 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1367,6 +1367,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) { struct expr_ctx ectx = ctx->ectx; struct expr *map = *expr, *mappings; + const struct datatype *dtype; struct expr *key; expr_set_context(&ctx->ectx, NULL, 0); @@ -1389,10 +1390,14 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) mappings = implicit_set_declaration(ctx, "__map%d", key, mappings); - mappings->set->datatype = - datatype_get(set_datatype_alloc(ectx.dtype, - ectx.byteorder)); - mappings->set->datalen = ectx.len; + + dtype = set_datatype_alloc(ectx.dtype, ectx.byteorder); + + mappings->set->data = constant_expr_alloc(&netlink_location, + dtype, dtype->byteorder, + ectx.len, NULL); + if (ectx.len && mappings->set->data->len != ectx.len) + BUG("%d vs %d\n", mappings->set->data->len, ectx.len); map->mappings = mappings; @@ -1428,7 +1433,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) map->mappings->set->key->dtype->desc, map->map->dtype->desc); - datatype_set(map, map->mappings->set->datatype); + datatype_set(map, map->mappings->set->data->dtype); map->flags |= EXPR_F_CONSTANT; /* Data for range lookups needs to be in big endian order */ @@ -1458,7 +1463,12 @@ static int expr_evaluate_mapping(struct eval_ctx *ctx, struct expr **expr) "Key must be a constant"); mapping->flags |= mapping->left->flags & EXPR_F_SINGLETON; - expr_set_context(&ctx->ectx, set->datatype, set->datalen); + if (set->data) { + expr_set_context(&ctx->ectx, set->data->dtype, set->data->len); + } else { + assert((set->flags & NFT_SET_MAP) == 0); + } + if (expr_evaluate(ctx, &mapping->right) < 0) return -1; if (!expr_is_constant(mapping->right)) @@ -2103,7 +2113,7 @@ static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt, (*expr)->len); else if ((*expr)->dtype->type != TYPE_INTEGER && !datatype_equal((*expr)->dtype, dtype)) - return stmt_binary_error(ctx, *expr, stmt, + return stmt_binary_error(ctx, *expr, stmt, /* verdict vs invalid? */ "datatype mismatch: expected %s, " "expression has type %s", dtype->desc, (*expr)->dtype->desc); @@ -3097,9 +3107,9 @@ static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt) "Key expression comments are not supported"); if (stmt_evaluate_arg(ctx, stmt, - stmt->map.set->set->datatype, - stmt->map.set->set->datalen, - stmt->map.set->set->datatype->byteorder, + stmt->map.set->set->data->dtype, + stmt->map.set->set->data->len, + stmt->map.set->set->data->byteorder, &stmt->map.data->key) < 0) return -1; if (expr_is_constant(stmt->map.data)) @@ -3145,8 +3155,12 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) mappings = implicit_set_declaration(ctx, "__objmap%d", key, mappings); - mappings->set->datatype = &string_type; - mappings->set->datalen = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE; + + mappings->set->data = constant_expr_alloc(&netlink_location, + &string_type, + BYTEORDER_HOST_ENDIAN, + NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE, + NULL); mappings->set->objtype = stmt->objref.type; map->mappings = mappings; @@ -3181,7 +3195,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) map->mappings->set->key->dtype->desc, map->map->dtype->desc); - datatype_set(map, map->mappings->set->datatype); + datatype_set(map, map->mappings->set->data->dtype); map->flags |= EXPR_F_CONSTANT; /* Data for range lookups needs to be in big endian order */ @@ -3326,17 +3340,25 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return set_error(ctx, set, "concatenated types not supported in interval sets"); if (set_is_datamap(set->flags)) { - if (set->datatype == NULL) + if (set->data == NULL) return set_error(ctx, set, "map definition does not " "specify mapping data type"); - set->datalen = set->datatype->size; - if (set->datalen == 0 && set->datatype->type != TYPE_VERDICT) + if (set->data->len == 0 && set->data->dtype->type != TYPE_VERDICT) return set_error(ctx, set, "unqualified mapping data " "type specified in map definition"); } else if (set_is_objmap(set->flags)) { - set->datatype = &string_type; - set->datalen = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE; + if (set->data) { + assert(set->data->etype == EXPR_VALUE); + assert(set->data->dtype == &string_type); + } + + assert(set->data == NULL); + set->data = constant_expr_alloc(&netlink_location, &string_type, + BYTEORDER_HOST_ENDIAN, + NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE, + NULL); + } ctx->set = set; |