summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/json.h2
-rw-r--r--src/json.c26
-rw-r--r--src/parser_json.c43
-rw-r--r--src/statement.c1
-rw-r--r--tests/py/inet/tproxy.t.json90
-rw-r--r--tests/py/ip/tproxy.t.json93
-rw-r--r--tests/py/ip6/tproxy.t.json90
7 files changed, 345 insertions, 0 deletions
diff --git a/include/json.h b/include/json.h
index 78c026a7..e64151de 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 eac7a3a0..e8870a13 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1297,6 +1297,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 6d8cda97..3d96000b 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 98e56844..45d2067c 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -810,6 +810,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 00000000..88304206
--- /dev/null
+++ b/tests/py/inet/tproxy.t.json
@@ -0,0 +1,90 @@
+# 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 00000000..81b7c188
--- /dev/null
+++ b/tests/py/ip/tproxy.t.json
@@ -0,0 +1,93 @@
+# 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 00000000..b627b20e
--- /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
+ }
+ }
+]