From c36288dbe2ba363586424c2951fd715873608581 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Mon, 28 May 2018 18:51:02 +0200 Subject: JSON: Fix parsing and printing of limit objects Fix parsing and printing of named limit objects by aligning the code with parser/printer of anonymous ones. Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- src/json.c | 43 +++++++++++++++++++++---------------------- src/parser_json.c | 49 +++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/json.c b/src/json.c index 83366df8..11607b67 100644 --- a/src/json.c +++ b/src/json.c @@ -236,10 +236,10 @@ static json_t *proto_name_json(uint8_t proto) static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) { + const char *rate_unit = NULL, *burst_unit = NULL; const char *type = obj_type_name(obj->type); + uint64_t rate, burst; json_t *root, *tmp; - const char *unit; - uint64_t rate; root = json_pack("{s:s, s:s, s:s, s:I}", "family", family2str(obj->handle.family), @@ -273,29 +273,28 @@ static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) json_decref(tmp); break; case NFT_OBJECT_LIMIT: - tmp = json_pack("{s:b, s:s}", - "inv", obj->limit.flags & NFT_LIMIT_F_INV, + rate = obj->limit.rate; + burst = obj->limit.burst; + + if (obj->limit.type == NFT_LIMIT_PKT_BYTES) { + rate_unit = get_rate(obj->limit.rate, &rate); + burst_unit = get_rate(obj->limit.burst, &burst); + } + + tmp = json_pack("{s:I, s:s}", + "rate", rate, "per", get_unit(obj->limit.unit)); - switch (obj->limit.type) { - case NFT_LIMIT_PKTS: - json_object_set_new(tmp, "rate", - json_integer(obj->limit.rate)); - json_object_set_new(tmp, "burst", - json_integer(obj->limit.burst)); - break; - case NFT_LIMIT_PKT_BYTES: - unit = get_rate(obj->limit.rate, &rate); - json_object_set_new(tmp, "rate", json_integer(rate)); + + if (obj->limit.flags & NFT_LIMIT_F_INV) + json_object_set_new(tmp, "inv", json_true()); + if (rate_unit) json_object_set_new(tmp, "rate_unit", - json_string(unit)); - if (obj->limit.burst) { - unit = get_rate(obj->limit.burst, &rate); - json_object_set_new(tmp, "burst", - json_integer(rate)); + json_string(rate_unit)); + if (burst) { + json_object_set_new(tmp, "burst", json_integer(burst)); + if (burst_unit) json_object_set_new(tmp, "burst_unit", - json_string(unit)); - } - break; + json_string(burst_unit)); } json_object_update(root, tmp); diff --git a/src/parser_json.c b/src/parser_json.c index fd60c59c..f3d2c0f1 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1569,15 +1569,15 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx, const char *key, json_t *value) { struct stmt *stmt; - int rate, burst = 0; + uint64_t rate, burst = 0; const char *rate_unit = "packets", *time, *burst_unit = "bytes"; int inv = 0; - if (!json_unpack(value, "{s:i, s:s}", - "rate", &rate, "per", &time)) { + if (!json_unpack(value, "{s:I, s:s}", + "rate", &rate, "per", &time)) { json_unpack(value, "{s:s}", "rate_unit", &rate_unit); json_unpack(value, "{s:b}", "inv", &inv); - json_unpack(value, "{s:i}", "burst", &burst); + json_unpack(value, "{s:I}", "burst", &burst); json_unpack(value, "{s:s}", "burst_unit", &burst_unit); stmt = limit_stmt_alloc(int_loc); @@ -2580,9 +2580,10 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, json_t *root, enum cmd_ops op, enum cmd_obj cmd_obj) { - const char *family, *tmp; + const char *family, *tmp, *rate_unit = "packets", *burst_unit = "bytes"; struct handle h = { 0 }; struct obj *obj; + int inv = 0; if (json_unpack_err(ctx, root, "{s:s, s:s}", "family", &family, @@ -2674,24 +2675,28 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, break; case CMD_OBJ_LIMIT: obj->type = NFT_OBJECT_LIMIT; - json_unpack(root, "{s:i}", "rate", &obj->limit.rate); - if (!json_unpack(root, "{s:s}", "per", &tmp)) - obj->limit.unit = seconds_from_unit(tmp); - json_unpack(root, "{s:i}", "burst", &obj->limit.burst); - if (!json_unpack(root, "{s:s}", "unit", &tmp)) { - if (!strcmp(tmp, "packets")) { - obj->limit.type = NFT_LIMIT_PKTS; - } else if (!strcmp(tmp, "bytes")) { - obj->limit.type = NFT_LIMIT_PKT_BYTES; - } else { - json_error(ctx, "Invalid limit unit '%s'.", tmp); - obj_free(obj); - return NULL; - } + if (json_unpack_err(ctx, root, "{s:I, s:s}", + "rate", &obj->limit.rate, + "per", &tmp)) { + obj_free(obj); + return NULL; } - json_unpack(root, "{s:b}", "inv", &obj->limit.flags); - if (obj->limit.flags) - obj->limit.flags = NFT_LIMIT_F_INV; + json_unpack(root, "{s:s}", "rate_unit", &rate_unit); + json_unpack(root, "{s:b}", "inv", &inv); + json_unpack(root, "{s:I}", "burst", &obj->limit.burst); + json_unpack(root, "{s:s}", "burst_unit", &burst_unit); + + if (!strcmp(rate_unit, "packets")) { + obj->limit.type = NFT_LIMIT_PKTS; + } else { + obj->limit.type = NFT_LIMIT_PKT_BYTES; + obj->limit.rate = rate_to_bytes(obj->limit.rate, + rate_unit); + obj->limit.burst = rate_to_bytes(obj->limit.burst, + burst_unit); + } + obj->limit.unit = seconds_from_unit(tmp); + obj->limit.flags = inv ? NFT_LIMIT_F_INV : 0; break; default: BUG("Invalid CMD '%d'", cmd_obj); -- cgit v1.2.3