]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
JSON: Fix parsing and printing of limit objects
authorPhil Sutter <phil@nwl.cc>
Mon, 28 May 2018 16:51:02 +0000 (18:51 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 1 Jun 2018 07:16:48 +0000 (09:16 +0200)
Fix parsing and printing of named limit objects by aligning the code
with parser/printer of anonymous ones.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/json.c
src/parser_json.c

index 83366df89804c2498bc6364a575080f5b3194ec3..11607b677ffbbe47d74bfaa718d376116a1cedba 100644 (file)
@@ -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);
index fd60c59c396270058281a0b994aec43bfdec4a10..f3d2c0f1d3dfcf020b34a43411e8b66e229b6429 100644 (file)
@@ -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);