From 48d688ddb20d4594ee946014a661d30c82c9247d Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Fri, 8 Jun 2018 17:27:18 +0200
Subject: [PATCH] JSON: Support latest enhancements of fwd statement
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@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit f63b54623fcd1ab7d2f51928571c164409f00175)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
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 7d89754bd666d..eeba90e266f75 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 6e14fb7278fb0..af57b3025a104 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1561,11 +1561,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.21.0