[PATCH nft] json: add table map statement support

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

 



When listing a map with statements with JSON support, the statement list were
ignored.

Output example:

{
  "map": {
    "family": "ip",
    "name": "m",
    "table": "t",
    "type": "ipv4_addr",
    "handle": 1,
    "map": "mark",
    "stmt": [
      {
        "counter": {
          "packets": 0,
          "bytes": 0
        }
      }
    ]
  }
}

Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1588
Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
---
 src/json.c                                    | 70 +++++++++++--------
 src/parser_json.c                             |  5 +-
 tests/shell/testcases/json/0002table_map_0    |  9 +++
 .../testcases/json/dumps/0002table_map_0.nft  |  6 ++
 4 files changed, 61 insertions(+), 29 deletions(-)
 create mode 100755 tests/shell/testcases/json/0002table_map_0
 create mode 100644 tests/shell/testcases/json/dumps/0002table_map_0.nft

diff --git a/src/json.c b/src/json.c
index 55959eea..1f2889c6 100644
--- a/src/json.c
+++ b/src/json.c
@@ -77,6 +77,34 @@ static json_t *set_dtype_json(const struct expr *key)
 	return root;
 }
 
+static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
+{
+	char buf[1024];
+	FILE *fp;
+
+	/* XXX: Can't be supported at this point:
+	 * xt_stmt_xlate() ignores output_fp.
+	 */
+	if (stmt->ops->type == STMT_XT)
+		return json_pack("{s:n}", "xt");
+
+	if (stmt->ops->json)
+		return stmt->ops->json(stmt, octx);
+
+	fprintf(stderr, "warning: stmt ops %s have no json callback\n",
+		stmt->ops->name);
+
+	fp = octx->output_fp;
+	octx->output_fp = fmemopen(buf, 1024, "w");
+
+	stmt->ops->print(stmt, octx);
+
+	fclose(octx->output_fp);
+	octx->output_fp = fp;
+
+	return json_pack("s", buf);
+}
+
 static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 {
 	json_t *root, *tmp;
@@ -152,6 +180,20 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 		json_object_set_new(root, "elem", array);
 	}
 
+	if (!list_empty(&set->stmt_list)) {
+		json_t *array, *tmp;
+		struct stmt *stmt;
+
+		array = json_array();
+
+		list_for_each_entry(stmt, &set->stmt_list, list) {
+			tmp = stmt_print_json(stmt, octx);
+			json_array_append_new(array, tmp);
+		}
+
+		json_object_set_new(root, "stmt", array);
+	}
+
 	return json_pack("{s:o}", type, root);
 }
 
@@ -168,34 +210,6 @@ static json_t *element_print_json(struct output_ctx *octx,
 			 "elem", root);
 }
 
-static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
-{
-	char buf[1024];
-	FILE *fp;
-
-	/* XXX: Can't be supported at this point:
-	 * xt_stmt_xlate() ignores output_fp.
-	 */
-	if (stmt->ops->type == STMT_XT)
-		return json_pack("{s:n}", "xt");
-
-	if (stmt->ops->json)
-		return stmt->ops->json(stmt, octx);
-
-	fprintf(stderr, "warning: stmt ops %s have no json callback\n",
-		stmt->ops->name);
-
-	fp = octx->output_fp;
-	octx->output_fp = fmemopen(buf, 1024, "w");
-
-	stmt->ops->print(stmt, octx);
-
-	fclose(octx->output_fp);
-	octx->output_fp = fp;
-
-	return json_pack("s", buf);
-}
-
 static json_t *rule_print_json(struct output_ctx *octx,
 			       const struct rule *rule)
 {
diff --git a/src/parser_json.c b/src/parser_json.c
index fc72c25f..7180474e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -3002,8 +3002,8 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 {
 	struct handle h = { 0 };
 	const char *family = "", *policy, *dtype_ext = NULL;
+	json_t *tmp, *stmt_json;
 	struct set *set;
-	json_t *tmp;
 
 	if (json_unpack_err(ctx, root, "{s:s, s:s}",
 			    "family", &family,
@@ -3114,6 +3114,9 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 		set->gc_int *= 1000;
 	json_unpack(root, "{s:i}", "size", &set->desc.size);
 
+	if (!json_unpack(root, "{s:o}", "stmt", &stmt_json))
+		json_parse_set_stmt_list(ctx, &set->stmt_list, stmt_json);
+
 	handle_merge(&set->handle, &h);
 
 	if (op == CMD_ADD)
diff --git a/tests/shell/testcases/json/0002table_map_0 b/tests/shell/testcases/json/0002table_map_0
new file mode 100755
index 00000000..4b54527b
--- /dev/null
+++ b/tests/shell/testcases/json/0002table_map_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "ip", "name": "t", "handle": 4}}, {"map": {"family": "ip", "name": "m", "table": "t", "type": "ipv4_addr", "handle": 1, "map": "mark", "stmt": [{"counter": {"packets": 0, "bytes": 0}}]}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/dumps/0002table_map_0.nft b/tests/shell/testcases/json/dumps/0002table_map_0.nft
new file mode 100644
index 00000000..357e92cc
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0002table_map_0.nft
@@ -0,0 +1,6 @@
+table ip t {
+	map m {
+		type ipv4_addr : mark
+		counter
+	}
+}
-- 
2.30.2




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

  Powered by Linux