summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-08-29 16:23:23 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-08-30 12:19:36 +0200
commit8125785d5c5d35ec275e508166091d5472748bc1 (patch)
treef95de547642eab67d12762a5297645e80ffa22c3
parent2a4a5a2c8ae21f2bcf7e81b5eafea91d799ee88a (diff)
JSON: Review verdict statement and expression
Change jump and goto verdicts to become extensible by dedicating an object for the target parameter. While being at it, drop break and queue verdict expressions since they don't seem to exist, no idea where I got those from in the first place. For queue, there is a dedicated expression at least. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--doc/libnftables-json.adoc18
-rw-r--r--src/json.c5
-rw-r--r--src/parser_json.c10
-rwxr-xr-xtests/py/nft-test.py4
4 files changed, 19 insertions, 18 deletions
diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index 058573df..74e7d027 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -548,13 +548,13 @@ single statement.
*{ "drop": null }*
*{ "continue": null }*
*{ "return": null }*
-*{ "jump":* 'STRING' *}*
-*{ "goto":* 'STRING' *}*
+*{ "jump": { "target": * 'STRING' *}}*
+*{ "goto": { "target": * 'STRING' *}}*
A verdict either terminates packet traversal through the current chain or
delegates to a different one.
-*jump* and *goto* statements expect a target chain name as value.
+*jump* and *goto* statements expect a target chain name.
=== MATCH
[verse]
@@ -1177,18 +1177,16 @@ side.
=== VERDICT
[verse]
-*{ "continue": null }*
-*{ "break": null }*
-*{ "jump":* 'STRING' *}*
-*{ "goto":* 'STRING' *}*
-*{ "return": null }*
*{ "accept": null }*
*{ "drop": null }*
-*{ "queue": null }*
+*{ "continue": null }*
+*{ "return": null }*
+*{ "jump": { "target":* 'STRING' *}}*
+*{ "goto": { "target":* 'STRING' *}}*
Same as *verdict* statement, but for use in verdict maps.
-Only *jump* and *goto* verdicts expect a string denoting the target chain name.
+*jump* and *goto* verdicts expect a target chain name.
=== ELEM
[verse]
diff --git a/src/json.c b/src/json.c
index 0c708c7d..30ee81cf 100644
--- a/src/json.c
+++ b/src/json.c
@@ -642,7 +642,10 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx)
BUG("Unknown verdict %d.", expr->verdict);
return NULL;
}
- return json_pack("{s:o}", name, chain ? json_string(chain) : json_null());
+ if (chain)
+ return json_pack("{s:{s:s}}", name, "target", chain);
+ else
+ return json_pack("{s:n}", name);
}
json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx)
diff --git a/src/parser_json.c b/src/parser_json.c
index 88390432..dd21d428 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1031,27 +1031,25 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx,
bool chain;
} verdict_tbl[] = {
{ NFT_CONTINUE, "continue", false },
- { NFT_BREAK, "break", false },
{ NFT_JUMP, "jump", true },
{ NFT_GOTO, "goto", true },
{ NFT_RETURN, "return", false },
{ NF_ACCEPT, "accept", false },
{ NF_DROP, "drop", false },
- { NF_QUEUE, "queue", false },
};
const char *chain = NULL;
unsigned int i;
- json_unpack(root, "s", &chain);
+ json_unpack(root, "{s:s}", "target", &chain);
for (i = 0; i < array_size(verdict_tbl); i++) {
if (strcmp(type, verdict_tbl[i].name))
continue;
- if (verdict_tbl[i].chain && !chain) {
- json_error(ctx, "Verdict %s needs chain argument.", type);
+ if (verdict_tbl[i].chain &&
+ json_unpack_err(ctx, root, "{s:s}", "target", &chain))
return NULL;
- }
+
return verdict_expr_alloc(int_loc,
verdict_tbl[i].verdict, chain);
}
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 1b7e04c9..3b89ec35 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -278,7 +278,9 @@ def chain_create(chain, table, filename):
print_error(reason, filename, chain.lineno)
return -1
- cmd = "add chain %s %s { %s; }" % (table, chain, chain.config)
+ cmd = "add chain %s %s" % (table, chain)
+ if chain.config:
+ cmd += " { %s; }" % chain.config
ret = execute_cmd(cmd, filename, chain.lineno)
if ret != 0: