[PATCH nft 3/5] parser_json: add and use CMD_ERR helpers

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

 



Upcoming patch will make NULL a valid return value,
indicating that the data was appended to an existing object,
e.g. table->chains, table->objs, chain->rules, etc.

Switch all return locations queueing erros to return CMD_ERR_PTR(-1).

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 src/parser_json.c | 128 ++++++++++++++++++++++++++--------------------
 1 file changed, 73 insertions(+), 55 deletions(-)

diff --git a/src/parser_json.c b/src/parser_json.c
index 7540df59dc8f..91c1e01cee52 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -63,6 +63,18 @@ struct json_ctx {
 #define is_DTYPE(ctx)	(ctx->flags & CTX_F_DTYPE)
 #define is_SET_RHS(ctx)	(ctx->flags & CTX_F_SET_RHS)
 
+static inline bool CMD_IS_ERR(struct cmd *cmd)
+{
+	long x = (long)cmd;
+
+	return x < 0;
+}
+
+static inline struct cmd *CMD_ERR_PTR(long err)
+{
+	return (struct cmd *)err;
+}
+
 struct json_cmd_assoc {
 	struct json_cmd_assoc *next;
 	struct hlist_node hnode;
@@ -2976,22 +2988,22 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root,
 
 	if (json_unpack_err(ctx, root, "{s:s}",
 			    "family", &family))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 
 	if (op != CMD_DELETE) {
 		if (json_unpack_err(ctx, root, "{s:s}", "name", &h.table.name))
-			return NULL;
+			return CMD_ERR_PTR(-1);
 
 		json_unpack(root, "{s:s}", "comment", &comment);
 	} else if (op == CMD_DELETE &&
 		   json_unpack(root, "{s:s}", "name", &h.table.name) &&
 		   json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
 		json_error(ctx, "Either name or handle required to delete a table.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	if (h.table.name)
 		h.table.name = xstrdup(h.table.name);
@@ -3072,21 +3084,21 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
 	if (json_unpack_err(ctx, root, "{s:s, s:s}",
 			    "family", &family,
 			    "table", &h.table.name))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	if (op != CMD_DELETE) {
 		if (json_unpack_err(ctx, root, "{s:s}", "name", &h.chain.name))
-			return NULL;
+			return CMD_ERR_PTR(-1);
 
 		json_unpack(root, "{s:s}", "comment", &comment);
 	} else if (op == CMD_DELETE &&
 		   json_unpack(root, "{s:s}", "name", &h.chain.name) &&
 		   json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
 		json_error(ctx, "Either name or handle required to delete a chain.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	h.table.name = xstrdup(h.table.name);
 	if (h.chain.name)
@@ -3118,7 +3130,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
 	if (!chain->hook.name) {
 		json_error(ctx, "Invalid chain hook '%s'.", hookstr);
 		chain_free(chain);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	json_unpack(root, "{s:o}", "dev", &devs);
@@ -3128,7 +3140,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
 		if (!chain->dev_expr) {
 			json_error(ctx, "Invalid chain dev.");
 			chain_free(chain);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 
@@ -3137,7 +3149,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
 		if (!chain->policy) {
 			json_error(ctx, "Unknown policy '%s'.", policy);
 			chain_free(chain);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 
@@ -3165,17 +3177,17 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
 			    "family", &family,
 			    "table", &h.table.name,
 			    "chain", &h.chain.name))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	if (op != CMD_DELETE &&
 	    json_unpack_err(ctx, root, "{s:o}", "expr", &tmp))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	else if ((op == CMD_DELETE || op == CMD_DESTROY) &&
 		 json_unpack_err(ctx, root, "{s:I}", "handle", &h.handle.id))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	h.table.name = xstrdup(h.table.name);
 	h.chain.name = xstrdup(h.chain.name);
@@ -3185,7 +3197,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
 
 	if (!json_is_array(tmp)) {
 		json_error(ctx, "Value of property \"expr\" must be an array.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	if (!json_unpack(root, "{s:I}", "index", &h.index.id)) {
@@ -3205,7 +3217,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
 			json_error(ctx, "Unexpected expr array element of type %s, expected object.",
 				   json_typename(value));
 			rule_free(rule);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 
 		stmt = json_parse_stmt(ctx, value);
@@ -3213,7 +3225,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
 		if (!stmt) {
 			json_error(ctx, "Parsing expr array at index %zd failed.", index);
 			rule_free(rule);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 
 		rule_stmt_append(rule, stmt);
@@ -3273,15 +3285,15 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 	if (json_unpack_err(ctx, root, "{s:s, s:s}",
 			    "family", &family,
 			    "table", &h.table.name))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	if (op != CMD_DELETE &&
 	    json_unpack_err(ctx, root, "{s:s}", "name", &h.set.name)) {
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	} else if ((op == CMD_DELETE || op == CMD_DESTROY) &&
 		   json_unpack(root, "{s:s}", "name", &h.set.name) &&
 		   json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
 		json_error(ctx, "Either name or handle required to delete a set.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	if (parse_family(family, &h.family)) {
@@ -3309,14 +3321,14 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 		json_error(ctx, "Invalid set type.");
 		set_free(set);
 		handle_free(&h);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	set->key = json_parse_dtype_expr(ctx, tmp);
 	if (!set->key) {
 		json_error(ctx, "Invalid set type.");
 		set_free(set);
 		handle_free(&h);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	if (!json_unpack(root, "{s:s}", "map", &dtype_ext)) {
@@ -3334,7 +3346,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 			json_error(ctx, "Invalid map type '%s'.", dtype_ext);
 			set_free(set);
 			handle_free(&h);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 	if (!json_unpack(root, "{s:s}", "policy", &policy)) {
@@ -3346,7 +3358,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 			json_error(ctx, "Unknown set policy '%s'.", policy);
 			set_free(set);
 			handle_free(&h);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 	if (!json_unpack(root, "{s:o}", "flags", &tmp)) {
@@ -3361,7 +3373,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 				json_error(ctx, "Invalid set flag at index %zu.", index);
 				set_free(set);
 				handle_free(&h);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 			set->flags |= flag;
 		}
@@ -3372,7 +3384,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
 			json_error(ctx, "Invalid set elem expression.");
 			set_free(set);
 			handle_free(&h);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 	if (!json_unpack(root, "{s:I}", "timeout", &set->timeout))
@@ -3407,11 +3419,11 @@ static struct cmd *json_parse_cmd_add_element(struct json_ctx *ctx,
 			    "table", &h.table.name,
 			    "name", &h.set.name,
 			    "elem", &tmp))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	h.table.name = xstrdup(h.table.name);
 	h.set.name = xstrdup(h.set.name);
@@ -3420,7 +3432,7 @@ static struct cmd *json_parse_cmd_add_element(struct json_ctx *ctx,
 	if (!expr) {
 		json_error(ctx, "Invalid set.");
 		handle_free(&h);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	return cmd_alloc(op, cmd_obj, &h, int_loc, expr);
 }
@@ -3438,21 +3450,21 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
 	if (json_unpack_err(ctx, root, "{s:s, s:s}",
 			    "family", &family,
 			    "table", &h.table.name))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 
 	if (op != CMD_DELETE &&
 	    json_unpack_err(ctx, root, "{s:s}", "name", &h.flowtable.name)) {
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	} else if ((op == CMD_DELETE || op == CMD_DESTROY) &&
 		   json_unpack(root, "{s:s}", "name", &h.flowtable.name) &&
 		   json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
 		json_error(ctx, "Either name or handle required to delete a flowtable.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	h.table.name = xstrdup(h.table.name);
 	if (h.flowtable.name)
@@ -3465,7 +3477,7 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
 			    "hook", &hook,
 			    "prio", &prio)) {
 		handle_free(&h);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	json_unpack(root, "{s:o}", "dev", &devs);
@@ -3474,7 +3486,7 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
 	if (!hookstr) {
 		json_error(ctx, "Invalid flowtable hook '%s'.", hook);
 		handle_free(&h);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	flowtable = flowtable_alloc(int_loc);
@@ -3490,7 +3502,7 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx,
 			json_error(ctx, "Invalid flowtable dev.");
 			flowtable_free(flowtable);
 			handle_free(&h);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 	}
 	return cmd_alloc(op, cmd_obj, &h, int_loc, flowtable);
@@ -3542,22 +3554,22 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 	if (json_unpack_err(ctx, root, "{s:s, s:s}",
 			    "family", &family,
 			    "table", &h.table.name))
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	if ((op != CMD_DELETE ||
 	     cmd_obj == NFT_OBJECT_CT_HELPER) &&
 	    json_unpack_err(ctx, root, "{s:s}", "name", &h.obj.name)) {
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	} else if ((op == CMD_DELETE || op == CMD_DESTROY) &&
 		   cmd_obj != NFT_OBJECT_CT_HELPER &&
 		   json_unpack(root, "{s:s}", "name", &h.obj.name) &&
 		   json_unpack(root, "{s:I}", "handle", &h.handle.id)) {
 		json_error(ctx, "Either name or handle required to delete an object.");
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	if (parse_family(family, &h.family)) {
 		json_error(ctx, "Unknown family '%s'.", family);
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 	h.table.name = xstrdup(h.table.name);
 	if (h.obj.name)
@@ -3598,7 +3610,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 				json_error(ctx, "Invalid secmark context '%s', max length is %zu.",
 					   tmp, sizeof(obj->secmark.ctx));
 				obj_free(obj);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 		}
 		break;
@@ -3615,7 +3627,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 				json_error(ctx, "Invalid CT helper type '%s', max length is %zu.",
 					   tmp, sizeof(obj->ct_helper.name));
 				obj_free(obj);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 		}
 		if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
@@ -3626,14 +3638,14 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 			} else {
 				json_error(ctx, "Invalid ct helper protocol '%s'.", tmp);
 				obj_free(obj);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 		}
 		if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
 		    parse_family(tmp, &l3proto)) {
 			json_error(ctx, "Invalid ct helper l3proto '%s'.", tmp);
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		obj->ct_helper.l3proto = l3proto;
 		break;
@@ -3648,21 +3660,21 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 			} else {
 				json_error(ctx, "Invalid ct timeout protocol '%s'.", tmp);
 				obj_free(obj);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 		}
 		if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
 		    parse_family(tmp, &l3proto)) {
 			json_error(ctx, "Invalid ct timeout l3proto '%s'.", tmp);
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		obj->ct_timeout.l3proto = l3proto;
 
 		init_list_head(&obj->ct_timeout.timeout_list);
 		if (json_parse_ct_timeout_policy(ctx, root, obj)) {
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		break;
 	case NFT_OBJECT_CT_EXPECT:
@@ -3672,7 +3684,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 		    parse_family(tmp, &l3proto)) {
 			json_error(ctx, "Invalid ct expectation l3proto '%s'.", tmp);
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		obj->ct_expect.l3proto = l3proto;
 		if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
@@ -3683,7 +3695,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 			} else {
 				json_error(ctx, "Invalid ct expectation protocol '%s'.", tmp);
 				obj_free(obj);
-				return NULL;
+				return CMD_ERR_PTR(-1);
 			}
 		}
 		if (!json_unpack(root, "{s:i}", "dport", &i))
@@ -3699,7 +3711,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 				    "rate", &obj->limit.rate,
 				    "per", &tmp)) {
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		json_unpack(root, "{s:s}", "rate_unit", &rate_unit);
 		json_unpack(root, "{s:b}", "inv", &inv);
@@ -3723,7 +3735,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
 		if (json_unpack_err(ctx, root, "{s:i, s:i}",
 				    "mss", &i, "wscale", &j)) {
 			obj_free(obj);
-			return NULL;
+			return CMD_ERR_PTR(-1);
 		}
 		obj->synproxy.mss = i;
 		obj->synproxy.wscale = j;
@@ -3778,7 +3790,7 @@ static struct cmd *json_parse_cmd_add(struct json_ctx *ctx,
 	if (!json_is_object(root)) {
 		json_error(ctx, "Value of add command must be object (got %s instead).",
 			   json_typename(root));
-		return NULL;
+		return CMD_ERR_PTR(-1);
 	}
 
 	for (i = 0; i < array_size(cmd_obj_table); i++) {
@@ -3794,7 +3806,7 @@ static struct cmd *json_parse_cmd_add(struct json_ctx *ctx,
 		return cmd_obj_table[i].cb(ctx, tmp, op, cmd_obj_table[i].obj);
 	}
 	json_error(ctx, "Unknown object passed to add command.");
-	return NULL;
+	return CMD_ERR_PTR(-1);
 }
 
 static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
@@ -4142,11 +4154,17 @@ static int json_parse_cmd(struct json_ctx *ctx, json_t *root)
 			continue;
 
 		cmd = parse_cb_table[i].cb(ctx, tmp, parse_cb_table[i].op);
-		goto out;
+		if (!CMD_IS_ERR(cmd))
+			goto out;
+
+		return -1;
 	}
 
 	/* to accept 'list ruleset' output 1:1, try add command */
 	cmd = json_parse_cmd_add(ctx, root, CMD_ADD);
+	if (CMD_IS_ERR(cmd))
+		return -1;
+
 out:
 	if (cmd) {
 		list_add_tail(&cmd->list, ctx->cmds);
-- 
2.43.0





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

  Powered by Linux