From fc53d1b6b93d9ca194334c43931753e19bcb127b Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Fri, 3 Oct 2014 14:46:41 +0200 Subject: src: add nat persistent and random options This patch adds more configuration options to the nat expression. The syntax is as follow: % nft add rule nat postrouting [flags] Flags are: random, persistent, random-fully. Example: % nft add rule nat postrouting dnat 1.1.1.1 random,persistent A requirement is to cache some [recent] copies of kernel headers. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 4 ++++ src/netlink_linearize.c | 3 +++ src/parser.y | 21 +++++++++++++++++++++ src/scanner.l | 3 +++ src/statement.c | 26 ++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) (limited to 'src') diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 397b65c0..4bb4697c 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -501,6 +501,10 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx, family = nft_rule_expr_get_u32(nle, NFT_EXPR_NAT_FAMILY); + if (nft_rule_expr_is_set(nle, NFT_EXPR_NAT_FLAGS)) + stmt->nat.flags = nft_rule_expr_get_u32(nle, + NFT_EXPR_NAT_FLAGS); + reg1 = nft_rule_expr_get_u32(nle, NFT_EXPR_NAT_REG_ADDR_MIN); if (reg1) { addr = netlink_get_register(ctx, loc, reg1); diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 29f8e9ae..895cfa99 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -634,6 +634,9 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx, family = nft_rule_attr_get_u32(ctx->nlr, NFT_RULE_ATTR_FAMILY); nft_rule_expr_set_u32(nle, NFT_EXPR_NAT_FAMILY, family); + if (stmt->nat.flags != 0) + nft_rule_expr_set_u32(nle, NFT_EXPR_NAT_FLAGS, stmt->nat.flags); + if (stmt->nat.addr) { amin_reg = get_register(ctx); registers++; diff --git a/src/parser.y b/src/parser.y index 03d6d138..aac25679 100644 --- a/src/parser.y +++ b/src/parser.y @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -376,6 +377,9 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token SNAT "snat" %token DNAT "dnat" +%token RANDOM "random" +%token RANDOM_FULLY "random-fully" +%token PERSISTENT "persistent" %token QUEUE "queue" %token QUEUENUM "num" @@ -440,6 +444,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc %type nat_stmt nat_stmt_alloc %destructor { stmt_free($$); } nat_stmt nat_stmt_alloc +%type nf_nat_flags nf_nat_flag %type queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc %type queue_stmt_flags queue_stmt_flag @@ -1456,6 +1461,22 @@ nat_stmt_args : expr { $0->nat.proto = $2; } + | nat_stmt_args nf_nat_flags + { + $0->nat.flags = $2; + } + ; + +nf_nat_flags : nf_nat_flag + | nf_nat_flags COMMA nf_nat_flag + { + $$ = $1 | $3; + } + ; + +nf_nat_flag : RANDOM { $$ = NF_NAT_RANGE_PROTO_RANDOM; } + | RANDOM_FULLY { $$ = NF_NAT_RANGE_PROTO_RANDOM_FULLY; } + | PERSISTENT { $$ = NF_NAT_RANGE_PERSISTENT; } ; queue_stmt : queue_stmt_alloc diff --git a/src/scanner.l b/src/scanner.l index 9f054fdf..0955c4af 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -319,6 +319,9 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "snat" { return SNAT; } "dnat" { return DNAT; } +"random" { return RANDOM; } +"random-fully" { return RANDOM_FULLY; } +"persistent" { return PERSISTENT; } "ll" { return LL_HDR; } "nh" { return NETWORK_HDR; } diff --git a/src/statement.c b/src/statement.c index 357f0948..f1d83fcb 100644 --- a/src/statement.c +++ b/src/statement.c @@ -24,6 +24,9 @@ #include #include +#include +#include + struct stmt *stmt_alloc(const struct location *loc, const struct stmt_ops *ops) { @@ -271,6 +274,27 @@ struct stmt *reject_stmt_alloc(const struct location *loc) return stmt_alloc(loc, &reject_stmt_ops); } +static void print_nf_nat_flags(uint32_t flags) +{ + const char *delim = " "; + + if (flags == 0) + return; + + if (flags & NF_NAT_RANGE_PROTO_RANDOM) { + printf("%srandom", delim); + delim = ","; + } + + if (flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) { + printf("%srandom-fully", delim); + delim = ","; + } + + if (flags & NF_NAT_RANGE_PERSISTENT) + printf("%spersistent", delim); +} + static void nat_stmt_print(const struct stmt *stmt) { static const char *nat_types[] = { @@ -285,6 +309,8 @@ static void nat_stmt_print(const struct stmt *stmt) printf(":"); expr_print(stmt->nat.proto); } + + print_nf_nat_flags(stmt->nat.flags); } static void nat_stmt_destroy(struct stmt *stmt) -- cgit v1.2.3