src: add redirect support
PATCH v2 1/1 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 <[email protected]>
---
v2: include regression tests-files
include/statement.h | 10 ++++++++ src/evaluate.c | 40 ++++++++++++++++++++++++++++++ src/netlink_delinearize.c | 52 +++++++++++++++++++++++++++++++++++++++ src/netlink_linearize.c | 49 +++++++++++++++++++++++++++++++++++++ src/parser.y | 23 ++++++++++++++++- src/scanner.l | 1 + src/statement.c | 29 ++++++++++++++++++++++ tests/regression/ip/redirect.t | 41 +++++++++++++++++++++++++++++++ tests/regression/ip6/redirect.t | 42 ++++++++++++++++++++++++++++++++ 9 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 tests/regression/ip/redirect.t create mode 100644 tests/regression/ip6/redirect.t
include/statement.h +10 -0
@@ -79,6 +79,13 @@ struct masq_stmt {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); +struct queue_stmt {struct expr *queue;uint16_t flags;
@@ -110,6 +117,7 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc,* @STMT_REJECT: REJECT statement * @STMT_NAT: NAT statement * @STMT_MASQ: masquerade statement +* @STMT_REDIR: redirect statement * @STMT_QUEUE: QUEUE statement * @STMT_CT: conntrack statement */
@@ -124,6 +132,7 @@ enum stmt_types {STMT_REJECT ,STMT_NAT ,STMT_MASQ , +STMT_REDIR ,STMT_QUEUE , STMT_CT, };
@@ -172,6 +181,7 @@ struct stmt {struct reject_stmt reject;struct nat_stmt nat;struct masq_stmt masq; +struct redir_stmt redir;struct queue_stmt queue;struct ct_stmt ct; };
src/evaluate.c +40 -0
@@ -1546,6 +1546,44 @@ out:return 0 ; } +static int stmt_evaluate_redir (struct eval_ctx *ctx,struct stmt *stmt) +{ +int err; +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" ); + } + +if (stmt->redir.proto !=NULL ) { +if (pctx->protocol[PROTO_BASE_TRANSPORT_HDR ].desc ==NULL ) +return stmt_binary_error (ctx, stmt->redir.proto, stmt, +"missing transport protocol match" ); + +expr_set_context (&ctx->ectx, &inet_service_type, +2 *BITS_PER_BYTE ); + err =expr_evaluate (ctx, &stmt->redir.proto); +if (err <0 ) +return err; + } + +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,
@@ -1608,6 +1646,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)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_CT :
src/netlink_delinearize.c +52 -0
70 lines not on this page · raw message
src/netlink_linearize.c +49 -0
61 lines not on this page · raw message
src/parser.y +21 -2
@@ -375,6 +375,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token SNAT "snat" %token DNAT "dnat" %token MASQUERADE "masquerade" +%token REDIRECT "redirect" %token RANDOM "random" %token RANDOM_FULLY "random-fully" %token PERSISTENT "persistent"
@@ -440,8 +441,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 masq_stmt masq_stmt_alloc -%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc +%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc +%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_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
@@ -1186,6 +1187,7 @@ stmt : verdict_stmt | queue_stmt | ct_stmt | masq_stmt + | redir_stmt ; verdict_stmt : verdict_expr
@@ -1420,6 +1422,23 @@ masq_stmt : masq_stmt_alloc masq_stmt_alloc : MASQUERADE { $$ = masq_stmt_alloc(&@$); } ; +redir_stmt : redir_stmt_alloc redir_stmt_arg + | redir_stmt_alloc + ; + +redir_stmt_alloc : REDIRECT { $$ = redir_stmt_alloc(&@$); } + ; + +redir_stmt_arg : COLON expr + { + $<stmt>0->redir.proto = $2; + } + | nf_nat_flags + { + $<stmt>0->redir.flags = $1; + } + ; + nf_nat_flags : nf_nat_flag | nf_nat_flags COMMA nf_nat_flag {
src/scanner.l +1 -0
@@ -317,6 +317,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "snat" { return SNAT; } "dnat" { return DNAT; } "masquerade" { return MASQUERADE; } +"redirect" { return REDIRECT; } "random" { return RANDOM; } "random-fully" { return RANDOM_FULLY; } "persistent" { return PERSISTENT; }
src/statement.c +29 -0
@@ -348,3 +348,32 @@ 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) +{ +printf ("redirect" ); + +if (stmt->redir.proto) { +printf (" :" ); +expr_print (stmt->redir.proto); + } + +print_nf_nat_flags (stmt->redir.flags); +} + +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); +}
tests/regression/ip/redirect.t new file +41 -0
41 lines not on this page · raw message
tests/regression/ip6/redirect.t new file +42 -0
42 lines not on this page · raw message