diff options
author | Arturo Borrero <arturo.borrero.glez@gmail.com> | 2014-11-03 21:20:11 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-11-04 14:38:04 +0100 |
commit | a7469ab47400bf4add8269a2908965e82ceefc48 (patch) | |
tree | 649d8911984c4a200dc1f61247b518e2d019a78f /src/netlink_delinearize.c | |
parent | 8f4c613c9c1aa0ea6b565bbd1c5332317a3e7fdc (diff) |
src: add redirect support
This patch adds redirect support for nft.
The syntax is:
% nft add rule nat prerouting redirect [port] [nat_flags]
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r-- | src/netlink_delinearize.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 8f90cc03..1be409b1 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -583,6 +583,52 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx, list_add_tail(&stmt->list, &ctx->rule->stmts); } +static void netlink_parse_redir(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nft_rule_expr *nle) +{ + struct stmt *stmt; + struct expr *proto; + enum nft_registers reg1, reg2; + uint32_t flags; + + stmt = redir_stmt_alloc(loc); + + if (nft_rule_expr_is_set(nle, NFT_EXPR_REDIR_FLAGS)) { + flags = nft_rule_expr_get_u32(nle, NFT_EXPR_REDIR_FLAGS); + stmt->redir.flags = flags; + } + + reg1 = nft_rule_expr_get_u32(nle, NFT_EXPR_REDIR_REG_PROTO_MIN); + if (reg1) { + proto = netlink_get_register(ctx, loc, reg1); + if (proto == NULL) + return netlink_error(ctx, loc, + "redirect statement has no proto " + "expression"); + + expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); + stmt->redir.proto = proto; + } + + reg2 = nft_rule_expr_get_u32(nle, NFT_EXPR_REDIR_REG_PROTO_MAX); + if (reg2 && reg2 != reg1) { + proto = netlink_get_register(ctx, loc, reg2); + if (proto == NULL) + return netlink_error(ctx, loc, + "redirect statement has no proto " + "expression"); + + expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN); + if (stmt->redir.proto != NULL) + proto = range_expr_alloc(loc, stmt->redir.proto, + proto); + stmt->redir.proto = proto; + } + + 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) @@ -630,6 +676,7 @@ static const struct { { .name = "reject", .parse = netlink_parse_reject }, { .name = "nat", .parse = netlink_parse_nat }, { .name = "masq", .parse = netlink_parse_masq }, + { .name = "redir", .parse = netlink_parse_redir }, { .name = "queue", .parse = netlink_parse_queue }, }; @@ -1014,6 +1061,11 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r if (stmt->nat.proto != NULL) expr_postprocess(&rctx, stmt, &stmt->nat.proto); break; + case STMT_REDIR: + if (stmt->redir.proto != NULL) + expr_postprocess(&rctx, stmt, + &stmt->redir.proto); + break; case STMT_REJECT: stmt_reject_postprocess(rctx, stmt); break; |