]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
json: Fix tproxy support regarding latest changes
authorPhil Sutter <phil@nwl.cc>
Thu, 9 May 2019 11:35:41 +0000 (13:35 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 9 May 2019 15:19:50 +0000 (17:19 +0200)
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 <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/json.c
src/parser_json.c
tests/py/inet/tproxy.t
tests/py/inet/tproxy.t.json
tests/py/inet/tproxy.t.payload
tests/py/ip/tproxy.t
tests/py/ip/tproxy.t.json
tests/py/ip/tproxy.t.json.output [new file with mode: 0644]
tests/py/ip6/tproxy.t
tests/py/ip6/tproxy.t.json
tests/py/ip6/tproxy.t.json.output [new file with mode: 0644]

index a8538bdca973bb7a17bca0007fe1130eabf5cfe2..ff79b0cc729c78c4a81b04fe24b220dda9c1bd80 100644 (file)
@@ -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);
 }
index e042d77672500c7715df6a280c7267430c75d8a6..9c5fafbaed37881b07cb463c8daeaff0c5bd2b3e 100644 (file)
@@ -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) {
index 0ba78ef1826a24ecb6b289fca3d4a3ee9a43146d..d23bbcb56cdcded17bc1bde6954840d21922e355 100644 (file)
@@ -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
index 2897d2007192a85239850efa60be013ae9d4a7c6..7b3b11c49205ab2c4983f9d62567c37069de5b58 100644 (file)
     }
 ]
 
+# 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
 [
     {
         }
     }
 ]
+
+# 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
+        }
+    }
+]
index 8a6ba03656059eb18fe8839714dfeee4193c6114..82ff928db772f452f04a6bd582a11d638ab8f927 100644 (file)
@@ -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 ]
index 966898c037b26658ada1edd7a60a106049a977f6..544c5193efea67df27d56f8b94fa98fd2ad2a222 100644 (file)
@@ -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
index 1936b5f43be0069a95262fe2bd24a5abda369814..4635fc1f84e4b9d850df2a941217a85fd40c2da3 100644 (file)
@@ -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
         }
     }
         }
     }
 ]
+
+# 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 (file)
index 0000000..2690f22
--- /dev/null
@@ -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
+        }
+    }
+]
index 48fe4ca76505239aed833c1d83ddd60d836e8e6f..d4c6bffb969bc6597d64e0b51e795b1eb509741b 100644 (file)
@@ -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
index 7372acb93f50091e6634121e87182c3bfb213856..0e02d49c9b9db1ab883ced908722ca91c3f987e6 100644 (file)
@@ -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
         }
     }
         }
     }
 ]
+
+# 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 (file)
index 0000000..461738b
--- /dev/null
@@ -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
+        }
+    }
+]