From fde8ddfc31bbc4015e8a76b40cc7e27bcd7920ff Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 17 Mar 2018 10:39:27 +0100 Subject: 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 Signed-off-by: Pablo Neira Ayuso --- src/statement.c | 74 +++++++++++---------------------------------------------- 1 file changed, 14 insertions(+), 60 deletions(-) (limited to 'src/statement.c') diff --git a/src/statement.c b/src/statement.c index d495ec44..b8e0b036 100644 --- a/src/statement.c +++ b/src/statement.c @@ -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) -{ - return 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) +struct stmt *nat_stmt_alloc(const struct location *loc, + enum nft_nat_etypes type) { - 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); -} + struct stmt *stmt = stmt_alloc(loc, &nat_stmt_ops); -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[] = { -- cgit v1.2.3