When listing a set with statements with JSON support, the statements were ignored. Output example: { "set": { "op": "add", "elem": { "payload": { "protocol": "ip", "field": "saddr" } }, "stmt": [ { "limit": { "rate": 10, "burst": 5, "per": "second" } }, { "counter": { "packets": 0, "bytes": 0 } } ], "set": "@my_ssh_meter" } } Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1495 Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx> --- src/json.c | 19 ++++++++++++++++++- src/parser_json.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/json.c b/src/json.c index a525fd1b..55959eea 100644 --- a/src/json.c +++ b/src/json.c @@ -1439,11 +1439,28 @@ 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:s+}}", "set", + return json_pack("{s:{s:s, s:o, s:o, s:s+}}", "set", "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); } diff --git a/src/parser_json.c b/src/parser_json.c index 9e93927a..a8dbb890 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2227,13 +2227,36 @@ static struct stmt *json_parse_reject_stmt(struct json_ctx *ctx, return stmt; } +static void json_parse_set_stmt_list(struct json_ctx *ctx, + struct list_head *stmt_list, + json_t *stmt_json) +{ + struct list_head *head; + struct stmt *tmp; + json_t *value; + size_t index; + + if (!stmt_json) + return; + + if (!json_is_array(stmt_json)) + json_error(ctx, "Unexpected object type in stmt"); + + head = stmt_list; + json_array_foreach(stmt_json, index, value) { + tmp = json_parse_stmt(ctx, value); + list_add(&tmp->list, head); + head = &tmp->list; + } +} + static struct stmt *json_parse_set_stmt(struct json_ctx *ctx, const char *key, json_t *value) { const char *opstr, *set; struct expr *expr, *expr2; + json_t *elem, *stmt_json; struct stmt *stmt; - json_t *elem; int op; if (json_unpack_err(ctx, value, "{s:s, s:o, s:s}", @@ -2268,6 +2291,10 @@ static struct stmt *json_parse_set_stmt(struct json_ctx *ctx, stmt->set.op = op; stmt->set.key = expr; stmt->set.set = expr2; + + if (!json_unpack(value, "{s:o}", "stmt", &stmt_json)) + json_parse_set_stmt_list(ctx, &stmt->set.stmt_list, stmt_json); + return stmt; } -- 2.30.2