JSON equivalent of fwd statement was too primitive to support the added address and family parameters, so make its value an object and accept the device expression as value of a "dev" property in there. Then add optional "addr" and "family" properties to it. While being at it, add a testcase to make sure the extended syntax works right. Signed-off-by: Phil Sutter <phil@xxxxxx> --- src/json.c | 13 ++++++++-- src/parser_json.c | 40 ++++++++++++++++++++++++++++-- tests/py/any/fwd.t | 1 + tests/py/any/fwd.t.json | 45 ++++++++++++++++++++++------------ tests/py/any/fwd.t.json.output | 30 ++++++++++++----------- tests/py/any/fwd.t.payload | 6 +++++ 6 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/json.c b/src/json.c index a871c934f020c..c1cd0fbfa07f8 100644 --- a/src/json.c +++ b/src/json.c @@ -1008,9 +1008,18 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx) json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx) { - json_t *root; + json_t *root, *tmp; + + root = json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx)); + + if (stmt->fwd.addr) { + tmp = json_string(family2str(stmt->fwd.family)); + json_object_set_new(root, "family", tmp); + + tmp = expr_print_json(stmt->fwd.addr, octx); + json_object_set_new(root, "addr", tmp); + } - root = expr_print_json(stmt->fwd.dev, octx); return json_pack("{s:o}", "fwd", root); } diff --git a/src/parser_json.c b/src/parser_json.c index bc36136f825fc..2fd0ef832bd0e 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1584,11 +1584,47 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx, static struct stmt *json_parse_fwd_stmt(struct json_ctx *ctx, const char *key, json_t *value) { - struct stmt *stmt = fwd_stmt_alloc(int_loc); + json_t *jaddr, *jdev; + const char *family; + struct stmt *stmt; + int familyval; + + if (json_unpack_err(ctx, value, "{s:o}", "dev", &jdev)) + return NULL; - stmt->fwd.dev = json_parse_expr(ctx, value); + stmt = fwd_stmt_alloc(int_loc); + + stmt->fwd.dev = json_parse_stmt_expr(ctx, jdev); + if (!stmt->fwd.dev) { + json_error(ctx, "Invalid fwd dev value."); + goto out_err; + } + + if (json_unpack(value, "{s:s, s:o}", + "family", &family, "addr", &jaddr)) + return stmt; + + familyval = parse_family(family); + switch (familyval) { + case NFPROTO_IPV4: + case NFPROTO_IPV6: + stmt->fwd.family = familyval; + break; + default: + json_error(ctx, "Invalid fwd family value '%s'.", family); + goto out_err; + } + + stmt->fwd.addr = json_parse_stmt_expr(ctx, jaddr); + if (!stmt->fwd.addr) { + json_error(ctx, "Invalid fwd addr value."); + goto out_err; + } return stmt; +out_err: + stmt_free(stmt); + return NULL; } static struct stmt *json_parse_notrack_stmt(struct json_ctx *ctx, diff --git a/tests/py/any/fwd.t b/tests/py/any/fwd.t index d9b4514ee29a1..986a16d9e2c8c 100644 --- a/tests/py/any/fwd.t +++ b/tests/py/any/fwd.t @@ -5,3 +5,4 @@ fwd to "lo";ok fwd to mark map { 0x00000001 : "lo", 0x00000002 : "lo"};ok +fwd ip to 192.168.2.200 device "lo";ok diff --git a/tests/py/any/fwd.t.json b/tests/py/any/fwd.t.json index 644d6d48c2a19..e58a8ad25829b 100644 --- a/tests/py/any/fwd.t.json +++ b/tests/py/any/fwd.t.json @@ -1,7 +1,9 @@ # fwd to "lo" [ { - "fwd": "lo" + "fwd": { + "dev": "lo" + } } ] @@ -9,24 +11,37 @@ [ { "fwd": { - "map": { - "left": { - "meta": "mark" - }, - "right": { - "set": [ - [ - "0x00000001", - "lo" - ], - [ - "0x00000002", - "lo" + "dev": { + "map": { + "left": { + "meta": "mark" + }, + "right": { + "set": [ + [ + "0x00000001", + "lo" + ], + [ + "0x00000002", + "lo" + ] ] - ] + } } } } } ] +# fwd ip to 192.168.2.200 device "lo" +[ + { + "fwd": { + "addr": "192.168.2.200", + "dev": "lo", + "family": "ip" + } + } +] + diff --git a/tests/py/any/fwd.t.json.output b/tests/py/any/fwd.t.json.output index 5a943567adb0c..e4bad620b22d4 100644 --- a/tests/py/any/fwd.t.json.output +++ b/tests/py/any/fwd.t.json.output @@ -2,21 +2,23 @@ [ { "fwd": { - "map": { - "left": { - "meta": "mark" - }, - "right": { - "set": [ - [ - 1, - "lo" - ], - [ - 2, - "lo" + "dev": { + "map": { + "left": { + "meta": "mark" + }, + "right": { + "set": [ + [ + 1, + "lo" + ], + [ + 2, + "lo" + ] ] - ] + } } } } diff --git a/tests/py/any/fwd.t.payload b/tests/py/any/fwd.t.payload index 696b55efe8207..966c08b0959c3 100644 --- a/tests/py/any/fwd.t.payload +++ b/tests/py/any/fwd.t.payload @@ -12,3 +12,9 @@ netdev test-netdev ingress [ lookup reg 1 set __map%d dreg 1 ] [ fwd sreg_dev 1 ] +# fwd ip to 192.168.2.200 device "lo" +netdev test-netdev ingress + [ immediate reg 1 0x00000001 ] + [ immediate reg 2 0xc802a8c0 ] + [ fwd sreg_dev 1 sreg_addr 2 nfproto 2 ] + -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html