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]
---
v2: some cosmetic changes requested by Pablo.
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 +++++++++++++++++++++++++ 7 files changed, 202 insertions(+), 2 deletions(-)
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
@@ -1375,6 +1375,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,
@@ -1437,6 +1475,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); +}
Pablo Neira Ayuso
maintainerQuoted 5 lines · Arturo Borrero Gonzalez
This patch adds redirect support for nft.
The syntax is:
% nft add rule nat prerouting redirect [port|nat_flags]
I prefer if you add a couple of valid examples to the patch description. This won't work as the protocol is not specified.
There's also some minor issues with this patch:
% nft add rule nat prerouting redirect
Memory allocation failure
Please, address and resubmit, thanks Arturo.
Pablo Neira Ayuso
maintainerQuoted 10 lines · Pablo Neira Ayuso
Quoted 5 lines · Arturo Borrero Gonzalez
This patch adds redirect support for nft.
The syntax is:
% nft add rule nat prerouting redirect [port|nat_flags]
I prefer if you add a couple of valid examples to the patch description. This won't work as the protocol is not specified.
Quoted 6 lines
There's also some minor issues with this patch:
% nft add rule nat prerouting redirect
Memory allocation failurePlease, address and resubmit, thanks Arturo.
BTW, please integrate the .t test file for the automated regression testing in the next version of this patch.
Quoted 10 lines · Pablo Neira Ayuso
Quoted 5 lines · Arturo Borrero Gonzalez
This patch adds redirect support for nft.
The syntax is:
% nft add rule nat prerouting redirect [port|nat_flags]
I prefer if you add a couple of valid examples to the patch description. This won't work as the protocol is not specified.
Quoted 6 lines
There's also some minor issues with this patch:
% nft add rule nat prerouting redirect
Memory allocation failurePlease, address and resubmit, thanks Arturo.
Hi Pablo,
I've take further look at this patch. I don't see any issue.
As masquerade, I think redirect without protocol should work. I just tested again the patch with ICMP packets and the redirection simply works. I used tcpdump for the checks. The rule I used is the same as in the patch description.
Regarding the memory allocation failure, I'm unable to find the issue. Do you think is related to this patch? I just added thousands of redirect rules in both IPv4 and IPv6 with no failures nor leakages reported by valgrind.
I would request you a bit more info, please.
regards.
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso
maintainerQuoted 18 lines · Arturo Borrero Gonzalez
Quoted 10 lines · Pablo Neira Ayuso
Quoted 5 lines · Arturo Borrero Gonzalez
This patch adds redirect support for nft.
The syntax is:
% nft add rule nat prerouting redirect [port|nat_flags]
I prefer if you add a couple of valid examples to the patch description. This won't work as the protocol is not specified.
Quoted 6 lines
There's also some minor issues with this patch:
% nft add rule nat prerouting redirect
Memory allocation failurePlease, address and resubmit, thanks Arturo.
Quoted 8 lines
Hi Pablo,
I've take further look at this patch. I don't see any issue.
As masquerade, I think redirect without protocol should work. I just tested again the patch with ICMP packets and the redirection simply works. I used tcpdump for the checks. The rule I used is the same as in the patch description.
I think this needs to be:
% nft add rule nat prerouting redirect [port] [nat_flags]
And, I think it doesn't make any bad if you extend the description with some examples as I requested.
Or update the documentation in the same patch including the new redirect expression.
I'm going to apply this now, but next time please address my requests.
Quoted 1 line
Regarding the memory allocation failure, I'm unable to find the issue.
My fault, the "memory allocation failure" happens when you use an old libnftnl with no redirect support, which was the case in my testbed. I just fixed it here.
Quoted 5 lines · Pablo Neira Ayuso
I think this needs to be:
% nft add rule nat prerouting redirect [port] [
nat_flags]
The port and nat_flags arguments are mutually exclusives. That's why I used the [port|nat_flags] syntax.
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso
maintainerQuoted 9 lines · Arturo Borrero Gonzalez
Quoted 5 lines · Pablo Neira Ayuso
I think this needs to be:
% nft add rule nat prerouting redirect [port] [
nat_flags]The port and
nat_flagsarguments are mutually exclusives. That's why I used the [port|nat_flags] syntax.
iptables allows this:
-j REDIRECT --to-ports 8000-8010 --random
Quoted 8 lines · Pablo Neira Ayuso
Quoted 7 lines · Arturo Borrero Gonzalez
Quoted 5 lines · Pablo Neira Ayuso
I think this needs to be:
% nft add rule nat prerouting redirect [port] [
nat_flags]
Quoted 6 lines
Quoted 2 lines
The port and
nat_flagsarguments are mutually exclusives. That's why I used the [port|nat_flags] syntax.iptables allows this:
-j REDIRECT --to-ports 8000-8010 --random
Then, should I change the behaviour of the nft redirect parser? The code in my patch doesn't allow that.
I think it makes no sense: "redirect to this port; no sorry, redirect to a random one."
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso
maintainerQuoted 12 lines · Arturo Borrero Gonzalez
Quoted 11 lines · Pablo Neira Ayuso
Quoted 9 lines · Arturo Borrero Gonzalez
Quoted 5 lines · Pablo Neira Ayuso
I think this needs to be:
% nft add rule nat prerouting redirect [port] [
nat_flags]The port and
nat_flagsarguments are mutually exclusives. That's why I used the [port|nat_flags] syntax.
Quoted 6 lines
Quoted 3 lines
iptables allows this:
-j REDIRECT --to-ports 8000-8010 --random
Then, should I change the behaviour of the nft redirect parser? The code in my patch doesn't allow that.
Yes, you have to fix this.
Quoted 2 lines
I think it makes no sense: "redirect to this port; no sorry, redirect to a random one."
--to-ports reads as "redirect all traffic from ports 8000 to 8010" --random refers to --to-ports, it reads as "select the port from the 8000-8010 range at random"
If --random is not specified, then the NAT engines selects the destination port in that range one after another (8000, 8001, 8002, ...) IIRC.
Quoted 25 lines · Pablo Neira Ayuso
Quoted 12 lines · Arturo Borrero Gonzalez
Quoted 11 lines · Pablo Neira Ayuso
Quoted 9 lines · Arturo Borrero Gonzalez
Quoted 5 lines · Pablo Neira Ayuso
I think this needs to be:
% nft add rule nat prerouting redirect [port] [
nat_flags]The port and
nat_flagsarguments are mutually exclusives. That's why I used the [port|nat_flags] syntax.Quoted 6 lines
Quoted 3 lines
iptables allows this:
-j REDIRECT --to-ports 8000-8010 --random
Then, should I change the behaviour of the nft redirect parser? The code in my patch doesn't allow that.
Yes, you have to fix this.
Quoted 2 lines
I think it makes no sense: "redirect to this port; no sorry, redirect to a random one."
Quoted 6 lines
--to-ports reads as "redirect all traffic from ports 8000 to 8010" --random refers to --to-ports, it reads as "select the port from the 8000-8010 range at random"
If --random is not specified, then the NAT engines selects the destination port in that range one after another (8000, 8001, 8002, ...) IIRC.
Understood, thanks.
Signature · 5 lines
Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html