summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-08-29 16:23:27 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-08-30 12:19:36 +0200
commit90d4ee087171e75d5313359ad6b6f1341e51ddc5 (patch)
tree59572c39aa334813b9b090fa46a57fedf9ff5aac /src
parent8f6e1c37e3e74e1fd490a0de5360ff1467c521cd (diff)
JSON: Make match op mandatory, introduce 'in' operator
This special operator is required for cases where missing operator does not lead to same results as equal operator, i.e. with bitmasks on RHS. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/json.c17
-rw-r--r--src/parser_json.c24
2 files changed, 16 insertions, 25 deletions
diff --git a/src/json.c b/src/json.c
index 4af8ee8e..2a13dfe7 100644
--- a/src/json.c
+++ b/src/json.c
@@ -385,19 +385,10 @@ json_t *binop_expr_json(const struct expr *expr, struct output_ctx *octx)
json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- json_t *tmp;
-
- tmp = json_pack("{s:o, s:o}",
- "left", expr_print_json(expr->left, octx),
- "right", expr_print_json(expr->right, octx));
- /* XXX: check taken from binop_expr_print()
- * if right is range, op is OP_EQ which in turn crashes nft if fed with it */
- if (expr_op_symbols[expr->op] &&
- (expr->op != OP_EQ || must_print_eq_op(expr)))
- json_object_set_new(tmp, "op",
- json_string(expr_op_symbols[expr->op]));
-
- return json_pack("{s:o}", "match", tmp);
+ return json_pack("{s:{s:s, s:o, s:o}}", "match",
+ "op", expr_op_symbols[expr->op] ? : "in",
+ "left", expr_print_json(expr->left, octx),
+ "right", expr_print_json(expr->right, octx));
}
json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
diff --git a/src/parser_json.c b/src/parser_json.c
index 2f7e0a3e..6870434e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1363,24 +1363,24 @@ static struct stmt *json_parse_match_stmt(struct json_ctx *ctx,
const char *opstr = NULL;
enum ops op;
- if (json_unpack_err(ctx, value, "{s:o, s:o}",
+ if (json_unpack_err(ctx, value, "{s:o, s:o, s:s}",
"left", &jleft,
- "right", &jright))
+ "right", &jright,
+ "op", &opstr))
return NULL;
- json_unpack(value, "{s:s}", "op", &opstr);
- if (opstr) {
- for (op = OP_INVALID; op < __OP_MAX; op++) {
- if (expr_op_symbols[op] &&
- !strcmp(opstr, expr_op_symbols[op]))
- break;
- }
- if (op == __OP_MAX) {
+ for (op = OP_INVALID; op < __OP_MAX; op++) {
+ if (expr_op_symbols[op] &&
+ !strcmp(opstr, expr_op_symbols[op]))
+ break;
+ }
+ if (op == __OP_MAX) {
+ if (!strcmp(opstr, "in")) {
+ op = OP_IMPLICIT;
+ } else {
json_error(ctx, "Unknown relational op '%s'.", opstr);
return NULL;
}
- } else {
- op = OP_IMPLICIT;
}
left = json_parse_expr(ctx, jleft);