diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluate.c | 41 | ||||
-rw-r--r-- | src/json.c | 2 | ||||
-rw-r--r-- | src/statement.c | 4 |
3 files changed, 41 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 13888e5b..7d59e260 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1579,6 +1579,9 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) return expr_error(ctx->msgs, map->mappings, "Expression is not a map"); break; + case EXPR_SET_REF: + /* symbol has been already evaluated to set reference */ + break; default: BUG("invalid mapping expression %s\n", expr_name(map->mappings)); @@ -3172,6 +3175,40 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt) return err; } +static bool nat_concat_map(struct eval_ctx *ctx, struct stmt *stmt) +{ + struct expr *i; + + if (stmt->nat.addr->etype != EXPR_MAP) + return false; + + switch (stmt->nat.addr->mappings->etype) { + case EXPR_SET: + list_for_each_entry(i, &stmt->nat.addr->mappings->expressions, list) { + if (i->etype == EXPR_MAPPING && + i->right->etype == EXPR_CONCAT) { + stmt->nat.type_flags |= STMT_NAT_F_CONCAT; + return true; + } + } + break; + case EXPR_SYMBOL: + /* expr_evaluate_map() see EXPR_SET_REF after this evaluation. */ + if (expr_evaluate(ctx, &stmt->nat.addr->mappings)) + return false; + + if (stmt->nat.addr->mappings->set->data->etype == EXPR_CONCAT) { + stmt->nat.type_flags |= STMT_NAT_F_CONCAT; + return true; + } + break; + default: + break; + } + + return false; +} + static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt) { int err; @@ -3185,7 +3222,9 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt) if (err < 0) return err; - if (stmt->nat.type_flags & STMT_NAT_F_CONCAT) { + if (nat_concat_map(ctx, stmt) || + stmt->nat.type_flags & STMT_NAT_F_CONCAT) { + err = stmt_evaluate_nat_map(ctx, stmt); if (err < 0) return err; @@ -1331,8 +1331,6 @@ static json_t *nat_type_flags_json(uint32_t type_flags) if (type_flags & STMT_NAT_F_PREFIX) json_array_append_new(array, json_string("prefix")); - if (type_flags & STMT_NAT_F_CONCAT) - json_array_append_new(array, json_string("concat")); return array; } diff --git a/src/statement.c b/src/statement.c index 6db7e397..06742c04 100644 --- a/src/statement.c +++ b/src/statement.c @@ -673,9 +673,7 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx) break; } - if (stmt->nat.type_flags & STMT_NAT_F_CONCAT) - nft_print(octx, " addr . port"); - else if (stmt->nat.type_flags & STMT_NAT_F_PREFIX) + if (stmt->nat.type_flags & STMT_NAT_F_PREFIX) nft_print(octx, " prefix"); nft_print(octx, " to"); |