[PATCH 7/6 nft,v2] src: nat concatenation support with anonymous maps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch extends the parser to define the mapping datatypes, eg.

  ... dnat ip addr . port to ip saddr map { 1.1.1.1 : 2.2.2.2 . 30 }
  ... dnat ip addr . port to ip saddr map @y

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
v2: IPv6 support and fix incorrect datatype.

 src/evaluate.c            | 23 ++++++++++++++++++++---
 src/netlink_delinearize.c |  1 +
 src/parser_bison.y        |  7 +++++++
 src/scanner.l             |  1 +
 src/statement.c           |  3 +++
 5 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 0afd0403d3a4..2d4985c0d409 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2853,15 +2853,32 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
 {
 	struct expr *one, *two, *data, *tmp;
 	const struct datatype *dtype;
-	int err;
+	int addr_type, err;
 
-	dtype = get_addr_dtype(stmt->nat.family);
+	if (stmt->nat.ipportmap) {
+		switch (stmt->nat.family) {
+		case NFPROTO_IPV4:
+			addr_type = TYPE_IPADDR;
+			break;
+		case NFPROTO_IPV6:
+			addr_type = TYPE_IP6ADDR;
+			break;
+		default:
+			return -1;
+		}
+		dtype = concat_type_alloc((addr_type << TYPE_BITS) |
+					   TYPE_INET_SERVICE);
+	} else {
+		dtype = get_addr_dtype(stmt->nat.family);
+	}
 
 	expr_set_context(&ctx->ectx, dtype, dtype->size);
 	if (expr_evaluate(ctx, &stmt->nat.addr))
 		return -1;
 
 	data = stmt->nat.addr->mappings->set->data;
+	datatype_set(data, dtype);
+
 	if (expr_ops(data)->type != EXPR_CONCAT)
 		return __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
 					   BYTEORDER_BIG_ENDIAN,
@@ -2875,6 +2892,7 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
 					   BYTEORDER_BIG_ENDIAN,
 					   &stmt->nat.addr);
 
+	dtype = get_addr_dtype(stmt->nat.family);
 	tmp = one;
 	err = __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
 				  BYTEORDER_BIG_ENDIAN,
@@ -2891,7 +2909,6 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
 	if (tmp != two)
 		BUG("Internal error: Unexpected alteration of l4 expression");
 
-	stmt->nat.ipportmap = true;
 	return err;
 }
 
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 6203a53c6154..0058e2cfe42a 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1065,6 +1065,7 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
 	}
 
 	if (is_nat_proto_map(addr, family)) {
+		stmt->nat.family = family;
 		stmt->nat.ipportmap = true;
 		ctx->stmt = stmt;
 		return;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index fd00b40a104a..4c27fcc635dc 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -373,6 +373,7 @@ int nft_lex(void *, void *, void *);
 %token FLAGS			"flags"
 %token CPI			"cpi"
 
+%token PORT			"port"
 %token UDP			"udp"
 %token SPORT			"sport"
 %token DPORT			"dport"
@@ -3141,6 +3142,12 @@ nat_stmt_args		:	stmt_expr
 			{
 				$<stmt>0->nat.flags = $2;
 			}
+			|	nf_key_proto ADDR DOT	PORT	TO	stmt_expr
+			{
+				$<stmt>0->nat.family = $1;
+				$<stmt>0->nat.addr = $6;
+				$<stmt>0->nat.ipportmap = true;
+			}
 			;
 
 masq_stmt		:	masq_stmt_alloc		masq_stmt_args
diff --git a/src/scanner.l b/src/scanner.l
index 3932883b9ade..45699c85d7d0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -471,6 +471,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "udplite"		{ return UDPLITE; }
 "sport"			{ return SPORT; }
 "dport"			{ return DPORT; }
+"port"			{ return PORT; }
 
 "tcp"			{ return TCP; }
 "ackseq"		{ return ACKSEQ; }
diff --git a/src/statement.c b/src/statement.c
index be35bceff19a..182edac8f2ec 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -607,6 +607,9 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
 			break;
 		}
 
+		if (stmt->nat.ipportmap)
+			nft_print(octx, " addr . port");
+
 		nft_print(octx, " to");
 	}
 
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux