[nft PATCH 1/9] json: Support nat in inet family

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add the missing bits to JSON parser, printer, man page and testsuite.

Fixes: fbe27464dee45 ("src: add nat support for the inet family")
Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 doc/libnftables-json.adoc |   5 ++
 src/json.c                |   8 ++
 src/parser_json.c         |   7 +-
 tests/py/inet/dnat.t.json | 166 ++++++++++++++++++++++++++++++++++++++
 tests/py/inet/snat.t.json | 131 ++++++++++++++++++++++++++++++
 5 files changed, 316 insertions(+), 1 deletion(-)
 create mode 100644 tests/py/inet/dnat.t.json
 create mode 100644 tests/py/inet/snat.t.json

diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index dbe5ac33d999e..429f530db913c 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -808,12 +808,14 @@ Duplicate a packet to a different destination.
 ____
 *{ "snat": {
 	"addr":* 'EXPRESSION'*,
+	"family":* 'STRING'*,
 	"port":* 'EXPRESSION'*,
 	"flags":* 'FLAGS'
 *}}*
 
 *{ "dnat": {
 	"addr":* 'EXPRESSION'*,
+	"family":* 'STRING'*,
 	"port":* 'EXPRESSION'*,
 	"flags":* 'FLAGS'
 *}}*
@@ -837,6 +839,9 @@ Perform Network Address Translation.
 
 *addr*::
 	Address to translate to.
+*family*::
+	Family of *addr*, either *ip* or *ip6*. Required in *inet*
+	table family.
 *port*::
 	Port to translate to.
 *flags*::
diff --git a/src/json.c b/src/json.c
index 4900c02336b56..a8538bdca973b 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1260,6 +1260,14 @@ json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
 	json_t *root = json_object();
 	json_t *array = nat_flags_json(stmt->nat.flags);
 
+	switch (stmt->nat.family) {
+	case NFPROTO_IPV4:
+	case NFPROTO_IPV6:
+		json_object_set_new(root, "family",
+				    json_string(family2str(stmt->nat.family)));
+		break;
+	}
+
 	if (stmt->nat.addr)
 		json_object_set_new(root, "addr",
 				    expr_print_json(stmt->nat.addr, octx));
diff --git a/src/parser_json.c b/src/parser_json.c
index 315f247811567..0c4f5d913813a 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1840,9 +1840,9 @@ static int nat_type_parse(const char *type)
 static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx,
 					const char *key, json_t *value)
 {
+	int type, familyval;
 	struct stmt *stmt;
 	json_t *tmp;
-	int type;
 
 	type = nat_type_parse(key);
 	if (type < 0) {
@@ -1850,7 +1850,12 @@ static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx,
 		return NULL;
 	}
 
+	familyval = json_parse_family(ctx, value);
+	if (familyval < 0)
+		return NULL;
+
 	stmt = nat_stmt_alloc(int_loc, type);
+	stmt->nat.family = familyval;
 
 	if (!json_unpack(value, "{s:o}", "addr", &tmp)) {
 		stmt->nat.addr = json_parse_stmt_expr(ctx, tmp);
diff --git a/tests/py/inet/dnat.t.json b/tests/py/inet/dnat.t.json
new file mode 100644
index 0000000000000..ac6dac620a85e
--- /dev/null
+++ b/tests/py/inet/dnat.t.json
@@ -0,0 +1,166 @@
+# iifname "foo" tcp dport 80 redirect to :8080
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "foo"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 80
+        }
+    },
+    {
+        "redirect": {
+            "port": 8080
+        }
+    }
+]
+
+# iifname "eth0" tcp dport 443 dnat ip to 192.168.3.2
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "eth0"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 443
+        }
+    },
+    {
+        "dnat": {
+            "addr": "192.168.3.2",
+            "family": "ip"
+        }
+    }
+]
+
+# iifname "eth0" tcp dport 443 dnat ip6 to [dead::beef]:4443
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "eth0"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 443
+        }
+    },
+    {
+        "dnat": {
+            "addr": "dead::beef",
+            "family": "ip6",
+            "port": 4443
+        }
+    }
+]
+
+# dnat ip to ct mark map { 0x00000014 : 1.2.3.4}
+[
+    {
+        "dnat": {
+            "addr": {
+                "map": {
+                    "data": {
+                        "set": [
+                            [
+                                20,
+                                "1.2.3.4"
+                            ]
+                        ]
+                    },
+                    "key": {
+                        "ct": {
+                            "key": "mark"
+                        }
+                    }
+                }
+            },
+            "family": "ip"
+        }
+    }
+]
+
+# dnat ip to ct mark . ip daddr map { 0x00000014 . 1.1.1.1 : 1.2.3.4}
+[
+    {
+        "dnat": {
+            "addr": {
+                "map": {
+                    "data": {
+                        "set": [
+                            [
+                                {
+                                    "concat": [
+                                        20,
+                                        "1.1.1.1"
+                                    ]
+                                },
+                                "1.2.3.4"
+                            ]
+                        ]
+                    },
+                    "key": {
+                        "concat": [
+                            {
+                                "ct": {
+                                    "key": "mark"
+                                }
+                            },
+                            {
+                                "payload": {
+                                    "field": "daddr",
+                                    "protocol": "ip"
+                                }
+                            }
+                        ]
+                    }
+                }
+            },
+            "family": "ip"
+        }
+    }
+]
+
diff --git a/tests/py/inet/snat.t.json b/tests/py/inet/snat.t.json
new file mode 100644
index 0000000000000..4671625dc06d9
--- /dev/null
+++ b/tests/py/inet/snat.t.json
@@ -0,0 +1,131 @@
+# iifname "eth0" tcp dport 81 snat ip to 192.168.3.2
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "eth0"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 81
+        }
+    },
+    {
+        "snat": {
+            "addr": "192.168.3.2",
+            "family": "ip"
+        }
+    }
+]
+
+# iifname "eth0" tcp dport 81 ip saddr 10.1.1.1 snat to 192.168.3.2
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "eth0"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 81
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "saddr",
+                    "protocol": "ip"
+                }
+            },
+            "op": "==",
+            "right": "10.1.1.1"
+        }
+    },
+    {
+        "snat": {
+            "addr": "192.168.3.2",
+            "family": "ip"
+        }
+    }
+]
+
+# iifname "eth0" tcp dport 81 snat ip6 to dead::beef
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "eth0"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "dport",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 81
+        }
+    },
+    {
+        "snat": {
+            "addr": "dead::beef",
+            "family": "ip6"
+        }
+    }
+]
+
+# iifname "foo" masquerade random
+[
+    {
+        "match": {
+            "left": {
+                "meta": {
+                    "key": "iifname"
+                }
+            },
+            "op": "==",
+            "right": "foo"
+        }
+    },
+    {
+        "masquerade": {
+            "flags": "random"
+        }
+    }
+]
+
-- 
2.21.0




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux