[PATCH nft] json: fix empty statement list output in sets and maps

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

 



JSON output of sets and map should not include the statements list if is is
empty. The statement output should be stateless also.

In addition, removes duplicated code.

Fixes: 07958ec53830 ("json: add set statement list support")
Fixes: e66f3187d891 ("json: add table map statement support")
Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
---
 src/json.c                                    | 64 ++++++++++---------
 .../shell/testcases/json/0001set_statements_0 |  2 +-
 tests/shell/testcases/json/0002table_map_0    |  2 +-
 3 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/src/json.c b/src/json.c
index 1f2889c6..87f87f37 100644
--- a/src/json.c
+++ b/src/json.c
@@ -105,6 +105,25 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
 	return json_pack("s", buf);
 }
 
+static json_t *set_stmt_list_json(const struct list_head *stmt_list,
+				   struct output_ctx *octx)
+{
+	unsigned int flags = octx->flags;
+	json_t *root, *tmp;
+	struct stmt *i;
+
+	root = json_array();
+	octx->flags |= NFT_CTX_OUTPUT_STATELESS;
+
+	list_for_each_entry(i, stmt_list, list) {
+		tmp = stmt_print_json(i, octx);
+		json_array_append_new(root, tmp);
+	}
+	octx->flags = flags;
+
+	return root;
+}
+
 static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 {
 	json_t *root, *tmp;
@@ -180,19 +199,10 @@ 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);
-	}
+	if (!list_empty(&set->stmt_list))
+		json_object_set_new(root, "stmt",
+				    set_stmt_list_json(&set->stmt_list,
+						       octx));
 
 	return json_pack("{s:o}", type, root);
 }
@@ -1453,29 +1463,21 @@ json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
 			 "bytes", stmt->counter.bytes);
 }
 
-static json_t *set_stmt_list_json(const struct list_head *stmt_list,
-	                           struct output_ctx *octx)
-{
-	json_t *root, *tmp;
-	struct stmt *i;
-
-	root = json_array();
-
-	list_for_each_entry(i, stmt_list, list) {
-		tmp = stmt_print_json(i, octx);
-		json_array_append_new(root, tmp);
-	}
-
-	return root;
-}
-
 json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
 {
-	return json_pack("{s:{s:s, s:o, s:o, s:s+}}", "set",
+	json_t *root;
+
+	root = json_pack("{s:s, s:o, s:s+}",
 			 "op", set_stmt_op_names[stmt->set.op],
 			 "elem", expr_print_json(stmt->set.key, octx),
-			 "stmt", set_stmt_list_json(&stmt->set.stmt_list, octx),
 			 "set", "@", stmt->set.set->set->handle.set.name);
+
+	if (!list_empty(&stmt->set.stmt_list))
+		json_object_set_new(root, "stmt",
+				    set_stmt_list_json(&stmt->set.stmt_list,
+						       octx));
+
+	return json_pack("{s:o}", "set", root);
 }
 
 json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
diff --git a/tests/shell/testcases/json/0001set_statements_0 b/tests/shell/testcases/json/0001set_statements_0
index 1c72d35b..388b0bfe 100755
--- a/tests/shell/testcases/json/0001set_statements_0
+++ b/tests/shell/testcases/json/0001set_statements_0
@@ -4,6 +4,6 @@ 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": "testt", "handle": 3}}, {"set": {"family": "ip", "name": "ssh_meter", "table": "testt", "type": "ipv4_addr", "handle": 2, "size": 65535}}, {"chain": {"family": "ip", "table": "testt", "name": "testc", "handle": 1, "type": "filter", "hook": "input", "prio": 0, "policy": "accept"}}, {"rule": {"family": "ip", "table": "testt", "chain": "testc", "handle": 3, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 22}}, {"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"set": {"op": "add", "elem": {"payload": {"protocol": "ip", "field": "saddr"}}, "stmt": [{"limit": {"rate": 10, "burst": 5, "per": "second"}}], "set": "@ssh_meter"}}, {"accept": null}]}}]}'
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "ip", "name": "testt", "handle": 11}}, {"set": {"family": "ip", "name": "ssh_meter", "table": "testt", "type": "ipv4_addr", "handle": 1, "size": 65535}}, {"chain": {"family": "ip", "table": "testt", "name": "testc", "handle": 2, "type": "filter", "hook": "input", "prio": 0, "policy": "accept"}}, {"rule": {"family": "ip", "table": "testt", "chain": "testc", "handle": 3, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 22}}, {"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"set": {"op": "add", "elem": {"payload": {"protocol": "ip", "field": "saddr"}}, "set": "@ssh_meter", "stmt": [{"limit": {"rate": 10, "burst": 5, "per": "second"}}]}}, {"accept": null}]}}]}'
 
 $NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/0002table_map_0 b/tests/shell/testcases/json/0002table_map_0
index 4b54527b..9619de2d 100755
--- a/tests/shell/testcases/json/0002table_map_0
+++ b/tests/shell/testcases/json/0002table_map_0
@@ -4,6 +4,6 @@ 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}}]}}]}'
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "ip", "name": "t", "handle": 12}}, {"map": {"family": "ip", "name": "m", "table": "t", "type": "ipv4_addr", "handle": 1, "map": "mark", "stmt": [{"counter": null}]}}]}'
 
 $NFT -j -f - <<< $RULESET
-- 
2.30.2




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

  Powered by Linux