summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-07-13 20:18:27 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2021-07-13 20:25:33 +0200
commitc68314dd4263575abaed43e052c7e61f6b359040 (patch)
tree858f9baaf7ebd9e697ca224739319c314b9519c2 /src
parent9b169bfc650ebeb81aff80ba2bf87d729dc3143e (diff)
src: infer NAT mapping with concatenation from set
If the map is anonymous, infer it from the set elements. Otherwise, the set definition already have an explicit concatenation definition in the data side of the mapping. This update simplifies the NAT mapping syntax with concatenations, e.g. snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c41
-rw-r--r--src/json.c2
-rw-r--r--src/statement.c4
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;
diff --git a/src/json.c b/src/json.c
index edc9d640..63b325af 100644
--- a/src/json.c
+++ b/src/json.c
@@ -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");