[nft PATCH] Combine redir and masq statements into nat

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

 



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 <phil@xxxxxx>
---
 include/statement.h       |  32 ++++-------
 src/evaluate.c            |  40 --------------
 src/netlink_delinearize.c |  32 +++++------
 src/netlink_linearize.c   | 135 +++++++++++++---------------------------------
 src/parser_bison.y        |  38 ++++++-------
 src/statement.c           |  74 +++++--------------------
 6 files changed, 89 insertions(+), 262 deletions(-)

diff --git a/include/statement.h b/include/statement.h
index bb4af9d341228..fa0b5dfa4bf56 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -98,28 +98,22 @@ struct reject_stmt {
 
 extern struct stmt *reject_stmt_alloc(const struct location *loc);
 
-struct nat_stmt {
-	enum nft_nat_types	type;
-	struct expr		*addr;
-	struct expr		*proto;
-	uint32_t		flags;
-};
-
-extern struct stmt *nat_stmt_alloc(const struct location *loc);
-
-struct masq_stmt {
-	uint32_t		flags;
-	struct expr		*proto;
+enum nft_nat_etypes {
+	__NFT_NAT_SNAT = NFT_NAT_SNAT,
+	__NFT_NAT_DNAT = NFT_NAT_DNAT,
+	NFT_NAT_MASQ,
+	NFT_NAT_REDIR,
 };
 
-extern struct stmt *masq_stmt_alloc(const struct location *loc);
-
-struct redir_stmt {
+struct nat_stmt {
+	enum nft_nat_etypes	type;
+	struct expr		*addr;
 	struct expr		*proto;
 	uint32_t		flags;
 };
 
-extern struct stmt *redir_stmt_alloc(const struct location *loc);
+extern struct stmt *nat_stmt_alloc(const struct location *loc,
+				   enum nft_nat_etypes type);
 
 struct queue_stmt {
 	struct expr		*queue;
@@ -233,8 +227,6 @@ extern struct stmt *xt_stmt_alloc(const struct location *loc);
  * @STMT_LOG:		log statement
  * @STMT_REJECT:	REJECT statement
  * @STMT_NAT:		NAT statement
- * @STMT_MASQ:		masquerade statement
- * @STMT_REDIR:		redirect statement
  * @STMT_QUEUE:		QUEUE statement
  * @STMT_CT:		conntrack statement
  * @STMT_SET:		set statement
@@ -260,8 +252,6 @@ enum stmt_types {
 	STMT_LOG,
 	STMT_REJECT,
 	STMT_NAT,
-	STMT_MASQ,
-	STMT_REDIR,
 	STMT_QUEUE,
 	STMT_CT,
 	STMT_SET,
@@ -324,8 +314,6 @@ struct stmt {
 		struct limit_stmt	limit;
 		struct reject_stmt	reject;
 		struct nat_stmt		nat;
-		struct masq_stmt	masq;
-		struct redir_stmt	redir;
 		struct queue_stmt	queue;
 		struct quota_stmt	quota;
 		struct ct_stmt		ct;
diff --git a/src/evaluate.c b/src/evaluate.c
index 8de5e48d728ad..6ae94b0f56de5 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2465,42 +2465,6 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
 	return 0;
 }
 
-static int stmt_evaluate_masq(struct eval_ctx *ctx, struct stmt *stmt)
-{
-	int err;
-
-	err = nat_evaluate_family(ctx, stmt);
-	if (err < 0)
-		return err;
-
-	if (stmt->masq.proto != NULL) {
-		err = nat_evaluate_transport(ctx, stmt, &stmt->masq.proto);
-		if (err < 0)
-			return err;
-	}
-
-	stmt->flags |= STMT_F_TERMINAL;
-	return 0;
-}
-
-static int stmt_evaluate_redir(struct eval_ctx *ctx, struct stmt *stmt)
-{
-	int err;
-
-	err = nat_evaluate_family(ctx, stmt);
-	if (err < 0)
-		return err;
-
-	if (stmt->redir.proto != NULL) {
-		err = nat_evaluate_transport(ctx, stmt, &stmt->redir.proto);
-		if (err < 0)
-			return err;
-	}
-
-	stmt->flags |= STMT_F_TERMINAL;
-	return 0;
-}
-
 static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt)
 {
 	int err;
@@ -2758,10 +2722,6 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
 		return stmt_evaluate_reject(ctx, stmt);
 	case STMT_NAT:
 		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_DUP:
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index b20047f14b55e..754a307e99f52 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -861,8 +861,8 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
 	enum nft_registers reg1, reg2;
 	int family;
 
-	stmt = nat_stmt_alloc(loc);
-	stmt->nat.type = nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_TYPE);
+	stmt = nat_stmt_alloc(loc,
+			      nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_TYPE));
 
 	family = nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_FAMILY);
 
@@ -951,8 +951,8 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
 	if (nftnl_expr_is_set(nle, NFTNL_EXPR_MASQ_FLAGS))
 		flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_MASQ_FLAGS);
 
-	stmt = masq_stmt_alloc(loc);
-	stmt->masq.flags = flags;
+	stmt = nat_stmt_alloc(loc, NFT_NAT_MASQ);
+	stmt->nat.flags = flags;
 
 	reg1 = netlink_parse_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN);
 	if (reg1) {
@@ -963,7 +963,7 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
 			goto out_err;
 		}
 		expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
-		stmt->masq.proto = proto;
+		stmt->nat.proto = proto;
 	}
 
 	reg2 = netlink_parse_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MAX);
@@ -975,9 +975,9 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
 			goto out_err;
 		}
 		expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
-		if (stmt->masq.proto != NULL)
-			proto = range_expr_alloc(loc, stmt->masq.proto, proto);
-		stmt->masq.proto = proto;
+		if (stmt->nat.proto != NULL)
+			proto = range_expr_alloc(loc, stmt->nat.proto, proto);
+		stmt->nat.proto = proto;
 	}
 
 	ctx->stmt = stmt;
@@ -995,11 +995,11 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
 	enum nft_registers reg1, reg2;
 	uint32_t flags;
 
-	stmt = redir_stmt_alloc(loc);
+	stmt = nat_stmt_alloc(loc, NFT_NAT_REDIR);
 
 	if (nftnl_expr_is_set(nle, NFTNL_EXPR_REDIR_FLAGS)) {
 		flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_REDIR_FLAGS);
-		stmt->redir.flags = flags;
+		stmt->nat.flags = flags;
 	}
 
 	reg1 = netlink_parse_register(nle, NFTNL_EXPR_REDIR_REG_PROTO_MIN);
@@ -1012,7 +1012,7 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
 		}
 
 		expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
-		stmt->redir.proto = proto;
+		stmt->nat.proto = proto;
 	}
 
 	reg2 = netlink_parse_register(nle, NFTNL_EXPR_REDIR_REG_PROTO_MAX);
@@ -1025,10 +1025,10 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
 		}
 
 		expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
-		if (stmt->redir.proto != NULL)
-			proto = range_expr_alloc(loc, stmt->redir.proto,
+		if (stmt->nat.proto != NULL)
+			proto = range_expr_alloc(loc, stmt->nat.proto,
 						 proto);
-		stmt->redir.proto = proto;
+		stmt->nat.proto = proto;
 	}
 
 	ctx->stmt = stmt;
@@ -2366,10 +2366,6 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
 			if (stmt->nat.proto != NULL)
 				expr_postprocess(&rctx, &stmt->nat.proto);
 			break;
-		case STMT_REDIR:
-			if (stmt->redir.proto != NULL)
-				expr_postprocess(&rctx, &stmt->redir.proto);
-			break;
 		case STMT_REJECT:
 			stmt_reject_postprocess(&rctx);
 			break;
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 12d143b5acc0d..1c06fc07e2fa6 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -946,15 +946,43 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
 	enum nft_registers pmin_reg, pmax_reg;
 	int registers = 0;
 	int family;
+	int nftnl_flag_attr;
+	int nftnl_reg_pmin, nftnl_reg_pmax;
 
-	nle = alloc_nft_expr("nat");
-	nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_TYPE, stmt->nat.type);
+	switch (stmt->nat.type) {
+	case NFT_NAT_SNAT:
+	case NFT_NAT_DNAT:
+		nle = alloc_nft_expr("nat");
+		nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_TYPE, stmt->nat.type);
 
-	family = nftnl_rule_get_u32(ctx->nlr, NFTNL_RULE_FAMILY);
-	nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FAMILY, family);
+		family = nftnl_rule_get_u32(ctx->nlr, NFTNL_RULE_FAMILY);
+		nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FAMILY, family);
+
+		nftnl_flag_attr = NFTNL_EXPR_NAT_FLAGS;
+		nftnl_reg_pmin = NFTNL_EXPR_NAT_REG_PROTO_MIN;
+		nftnl_reg_pmax = NFTNL_EXPR_NAT_REG_PROTO_MAX;
+		break;
+	case NFT_NAT_MASQ:
+		nle = alloc_nft_expr("masq");
+
+		nftnl_flag_attr = NFTNL_EXPR_MASQ_FLAGS;
+		nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN;
+		nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX;
+		break;
+	case NFT_NAT_REDIR:
+		nle = alloc_nft_expr("redir");
+
+		nftnl_flag_attr = NFTNL_EXPR_REDIR_FLAGS;
+		nftnl_reg_pmin = NFTNL_EXPR_REDIR_REG_PROTO_MIN;
+		nftnl_reg_pmax = NFTNL_EXPR_REDIR_REG_PROTO_MAX;
+		break;
+	default:
+		BUG("unknown nat type %d\n", stmt->nat.type);
+		break;
+	}
 
 	if (stmt->nat.flags != 0)
-		nftnl_expr_set_u32(nle, NFTNL_EXPR_NAT_FLAGS, stmt->nat.flags);
+		nftnl_expr_set_u32(nle, nftnl_flag_attr, stmt->nat.flags);
 
 	if (stmt->nat.addr) {
 		amin_reg = get_register(ctx, NULL);
@@ -988,98 +1016,11 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
 
 			netlink_gen_expr(ctx, stmt->nat.proto->left, pmin_reg);
 			netlink_gen_expr(ctx, stmt->nat.proto->right, pmax_reg);
-			netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MIN,
-					     pmin_reg);
-			netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MAX,
-					     pmax_reg);
+			netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
+			netlink_put_register(nle, nftnl_reg_pmax, pmax_reg);
 		} else {
 			netlink_gen_expr(ctx, stmt->nat.proto, pmin_reg);
-			netlink_put_register(nle, NFTNL_EXPR_NAT_REG_PROTO_MIN,
-					     pmin_reg);
-		}
-	}
-
-	while (registers > 0) {
-		release_register(ctx, NULL);
-		registers--;
-	}
-
-	nftnl_rule_add_expr(ctx->nlr, nle);
-}
-
-static void netlink_gen_masq_stmt(struct netlink_linearize_ctx *ctx,
-				  const struct stmt *stmt)
-{
-	enum nft_registers pmin_reg, pmax_reg;
-	struct nftnl_expr *nle;
-	int registers = 0;
-
-	nle = alloc_nft_expr("masq");
-	if (stmt->masq.flags != 0)
-		nftnl_expr_set_u32(nle, NFTNL_EXPR_MASQ_FLAGS,
-				      stmt->masq.flags);
-	if (stmt->masq.proto) {
-		pmin_reg = get_register(ctx, NULL);
-		registers++;
-
-		if (stmt->masq.proto->ops->type == EXPR_RANGE) {
-			pmax_reg = get_register(ctx, NULL);
-			registers++;
-
-			netlink_gen_expr(ctx, stmt->masq.proto->left, pmin_reg);
-			netlink_gen_expr(ctx, stmt->masq.proto->right, pmax_reg);
-			netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN, pmin_reg);
-			netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MAX, pmax_reg);
-		} else {
-			netlink_gen_expr(ctx, stmt->masq.proto, pmin_reg);
-			netlink_put_register(nle, NFTNL_EXPR_MASQ_REG_PROTO_MIN, pmin_reg);
-		}
-	}
-
-	while (registers > 0) {
-		release_register(ctx, NULL);
-		registers--;
-	}
-
-	nftnl_rule_add_expr(ctx->nlr, nle);
-}
-
-static void netlink_gen_redir_stmt(struct netlink_linearize_ctx *ctx,
-				   const struct stmt *stmt)
-{
-	struct nftnl_expr *nle;
-	enum nft_registers pmin_reg, pmax_reg;
-	int registers = 0;
-
-	nle = alloc_nft_expr("redir");
-
-	if (stmt->redir.flags != 0)
-		nftnl_expr_set_u32(nle, NFTNL_EXPR_REDIR_FLAGS,
-				      stmt->redir.flags);
-
-	if (stmt->redir.proto) {
-		pmin_reg = get_register(ctx, NULL);
-		registers++;
-
-		if (stmt->redir.proto->ops->type == EXPR_RANGE) {
-			pmax_reg = get_register(ctx, NULL);
-			registers++;
-
-			netlink_gen_expr(ctx, stmt->redir.proto->left,
-					 pmin_reg);
-			netlink_gen_expr(ctx, stmt->redir.proto->right,
-					 pmax_reg);
-			netlink_put_register(nle,
-					     NFTNL_EXPR_REDIR_REG_PROTO_MIN,
-					     pmin_reg);
-			netlink_put_register(nle,
-					     NFTNL_EXPR_REDIR_REG_PROTO_MAX,
-					     pmax_reg);
-		} else {
-			netlink_gen_expr(ctx, stmt->redir.proto, pmin_reg);
-			netlink_put_register(nle,
-					     NFTNL_EXPR_REDIR_REG_PROTO_MIN,
-					     pmin_reg);
+			netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
 		}
 	}
 
@@ -1310,10 +1251,6 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 		return netlink_gen_reject_stmt(ctx, stmt);
 	case STMT_NAT:
 		return netlink_gen_nat_stmt(ctx, stmt);
-	case STMT_MASQ:
-		return netlink_gen_masq_stmt(ctx, stmt);
-	case STMT_REDIR:
-		return netlink_gen_redir_stmt(ctx, stmt);
 	case STMT_DUP:
 		return netlink_gen_dup_stmt(ctx, stmt);
 	case STMT_QUEUE:
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 9c143832eed6e..f1617eeaf1496 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2417,16 +2417,8 @@ reject_opts		:       /* empty */
 nat_stmt		:	nat_stmt_alloc	nat_stmt_args
 			;
 
-nat_stmt_alloc		:	SNAT
-			{
-				$$ = nat_stmt_alloc(&@$);
-				$$->nat.type = NFT_NAT_SNAT;
-			}
-			|	DNAT
-			{
-				$$ = nat_stmt_alloc(&@$);
-				$$->nat.type = NFT_NAT_DNAT;
-			}
+nat_stmt_alloc		:	SNAT	{ $$ = nat_stmt_alloc(&@$, NFT_NAT_SNAT); }
+			|	DNAT	{ $$ = nat_stmt_alloc(&@$, NFT_NAT_DNAT); }
 			;
 
 primary_stmt_expr	:	symbol_expr		{ $$ = $1; }
@@ -2576,21 +2568,21 @@ masq_stmt		:	masq_stmt_alloc		masq_stmt_args
 			|	masq_stmt_alloc
 			;
 
-masq_stmt_alloc		:	MASQUERADE 	{ $$ = masq_stmt_alloc(&@$); }
+masq_stmt_alloc		:	MASQUERADE	{ $$ = nat_stmt_alloc(&@$, NFT_NAT_MASQ); }
 			;
 
 masq_stmt_args		:	TO 	COLON	stmt_expr
 			{
-				$<stmt>0->masq.proto = $3;
+				$<stmt>0->nat.proto = $3;
 			}
 			|	TO 	COLON	stmt_expr	nf_nat_flags
 			{
-				$<stmt>0->masq.proto = $3;
-				$<stmt>0->masq.flags = $4;
+				$<stmt>0->nat.proto = $3;
+				$<stmt>0->nat.flags = $4;
 			}
 			|	nf_nat_flags
 			{
-				$<stmt>0->masq.flags = $1;
+				$<stmt>0->nat.flags = $1;
 			}
 			;
 
@@ -2598,30 +2590,30 @@ redir_stmt		:	redir_stmt_alloc	redir_stmt_arg
 			|	redir_stmt_alloc
 			;
 
-redir_stmt_alloc	:	REDIRECT	{ $$ = redir_stmt_alloc(&@$); }
+redir_stmt_alloc	:	REDIRECT	{ $$ = nat_stmt_alloc(&@$, NFT_NAT_REDIR); }
 			;
 
 redir_stmt_arg		:	TO	stmt_expr
 			{
-				$<stmt>0->redir.proto = $2;
+				$<stmt>0->nat.proto = $2;
 			}
 			|	TO	COLON	stmt_expr
 			{
-				$<stmt>0->redir.proto = $3;
+				$<stmt>0->nat.proto = $3;
 			}
 			|	nf_nat_flags
 			{
-				$<stmt>0->redir.flags = $1;
+				$<stmt>0->nat.flags = $1;
 			}
 			|	TO	stmt_expr	nf_nat_flags
 			{
-				$<stmt>0->redir.proto = $2;
-				$<stmt>0->redir.flags = $3;
+				$<stmt>0->nat.proto = $2;
+				$<stmt>0->nat.flags = $3;
 			}
 			|	TO	COLON	stmt_expr	nf_nat_flags
 			{
-				$<stmt>0->redir.proto = $3;
-				$<stmt>0->redir.flags = $4;
+				$<stmt>0->nat.proto = $3;
+				$<stmt>0->nat.flags = $4;
 			}
 			;
 
diff --git a/src/statement.c b/src/statement.c
index d495ec447dfdc..b8e0b036b9ebd 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[] = {
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux