diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluate.c | 27 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 16 | ||||
-rw-r--r-- | src/netlink_linearize.c | 15 | ||||
-rw-r--r-- | src/parser.y | 17 | ||||
-rw-r--r-- | src/scanner.l | 1 | ||||
-rw-r--r-- | src/statement.c | 18 |
6 files changed, 92 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 83ef7498..108248a7 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1350,6 +1350,31 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt) return 0; } +static int stmt_evaluate_masq(struct eval_ctx *ctx, struct stmt *stmt) +{ + struct proto_ctx *pctx = &ctx->pctx; + + if (!pctx) + goto out; + + switch (pctx->family) { + case AF_INET: + expr_set_context(&ctx->ectx, &ipaddr_type, + 4 * BITS_PER_BYTE); + break; + case AF_INET6: + expr_set_context(&ctx->ectx, &ip6addr_type, + 16 * BITS_PER_BYTE); + break; + default: + return stmt_error(ctx, stmt, "ip and ip6 support only"); + } + +out: + stmt->flags |= STMT_F_TERMINAL; + return 0; +} + static int stmt_evaluate_ct(struct eval_ctx *ctx, struct stmt *stmt) { expr_set_context(&ctx->ectx, stmt->ct.tmpl->dtype, @@ -1410,6 +1435,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) return stmt_evaluate_reject(ctx, stmt); case STMT_NAT: return stmt_evaluate_nat(ctx, stmt); + case STMT_MASQ: + return stmt_evaluate_masq(ctx, stmt); case STMT_QUEUE: return stmt_evaluate_queue(ctx, stmt); case STMT_CT: diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 4bb4697c..38618ee8 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -568,6 +568,21 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx, list_add_tail(&stmt->list, &ctx->rule->stmts); } +static void netlink_parse_masq(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nft_rule_expr *nle) +{ + struct stmt *stmt; + + stmt = masq_stmt_alloc(loc); + + if (nft_rule_expr_is_set(nle, NFT_EXPR_MASQ_FLAGS)) + stmt->masq.flags = nft_rule_expr_get_u32(nle, + NFT_EXPR_MASQ_FLAGS); + + list_add_tail(&stmt->list, &ctx->rule->stmts); +} + static void netlink_parse_queue(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nft_rule_expr *nle) @@ -614,6 +629,7 @@ static const struct { { .name = "limit", .parse = netlink_parse_limit }, { .name = "reject", .parse = netlink_parse_reject }, { .name = "nat", .parse = netlink_parse_nat }, + { .name = "masq", .parse = netlink_parse_masq }, { .name = "queue", .parse = netlink_parse_queue }, }; diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 895cfa99..62155cc3 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -688,6 +688,19 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx, nft_rule_add_expr(ctx->nlr, nle); } +static void netlink_gen_masq_stmt(struct netlink_linearize_ctx *ctx, + const struct stmt *stmt) +{ + struct nft_rule_expr *nle; + + nle = alloc_nft_expr("masq"); + if (stmt->masq.flags != 0) + nft_rule_expr_set_u32(nle, NFT_EXPR_MASQ_FLAGS, + stmt->masq.flags); + + nft_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_queue_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { @@ -752,6 +765,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, return netlink_gen_reject_stmt(ctx, stmt); case STMT_NAT: return netlink_gen_nat_stmt(ctx, stmt); + case STMT_MASQ: + return netlink_gen_masq_stmt(ctx, stmt); case STMT_QUEUE: return netlink_gen_queue_stmt(ctx, stmt); case STMT_CT: diff --git a/src/parser.y b/src/parser.y index e813b258..9e9a8393 100644 --- a/src/parser.y +++ b/src/parser.y @@ -374,6 +374,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token SNAT "snat" %token DNAT "dnat" +%token MASQUERADE "masquerade" %token RANDOM "random" %token RANDOM_FULLY "random-fully" %token PERSISTENT "persistent" @@ -439,8 +440,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type <val> time_unit %type <stmt> reject_stmt reject_stmt_alloc %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc -%type <stmt> nat_stmt nat_stmt_alloc -%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc +%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc +%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc %type <val> nf_nat_flags nf_nat_flag %type <stmt> queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc @@ -1184,6 +1185,7 @@ stmt : verdict_stmt | nat_stmt | queue_stmt | ct_stmt + | masq_stmt ; verdict_stmt : verdict_expr @@ -1407,6 +1409,17 @@ nat_stmt_args : expr } ; +masq_stmt : masq_stmt_alloc + | masq_stmt_alloc nf_nat_flags + { + $$ = $1; + $$->masq.flags = $2; + } + ; + +masq_stmt_alloc : MASQUERADE { $$ = masq_stmt_alloc(&@$); } + ; + nf_nat_flags : nf_nat_flag | nf_nat_flags COMMA nf_nat_flag { diff --git a/src/scanner.l b/src/scanner.l index b5d7d4f9..32e59d98 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -316,6 +316,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "snat" { return SNAT; } "dnat" { return DNAT; } +"masquerade" { return MASQUERADE; } "random" { return RANDOM; } "random-fully" { return RANDOM_FULLY; } "persistent" { return PERSISTENT; } diff --git a/src/statement.c b/src/statement.c index f1d83fcb..0ae616a8 100644 --- a/src/statement.c +++ b/src/statement.c @@ -330,3 +330,21 @@ struct stmt *nat_stmt_alloc(const struct location *loc) { return stmt_alloc(loc, &nat_stmt_ops); } + +static void masq_stmt_print(const struct stmt *stmt) +{ + printf("masquerade"); + + print_nf_nat_flags(stmt->masq.flags); +} + +static const struct stmt_ops masq_stmt_ops = { + .type = STMT_MASQ, + .name = "masq", + .print = masq_stmt_print, +}; + +struct stmt *masq_stmt_alloc(const struct location *loc) +{ + return stmt_alloc(loc, &masq_stmt_ops); +} |