summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/statement.h9
-rw-r--r--src/evaluate.c27
-rw-r--r--src/netlink_delinearize.c16
-rw-r--r--src/netlink_linearize.c15
-rw-r--r--src/parser.y17
-rw-r--r--src/scanner.l1
-rw-r--r--src/statement.c18
7 files changed, 101 insertions, 2 deletions
diff --git a/include/statement.h b/include/statement.h
index e5232542..35c1b7ae 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -73,6 +73,12 @@ struct nat_stmt {
extern struct stmt *nat_stmt_alloc(const struct location *loc);
+struct masq_stmt {
+ uint32_t flags;
+};
+
+extern struct stmt *masq_stmt_alloc(const struct location *loc);
+
struct queue_stmt {
struct expr *queue;
uint16_t flags;
@@ -103,6 +109,7 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc,
* @STMT_LOG: log statement
* @STMT_REJECT: REJECT statement
* @STMT_NAT: NAT statement
+ * @STMT_MASQ: masquerade statement
* @STMT_QUEUE: QUEUE statement
* @STMT_CT: conntrack statement
*/
@@ -116,6 +123,7 @@ enum stmt_types {
STMT_LOG,
STMT_REJECT,
STMT_NAT,
+ STMT_MASQ,
STMT_QUEUE,
STMT_CT,
};
@@ -163,6 +171,7 @@ struct stmt {
struct limit_stmt limit;
struct reject_stmt reject;
struct nat_stmt nat;
+ struct masq_stmt masq;
struct queue_stmt queue;
struct ct_stmt ct;
};
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);
+}