mirror of
https://git.netfilter.org/nftables
synced 2026-01-26 10:34:27 +00:00
Combine redir and masq statements into nat
All these statements are very similar, handling them with the same code is obvious. The only thing required here is a custom extension of enum nft_nat_types which is used in nat_stmt to distinguish between snat and dnat already. Though since enum nft_nat_types is part of kernel uAPI, create a local extended version containing the additional fields. Note that nat statement printing got a bit more complicated to get the number of spaces right for every possible combination of attributes. Note also that there wasn't a case for STMT_MASQ in rule_parse_postprocess(), which seems like a bug. Since STMT_MASQ became just a variant of STMT_NAT, postprocessing will take place for it now anyway. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
48632359f4
commit
fde8ddfc31
@ -98,28 +98,22 @@ struct reject_stmt {
|
||||
|
||||
extern struct stmt *reject_stmt_alloc(const struct location *loc);
|
||||
|
||||
enum nft_nat_etypes {
|
||||
__NFT_NAT_SNAT = NFT_NAT_SNAT,
|
||||
__NFT_NAT_DNAT = NFT_NAT_DNAT,
|
||||
NFT_NAT_MASQ,
|
||||
NFT_NAT_REDIR,
|
||||
};
|
||||
|
||||
struct nat_stmt {
|
||||
enum nft_nat_types type;
|
||||
enum nft_nat_etypes type;
|
||||
struct expr *addr;
|
||||
struct expr *proto;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
extern struct stmt *nat_stmt_alloc(const struct location *loc);
|
||||
|
||||
struct masq_stmt {
|
||||
uint32_t flags;
|
||||
struct expr *proto;
|
||||
};
|
||||
|
||||
extern struct stmt *masq_stmt_alloc(const struct location *loc);
|
||||
|
||||
struct redir_stmt {
|
||||
struct expr *proto;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
extern struct stmt *redir_stmt_alloc(const struct location *loc);
|
||||
extern struct stmt *nat_stmt_alloc(const struct location *loc,
|
||||
enum nft_nat_etypes type);
|
||||
|
||||
struct queue_stmt {
|
||||
struct expr *queue;
|
||||
@ -233,8 +227,6 @@ extern struct stmt *xt_stmt_alloc(const struct location *loc);
|
||||
* @STMT_LOG: log statement
|
||||
* @STMT_REJECT: REJECT statement
|
||||
* @STMT_NAT: NAT statement
|
||||
* @STMT_MASQ: masquerade statement
|
||||
* @STMT_REDIR: redirect statement
|
||||
* @STMT_QUEUE: QUEUE statement
|
||||
* @STMT_CT: conntrack statement
|
||||
* @STMT_SET: set statement
|
||||
@ -260,8 +252,6 @@ enum stmt_types {
|
||||
STMT_LOG,
|
||||
STMT_REJECT,
|
||||
STMT_NAT,
|
||||
STMT_MASQ,
|
||||
STMT_REDIR,
|
||||
STMT_QUEUE,
|
||||
STMT_CT,
|
||||
STMT_SET,
|
||||
@ -324,8 +314,6 @@ struct stmt {
|
||||
struct limit_stmt limit;
|
||||
struct reject_stmt reject;
|
||||
struct nat_stmt nat;
|
||||
struct masq_stmt masq;
|
||||
struct redir_stmt redir;
|
||||
struct queue_stmt queue;
|
||||
struct quota_stmt quota;
|
||||
struct ct_stmt ct;
|
||||
|
||||
@ -2465,42 +2465,6 @@ 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)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nat_evaluate_family(ctx, stmt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (stmt->masq.proto != NULL) {
|
||||
err = nat_evaluate_transport(ctx, stmt, &stmt->masq.proto);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
stmt->flags |= STMT_F_TERMINAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmt_evaluate_redir(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nat_evaluate_family(ctx, stmt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (stmt->redir.proto != NULL) {
|
||||
err = nat_evaluate_transport(ctx, stmt, &stmt->redir.proto);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
stmt->flags |= STMT_F_TERMINAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
{
|
||||
int err;
|
||||
@ -2758,10 +2722,6 @@ 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_REDIR:
|
||||
return stmt_evaluate_redir(ctx, stmt);
|
||||
case STMT_QUEUE:
|
||||
return stmt_evaluate_queue(ctx, stmt);
|
||||
case STMT_DUP:
|
||||
|
||||
@ -861,8 +861,8 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
|
||||
enum nft_registers reg1, reg2;
|
||||
int family;
|
||||
|
||||
stmt = nat_stmt_alloc(loc);
|
||||
stmt->nat.type = nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_TYPE);
|
||||
stmt = nat_stmt_alloc(loc,
|
||||
nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_TYPE));
|
||||
|
||||
family = nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_FAMILY);
|
||||
|
||||
@ -951,8 +951,8 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
|
||||
if (nftnl_expr_is_set(nle, NFTNL_EXPR_MASQ_FLAGS))
|
||||
flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_MASQ_FLAGS);
|
||||
|
||||
stmt = masq_stmt_alloc(loc);
|
||||
stmt->masq.flags = flags;
|
||||
stmt = nat_stmt_alloc(loc, NFT_NAT_MASQ);
|
||||
stmt->nat.flags = flags;
|
||||
|
||||
reg1 = netlink_parse_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN);
|
||||
if (reg1) {
|
||||
@ -963,7 +963,7 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
|
||||
goto out_err;
|
||||
}
|
||||
expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
stmt->masq.proto = proto;
|
||||
stmt->nat.proto = proto;
|
||||
}
|
||||
|
||||
reg2 = netlink_parse_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MAX);
|
||||
@ -975,9 +975,9 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
|
||||
goto out_err;
|
||||
}
|
||||
expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
if (stmt->masq.proto != NULL)
|
||||
proto = range_expr_alloc(loc, stmt->masq.proto, proto);
|
||||
stmt->masq.proto = proto;
|
||||
if (stmt->nat.proto != NULL)
|
||||
proto = range_expr_alloc(loc, stmt->nat.proto, proto);
|
||||
stmt->nat.proto = proto;
|
||||
}
|
||||
|
||||
ctx->stmt = stmt;
|
||||
@ -995,11 +995,11 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
|
||||
enum nft_registers reg1, reg2;
|
||||
uint32_t flags;
|
||||
|
||||
stmt = redir_stmt_alloc(loc);
|
||||
stmt = nat_stmt_alloc(loc, NFT_NAT_REDIR);
|
||||
|
||||
if (nftnl_expr_is_set(nle, NFTNL_EXPR_REDIR_FLAGS)) {
|
||||
flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_REDIR_FLAGS);
|
||||
stmt->redir.flags = flags;
|
||||
stmt->nat.flags = flags;
|
||||
}
|
||||
|
||||
reg1 = netlink_parse_register(nle, NFTNL_EXPR_REDIR_REG_PROTO_MIN);
|
||||
@ -1012,7 +1012,7 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
|
||||
}
|
||||
|
||||
expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
stmt->redir.proto = proto;
|
||||
stmt->nat.proto = proto;
|
||||
}
|
||||
|
||||
reg2 = netlink_parse_register(nle, NFTNL_EXPR_REDIR_REG_PROTO_MAX);
|
||||
@ -1025,10 +1025,10 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
|
||||
}
|
||||
|
||||
expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
if (stmt->redir.proto != NULL)
|
||||
proto = range_expr_alloc(loc, stmt->redir.proto,
|
||||
if (stmt->nat.proto != NULL)
|
||||
proto = range_expr_alloc(loc, stmt->nat.proto,
|
||||
proto);
|
||||
stmt->redir.proto = proto;
|
||||
stmt->nat.proto = proto;
|
||||
}
|
||||
|
||||
ctx->stmt = stmt;
|
||||
@ -2366,10 +2366,6 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
|
||||
if (stmt->nat.proto != NULL)
|
||||
expr_postprocess(&rctx, &stmt->nat.proto);
|
||||
break;
|
||||
case STMT_REDIR:
|
||||
if (stmt->redir.proto != NULL)
|
||||
expr_postprocess(&rctx, &stmt->redir.proto);
|
||||
break;
|
||||
case STMT_REJECT:
|
||||
stmt_reject_postprocess(&rctx);
|
||||
break;
|
||||
|
||||
@ -946,15 +946,43 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
|
||||
enum nft_registers pmin_reg, pmax_reg;
|
||||
int registers = 0;
|
||||
int family;
|
||||
int nftnl_flag_attr;
|
||||
int nftnl_reg_pmin, nftnl_reg_pmax;
|
||||
|
||||
nle = alloc_nft_expr("nat");
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_TYPE, stmt->nat.type);
|
||||
switch (stmt->nat.type) {
|
||||
case NFT_NAT_SNAT:
|
||||
case NFT_NAT_DNAT:
|
||||
nle = alloc_nft_expr("nat");
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_TYPE, stmt->nat.type);
|
||||
|
||||
family = nftnl_rule_get_u32(ctx->nlr, NFTNL_RULE_FAMILY);
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FAMILY, family);
|
||||
family = nftnl_rule_get_u32(ctx->nlr, NFTNL_RULE_FAMILY);
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FAMILY, family);
|
||||
|
||||
nftnl_flag_attr = NFTNL_EXPR_NAT_FLAGS;
|
||||
nftnl_reg_pmin = NFTNL_EXPR_NAT_REG_PROTO_MIN;
|
||||
nftnl_reg_pmax = NFTNL_EXPR_NAT_REG_PROTO_MAX;
|
||||
break;
|
||||
case NFT_NAT_MASQ:
|
||||
nle = alloc_nft_expr("masq");
|
||||
|
||||
nftnl_flag_attr = NFTNL_EXPR_MASQ_FLAGS;
|
||||
nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN;
|
||||
nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX;
|
||||
break;
|
||||
case NFT_NAT_REDIR:
|
||||
nle = alloc_nft_expr("redir");
|
||||
|
||||
nftnl_flag_attr = NFTNL_EXPR_REDIR_FLAGS;
|
||||
nftnl_reg_pmin = NFTNL_EXPR_REDIR_REG_PROTO_MIN;
|
||||
nftnl_reg_pmax = NFTNL_EXPR_REDIR_REG_PROTO_MAX;
|
||||
break;
|
||||
default:
|
||||
BUG("unknown nat type %d\n", stmt->nat.type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stmt->nat.flags != 0)
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FLAGS, stmt->nat.flags);
|
||||
nftnl_expr_set_u32(nle, nftnl_flag_attr, stmt->nat.flags);
|
||||
|
||||
if (stmt->nat.addr) {
|
||||
amin_reg = get_register(ctx, NULL);
|
||||
@ -988,98 +1016,11 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
|
||||
|
||||
netlink_gen_expr(ctx, stmt->nat.proto->left, pmin_reg);
|
||||
netlink_gen_expr(ctx, stmt->nat.proto->right, pmax_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MIN,
|
||||
pmin_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MAX,
|
||||
pmax_reg);
|
||||
netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
|
||||
netlink_put_register(nle, nftnl_reg_pmax, pmax_reg);
|
||||
} else {
|
||||
netlink_gen_expr(ctx, stmt->nat.proto, pmin_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MIN,
|
||||
pmin_reg);
|
||||
}
|
||||
}
|
||||
|
||||
while (registers > 0) {
|
||||
release_register(ctx, NULL);
|
||||
registers--;
|
||||
}
|
||||
|
||||
nftnl_rule_add_expr(ctx->nlr, nle);
|
||||
}
|
||||
|
||||
static void netlink_gen_masq_stmt(struct netlink_linearize_ctx *ctx,
|
||||
const struct stmt *stmt)
|
||||
{
|
||||
enum nft_registers pmin_reg, pmax_reg;
|
||||
struct nftnl_expr *nle;
|
||||
int registers = 0;
|
||||
|
||||
nle = alloc_nft_expr("masq");
|
||||
if (stmt->masq.flags != 0)
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_MASQ_FLAGS,
|
||||
stmt->masq.flags);
|
||||
if (stmt->masq.proto) {
|
||||
pmin_reg = get_register(ctx, NULL);
|
||||
registers++;
|
||||
|
||||
if (stmt->masq.proto->ops->type == EXPR_RANGE) {
|
||||
pmax_reg = get_register(ctx, NULL);
|
||||
registers++;
|
||||
|
||||
netlink_gen_expr(ctx, stmt->masq.proto->left, pmin_reg);
|
||||
netlink_gen_expr(ctx, stmt->masq.proto->right, pmax_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN, pmin_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MAX, pmax_reg);
|
||||
} else {
|
||||
netlink_gen_expr(ctx, stmt->masq.proto, pmin_reg);
|
||||
netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN, pmin_reg);
|
||||
}
|
||||
}
|
||||
|
||||
while (registers > 0) {
|
||||
release_register(ctx, NULL);
|
||||
registers--;
|
||||
}
|
||||
|
||||
nftnl_rule_add_expr(ctx->nlr, nle);
|
||||
}
|
||||
|
||||
static void netlink_gen_redir_stmt(struct netlink_linearize_ctx *ctx,
|
||||
const struct stmt *stmt)
|
||||
{
|
||||
struct nftnl_expr *nle;
|
||||
enum nft_registers pmin_reg, pmax_reg;
|
||||
int registers = 0;
|
||||
|
||||
nle = alloc_nft_expr("redir");
|
||||
|
||||
if (stmt->redir.flags != 0)
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_REDIR_FLAGS,
|
||||
stmt->redir.flags);
|
||||
|
||||
if (stmt->redir.proto) {
|
||||
pmin_reg = get_register(ctx, NULL);
|
||||
registers++;
|
||||
|
||||
if (stmt->redir.proto->ops->type == EXPR_RANGE) {
|
||||
pmax_reg = get_register(ctx, NULL);
|
||||
registers++;
|
||||
|
||||
netlink_gen_expr(ctx, stmt->redir.proto->left,
|
||||
pmin_reg);
|
||||
netlink_gen_expr(ctx, stmt->redir.proto->right,
|
||||
pmax_reg);
|
||||
netlink_put_register(nle,
|
||||
NFTNL_EXPR_REDIR_REG_PROTO_MIN,
|
||||
pmin_reg);
|
||||
netlink_put_register(nle,
|
||||
NFTNL_EXPR_REDIR_REG_PROTO_MAX,
|
||||
pmax_reg);
|
||||
} else {
|
||||
netlink_gen_expr(ctx, stmt->redir.proto, pmin_reg);
|
||||
netlink_put_register(nle,
|
||||
NFTNL_EXPR_REDIR_REG_PROTO_MIN,
|
||||
pmin_reg);
|
||||
netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1310,10 +1251,6 @@ 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_REDIR:
|
||||
return netlink_gen_redir_stmt(ctx, stmt);
|
||||
case STMT_DUP:
|
||||
return netlink_gen_dup_stmt(ctx, stmt);
|
||||
case STMT_QUEUE:
|
||||
|
||||
@ -2417,16 +2417,8 @@ reject_opts : /* empty */
|
||||
nat_stmt : nat_stmt_alloc nat_stmt_args
|
||||
;
|
||||
|
||||
nat_stmt_alloc : SNAT
|
||||
{
|
||||
$$ = nat_stmt_alloc(&@$);
|
||||
$$->nat.type = NFT_NAT_SNAT;
|
||||
}
|
||||
| DNAT
|
||||
{
|
||||
$$ = nat_stmt_alloc(&@$);
|
||||
$$->nat.type = NFT_NAT_DNAT;
|
||||
}
|
||||
nat_stmt_alloc : SNAT { $$ = nat_stmt_alloc(&@$, NFT_NAT_SNAT); }
|
||||
| DNAT { $$ = nat_stmt_alloc(&@$, NFT_NAT_DNAT); }
|
||||
;
|
||||
|
||||
primary_stmt_expr : symbol_expr { $$ = $1; }
|
||||
@ -2576,21 +2568,21 @@ masq_stmt : masq_stmt_alloc masq_stmt_args
|
||||
| masq_stmt_alloc
|
||||
;
|
||||
|
||||
masq_stmt_alloc : MASQUERADE { $$ = masq_stmt_alloc(&@$); }
|
||||
masq_stmt_alloc : MASQUERADE { $$ = nat_stmt_alloc(&@$, NFT_NAT_MASQ); }
|
||||
;
|
||||
|
||||
masq_stmt_args : TO COLON stmt_expr
|
||||
{
|
||||
$<stmt>0->masq.proto = $3;
|
||||
$<stmt>0->nat.proto = $3;
|
||||
}
|
||||
| TO COLON stmt_expr nf_nat_flags
|
||||
{
|
||||
$<stmt>0->masq.proto = $3;
|
||||
$<stmt>0->masq.flags = $4;
|
||||
$<stmt>0->nat.proto = $3;
|
||||
$<stmt>0->nat.flags = $4;
|
||||
}
|
||||
| nf_nat_flags
|
||||
{
|
||||
$<stmt>0->masq.flags = $1;
|
||||
$<stmt>0->nat.flags = $1;
|
||||
}
|
||||
;
|
||||
|
||||
@ -2598,30 +2590,30 @@ redir_stmt : redir_stmt_alloc redir_stmt_arg
|
||||
| redir_stmt_alloc
|
||||
;
|
||||
|
||||
redir_stmt_alloc : REDIRECT { $$ = redir_stmt_alloc(&@$); }
|
||||
redir_stmt_alloc : REDIRECT { $$ = nat_stmt_alloc(&@$, NFT_NAT_REDIR); }
|
||||
;
|
||||
|
||||
redir_stmt_arg : TO stmt_expr
|
||||
{
|
||||
$<stmt>0->redir.proto = $2;
|
||||
$<stmt>0->nat.proto = $2;
|
||||
}
|
||||
| TO COLON stmt_expr
|
||||
{
|
||||
$<stmt>0->redir.proto = $3;
|
||||
$<stmt>0->nat.proto = $3;
|
||||
}
|
||||
| nf_nat_flags
|
||||
{
|
||||
$<stmt>0->redir.flags = $1;
|
||||
$<stmt>0->nat.flags = $1;
|
||||
}
|
||||
| TO stmt_expr nf_nat_flags
|
||||
{
|
||||
$<stmt>0->redir.proto = $2;
|
||||
$<stmt>0->redir.flags = $3;
|
||||
$<stmt>0->nat.proto = $2;
|
||||
$<stmt>0->nat.flags = $3;
|
||||
}
|
||||
| TO COLON stmt_expr nf_nat_flags
|
||||
{
|
||||
$<stmt>0->redir.proto = $3;
|
||||
$<stmt>0->redir.flags = $4;
|
||||
$<stmt>0->nat.proto = $3;
|
||||
$<stmt>0->nat.flags = $4;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@ -499,10 +499,16 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||||
static const char * const nat_types[] = {
|
||||
[NFT_NAT_SNAT] = "snat",
|
||||
[NFT_NAT_DNAT] = "dnat",
|
||||
[NFT_NAT_MASQ] = "masquerade",
|
||||
[NFT_NAT_REDIR] = "redirect",
|
||||
};
|
||||
|
||||
nft_print(octx, "%s to ", nat_types[stmt->nat.type]);
|
||||
nft_print(octx, "%s", nat_types[stmt->nat.type]);
|
||||
if (stmt->nat.addr || stmt->nat.proto)
|
||||
nft_print(octx, " to");
|
||||
|
||||
if (stmt->nat.addr) {
|
||||
nft_print(octx, " ");
|
||||
if (stmt->nat.proto) {
|
||||
if (stmt->nat.addr->ops->type == EXPR_VALUE &&
|
||||
stmt->nat.addr->dtype->type == TYPE_IP6ADDR) {
|
||||
@ -525,6 +531,8 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||||
}
|
||||
|
||||
if (stmt->nat.proto) {
|
||||
if (!stmt->nat.addr)
|
||||
nft_print(octx, " ");
|
||||
nft_print(octx, ":");
|
||||
expr_print(stmt->nat.proto, octx);
|
||||
}
|
||||
@ -545,67 +553,13 @@ static const struct stmt_ops nat_stmt_ops = {
|
||||
.destroy = nat_stmt_destroy,
|
||||
};
|
||||
|
||||
struct stmt *nat_stmt_alloc(const struct location *loc)
|
||||
struct stmt *nat_stmt_alloc(const struct location *loc,
|
||||
enum nft_nat_etypes type)
|
||||
{
|
||||
return stmt_alloc(loc, &nat_stmt_ops);
|
||||
}
|
||||
struct stmt *stmt = stmt_alloc(loc, &nat_stmt_ops);
|
||||
|
||||
static void masq_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||||
{
|
||||
nft_print(octx, "masquerade");
|
||||
|
||||
if (stmt->masq.proto) {
|
||||
nft_print(octx, " to :");
|
||||
expr_print(stmt->masq.proto, octx);
|
||||
}
|
||||
|
||||
print_nf_nat_flags(stmt->masq.flags, octx);
|
||||
}
|
||||
|
||||
static void masq_stmt_destroy(struct stmt *stmt)
|
||||
{
|
||||
expr_free(stmt->masq.proto);
|
||||
}
|
||||
|
||||
static const struct stmt_ops masq_stmt_ops = {
|
||||
.type = STMT_MASQ,
|
||||
.name = "masq",
|
||||
.print = masq_stmt_print,
|
||||
.destroy = masq_stmt_destroy,
|
||||
};
|
||||
|
||||
struct stmt *masq_stmt_alloc(const struct location *loc)
|
||||
{
|
||||
return stmt_alloc(loc, &masq_stmt_ops);
|
||||
}
|
||||
|
||||
static void redir_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||||
{
|
||||
nft_print(octx, "redirect");
|
||||
|
||||
if (stmt->redir.proto) {
|
||||
nft_print(octx, " to :");
|
||||
expr_print(stmt->redir.proto, octx);
|
||||
}
|
||||
|
||||
print_nf_nat_flags(stmt->redir.flags, octx);
|
||||
}
|
||||
|
||||
static void redir_stmt_destroy(struct stmt *stmt)
|
||||
{
|
||||
expr_free(stmt->redir.proto);
|
||||
}
|
||||
|
||||
static const struct stmt_ops redir_stmt_ops = {
|
||||
.type = STMT_REDIR,
|
||||
.name = "redir",
|
||||
.print = redir_stmt_print,
|
||||
.destroy = redir_stmt_destroy,
|
||||
};
|
||||
|
||||
struct stmt *redir_stmt_alloc(const struct location *loc)
|
||||
{
|
||||
return stmt_alloc(loc, &redir_stmt_ops);
|
||||
stmt->nat.type = type;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static const char * const set_stmt_op_names[] = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user