[PATCH nft 4/4] src: tproxy: add json support

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

 



Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 include/json.h              |  2 +
 src/json.c                  | 26 +++++++++++++
 src/parser_json.c           | 43 ++++++++++++++++++++
 src/statement.c             |  1 +
 tests/py/inet/tproxy.t.json | 91 +++++++++++++++++++++++++++++++++++++++++++
 tests/py/ip/tproxy.t.json   | 95 +++++++++++++++++++++++++++++++++++++++++++++
 tests/py/ip6/tproxy.t.json  | 90 ++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 348 insertions(+)
 create mode 100644 tests/py/inet/tproxy.t.json
 create mode 100644 tests/py/ip/tproxy.t.json
 create mode 100644 tests/py/ip6/tproxy.t.json

diff --git a/include/json.h b/include/json.h
index 78c026a7a7f6..e64151de66c0 100644
--- a/include/json.h
+++ b/include/json.h
@@ -76,6 +76,7 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *verdict_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
+json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx);
 
 int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd);
 
@@ -153,6 +154,7 @@ STMT_PRINT_STUB(meter)
 STMT_PRINT_STUB(queue)
 STMT_PRINT_STUB(verdict)
 STMT_PRINT_STUB(connlimit)
+STMT_PRINT_STUB(tproxy)
 
 #undef STMT_PRINT_STUB
 #undef EXPR_PRINT_STUB
diff --git a/src/json.c b/src/json.c
index 6112cf563125..6d9ddc151c07 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1300,6 +1300,32 @@ json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
 	return json_pack("{s:o}", "ct count", root);
 }
 
+json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
+{
+	json_t *root = json_object();
+
+	if (stmt->tproxy.addr) {
+		int family;
+		json_t *tmp;
+
+		family = stmt->tproxy.table_family;
+		if (family == NFPROTO_INET)
+			family = stmt->tproxy.family;
+
+		tmp = json_string(family2str(family));
+		json_object_set_new(root, "family", tmp);
+
+		tmp = expr_print_json(stmt->tproxy.addr, octx);
+		json_object_set_new(root, "addr", tmp);
+	}
+
+	if (stmt->tproxy.port)
+		json_object_set_new(root, "port",
+				    expr_print_json(stmt->tproxy.port, octx));
+
+	return json_pack("{s:o}", "tproxy", root);
+}
+
 static json_t *table_print_json_full(struct netlink_ctx *ctx,
 				     struct table *table)
 {
diff --git a/src/parser_json.c b/src/parser_json.c
index 6d8cda975ff9..3d96000b6066 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1796,6 +1796,48 @@ static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx,
 	return stmt;
 }
 
+static struct stmt *json_parse_tproxy_stmt(struct json_ctx *ctx,
+					const char *key, json_t *value)
+{
+	json_t *jaddr, *tmp;
+	const char *family;
+	struct stmt *stmt;
+	int familyval;
+
+	stmt = tproxy_stmt_alloc(int_loc);
+
+	if (json_unpack(value, "{s:s, s:o}",
+			"family", &family, "addr", &jaddr))
+		goto try_port;
+
+	familyval = parse_family(family);
+	if (familyval != NFPROTO_IPV4 &&
+	    familyval != NFPROTO_IPV6) {
+		json_error(ctx, "Invalid family '%s'.", family);
+		goto out_free;
+	}
+	stmt->tproxy.family = familyval;
+
+	stmt->tproxy.addr = json_parse_stmt_expr(ctx, jaddr);
+	if (!stmt->tproxy.addr) {
+		json_error(ctx, "Invalid addr.");
+		goto out_free;
+	}
+try_port:
+	if (!json_unpack(value, "{s:o}", "port", &tmp)) {
+		stmt->tproxy.port = json_parse_stmt_expr(ctx, tmp);
+		if (!stmt->tproxy.port) {
+			json_error(ctx, "Invalid port.");
+			goto out_free;
+		}
+	}
+	return stmt;
+
+out_free:
+	stmt_free(stmt);
+	return NULL;
+}
+
 static struct stmt *json_parse_reject_stmt(struct json_ctx *ctx,
 					  const char *key, json_t *value)
 {
@@ -2150,6 +2192,7 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root)
 		{ "meter", json_parse_meter_stmt },
 		{ "queue", json_parse_queue_stmt },
 		{ "ct count", json_parse_connlimit_stmt },
+		{ "tproxy", json_parse_tproxy_stmt },
 	};
 	const char *type;
 	unsigned int i;
diff --git a/src/statement.c b/src/statement.c
index 3040476fdfa1..2019f2b3ed10 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -797,6 +797,7 @@ static const struct stmt_ops tproxy_stmt_ops = {
 	.type		= STMT_TPROXY,
 	.name		= "tproxy",
 	.print		= tproxy_stmt_print,
+	.json		= tproxy_stmt_json,
 	.destroy	= tproxy_stmt_destroy,
 };
 
diff --git a/tests/py/inet/tproxy.t.json b/tests/py/inet/tproxy.t.json
new file mode 100644
index 000000000000..6c9f57d4c4c4
--- /dev/null
+++ b/tests/py/inet/tproxy.t.json
@@ -0,0 +1,91 @@
+# meta l4proto 17 tproxy ip to 192.0.2.1
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip"
+        }
+    }
+]
+
+# meta l4proto 6 tproxy ip to 192.0.2.1:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip",
+            "port": 50080
+        }
+    }
+]
+
+# meta l4proto 6 tproxy ip6 to [2001:db8::1]
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6"
+        }
+    }
+]
+
+# meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6",
+            "port": 50080
+        }
+    }
+]
+
+# meta l4proto 17 tproxy to :50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "port": 50080
+        }
+    }
+]
+
diff --git a/tests/py/ip/tproxy.t.json b/tests/py/ip/tproxy.t.json
new file mode 100644
index 000000000000..630285bf3f0b
--- /dev/null
+++ b/tests/py/ip/tproxy.t.json
@@ -0,0 +1,95 @@
+# meta l4proto 17 tproxy to 192.0.2.1
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip"
+        }
+    }
+]
+
+# meta l4proto 6 tproxy to 192.0.2.1:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip",
+            "port": 50080
+        }
+    }
+]
+
+# ip protocol 6 tproxy to :50080
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "protocol",
+                    "name": "ip"
+                }
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "port": 50080
+        }
+    }
+]
+
+# meta l4proto 17 tproxy ip to 192.0.2.1
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip"
+        }
+    }
+]
+
+# meta l4proto 6 tproxy ip to 192.0.2.1:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "192.0.2.1",
+            "family": "ip",
+            "port": 50080
+        }
+    }
+]
+
+
diff --git a/tests/py/ip6/tproxy.t.json b/tests/py/ip6/tproxy.t.json
new file mode 100644
index 000000000000..b627b20efc1c
--- /dev/null
+++ b/tests/py/ip6/tproxy.t.json
@@ -0,0 +1,90 @@
+# meta l4proto 6 tproxy to [2001:db8::1]
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6"
+        }
+    }
+]
+
+# meta l4proto 17 tproxy to [2001:db8::1]:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6",
+            "port": 50080
+        }
+    }
+]
+
+# meta l4proto 6 tproxy to :50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "port": 50080
+        }
+    }
+]
+
+# meta l4proto 6 tproxy ip6 to [2001:db8::1]
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 6
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6"
+        }
+    }
+]
+
+# meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080
+[
+    {
+        "match": {
+            "left": {
+                "meta": "l4proto"
+            },
+            "right": 17
+        }
+    },
+    {
+        "tproxy": {
+            "addr": "2001:db8::1",
+            "family": "ip6",
+            "port": 50080
+        }
+    }
+]
-- 
2.16.4




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

  Powered by Linux