[PATCH nft 2/5] parser_json: move list_add into json_parse_cmd

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

 



The existing parser cannot handle certain inputs.  Example:

  "map": {
   "family": "ip",
   "name": "testmap",
   "table": "test",
   "type": "ipv4_addr",
   "handle": 2,
   "map": "verdict",
   "elem": [ [ "*", {
        "jump": {
           "target": "testchain"
[..]
    },
    {
      "chain": {
        "family": "ip",
        "table": "test",
        "name": "testchain",
        ...

Problem is that the json input parser does cmd_add at the earliest opportunity.

For a simple input file defining a table, set, set element and chain, we get
following transaction:
 * add table
 * add set
 * add setelem
 * add chain

This is rejected by the kernel, because the set element references a chain
that does (not yet) exist.

Normal input parser only allocates a CMD_ADD request for the table.

Rest of the transactional commands are created much later, via nft_cmd_expand(),
which walks "struct table" and then creates the needed CMD_ADD for the objects
owned by that table.

This transaction will be:
 * add table
 * add chain
 * add set
 * add setelem

This is not fixable with the current json parser.  To make this work, we
will need to let nft_cmd_expand() take care of building the transaction
commands in the right order.

For this, we must suppress the cmd_alloc() and add the object to struct
table (->sets, ->chains, etc).

This preparation patch moves the list_add into json_parse_cmd so that
followup patches are allowed to avoid command allocation completely
and add objects to struct table/chain instead.

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

diff --git a/src/parser_json.c b/src/parser_json.c
index d4cc2c1e4e9c..7540df59dc8f 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -4111,7 +4111,7 @@ static void json_cmd_assoc_add(json_t *json, const struct cmd *cmd)
 	json_cmd_assoc_list = new;
 }
 
-static struct cmd *json_parse_cmd(struct json_ctx *ctx, json_t *root)
+static int json_parse_cmd(struct json_ctx *ctx, json_t *root)
 {
 	struct {
 		const char *key;
@@ -4132,6 +4132,7 @@ static struct cmd *json_parse_cmd(struct json_ctx *ctx, json_t *root)
 		//{ "monitor", CMD_MONITOR, json_parse_cmd_monitor },
 		//{ "describe", CMD_DESCRIBE, json_parse_cmd_describe }
 	};
+	struct cmd *cmd;
 	unsigned int i;
 	json_t *tmp;
 
@@ -4140,10 +4141,21 @@ static struct cmd *json_parse_cmd(struct json_ctx *ctx, json_t *root)
 		if (!tmp)
 			continue;
 
-		return parse_cb_table[i].cb(ctx, tmp, parse_cb_table[i].op);
+		cmd = parse_cb_table[i].cb(ctx, tmp, parse_cb_table[i].op);
+		goto out;
 	}
+
 	/* to accept 'list ruleset' output 1:1, try add command */
-	return json_parse_cmd_add(ctx, root, CMD_ADD);
+	cmd = json_parse_cmd_add(ctx, root, CMD_ADD);
+out:
+	if (cmd) {
+		list_add_tail(&cmd->list, ctx->cmds);
+
+		if (nft_output_echo(&ctx->nft->output))
+			json_cmd_assoc_add(root, cmd);
+	}
+
+	return 0;
 }
 
 static int json_verify_metainfo(struct json_ctx *ctx, json_t *root)
@@ -4222,10 +4234,8 @@ static int __json_parse(struct json_ctx *ctx)
 	}
 
 	json_array_foreach(tmp, index, value) {
-		/* this is more or less from parser_bison.y:716 */
-		LIST_HEAD(list);
-		struct cmd *cmd;
 		json_t *tmp2;
+		int err;
 
 		if (!json_is_object(value)) {
 			json_error(ctx, "Unexpected command array element of type %s, expected object.", json_typename(value));
@@ -4241,19 +4251,11 @@ static int __json_parse(struct json_ctx *ctx)
 			continue;
 		}
 
-		cmd = json_parse_cmd(ctx, value);
-
-		if (!cmd) {
+		err = json_parse_cmd(ctx, value);
+		if (err < 0) {
 			json_error(ctx, "Parsing command array at index %zd failed.", index);
 			return -1;
 		}
-
-		list_add_tail(&cmd->list, &list);
-
-		list_splice_tail(&list, ctx->cmds);
-
-		if (nft_output_echo(&ctx->nft->output))
-			json_cmd_assoc_add(value, cmd);
 	}
 
 	return 0;
-- 
2.43.0





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

  Powered by Linux