From patchwork Mon May 28 16:50:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921632 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZf6137z9rxs for ; Tue, 29 May 2018 02:52:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425494AbeE1Qw0 (ORCPT ); Mon, 28 May 2018 12:52:26 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34254 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1425493AbeE1QwZ (ORCPT ); Mon, 28 May 2018 12:52:25 -0400 Received: from localhost ([::1]:49530 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNg-0002Qe-Ec; Mon, 28 May 2018 18:52:24 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 01/14] objref: Use "ct helper" for NFT_OBJECT_CT_HELPER Date: Mon, 28 May 2018 18:50:56 +0200 Message-Id: <20180528165109.15992-2-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Change name of NFT_OBJECT_CT_HELPER in objref_type table to "ct helper" for consistency. Note that this is not used in regular nft output since objref_stmt_print() treats this object type separately. Signed-off-by: Phil Sutter --- src/parser_json.c | 2 +- src/statement.c | 2 +- tests/py/ip/objects.t.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index 88a69493ab7d3..f872977f5bcb4 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2109,7 +2109,7 @@ static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root) { "reject", json_parse_reject_stmt }, { "set", json_parse_set_stmt }, { "log", json_parse_log_stmt }, - { "cthelper", json_parse_cthelper_stmt }, + { "ct helper", json_parse_cthelper_stmt }, { "meter", json_parse_meter_stmt }, { "queue", json_parse_queue_stmt }, }; diff --git a/src/statement.c b/src/statement.c index d2910018b47eb..687ee351b0ca9 100644 --- a/src/statement.c +++ b/src/statement.c @@ -179,7 +179,7 @@ struct stmt *counter_stmt_alloc(const struct location *loc) static const char *objref_type[NFT_OBJECT_MAX + 1] = { [NFT_OBJECT_COUNTER] = "counter", [NFT_OBJECT_QUOTA] = "quota", - [NFT_OBJECT_CT_HELPER] = "cthelper", + [NFT_OBJECT_CT_HELPER] = "ct helper", [NFT_OBJECT_LIMIT] = "limit", }; diff --git a/tests/py/ip/objects.t.json b/tests/py/ip/objects.t.json index c83cc6a47c6e7..77c6886842b27 100644 --- a/tests/py/ip/objects.t.json +++ b/tests/py/ip/objects.t.json @@ -101,14 +101,14 @@ # ct helper set "cthelp1" [ { - "cthelper": "cthelp1" + "ct helper": "cthelp1" } ] # ct helper set tcp dport map {21 : "cthelp1", 2121 : "cthelp1" } [ { - "cthelper": { + "ct helper": { "map": { "left": { "payload": { From patchwork Mon May 28 16:50:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921631 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZY3D3Wz9rxs for ; Tue, 29 May 2018 02:52:21 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425492AbeE1QwV (ORCPT ); Mon, 28 May 2018 12:52:21 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34248 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1425480AbeE1QwU (ORCPT ); Mon, 28 May 2018 12:52:20 -0400 Received: from localhost ([::1]:49524 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNb-0002QL-1M; Mon, 28 May 2018 18:52:19 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 02/14] JSON: Use "type" for CT helper object Date: Mon, 28 May 2018 18:50:57 +0200 Message-Id: <20180528165109.15992-3-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Property name "helper" was a bit unclear, "type" is better. Signed-off-by: Phil Sutter --- src/json.c | 2 +- src/parser_json.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/json.c b/src/json.c index e458eb3e4bdd8..1b73b919d5df2 100644 --- a/src/json.c +++ b/src/json.c @@ -275,7 +275,7 @@ static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) case NFT_OBJECT_CT_HELPER: type = "ct helper"; tmp = json_pack("{s:s, s:o, s:s}", - "helper", obj->ct_helper.name, "protocol", + "type", obj->ct_helper.name, "protocol", proto_name_json(obj->ct_helper.l4proto), "l3proto", family2str(obj->ct_helper.l3proto)); json_object_update(root, tmp); diff --git a/src/parser_json.c b/src/parser_json.c index f872977f5bcb4..993368f04ea4a 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2643,14 +2643,14 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, case NFT_OBJECT_CT_HELPER: cmd_obj = CMD_OBJ_CT_HELPER; obj->type = NFT_OBJECT_CT_HELPER; - if (!json_unpack(root, "{s:s}", "helper", &tmp)) { + if (!json_unpack(root, "{s:s}", "type", &tmp)) { int ret; ret = snprintf(obj->ct_helper.name, sizeof(obj->ct_helper.name), "%s", tmp); if (ret < 0 || ret >= (int)sizeof(obj->ct_helper.name)) { - json_error(ctx, "Invalid CT helper name '%s', max length is %zu.", + json_error(ctx, "Invalid CT helper type '%s', max length is %zu.", tmp, sizeof(obj->ct_helper.name)); obj_free(obj); return NULL; From patchwork Mon May 28 16:50:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921628 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZD679fz9rxs for ; Tue, 29 May 2018 02:52:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S940464AbeE1QwE (ORCPT ); Mon, 28 May 2018 12:52:04 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34228 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932206AbeE1QwD (ORCPT ); Mon, 28 May 2018 12:52:03 -0400 Received: from localhost ([::1]:49504 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNK-0002Om-PJ; Mon, 28 May 2018 18:52:02 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 03/14] JSON: Disallow non-array concat expression values Date: Mon, 28 May 2018 18:50:58 +0200 Message-Id: <20180528165109.15992-4-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Concat expressions with just a single element don't make sense, so there's no point in supporting a shorter syntax for this. Signed-off-by: Phil Sutter --- src/parser_json.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index 993368f04ea4a..60929386be4da 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -910,9 +910,7 @@ static struct expr *json_parse_concat_expr(struct json_ctx *ctx, json_t *value; size_t index; - if (json_is_object(root)) - return json_parse_primary_expr(ctx, root); - else if (!json_is_array(root)) { + if (!json_is_array(root)) { json_error(ctx, "Unexpected concat object type %s.", json_typename(root)); return NULL; From patchwork Mon May 28 16:50:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921624 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYq5QZCz9rxs for ; Tue, 29 May 2018 02:51:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933732AbeE1Qvn (ORCPT ); Mon, 28 May 2018 12:51:43 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34204 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932206AbeE1Qvm (ORCPT ); Mon, 28 May 2018 12:51:42 -0400 Received: from localhost ([::1]:49480 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLMz-0002Nh-Eh; Mon, 28 May 2018 18:51:41 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 04/14] JSON: Sort out rule position and handles in general Date: Mon, 28 May 2018 18:50:59 +0200 Message-Id: <20180528165109.15992-5-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org First of all, don't print the position property when listing rules. This was there only because libnftnl JSON output has it too, but since the preferred way to *add* a rule at some location is via 'handle' keyword, keeping "position" in output would be non-intuitive. Changing "position" property name to "handle" instead is also a no-go since that would clash with the real rule handle. Secondly, turn all handle output on regardless of octx->handle setting. For a programmatic API like JSON, this should be fine. Thirdly, fix rule locations when parsing JSON: Respect "handle" property for CMD_INSERT and CMD_ADD and ignore "pos" at all (actually even a typo, should have read "position"). Also support "index" property recently added to standard syntax. Finally, adjust nft-test.py for the above changes: There is no "position" property to drop from rule output, and "handle" property will always be present. Signed-off-by: Phil Sutter --- src/json.c | 37 +++++++++++++------------------------ src/parser_json.c | 14 +++++++++----- tests/py/nft-test.py | 10 ++-------- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/json.c b/src/json.c index 1b73b919d5df2..622a10b30c580 100644 --- a/src/json.c +++ b/src/json.c @@ -89,14 +89,12 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set) type = "set"; } - root = json_pack("{s:s, s:s, s:s, s:o}", + root = json_pack("{s:s, s:s, s:s, s:o, s:I}", "family", family2str(set->handle.family), "name", set->handle.set.name, "table", set->handle.table.name, - "type", set_dtype_json(set->key)); - if (octx->handle) - json_object_set_new(root, "handle", - json_integer(set->handle.handle.id)); + "type", set_dtype_json(set->key), + "handle", set->handle.handle.id); if (datatype_ext) json_object_set_new(root, "map", json_string(datatype_ext)); @@ -181,10 +179,7 @@ static json_t *rule_print_json(struct output_ctx *octx, "family", family2str(rule->handle.family), "table", rule->handle.table.name, "chain", rule->handle.chain.name, - "position", rule->handle.position.id); - if (octx->handle) - json_object_set_new(root, "handle", - json_integer(rule->handle.handle.id)); + "handle", rule->handle.handle.id); if (rule->comment) json_object_set_new(root, "comment", json_string(rule->comment)); @@ -208,13 +203,11 @@ static json_t *chain_print_json(const struct output_ctx *octx, { json_t *root, *tmp; - root = json_pack("{s:s, s:s, s:s}", + root = json_pack("{s:s, s:s, s:s, s:I}", "family", family2str(chain->handle.family), "table", chain->handle.table.name, - "name", chain->handle.chain.name); - if (octx->handle) - json_object_set_new(root, "handle", - json_integer(chain->handle.handle.id)); + "name", chain->handle.chain.name, + "handle", chain->handle.handle.id); if (chain->flags & CHAIN_F_BASECHAIN) { tmp = json_pack("{s:s, s:s, s:i, s:s}", @@ -248,13 +241,11 @@ static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) const char *unit; uint64_t rate; - root = json_pack("{s:s, s:s, s:s}", + root = json_pack("{s:s, s:s, s:s, s:I}", "family", family2str(obj->handle.family), "name", obj->handle.obj.name, - "table", obj->handle.table.name); - if (octx->handle) - json_object_set_new(root, "handle", - json_integer(obj->handle.handle.id)); + "table", obj->handle.table.name, + "handle", obj->handle.handle.id); switch (obj->type) { case NFT_OBJECT_COUNTER: @@ -374,12 +365,10 @@ static json_t *table_print_json(const struct output_ctx *octx, { json_t *root, *tmp; - root = json_pack("{s:s, s:s}", + root = json_pack("{s:s, s:s, s:I}", "family", family2str(table->handle.family), - "name", table->handle.table.name); - if (octx->handle) - json_object_set_new(root, "handle", - json_integer(table->handle.handle.id)); + "name", table->handle.table.name, + "handle", table->handle.handle.id); tmp = table_flags_json(table); if (tmp) diff --git a/src/parser_json.c b/src/parser_json.c index 60929386be4da..1c5994f811e30 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2770,14 +2770,18 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx, "chain", &h.chain.name, "expr", &tmp)) return NULL; + json_unpack(root, "{s:I}", "handle", &h.handle.id); + json_unpack(root, "{s:I}", "index", &h.index.id); - if (op == CMD_REPLACE && - json_unpack_err(ctx, root, "{s:I}", "handle", &h.handle.id)) + if (op == CMD_REPLACE && !h.handle.id) { + json_error(ctx, "Handle is required when replacing a rule."); return NULL; + } - if (op == CMD_INSERT && - json_unpack_err(ctx, root, "{s:i}", "pos", &h.position.id)) - return NULL; + if ((op == CMD_INSERT || op == CMD_ADD) && h.handle.id) { + h.position.id = h.handle.id; + h.handle.id = 0; + } h.family = parse_family(family); if (h.family < 0) { diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py index edc0b4b11daf7..c02294ac54562 100755 --- a/tests/py/nft-test.py +++ b/tests/py/nft-test.py @@ -855,10 +855,7 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path): json_output = json.loads(json_output) for item in json_output["nftables"]: if "rule" in item: - if "handle" in item["rule"]: - del(item["rule"]["handle"]) - if "position" in item["rule"]: - del(item["rule"]["position"]) + del(item["rule"]["handle"]) json_output = item["rule"] break json_input = json.dumps(json_output["expr"], sort_keys = True) @@ -917,10 +914,7 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path): json_output = json.loads(json_output) for item in json_output["nftables"]: if "rule" in item: - if "handle" in item["rule"]: - del(item["rule"]["handle"]) - if "position" in item["rule"]: - del(item["rule"]["position"]) + del(item["rule"]["handle"]) json_output = item["rule"] break json_output = json.dumps(json_output["expr"], sort_keys = True) From patchwork Mon May 28 16:51:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921626 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZ23KGhz9rxs for ; Tue, 29 May 2018 02:51:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S940423AbeE1Qvx (ORCPT ); Mon, 28 May 2018 12:51:53 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34216 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932219AbeE1Qvx (ORCPT ); Mon, 28 May 2018 12:51:53 -0400 Received: from localhost ([::1]:49492 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNA-0002OL-4a; Mon, 28 May 2018 18:51:52 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 05/14] JSON: Review meter statement support Date: Mon, 28 May 2018 18:51:00 +0200 Message-Id: <20180528165109.15992-6-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Meter name being optional seems to come from old flow statement, so don't support this. Also add size support as was recently added to standard syntax. Signed-off-by: Phil Sutter --- src/json.c | 5 +++-- src/parser_json.c | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/json.c b/src/json.c index 622a10b30c580..e31e31327866f 100644 --- a/src/json.c +++ b/src/json.c @@ -1212,9 +1212,10 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx) tmp = stmt_print_json(stmt->meter.stmt, octx); octx->stateless--; - root = json_pack("{s:o, s:o}", + root = json_pack("{s:o, s:o, s:i}", "key", expr_print_json(stmt->meter.key, octx), - "stmt", tmp); + "stmt", tmp, + "size", stmt->meter.size); if (stmt->meter.set) { tmp = json_string(stmt->meter.set->set->handle.set.name); json_object_set_new(root, "name", tmp); diff --git a/src/parser_json.c b/src/parser_json.c index 1c5994f811e30..afcd10a34d718 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1989,15 +1989,16 @@ static struct stmt *json_parse_meter_stmt(struct json_ctx *ctx, json_t *jkey, *jstmt; struct stmt *stmt; const char *name; + uint32_t size = 0xffff; - if (json_unpack_err(ctx, value, "{s:o, s:o}", - "key", &jkey, "stmt", &jstmt)) + if (json_unpack_err(ctx, value, "{s:s, s:o, s:o}", + "name", &name, "key", &jkey, "stmt", &jstmt)) return NULL; + json_unpack(value, "{s:i}", "size", &size); stmt = meter_stmt_alloc(int_loc); - - if (!json_unpack(value, "{s:s}", "name", &name)) - stmt->meter.name = xstrdup(name); + stmt->meter.name = xstrdup(name); + stmt->meter.size = size; stmt->meter.key = json_parse_expr(ctx, jkey); if (!stmt->meter.key) { From patchwork Mon May 28 16:51:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921622 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYc5Wcmz9rxs for ; Tue, 29 May 2018 02:51:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932363AbeE1Qvc (ORCPT ); Mon, 28 May 2018 12:51:32 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34192 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932407AbeE1Qvb (ORCPT ); Mon, 28 May 2018 12:51:31 -0400 Received: from localhost ([::1]:49468 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLMo-0002N1-MH; Mon, 28 May 2018 18:51:30 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 06/14] JSON: Review set elem expressions Date: Mon, 28 May 2018 18:51:01 +0200 Message-Id: <20180528165109.15992-7-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org * There is no need to prefix element-specific properties with 'elem_', they can't conflict. * In json_parse_set_stmt(), searching for above properties is pointless since that's already done by called function. * Fix potential NULL-pointer deref in json_parse_set_elem_expr_stmt(): json_parse_flagged_expr() may return NULL. Signed-off-by: Phil Sutter --- Changes since v1: - Adjust JSON expected output for meter size. --- src/json.c | 6 +++--- src/parser_json.c | 15 ++++----------- tests/py/ip/flowtable.t.json | 2 +- tests/py/ip/flowtable.t.json.output | 24 ++++++++++++++++++++++++ tests/py/ip6/flowtable.t.json | 4 ++-- 5 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 tests/py/ip/flowtable.t.json.output diff --git a/src/json.c b/src/json.c index e31e31327866f..83366df89804c 100644 --- a/src/json.c +++ b/src/json.c @@ -508,13 +508,13 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx) root = json_pack("{s:o}", "val", root); if (expr->timeout) - json_object_set_new(root, "elem_timeout", + json_object_set_new(root, "timeout", json_integer(expr->timeout / 1000)); if (expr->expiration) - json_object_set_new(root, "elem_expires", + json_object_set_new(root, "expires", json_integer(expr->expiration / 1000)); if (expr->comment) - json_object_set_new(root, "elem_comment", + json_object_set_new(root, "comment", json_string(expr->comment)); return json_pack("{s:o}", "elem", root); } diff --git a/src/parser_json.c b/src/parser_json.c index afcd10a34d718..fd60c59c39627 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1140,11 +1140,11 @@ static struct expr *json_parse_set_elem_expr(struct json_ctx *ctx, expr = set_elem_expr_alloc(int_loc, expr); - if (!json_unpack(root, "{s:i}", "elem_timeout", &i)) + if (!json_unpack(root, "{s:i}", "timeout", &i)) expr->timeout = i * 1000; - if (!json_unpack(root, "{s:i}", "elem_expires", &i)) + if (!json_unpack(root, "{s:i}", "expires", &i)) expr->expiration = i * 1000; - if (!json_unpack(root, "{s:s}", "elem_comment", &expr->comment)) + if (!json_unpack(root, "{s:s}", "comment", &expr->comment)) expr->comment = xstrdup(expr->comment); return expr; @@ -1298,7 +1298,7 @@ static struct expr *json_parse_set_elem_expr_stmt(struct json_ctx *ctx, json_t * { struct expr *expr = json_parse_flagged_expr(ctx, CTX_F_SES, root); - if (expr->ops->type != EXPR_SET_ELEM) + if (expr && expr->ops->type != EXPR_SET_ELEM) expr = set_elem_expr_alloc(int_loc, expr); return expr; @@ -1820,7 +1820,6 @@ static struct stmt *json_parse_set_stmt(struct json_ctx *ctx, struct expr *expr, *expr2; struct stmt *stmt; json_t *elem; - uint64_t tmp; int op; if (json_unpack_err(ctx, value, "{s:s, s:o, s:s}", @@ -1842,12 +1841,6 @@ static struct stmt *json_parse_set_stmt(struct json_ctx *ctx, return NULL; } - if (!json_unpack(elem, "{s:I}", "elem_timeout", &tmp)) - expr->timeout = tmp * 1000; - if (!json_unpack(elem, "{s:I}", "elem_expires", &tmp)) - expr->expiration = tmp * 1000; - json_unpack(elem, "{s:s}", "elem_comment", &expr->comment); - if (set[0] != '@') { json_error(ctx, "Illegal set reference in set statement."); expr_free(expr); diff --git a/tests/py/ip/flowtable.t.json b/tests/py/ip/flowtable.t.json index e6fc09f4a3348..3b0664bd5c8c5 100644 --- a/tests/py/ip/flowtable.t.json +++ b/tests/py/ip/flowtable.t.json @@ -4,7 +4,7 @@ "meter": { "key": { "elem": { - "elem_timeout": 30, + "timeout": 30, "val": { "payload": { "field": "saddr", diff --git a/tests/py/ip/flowtable.t.json.output b/tests/py/ip/flowtable.t.json.output new file mode 100644 index 0000000000000..004349a89b27d --- /dev/null +++ b/tests/py/ip/flowtable.t.json.output @@ -0,0 +1,24 @@ +# meter xyz { ip saddr timeout 30s counter} +[ + { + "meter": { + "key": { + "elem": { + "timeout": 30, + "val": { + "payload": { + "field": "saddr", + "name": "ip" + } + } + } + }, + "name": "xyz", + "size": 65535, + "stmt": { + "counter": null + } + } + } +] + diff --git a/tests/py/ip6/flowtable.t.json b/tests/py/ip6/flowtable.t.json index f707ae9ad607f..9e67a53a84274 100644 --- a/tests/py/ip6/flowtable.t.json +++ b/tests/py/ip6/flowtable.t.json @@ -4,7 +4,7 @@ "meter": { "key": { "elem": { - "elem_timeout": 600, + "timeout": 600, "val": { "concat": [ { @@ -34,7 +34,7 @@ "meter": { "key": { "elem": { - "elem_timeout": 600, + "timeout": 600, "val": { "concat": [ { From patchwork Mon May 28 16:51:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921629 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZR1Lpbz9rxs for ; Tue, 29 May 2018 02:52:15 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425453AbeE1QwN (ORCPT ); Mon, 28 May 2018 12:52:13 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34234 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S940487AbeE1QwJ (ORCPT ); Mon, 28 May 2018 12:52:09 -0400 Received: from localhost ([::1]:49510 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNQ-0002PM-8v; Mon, 28 May 2018 18:52:08 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 07/14] JSON: Fix parsing and printing of limit objects Date: Mon, 28 May 2018 18:51:02 +0200 Message-Id: <20180528165109.15992-8-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Fix parsing and printing of named limit objects by aligning the code with parser/printer of anonymous ones. Signed-off-by: Phil Sutter --- src/json.c | 43 ++++++++++++++++++++--------------------- src/parser_json.c | 49 ++++++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/json.c b/src/json.c index 83366df89804c..11607b677ffbb 100644 --- a/src/json.c +++ b/src/json.c @@ -236,10 +236,10 @@ static json_t *proto_name_json(uint8_t proto) static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) { + const char *rate_unit = NULL, *burst_unit = NULL; const char *type = obj_type_name(obj->type); + uint64_t rate, burst; json_t *root, *tmp; - const char *unit; - uint64_t rate; root = json_pack("{s:s, s:s, s:s, s:I}", "family", family2str(obj->handle.family), @@ -273,29 +273,28 @@ static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) json_decref(tmp); break; case NFT_OBJECT_LIMIT: - tmp = json_pack("{s:b, s:s}", - "inv", obj->limit.flags & NFT_LIMIT_F_INV, + rate = obj->limit.rate; + burst = obj->limit.burst; + + if (obj->limit.type == NFT_LIMIT_PKT_BYTES) { + rate_unit = get_rate(obj->limit.rate, &rate); + burst_unit = get_rate(obj->limit.burst, &burst); + } + + tmp = json_pack("{s:I, s:s}", + "rate", rate, "per", get_unit(obj->limit.unit)); - switch (obj->limit.type) { - case NFT_LIMIT_PKTS: - json_object_set_new(tmp, "rate", - json_integer(obj->limit.rate)); - json_object_set_new(tmp, "burst", - json_integer(obj->limit.burst)); - break; - case NFT_LIMIT_PKT_BYTES: - unit = get_rate(obj->limit.rate, &rate); - json_object_set_new(tmp, "rate", json_integer(rate)); + + if (obj->limit.flags & NFT_LIMIT_F_INV) + json_object_set_new(tmp, "inv", json_true()); + if (rate_unit) json_object_set_new(tmp, "rate_unit", - json_string(unit)); - if (obj->limit.burst) { - unit = get_rate(obj->limit.burst, &rate); - json_object_set_new(tmp, "burst", - json_integer(rate)); + json_string(rate_unit)); + if (burst) { + json_object_set_new(tmp, "burst", json_integer(burst)); + if (burst_unit) json_object_set_new(tmp, "burst_unit", - json_string(unit)); - } - break; + json_string(burst_unit)); } json_object_update(root, tmp); diff --git a/src/parser_json.c b/src/parser_json.c index fd60c59c39627..f3d2c0f1d3dfc 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1569,15 +1569,15 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx, const char *key, json_t *value) { struct stmt *stmt; - int rate, burst = 0; + uint64_t rate, burst = 0; const char *rate_unit = "packets", *time, *burst_unit = "bytes"; int inv = 0; - if (!json_unpack(value, "{s:i, s:s}", - "rate", &rate, "per", &time)) { + if (!json_unpack(value, "{s:I, s:s}", + "rate", &rate, "per", &time)) { json_unpack(value, "{s:s}", "rate_unit", &rate_unit); json_unpack(value, "{s:b}", "inv", &inv); - json_unpack(value, "{s:i}", "burst", &burst); + json_unpack(value, "{s:I}", "burst", &burst); json_unpack(value, "{s:s}", "burst_unit", &burst_unit); stmt = limit_stmt_alloc(int_loc); @@ -2580,9 +2580,10 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, json_t *root, enum cmd_ops op, enum cmd_obj cmd_obj) { - const char *family, *tmp; + const char *family, *tmp, *rate_unit = "packets", *burst_unit = "bytes"; struct handle h = { 0 }; struct obj *obj; + int inv = 0; if (json_unpack_err(ctx, root, "{s:s, s:s}", "family", &family, @@ -2674,24 +2675,28 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, break; case CMD_OBJ_LIMIT: obj->type = NFT_OBJECT_LIMIT; - json_unpack(root, "{s:i}", "rate", &obj->limit.rate); - if (!json_unpack(root, "{s:s}", "per", &tmp)) - obj->limit.unit = seconds_from_unit(tmp); - json_unpack(root, "{s:i}", "burst", &obj->limit.burst); - if (!json_unpack(root, "{s:s}", "unit", &tmp)) { - if (!strcmp(tmp, "packets")) { - obj->limit.type = NFT_LIMIT_PKTS; - } else if (!strcmp(tmp, "bytes")) { - obj->limit.type = NFT_LIMIT_PKT_BYTES; - } else { - json_error(ctx, "Invalid limit unit '%s'.", tmp); - obj_free(obj); - return NULL; - } + if (json_unpack_err(ctx, root, "{s:I, s:s}", + "rate", &obj->limit.rate, + "per", &tmp)) { + obj_free(obj); + return NULL; } - json_unpack(root, "{s:b}", "inv", &obj->limit.flags); - if (obj->limit.flags) - obj->limit.flags = NFT_LIMIT_F_INV; + json_unpack(root, "{s:s}", "rate_unit", &rate_unit); + json_unpack(root, "{s:b}", "inv", &inv); + json_unpack(root, "{s:I}", "burst", &obj->limit.burst); + json_unpack(root, "{s:s}", "burst_unit", &burst_unit); + + if (!strcmp(rate_unit, "packets")) { + obj->limit.type = NFT_LIMIT_PKTS; + } else { + obj->limit.type = NFT_LIMIT_PKT_BYTES; + obj->limit.rate = rate_to_bytes(obj->limit.rate, + rate_unit); + obj->limit.burst = rate_to_bytes(obj->limit.burst, + burst_unit); + } + obj->limit.unit = seconds_from_unit(tmp); + obj->limit.flags = inv ? NFT_LIMIT_F_INV : 0; break; default: BUG("Invalid CMD '%d'", cmd_obj); From patchwork Mon May 28 16:51:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921627 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZB4Zfhz9rxs for ; Tue, 29 May 2018 02:52:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S940523AbeE1QwB (ORCPT ); Mon, 28 May 2018 12:52:01 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34222 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S940490AbeE1Qv6 (ORCPT ); Mon, 28 May 2018 12:51:58 -0400 Received: from localhost ([::1]:49498 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNF-0002Og-FE; Mon, 28 May 2018 18:51:57 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 08/14] JSON: Simplify tcp option expression parsing a bit Date: Mon, 28 May 2018 18:51:03 +0200 Message-Id: <20180528165109.15992-9-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org When parsing the optional "field" property, use return code of json_unpack() directly to check if it was present or not. Signed-off-by: Phil Sutter --- src/parser_json.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index f3d2c0f1d3dfc..bd1c0a04993c8 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -479,20 +479,19 @@ static struct expr *json_parse_payload_expr(struct json_ctx *ctx, static struct expr *json_parse_tcp_option_expr(struct json_ctx *ctx, const char *type, json_t *root) { - const char *desc, *field = NULL; + const char *desc, *field; int descval, fieldval; struct expr *expr; if (json_unpack_err(ctx, root, "{s:s}", "name", &desc)) return NULL; - json_unpack(root, "{s:s}", "field", &field); if (json_parse_tcp_option_type(desc, &descval)) { json_error(ctx, "Unknown tcp option name '%s'.", desc); return NULL; } - if (!field) { + if (json_unpack(root, "{s:s}", "field", &field)) { expr = tcpopt_expr_alloc(int_loc, descval, TCPOPTHDR_FIELD_KIND); expr->exthdr.flags = NFT_EXTHDR_F_PRESENT; From patchwork Mon May 28 16:51:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921625 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYw5bnkz9rxs for ; Tue, 29 May 2018 02:51:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S940266AbeE1Qvs (ORCPT ); Mon, 28 May 2018 12:51:48 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34210 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932206AbeE1Qvr (ORCPT ); Mon, 28 May 2018 12:51:47 -0400 Received: from localhost ([::1]:49486 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLN4-0002O2-Px; Mon, 28 May 2018 18:51:46 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 09/14] JSON: Improve prefix expression parsing error message a bit Date: Mon, 28 May 2018 18:51:04 +0200 Message-Id: <20180528165109.15992-10-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Phil Sutter --- src/parser_json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser_json.c b/src/parser_json.c index bd1c0a04993c8..432991fa152d4 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -951,7 +951,7 @@ static struct expr *json_parse_prefix_expr(struct json_ctx *ctx, expr = json_parse_primary_expr(ctx, addr); if (!expr) { - json_error(ctx, "Invalid prefix in prefix expr."); + json_error(ctx, "Invalid address in prefix expr."); return NULL; } return prefix_expr_alloc(int_loc, expr, len); From patchwork Mon May 28 16:51:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921623 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYk098hz9rxs for ; Tue, 29 May 2018 02:51:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933656AbeE1Qvh (ORCPT ); Mon, 28 May 2018 12:51:37 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34198 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932407AbeE1Qvh (ORCPT ); Mon, 28 May 2018 12:51:37 -0400 Received: from localhost ([::1]:49474 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLMu-0002NM-2y; Mon, 28 May 2018 18:51:36 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 10/14] JSON: Fix parsing of meter statement key Date: Mon, 28 May 2018 18:51:05 +0200 Message-Id: <20180528165109.15992-11-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The key must be a set elem expression, but if a "regular" expression was provided (which should be commonly accepted in case no set elem specific properties are required), the resulting object tree crashed libnftables. Signed-off-by: Phil Sutter --- src/parser_json.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index 432991fa152d4..864463f4f5a92 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1186,7 +1186,7 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "jump", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, { "goto", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, { "return", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, - { "elem", json_parse_set_elem_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY }, + { "elem", json_parse_set_elem_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SES }, }; const char *type; unsigned int i; @@ -1992,7 +1992,7 @@ static struct stmt *json_parse_meter_stmt(struct json_ctx *ctx, stmt->meter.name = xstrdup(name); stmt->meter.size = size; - stmt->meter.key = json_parse_expr(ctx, jkey); + stmt->meter.key = json_parse_set_elem_expr_stmt(ctx, jkey); if (!stmt->meter.key) { json_error(ctx, "Invalid meter key."); stmt_free(stmt); From patchwork Mon May 28 16:51:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921621 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYW3TFPz9rxs for ; Tue, 29 May 2018 02:51:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933396AbeE1Qv1 (ORCPT ); Mon, 28 May 2018 12:51:27 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34186 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932363AbeE1Qv0 (ORCPT ); Mon, 28 May 2018 12:51:26 -0400 Received: from localhost ([::1]:49462 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLMj-0002Mh-BP; Mon, 28 May 2018 18:51:25 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 11/14] JSON: Simplify immediate value parsing Date: Mon, 28 May 2018 18:51:06 +0200 Message-Id: <20180528165109.15992-12-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Since an explicit "immediate" expression doesn't exist in JSON (the values are represented as plain JSON string/integer/boolean types), there is no need for json_parse_immediate_expr() to comply to the common expression parser parameter format. Apart from that: * Drop CTX_F_RHS checks - caller assures sane context already. * Improve error message a bit for denied JSON types. Signed-off-by: Phil Sutter --- src/parser_json.c | 76 +++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/src/parser_json.c b/src/parser_json.c index 864463f4f5a92..336092b77c6ad 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -279,8 +279,7 @@ static struct expr *json_parse_constant(struct json_ctx *ctx, const char *name) } /* this is a combination of symbol_expr, integer_expr, boolean_expr ... */ -static struct expr *json_parse_immediate_expr(struct json_ctx *ctx, - const char *type, json_t *root) +static struct expr *json_parse_immediate(struct json_ctx *ctx, json_t *root) { enum symbol_types symtype = SYMBOL_VALUE; const char *str; @@ -293,12 +292,12 @@ static struct expr *json_parse_immediate_expr(struct json_ctx *ctx, if (str[0] == '@') { symtype = SYMBOL_SET; str++; - } - if (is_RHS(ctx) && is_keyword(str)) + } else if (is_keyword(str)) { return symbol_expr_alloc(int_loc, SYMBOL_VALUE, NULL, str); - if (is_RHS(ctx) && is_constant(str)) + } else if (is_constant(str)) { return json_parse_constant(ctx, str); + } break; case JSON_INTEGER: snprintf(buf, sizeof(buf), @@ -307,16 +306,12 @@ static struct expr *json_parse_immediate_expr(struct json_ctx *ctx, break; case JSON_TRUE: case JSON_FALSE: - if (is_RHS(ctx)) { - buf[0] = json_is_true(root); - return constant_expr_alloc(int_loc, &boolean_type, - BYTEORDER_HOST_ENDIAN, - 1, buf); - } - /* fall through */ + buf[0] = json_is_true(root); + return constant_expr_alloc(int_loc, &boolean_type, + BYTEORDER_HOST_ENDIAN, 1, buf); default: - json_error(ctx, "Invalid immediate value type '%d'.", - json_typeof(root)); + json_error(ctx, "Unexpected JSON type %s for immediate value.", + json_typename(root)); return NULL; } @@ -1033,12 +1028,11 @@ static struct expr *json_parse_set_expr(struct json_ctx *ctx, json_t *value; size_t index; - switch (json_typeof(root)) { - case JSON_OBJECT: - case JSON_ARRAY: - break; - default: - expr = json_parse_immediate_expr(ctx, type, root); + if (!json_is_array(root)) { + expr = json_parse_immediate(ctx, root); + if (!expr) + return NULL; + if (expr->ops->type == EXPR_SYMBOL && expr->symtype == SYMBOL_SET) return expr; @@ -1074,7 +1068,7 @@ static struct expr *json_parse_set_expr(struct json_ctx *ctx, } expr2 = mapping_expr_alloc(int_loc, expr, expr2); expr = expr2; - } else if (json_is_object(value)) { + } else { expr = json_parse_rhs_expr(ctx, value); if (!expr) { @@ -1085,9 +1079,6 @@ static struct expr *json_parse_set_expr(struct json_ctx *ctx, if (expr->ops->type != EXPR_SET_ELEM) expr = set_elem_expr_alloc(int_loc, expr); - } else { - expr = json_parse_immediate_expr(ctx, "elem", value); - expr = set_elem_expr_alloc(int_loc, expr); } if (!set_expr) @@ -1163,7 +1154,6 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT }, { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT }, { "*", json_parse_wildcard_expr, CTX_F_RHS | CTX_F_STMT }, - { "immediate", json_parse_immediate_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, /* symbol, boolean or integer expr */ { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP }, { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES }, @@ -1188,14 +1178,15 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "return", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, { "elem", json_parse_set_elem_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SES }, }; + struct expr *list; const char *type; unsigned int i; json_t *value; + size_t index; - if (json_is_array(root)) { - struct expr *list; - size_t index; + switch (json_typeof(root)) { + case JSON_ARRAY: if (!(ctx->flags & (CTX_F_RHS | CTX_F_STMT))) { json_error(ctx, "List expression only allowed on RHS or in statement expression."); return NULL; @@ -1217,23 +1208,18 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) compound_expr_add(list, expr); } return list; - } else if (json_is_string(root)) { - const struct datatype *dtype; - - if (is_DTYPE(ctx)) { - dtype = datatype_lookup_byname(json_string_value(root)); - if (!dtype) { - json_error(ctx, "Unknown datatype '%s'.", json_string_value(root)); - return NULL; - } - return constant_expr_alloc(int_loc, dtype, - dtype->byteorder, dtype->size, NULL); - } else { - return json_parse_immediate_expr(ctx, "immediate", root); + case JSON_TRUE: + case JSON_FALSE: + if (!is_RHS(ctx) && !is_PRIMARY(ctx)) { + json_error(ctx, "Boolean values not allowed in this context."); + return NULL; } - } else if ((is_RHS(ctx) || is_STMT(ctx) || is_PRIMARY(ctx)) && (json_is_integer(root) || json_is_boolean(root))) { - /* is_STMT for mangle statement */ - return json_parse_immediate_expr(ctx, "immediate", root); + /* fall through */ + case JSON_STRING: + case JSON_INTEGER: + return json_parse_immediate(ctx, root); + default: + break; } if (json_unpack_stmt(ctx, root, &type, &value)) @@ -1800,7 +1786,7 @@ static struct stmt *json_parse_reject_stmt(struct json_ctx *ctx, } } if (!json_unpack(value, "{s:o}", "expr", &tmp)) { - stmt->reject.expr = json_parse_immediate_expr(ctx, "immediate", tmp); + stmt->reject.expr = json_parse_immediate(ctx, tmp); if (!stmt->reject.expr) { json_error(ctx, "Illegal reject expr."); stmt_free(stmt); From patchwork Mon May 28 16:51:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921620 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjYR0wh5z9rxs for ; Tue, 29 May 2018 02:51:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932286AbeE1QvV (ORCPT ); Mon, 28 May 2018 12:51:21 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34180 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932128AbeE1QvV (ORCPT ); Mon, 28 May 2018 12:51:21 -0400 Received: from localhost ([::1]:49456 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLMd-0002ML-W8; Mon, 28 May 2018 18:51:20 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 12/14] tests/py: Adjust JSON for changes in any/ct.t Date: Mon, 28 May 2018 18:51:07 +0200 Message-Id: <20180528165109.15992-13-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Commit 71624f25f22b1 ("tests: py: add expires tests with different time bases") removed two testcases and added five other ones, adjust JSON equivalent and recorded output to those changes. Fixes: 71624f25f22b1 ("tests: py: add expires tests with different time bases") Signed-off-by: Phil Sutter --- tests/py/any/ct.t.json | 39 ++++++++++++++++++++--- tests/py/any/ct.t.json.output | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/tests/py/any/ct.t.json b/tests/py/any/ct.t.json index 83f1bbbd8e367..3ec00ab3b5d78 100644 --- a/tests/py/any/ct.t.json +++ b/tests/py/any/ct.t.json @@ -708,7 +708,7 @@ } ] -# ct expiration 30 +# ct expiration 30s [ { "match": { @@ -717,12 +717,12 @@ "key": "expiration" } }, - "right": 30 + "right": "30s" } } ] -# ct expiration 22 +# ct expiration 30000ms [ { "match": { @@ -731,7 +731,38 @@ "key": "expiration" } }, - "right": 22 + "right": "30000ms" + } + } +] + +# ct expiration 1m-1h +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "right": { + "range": [ "1m", "1h" ] + } + } + } +] + +# ct expiration > 4d23h59m59s +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "op": ">", + "right": "4d23h59m59s" } } ] diff --git a/tests/py/any/ct.t.json.output b/tests/py/any/ct.t.json.output index 01dbb486988e6..ce33a6810a496 100644 --- a/tests/py/any/ct.t.json.output +++ b/tests/py/any/ct.t.json.output @@ -400,6 +400,65 @@ } ] +# ct expiration 30s +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "right": 30 + } + } +] + +# ct expiration 30000ms +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "right": 30 + } + } +] + +# ct expiration 1m-1h +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "right": { + "range": [ 60, 3600 ] + } + } + } +] + +# ct expiration > 4d23h59m59s +[ + { + "match": { + "left": { + "ct": { + "key": "expiration" + } + }, + "op": ">", + "right": 431999 + } + } +] + # ct state . ct mark { new . 0x12345678} [ { From patchwork Mon May 28 16:51:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921630 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZS384Gz9s15 for ; Tue, 29 May 2018 02:52:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425490AbeE1QwP (ORCPT ); Mon, 28 May 2018 12:52:15 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34242 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1425480AbeE1QwO (ORCPT ); Mon, 28 May 2018 12:52:14 -0400 Received: from localhost ([::1]:49518 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNV-0002Pi-Mm; Mon, 28 May 2018 18:52:13 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 13/14] tests/py: Add missing JSON equivalent for inet/sets.t Date: Mon, 28 May 2018 18:51:08 +0200 Message-Id: <20180528165109.15992-14-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This adds the missing JSON variant for the two rules which are supposed to work. Fixes: 2efbdf7b8fcf7 ("tests: py: allow to specify sets with a timeout") Signed-off-by: Phil Sutter --- tests/py/inet/sets.t.json | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/py/inet/sets.t.json diff --git a/tests/py/inet/sets.t.json b/tests/py/inet/sets.t.json new file mode 100644 index 0000000000000..75881f7145ccd --- /dev/null +++ b/tests/py/inet/sets.t.json @@ -0,0 +1,37 @@ +# ip saddr @set1 drop +[ + { + "match": { + "left": { + "payload": { + "field": "saddr", + "name": "ip" + } + }, + "right": "@set1" + } + }, + { + "drop": null + } +] + +# ip6 daddr != @set2 accept +[ + { + "match": { + "left": { + "payload": { + "field": "daddr", + "name": "ip6" + } + }, + "op": "!=", + "right": "@set2" + } + }, + { + "accept": null + } +] + From patchwork Mon May 28 16:51:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 921633 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vjZm64Vzz9rxs for ; Tue, 29 May 2018 02:52:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425496AbeE1Qwc (ORCPT ); Mon, 28 May 2018 12:52:32 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:34260 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1425493AbeE1Qwb (ORCPT ); Mon, 28 May 2018 12:52:31 -0400 Received: from localhost ([::1]:49536 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fNLNl-0002R9-Qv; Mon, 28 May 2018 18:52:30 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH v2 14/14] tests/py: Add missing JSON equivalent for rule in inet/tcp.t Date: Mon, 28 May 2018 18:51:09 +0200 Message-Id: <20180528165109.15992-15-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528165109.15992-1-phil@nwl.cc> References: <20180528165109.15992-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Phil Sutter --- tests/py/inet/tcp.t.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json index 559206dfd323f..f5df72aa252a6 100644 --- a/tests/py/inet/tcp.t.json +++ b/tests/py/inet/tcp.t.json @@ -1021,6 +1021,22 @@ } ] +# tcp flags == syn +[ + { + "match": { + "left": { + "payload": { + "field": "flags", + "name": "tcp" + } + }, + "op": "==", + "right": "syn" + } + } +] + # tcp flags & (syn|fin) == (syn|fin) [ {