From 1b8953e75c20437b5c563d86c3ba11d1b24e3ec4 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 9 May 2019 13:35:41 +0200 Subject: json: Fix tproxy support regarding latest changes Family may be specified also if no address is given at the same time, make parser/printer tolerant to that. Also fix for missing/incorrect JSON equivalents in tests/py. While being at it, fix two issues in non-JSON tests: * Ruleset is printed in numeric mode, so use 'l4proto 6' instead of 'l4proto tcp' in rules to avoid having to specify expected output for that unrelated bit. * In ip and ip6 family tables, family parameter is not deserialized on output. Fixes: 3edb96200690b ("parser_bison: missing tproxy syntax with port only for inet family") Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- src/json.c | 23 +++++------ src/parser_json.c | 16 ++++---- tests/py/inet/tproxy.t | 2 +- tests/py/inet/tproxy.t.json | 80 +++++++++++++++++++++++++++++++++++++++ tests/py/inet/tproxy.t.payload | 2 +- tests/py/ip/tproxy.t | 2 +- tests/py/ip/tproxy.t.json | 26 +++++++++++-- tests/py/ip/tproxy.t.json.output | 61 +++++++++++++++++++++++++++++ tests/py/ip6/tproxy.t | 2 +- tests/py/ip6/tproxy.t.json | 26 +++++++++++-- tests/py/ip6/tproxy.t.json.output | 60 +++++++++++++++++++++++++++++ 11 files changed, 268 insertions(+), 32 deletions(-) create mode 100644 tests/py/ip/tproxy.t.json.output create mode 100644 tests/py/ip6/tproxy.t.json.output diff --git a/src/json.c b/src/json.c index a8538bdc..ff79b0cc 100644 --- a/src/json.c +++ b/src/json.c @@ -1437,26 +1437,23 @@ json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx) json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx) { - json_t *root = json_object(); - - if (stmt->tproxy.addr) { - int family; - json_t *tmp; - - family = stmt->tproxy.table_family; - if (family == NFPROTO_INET) - family = stmt->tproxy.family; + json_t *tmp, *root = json_object(); - tmp = json_string(family2str(family)); + if (stmt->tproxy.table_family == NFPROTO_INET && + stmt->tproxy.family != NFPROTO_UNSPEC) { + tmp = json_string(family2str(stmt->tproxy.family)); json_object_set_new(root, "family", tmp); + } + if (stmt->tproxy.addr) { tmp = expr_print_json(stmt->tproxy.addr, octx); json_object_set_new(root, "addr", tmp); } - if (stmt->tproxy.port) - json_object_set_new(root, "port", - expr_print_json(stmt->tproxy.port, octx)); + if (stmt->tproxy.port) { + tmp = expr_print_json(stmt->tproxy.port, octx); + json_object_set_new(root, "port", tmp); + } return json_pack("{s:o}", "tproxy", root); } diff --git a/src/parser_json.c b/src/parser_json.c index e042d776..9c5fafba 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1899,17 +1899,15 @@ static struct stmt *json_parse_tproxy_stmt(struct json_ctx *ctx, if (familyval < 0) goto out_free; - if (familyval == NFPROTO_UNSPEC || - json_unpack(value, "{s:o}", "addr", &jaddr)) - goto try_port; - stmt->tproxy.family = familyval; - stmt->tproxy.addr = json_parse_stmt_expr(ctx, jaddr); - if (!stmt->tproxy.addr) { - json_error(ctx, "Invalid addr."); - goto out_free; + + if (!json_unpack(value, "{s:o}", "addr", &jaddr)) { + stmt->tproxy.addr = json_parse_stmt_expr(ctx, jaddr); + if (!stmt->tproxy.addr) { + json_error(ctx, "Invalid addr."); + goto out_free; + } } -try_port: if (!json_unpack(value, "{s:o}", "port", &tmp)) { stmt->tproxy.port = json_parse_stmt_expr(ctx, tmp); if (!stmt->tproxy.port) { diff --git a/tests/py/inet/tproxy.t b/tests/py/inet/tproxy.t index 0ba78ef1..d23bbcb5 100644 --- a/tests/py/inet/tproxy.t +++ b/tests/py/inet/tproxy.t @@ -18,4 +18,4 @@ ip6 nexthdr 6 tproxy ip to 192.0.2.1;fail meta l4proto 17 tproxy ip to :50080;ok meta l4proto 17 tproxy ip6 to :50080;ok meta l4proto 17 tproxy to :50080;ok -ip daddr 0.0.0.0/0 meta l4proto tcp tproxy ip to :2000;ok +ip daddr 0.0.0.0/0 meta l4proto 6 tproxy ip to :2000;ok diff --git a/tests/py/inet/tproxy.t.json b/tests/py/inet/tproxy.t.json index 2897d200..7b3b11c4 100644 --- a/tests/py/inet/tproxy.t.json +++ b/tests/py/inet/tproxy.t.json @@ -84,6 +84,48 @@ } ] +# meta l4proto 17 tproxy ip to :50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 17 + } + }, + { + "tproxy": { + "family": "ip", + "port": 50080 + } + } +] + +# meta l4proto 17 tproxy ip6 to :50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 17 + } + }, + { + "tproxy": { + "family": "ip6", + "port": 50080 + } + } +] + # meta l4proto 17 tproxy to :50080 [ { @@ -103,3 +145,41 @@ } } ] + +# ip daddr 0.0.0.0/0 meta l4proto 6 tproxy ip to :2000 +[ + { + "match": { + "left": { + "payload": { + "field": "daddr", + "protocol": "ip" + } + }, + "op": "==", + "right": { + "prefix": { + "addr": "0.0.0.0", + "len": 0 + } + } + } + }, + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "family": "ip", + "port": 2000 + } + } +] diff --git a/tests/py/inet/tproxy.t.payload b/tests/py/inet/tproxy.t.payload index 8a6ba036..82ff928d 100644 --- a/tests/py/inet/tproxy.t.payload +++ b/tests/py/inet/tproxy.t.payload @@ -49,7 +49,7 @@ inet x y [ immediate reg 1 0x0000a0c3 ] [ tproxy ip6 port reg 1 ] -# ip daddr 0.0.0.0/0 meta l4proto tcp tproxy ip to :2000 +# ip daddr 0.0.0.0/0 meta l4proto 6 tproxy ip to :2000 inet x y [ meta load nfproto => reg 1 ] [ cmp eq reg 1 0x00000002 ] diff --git a/tests/py/ip/tproxy.t b/tests/py/ip/tproxy.t index 966898c0..544c5193 100644 --- a/tests/py/ip/tproxy.t +++ b/tests/py/ip/tproxy.t @@ -11,4 +11,4 @@ meta l4proto 6 tproxy to 192.0.2.1:50080;ok ip protocol 6 tproxy to :50080;ok meta l4proto 17 tproxy ip to 192.0.2.1;ok;meta l4proto 17 tproxy to 192.0.2.1 meta l4proto 6 tproxy ip to 192.0.2.1:50080;ok;meta l4proto 6 tproxy to 192.0.2.1:50080 -ip protocol 6 tproxy ip to :50080;ok +ip protocol 6 tproxy ip to :50080;ok;ip protocol 6 tproxy to :50080 diff --git a/tests/py/ip/tproxy.t.json b/tests/py/ip/tproxy.t.json index 1936b5f4..4635fc1f 100644 --- a/tests/py/ip/tproxy.t.json +++ b/tests/py/ip/tproxy.t.json @@ -13,8 +13,7 @@ }, { "tproxy": { - "addr": "192.0.2.1", - "family": "ip" + "addr": "192.0.2.1" } } ] @@ -35,7 +34,6 @@ { "tproxy": { "addr": "192.0.2.1", - "family": "ip", "port": 50080 } } @@ -104,3 +102,25 @@ } } ] + +# ip protocol 6 tproxy ip to :50080 +[ + { + "match": { + "left": { + "payload": { + "field": "protocol", + "protocol": "ip" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "family": "ip", + "port": 50080 + } + } +] diff --git a/tests/py/ip/tproxy.t.json.output b/tests/py/ip/tproxy.t.json.output new file mode 100644 index 00000000..2690f225 --- /dev/null +++ b/tests/py/ip/tproxy.t.json.output @@ -0,0 +1,61 @@ +# meta l4proto 17 tproxy ip to 192.0.2.1 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 17 + } + }, + { + "tproxy": { + "addr": "192.0.2.1" + } + } +] + +# meta l4proto 6 tproxy ip to 192.0.2.1:50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "addr": "192.0.2.1", + "port": 50080 + } + } +] + +# ip protocol 6 tproxy ip to :50080 +[ + { + "match": { + "left": { + "payload": { + "field": "protocol", + "protocol": "ip" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "port": 50080 + } + } +] diff --git a/tests/py/ip6/tproxy.t b/tests/py/ip6/tproxy.t index 48fe4ca7..d4c6bffb 100644 --- a/tests/py/ip6/tproxy.t +++ b/tests/py/ip6/tproxy.t @@ -11,4 +11,4 @@ meta l4proto 17 tproxy to [2001:db8::1]:50080;ok meta l4proto 6 tproxy to :50080;ok meta l4proto 6 tproxy ip6 to [2001:db8::1];ok;meta l4proto 6 tproxy to [2001:db8::1] meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080;ok;meta l4proto 17 tproxy to [2001:db8::1]:50080 -meta l4proto 6 tproxy ip6 to :50080;ok +meta l4proto 6 tproxy ip6 to :50080;ok;meta l4proto 6 tproxy to :50080 diff --git a/tests/py/ip6/tproxy.t.json b/tests/py/ip6/tproxy.t.json index 7372acb9..0e02d49c 100644 --- a/tests/py/ip6/tproxy.t.json +++ b/tests/py/ip6/tproxy.t.json @@ -13,8 +13,7 @@ }, { "tproxy": { - "addr": "2001:db8::1", - "family": "ip6" + "addr": "2001:db8::1" } } ] @@ -35,7 +34,6 @@ { "tproxy": { "addr": "2001:db8::1", - "family": "ip6", "port": 50080 } } @@ -103,3 +101,25 @@ } } ] + +# meta l4proto 6 tproxy ip6 to :50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "family": "ip6", + "port": 50080 + } + } +] + diff --git a/tests/py/ip6/tproxy.t.json.output b/tests/py/ip6/tproxy.t.json.output new file mode 100644 index 00000000..461738bd --- /dev/null +++ b/tests/py/ip6/tproxy.t.json.output @@ -0,0 +1,60 @@ +# meta l4proto 6 tproxy ip6 to [2001:db8::1] +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "addr": "2001:db8::1" + } + } +] + +# meta l4proto 17 tproxy ip6 to [2001:db8::1]:50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 17 + } + }, + { + "tproxy": { + "addr": "2001:db8::1", + "port": 50080 + } + } +] + +# meta l4proto 6 tproxy ip6 to :50080 +[ + { + "match": { + "left": { + "meta": { + "key": "l4proto" + } + }, + "op": "==", + "right": 6 + } + }, + { + "tproxy": { + "port": 50080 + } + } +] -- cgit v1.2.3