[PATCH nft 3/4] src: tproxy: relax family restrictions

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

 



evaluation step currently prohibits

tproxy ip to 1.2.3.4 in ip family, and
tproxy ip6 to dead::1 in ip6.

This seems an arbitrary limitation, just accept this.
The current restriction would make json output support harder than needed,
as the tproxy expression generated from json path would have to
special-case the table its currently in, rather than just using the
family attribute in the json output.

We obviously still reject the family in case it mismatches
the table family (e.g., can't use ip address in ip6 table).

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 src/evaluate.c                | 30 +++++++++++++-----------------
 tests/py/ip/tproxy.t          |  4 ++--
 tests/py/ip/tproxy.t.payload  | 14 ++++++++++++++
 tests/py/ip6/tproxy.t         |  6 ++----
 tests/py/ip6/tproxy.t.payload | 11 ++---------
 5 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 3f15b322d503..8882fc7cc273 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2487,12 +2487,16 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
 
 static int stmt_evaluate_tproxy(struct eval_ctx *ctx, struct stmt *stmt)
 {
+	const struct proto_desc *nproto;
 	const struct datatype *dtype;
 	int err, len;
 
 	switch (ctx->pctx.family) {
 	case NFPROTO_IPV4:
-	case NFPROTO_IPV6:
+	case NFPROTO_IPV6: /* fallthrough */
+		if (stmt->tproxy.family == NFPROTO_UNSPEC)
+			stmt->tproxy.family = ctx->pctx.family;
+		break;
 	case NFPROTO_INET:
 		break;
 	default:
@@ -2507,22 +2511,14 @@ static int stmt_evaluate_tproxy(struct eval_ctx *ctx, struct stmt *stmt)
 	if (!stmt->tproxy.addr && !stmt->tproxy.port)
 		return stmt_error(ctx, stmt, "Either address or port must be specified!");
 
-	if (ctx->pctx.family != NFPROTO_INET) {
-		if (stmt->tproxy.family != NFPROTO_UNSPEC)
-			return stmt_error(ctx, stmt, "Family can only be specified in inet tables.");
-		stmt->tproxy.family = ctx->pctx.family;
-	}
-	else {
-		const struct proto_desc *nproto =
-			ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
-		if ((nproto == &proto_ip && stmt->tproxy.family == NFPROTO_IPV6) ||
-		    (nproto == &proto_ip6 && stmt->tproxy.family == NFPROTO_IPV4))
-			/* this prevents us from rules like
-			 * ip protocol tcp tproxy ip6 to [dead::beef]
-			 */
-			return stmt_error(ctx, stmt,
-					  "Conflicting network layer protocols.");
-	}
+	nproto = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
+	if ((nproto == &proto_ip && stmt->tproxy.family != NFPROTO_IPV4) ||
+	    (nproto == &proto_ip6 && stmt->tproxy.family != NFPROTO_IPV6))
+		/* this prevents us from rules like
+		 * ip protocol tcp tproxy ip6 to [dead::beef]
+		 */
+		return stmt_error(ctx, stmt,
+				  "Conflicting network layer protocols.");
 
 	if (stmt->tproxy.addr != NULL) {
 		if (stmt->tproxy.addr->ops->type == EXPR_RANGE)
diff --git a/tests/py/ip/tproxy.t b/tests/py/ip/tproxy.t
index 6e959f47bff6..dbd8f5e90a04 100644
--- a/tests/py/ip/tproxy.t
+++ b/tests/py/ip/tproxy.t
@@ -9,6 +9,6 @@ tproxy to :50080;fail
 meta l4proto 17 tproxy to 192.0.2.1;ok
 meta l4proto 6 tproxy to 192.0.2.1:50080;ok
 ip protocol 6 tproxy to :50080;ok
-meta l4proto 17 tproxy ip to 192.0.2.1;fail
-meta l4proto 6 tproxy ip to 192.0.2.1:50080;fail
+meta l4proto 17 tproxy ip to 192.0.2.1;ok;meta l4proto 17 tproxy to 192.0.2.1
+meta l4proto 6 tproxy ip to 192.0.2.1:50080;ok;meta l4proto 6 tproxy to 192.0.2.1:50080
 ip protocol 6 tproxy ip to :50080;fail
diff --git a/tests/py/ip/tproxy.t.payload b/tests/py/ip/tproxy.t.payload
index 9a899a8de966..035651f48cb3 100644
--- a/tests/py/ip/tproxy.t.payload
+++ b/tests/py/ip/tproxy.t.payload
@@ -20,3 +20,17 @@ ip x y
   [ immediate reg 1 0x0000a0c3 ]
   [ tproxy ip port reg 1 ]
 
+# meta l4proto 17 tproxy ip to 192.0.2.1
+ip x y 
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x00000011 ]
+  [ immediate reg 1 0x010200c0 ]
+  [ tproxy ip addr reg 1 ]
+
+# meta l4proto 6 tproxy ip to 192.0.2.1:50080
+ip x y 
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+  [ immediate reg 1 0x010200c0 ]
+  [ immediate reg 2 0x0000a0c3 ]
+  [ tproxy ip addr reg 1 port reg 2 ]
diff --git a/tests/py/ip6/tproxy.t b/tests/py/ip6/tproxy.t
index dcd2bd8f580a..4e48d81f13cc 100644
--- a/tests/py/ip6/tproxy.t
+++ b/tests/py/ip6/tproxy.t
@@ -9,8 +9,6 @@ tproxy to :50080;fail
 meta l4proto 6 tproxy to [2001:db8::1];ok
 meta l4proto 17 tproxy to [2001:db8::1]:50080;ok
 meta l4proto 6 tproxy to :50080;ok
-meta l4proto 6 tproxy ip6 to [2001:db8::1];fail
-meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080;fail
+meta l4proto 6 tproxy ip6 to [2001:db8::1];ok;meta l4proto 6 tproxy to [2001:db8::1]
+meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080;ok;meta l4proto 17 tproxy to [2001:db8::1]:50080
 meta l4proto 6 tproxy ip6 to :50080;fail
-
-
diff --git a/tests/py/ip6/tproxy.t.payload b/tests/py/ip6/tproxy.t.payload
index d03beee4940d..c78c8a1dd20a 100644
--- a/tests/py/ip6/tproxy.t.payload
+++ b/tests/py/ip6/tproxy.t.payload
@@ -20,14 +20,14 @@ ip6 x y
   [ immediate reg 1 0x0000a0c3 ]
   [ tproxy ip6 port reg 1 ]
 
-# meta l4proto 6 tproxy to [2001:db8::1]
+# meta l4proto 6 tproxy ip6 to [2001:db8::1]
 ip6 x y 
   [ meta load l4proto => reg 1 ]
   [ cmp eq reg 1 0x00000006 ]
   [ immediate reg 1 0xb80d0120 0x00000000 0x00000000 0x01000000 ]
   [ tproxy ip6 addr reg 1 ]
 
-# meta l4proto 17 tproxy to [2001:db8::1]:50080
+# meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080
 ip6 x y 
   [ meta load l4proto => reg 1 ]
   [ cmp eq reg 1 0x00000011 ]
@@ -35,10 +35,3 @@ ip6 x y
   [ immediate reg 2 0x0000a0c3 ]
   [ tproxy ip6 addr reg 1 port reg 2 ]
 
-# meta l4proto 6 tproxy to :50080
-ip6 x y 
-  [ meta load l4proto => reg 1 ]
-  [ cmp eq reg 1 0x00000006 ]
-  [ immediate reg 1 0x0000a0c3 ]
-  [ tproxy ip6 port reg 1 ]
-
-- 
2.16.4




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

  Powered by Linux