diff mbox series

[nft,v2,07/14] JSON: Fix parsing and printing of limit objects

Message ID 20180528165109.15992-8-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series JSON: Some minor schema changes | expand

Commit Message

Phil Sutter May 28, 2018, 4:51 p.m. UTC
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>
---
 src/json.c        | 43 ++++++++++++++++++++---------------------
 src/parser_json.c | 49 ++++++++++++++++++++++++++---------------------
 2 files changed, 48 insertions(+), 44 deletions(-)
diff mbox series

Patch

diff --git a/src/json.c b/src/json.c
index 83366df89804c..11607b677ffbb 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 fd60c59c39627..f3d2c0f1d3dfc 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);