]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: tproxy: add json support
authorFlorian Westphal <fw@strlen.de>
Wed, 29 Aug 2018 09:37:41 +0000 (11:37 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 29 Aug 2018 21:55:02 +0000 (23:55 +0200)
Signed-off-by: Florian Westphal <fw@strlen.de>
include/json.h
src/json.c
src/parser_json.c
src/statement.c
tests/py/inet/tproxy.t.json [new file with mode: 0644]
tests/py/ip/tproxy.t.json [new file with mode: 0644]
tests/py/ip6/tproxy.t.json [new file with mode: 0644]

index 78c026a7a7f6732d7a5bc4ea26e8474f11f1bc40..e64151de66c05d4905a6b8195c7611c8b25565bc 100644 (file)
@@ -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
index eac7a3a01997e0dc1a4161f3bb17be0b0364bc21..e8870a137140e1dc3559c687bf1d4d806b1f3c6a 100644 (file)
@@ -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)
 {
index 6d8cda975ff90e94be28d2cd9d6425cdb00521fc..3d96000b6066b92c296f3ee2eb13da9e84db7bae 100644 (file)
@@ -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;
index 98e56844848624150ebf48753434f7ef328b2eb9..45d2067c5c702d266055d9186dcd39d3e38f251d 100644 (file)
@@ -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 (file)
index 0000000..8830420
--- /dev/null
@@ -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 (file)
index 0000000..81b7c18
--- /dev/null
@@ -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 (file)
index 0000000..b627b20
--- /dev/null
@@ -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
+        }
+    }
+]