[nft PATCH 2/2] expr: add jool expressions

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

 



Jool statements are used to send packets to the Jool kernel module,
which is an IP/ICMP translator: www.jool.mx

Sample usage:

        modprobe jool
        jool instance add "name" --iptables -6 64:ff9b::/96
        sudo nft add rule inet table1 chain1 jool nat64 "name"

This feature was requested in Jool's bug tracker:
https://github.com/NICMx/Jool/issues/285

Signed-off-by: Alberto Leiva Popper <ydahhrk@xxxxxxxxx>
---
 include/statement.h       | 15 +++++++++++++++
 src/evaluate.c            |  1 +
 src/netlink_delinearize.c | 15 +++++++++++++++
 src/netlink_linearize.c   | 15 +++++++++++++++
 src/parser_bison.y        | 31 +++++++++++++++++++++++++++++++
 src/scanner.l             |  2 ++
 src/statement.c           | 33 +++++++++++++++++++++++++++++++++
 7 files changed, 112 insertions(+)

diff --git a/include/statement.h b/include/statement.h
index 8fb459ca..8f4cb0fd 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -253,6 +253,18 @@ struct xt_stmt {
 
 extern struct stmt *xt_stmt_alloc(const struct location *loc);
 
+enum nft_jool_type {
+	NFT_JOOL_SIIT = (1 << 0),
+	NFT_JOOL_NAT64 = (1 << 1),
+};
+
+struct jool_stmt {
+	enum nft_jool_type	type;
+	const char		*instance;
+};
+
+extern struct stmt *jool_stmt_alloc(const struct location *loc);
+
 /**
  * enum stmt_types - statement types
  *
@@ -281,6 +293,7 @@ extern struct stmt *xt_stmt_alloc(const struct location *loc);
  * @STMT_CONNLIMIT:	connection limit statement
  * @STMT_MAP:		map statement
  * @STMT_SYNPROXY:	synproxy statement
+ * @STMT_JOOL:		Jool statement
  */
 enum stmt_types {
 	STMT_INVALID,
@@ -309,6 +322,7 @@ enum stmt_types {
 	STMT_CONNLIMIT,
 	STMT_MAP,
 	STMT_SYNPROXY,
+	STMT_JOOL,
 };
 
 /**
@@ -374,6 +388,7 @@ struct stmt {
 		struct flow_stmt	flow;
 		struct map_stmt		map;
 		struct synproxy_stmt	synproxy;
+		struct jool_stmt	jool;
 	};
 };
 
diff --git a/src/evaluate.c b/src/evaluate.c
index fcc79386..592a3cc8 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3353,6 +3353,7 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
 	case STMT_QUOTA:
 	case STMT_NOTRACK:
 	case STMT_FLOW_OFFLOAD:
+	case STMT_JOOL:
 		return 0;
 	case STMT_EXPRESSION:
 		return stmt_evaluate_expr(ctx, stmt);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 79efda12..58a802f8 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1106,6 +1106,20 @@ out_err:
 	xfree(stmt);
 }
 
+static void netlink_parse_jool(struct netlink_parse_ctx *ctx,
+			       const struct location *loc,
+			       const struct nftnl_expr *nle)
+{
+	struct stmt *stmt;
+
+	stmt = jool_stmt_alloc(loc);
+	stmt->jool.type = nftnl_expr_get_u8(nle, NFTNL_EXPR_JOOL_TYPE);
+	stmt->jool.instance = xstrdup(nftnl_expr_get_str(nle,
+						     NFTNL_EXPR_JOOL_INSTANCE));
+
+	ctx->stmt = stmt;
+}
+
 static void netlink_parse_synproxy(struct netlink_parse_ctx *ctx,
 				   const struct location *loc,
 				   const struct nftnl_expr *nle)
@@ -1594,6 +1608,7 @@ static const struct {
 	{ .name = "flow_offload", .parse = netlink_parse_flow_offload },
 	{ .name = "xfrm",	.parse = netlink_parse_xfrm },
 	{ .name = "synproxy",	.parse = netlink_parse_synproxy },
+	{ .name = "jool",	.parse = netlink_parse_jool },
 };
 
 static int netlink_parse_expr(const struct nftnl_expr *nle,
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index e70e63b3..c0597f39 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -1434,6 +1434,19 @@ static void netlink_gen_meter_stmt(struct netlink_linearize_ctx *ctx,
 	nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
+static void netlink_gen_jool_stmt(struct netlink_linearize_ctx *ctx,
+				  const struct stmt *stmt)
+{
+	struct nftnl_expr *nle;
+
+	nle = alloc_nft_expr("jool");
+
+	nftnl_expr_set_u8(nle, NFTNL_EXPR_JOOL_TYPE, stmt->jool.type);
+	nftnl_expr_set_str(nle, NFTNL_EXPR_JOOL_INSTANCE, stmt->jool.instance);
+
+	nftnl_rule_add_expr(ctx->nlr, nle);
+}
+
 static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 			     const struct stmt *stmt)
 {
@@ -1487,6 +1500,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 		return netlink_gen_objref_stmt(ctx, stmt);
 	case STMT_MAP:
 		return netlink_gen_map_stmt(ctx, stmt);
+	case STMT_JOOL:
+		return netlink_gen_jool_stmt(ctx, stmt);
 	default:
 		BUG("unknown statement type %s\n", stmt->ops->name);
 	}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 3e8d6bd6..0999172c 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -523,6 +523,8 @@ int nft_lex(void *, void *, void *);
 %token FULLY_RANDOM		"fully-random"
 %token PERSISTENT		"persistent"
 
+%token JOOL			"jool"
+
 %token QUEUE			"queue"
 %token QUEUENUM			"num"
 %token BYPASS			"bypass"
@@ -642,6 +644,8 @@ int nft_lex(void *, void *, void *);
 %destructor { stmt_free($$); }	tproxy_stmt
 %type <stmt>			synproxy_stmt synproxy_stmt_alloc
 %destructor { stmt_free($$); }	synproxy_stmt synproxy_stmt_alloc
+%type <stmt>			jool_stmt jool_stmt_alloc
+%destructor { stmt_free($$); }	jool_stmt jool_stmt_alloc
 
 
 %type <stmt>			queue_stmt queue_stmt_alloc
@@ -2492,6 +2496,7 @@ stmt			:	verdict_stmt
 			|	set_stmt
 			|	map_stmt
 			|	synproxy_stmt
+			|	jool_stmt
 			;
 
 verdict_stmt		:	verdict_expr
@@ -3014,6 +3019,32 @@ synproxy_sack		:	/* empty */	{ $$ = 0; }
 			}
 			;
 
+jool_stmt		:	jool_stmt_alloc	jool_opts
+			;
+
+jool_stmt_alloc		:	JOOL
+			{
+				$$ = jool_stmt_alloc(&@$);
+			}
+			;
+
+jool_opts		:	string	string
+			{
+				if (!strcmp("siit", $1))
+					$<stmt>0->jool.type = NFT_JOOL_SIIT;
+				else if (!strcmp("nat64", $1))
+					$<stmt>0->jool.type = NFT_JOOL_NAT64;
+				else {
+					erec_queue(error(&@1, "invalid jool type (expected siit or nat64)"),
+						   state->msgs);
+					xfree($1);
+					YYERROR;
+				}
+				xfree($1);
+				$<stmt>0->jool.instance = $2;
+			}
+			;
+
 primary_stmt_expr	:	symbol_expr			{ $$ = $1; }
 			|	integer_expr			{ $$ = $1; }
 			|	boolean_expr			{ $$ = $1; }
diff --git a/src/scanner.l b/src/scanner.l
index 45699c85..9e8d637c 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -375,6 +375,8 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "fully-random"		{ return FULLY_RANDOM; }
 "persistent"		{ return PERSISTENT; }
 
+"jool"			{ return JOOL; }
+
 "ll"			{ return LL_HDR; }
 "nh"			{ return NETWORK_HDR; }
 "th"			{ return TRANSPORT_HDR; }
diff --git a/src/statement.c b/src/statement.c
index 182edac8..4ec27658 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -942,3 +942,36 @@ struct stmt *synproxy_stmt_alloc(const struct location *loc)
 {
 	return stmt_alloc(loc, &synproxy_stmt_ops);
 }
+
+static void jool_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
+{
+	const char *type = "<unknown>";
+
+	switch (stmt->jool.type) {
+	case NFT_JOOL_SIIT:
+		type = "siit";
+		break;
+	case NFT_JOOL_NAT64:
+		type = "nat64";
+		break;
+	}
+
+	nft_print(octx, "jool \"%s\" \"%s\"", type, stmt->jool.instance);
+}
+
+static void jool_stmt_destroy(struct stmt *stmt)
+{
+	xfree(stmt->jool.instance);
+}
+
+static const struct stmt_ops jool_stmt_ops = {
+	.type		= STMT_JOOL,
+	.name		= "jool",
+	.print		= jool_stmt_print,
+	.destroy	= jool_stmt_destroy,
+};
+
+struct stmt *jool_stmt_alloc(const struct location *loc)
+{
+	return stmt_alloc(loc, &jool_stmt_ops);
+}
-- 
2.17.1




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

  Powered by Linux