From patchwork Fri Dec 24 17:17:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573084 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDKs0SQ3z9sXS for ; Sat, 25 Dec 2021 04:18:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344149AbhLXRSX (ORCPT ); Fri, 24 Dec 2021 12:18:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSV (ORCPT ); Fri, 24 Dec 2021 12:18:21 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D20B3C061401 for ; Fri, 24 Dec 2021 09:18:20 -0800 (PST) Received: from localhost ([::1]:59088 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oCx-0004w5-5r; Fri, 24 Dec 2021 18:18:19 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 01/11] xtables: Drop xtables' family on demand feature Date: Fri, 24 Dec 2021 18:17:44 +0100 Message-Id: <20211224171754.14210-2-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This conditional h->family assignment was added by commit 3f7877e6be987 ("xtables-restore: add -4 and -6 support") with the intention to support something like 'xtables-restore -6 --- iptables/xtables.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/iptables/xtables.c b/iptables/xtables.c index 57bec76c31fb3..5c48bd94644f3 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -657,10 +657,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], xtables_error(PARAMETER_PROBLEM, "nothing appropriate following !"); - /* Set only if required, needed by xtables-restore */ - if (h->family == AF_UNSPEC) - h->family = args->family; - h->ops->post_parse(p->command, cs, args); if (p->command == CMD_REPLACE && From patchwork Fri Dec 24 17:17:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573086 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDL05sTwz9sXS for ; Sat, 25 Dec 2021 04:18:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353285AbhLXRSc (ORCPT ); Fri, 24 Dec 2021 12:18:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSb (ORCPT ); Fri, 24 Dec 2021 12:18:31 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 770B3C061401 for ; Fri, 24 Dec 2021 09:18:31 -0800 (PST) Received: from localhost ([::1]:59092 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oD7-0004wf-P9; Fri, 24 Dec 2021 18:18:29 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 02/11] xtables: Pull table validity check out of do_parse() Date: Fri, 24 Dec 2021 18:17:45 +0100 Message-Id: <20211224171754.14210-3-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Makes do_parse() more generic, error codes don't change so this should be safe. Signed-off-by: Phil Sutter --- iptables/xtables.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iptables/xtables.c b/iptables/xtables.c index 5c48bd94644f3..ac864eb24a35e 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -514,10 +514,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], xtables_error(PARAMETER_PROBLEM, "The -t option cannot be used in %s.\n", xt_params->program_name); - if (!nft_table_builtin_find(h, optarg)) - xtables_error(VERSION_PROBLEM, - "table '%s' does not exist", - optarg); p->table = optarg; table_set = true; break; @@ -720,6 +716,10 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, do_parse(h, argc, argv, &p, &cs, &args); + if (!nft_table_builtin_find(h, p.table)) + xtables_error(VERSION_PROBLEM, + "table '%s' does not exist", + p.table); switch (p.command) { case CMD_APPEND: ret = h->ops->add_entry(h, p.chain, p.table, &cs, &args, From patchwork Fri Dec 24 17:17:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573085 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDKw24Ssz9sXS for ; Sat, 25 Dec 2021 04:18:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353287AbhLXRS1 (ORCPT ); Fri, 24 Dec 2021 12:18:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRS0 (ORCPT ); Fri, 24 Dec 2021 12:18:26 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C5F3C061401 for ; Fri, 24 Dec 2021 09:18:26 -0800 (PST) Received: from localhost ([::1]:59090 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oD2-0004wB-Fu; Fri, 24 Dec 2021 18:18:24 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 03/11] xtables: Move struct nft_xt_cmd_parse to xshared.h Date: Fri, 24 Dec 2021 18:17:46 +0100 Message-Id: <20211224171754.14210-4-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Preparing for shared use with legacy variants, move it to "neutral ground" and give it a more generic name. Signed-off-by: Phil Sutter --- iptables/nft-shared.h | 14 +------------- iptables/xshared.h | 12 ++++++++++++ iptables/xtables-eb-translate.c | 4 ++-- iptables/xtables-translate.c | 8 ++++---- iptables/xtables.c | 4 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index bcf8486eb44c4..4948aef761d10 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -210,20 +210,8 @@ struct xtables_args { unsigned long long pcnt_cnt, bcnt_cnt; }; -struct nft_xt_cmd_parse { - unsigned int command; - unsigned int rulenum; - char *table; - const char *chain; - const char *newname; - const char *policy; - bool restore; - int verbose; - bool xlate; -}; - void do_parse(struct nft_handle *h, int argc, char *argv[], - struct nft_xt_cmd_parse *p, struct iptables_command_state *cs, + struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args); struct nftnl_chain_list; diff --git a/iptables/xshared.h b/iptables/xshared.h index 2c05b0d7c4ace..dde94b7335f6a 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -262,4 +262,16 @@ int print_match_save(const struct xt_entry_match *e, const void *ip); void xtables_printhelp(const struct xtables_rule_match *matches); void exit_tryhelp(int status, int line) __attribute__((noreturn)); +struct xt_cmd_parse { + unsigned int command; + unsigned int rulenum; + char *table; + const char *chain; + const char *newname; + const char *policy; + bool restore; + int verbose; + bool xlate; +}; + #endif /* IPTABLES_XSHARED_H */ diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c index a6c86b6531e3f..86177024ec703 100644 --- a/iptables/xtables-eb-translate.c +++ b/iptables/xtables-eb-translate.c @@ -152,7 +152,7 @@ static void print_ebt_cmd(int argc, char *argv[]) printf("\n"); } -static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct nft_xt_cmd_parse *p, +static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct xt_cmd_parse *p, const struct iptables_command_state *cs, bool append) { struct xt_xlate *xl = xt_xlate_alloc(10240); @@ -191,7 +191,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char int selected_chain = -1; struct xtables_rule_match *xtrm_i; struct ebt_match *match; - struct nft_xt_cmd_parse p = { + struct xt_cmd_parse p = { .table = *table, }; diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c index e2948c5009dd6..9d312b244657e 100644 --- a/iptables/xtables-translate.c +++ b/iptables/xtables-translate.c @@ -150,7 +150,7 @@ const char *family2str[] = { }; static int nft_rule_xlate_add(struct nft_handle *h, - const struct nft_xt_cmd_parse *p, + const struct xt_cmd_parse *p, const struct iptables_command_state *cs, bool append) { @@ -186,11 +186,11 @@ err_out: return ret; } -static int xlate(struct nft_handle *h, struct nft_xt_cmd_parse *p, +static int xlate(struct nft_handle *h, struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args, bool append, int (*cb)(struct nft_handle *h, - const struct nft_xt_cmd_parse *p, + const struct xt_cmd_parse *p, const struct iptables_command_state *cs, bool append)) { @@ -248,7 +248,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], char **table, bool restore) { int ret = 0; - struct nft_xt_cmd_parse p = { + struct xt_cmd_parse p = { .table = *table, .restore = restore, .xlate = true, diff --git a/iptables/xtables.c b/iptables/xtables.c index ac864eb24a35e..837b399aba5b3 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -187,7 +187,7 @@ static void check_inverse(struct nft_handle *h, const char option[], } void do_parse(struct nft_handle *h, int argc, char *argv[], - struct nft_xt_cmd_parse *p, struct iptables_command_state *cs, + struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args) { struct xtables_match *m; @@ -699,7 +699,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore) { int ret = 1; - struct nft_xt_cmd_parse p = { + struct xt_cmd_parse p = { .table = *table, .restore = restore, }; From patchwork Fri Dec 24 17:17:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573089 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDLT1vkkz9sXS for ; Sat, 25 Dec 2021 04:18:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353290AbhLXRS4 (ORCPT ); Fri, 24 Dec 2021 12:18:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRS4 (ORCPT ); Fri, 24 Dec 2021 12:18:56 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1F5CC061401 for ; Fri, 24 Dec 2021 09:18:55 -0800 (PST) Received: from localhost ([::1]:59098 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oDW-0004xK-5k; Fri, 24 Dec 2021 18:18:54 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 04/11] xtables: Pass xtables_args to check_empty_interface() Date: Fri, 24 Dec 2021 18:17:47 +0100 Message-Id: <20211224171754.14210-5-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org It holds the accessed family field as well and is more generic than nft_handle. Signed-off-by: Phil Sutter --- iptables/xtables.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iptables/xtables.c b/iptables/xtables.c index 837b399aba5b3..db0cec2461741 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -145,14 +145,14 @@ list_rules(struct nft_handle *h, const char *chain, const char *table, return nft_cmd_rule_list_save(h, chain, table, rulenum, counters); } -static void check_empty_interface(struct nft_handle *h, const char *arg) +static void check_empty_interface(struct xtables_args *args, const char *arg) { const char *msg = "Empty interface is likely to be undesired"; if (*arg != '\0') return; - if (h->family != NFPROTO_ARP) + if (args->family != NFPROTO_ARP) xtables_error(PARAMETER_PROBLEM, msg); fprintf(stderr, "%s", msg); @@ -460,7 +460,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], break; case 'i': - check_empty_interface(h, optarg); + check_empty_interface(args, optarg); check_inverse(h, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_VIANAMEIN, &args->invflags, invert); @@ -470,7 +470,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], break; case 'o': - check_empty_interface(h, optarg); + check_empty_interface(args, optarg); check_inverse(h, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_VIANAMEOUT, &args->invflags, invert); From patchwork Fri Dec 24 17:17:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573083 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDKj6L33z9sXS for ; Sat, 25 Dec 2021 04:18:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353286AbhLXRSQ (ORCPT ); Fri, 24 Dec 2021 12:18:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353285AbhLXRSP (ORCPT ); Fri, 24 Dec 2021 12:18:15 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 875D8C061401 for ; Fri, 24 Dec 2021 09:18:15 -0800 (PST) Received: from localhost ([::1]:59086 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oCr-0004va-Su; Fri, 24 Dec 2021 18:18:13 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 05/11] xtables: Pass xtables_args to check_inverse() Date: Fri, 24 Dec 2021 18:17:48 +0100 Message-Id: <20211224171754.14210-6-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org It holds the accessed family field as well and is more generic than nft_handle. Signed-off-by: Phil Sutter --- iptables/xtables.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/iptables/xtables.c b/iptables/xtables.c index db0cec2461741..5e8c027b8471e 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -158,10 +158,10 @@ static void check_empty_interface(struct xtables_args *args, const char *arg) fprintf(stderr, "%s", msg); } -static void check_inverse(struct nft_handle *h, const char option[], +static void check_inverse(struct xtables_args *args, const char option[], bool *invert, int *optidx, int argc) { - switch (h->family) { + switch (args->family) { case NFPROTO_ARP: break; default: @@ -364,7 +364,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], * Option selection */ case 'p': - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_PROTOCOL, &args->invflags, invert); @@ -387,14 +387,14 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], break; case 's': - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_SOURCE, &args->invflags, invert); args->shostnetworkmask = argv[optind - 1]; break; case 'd': - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_DESTINATION, &args->invflags, invert); args->dhostnetworkmask = argv[optind - 1]; @@ -410,21 +410,21 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], #endif case 2:/* src-mac */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_S_MAC, &args->invflags, invert); args->src_mac = argv[optind - 1]; break; case 3:/* dst-mac */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_D_MAC, &args->invflags, invert); args->dst_mac = argv[optind - 1]; break; case 'l':/* hardware length */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_H_LENGTH, &args->invflags, invert); args->arp_hlen = argv[optind - 1]; @@ -433,21 +433,21 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], case 8: /* was never supported, not even in arptables-legacy */ xtables_error(PARAMETER_PROBLEM, "not supported"); case 4:/* opcode */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_OPCODE, &args->invflags, invert); args->arp_opcode = argv[optind - 1]; break; case 5:/* h-type */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_H_TYPE, &args->invflags, invert); args->arp_htype = argv[optind - 1]; break; case 6:/* proto-type */ - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_P_TYPE, &args->invflags, invert); args->arp_ptype = argv[optind - 1]; @@ -461,7 +461,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], case 'i': check_empty_interface(args, optarg); - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_VIANAMEIN, &args->invflags, invert); xtables_parse_interface(argv[optind - 1], @@ -471,7 +471,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], case 'o': check_empty_interface(args, optarg); - check_inverse(h, optarg, &invert, &optind, argc); + check_inverse(args, optarg, &invert, &optind, argc); set_option(&cs->options, OPT_VIANAMEOUT, &args->invflags, invert); xtables_parse_interface(argv[optind - 1], From patchwork Fri Dec 24 17:17:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573087 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDL61QWVz9sVq for ; Sat, 25 Dec 2021 04:18:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353288AbhLXRSh (ORCPT ); Fri, 24 Dec 2021 12:18:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSh (ORCPT ); Fri, 24 Dec 2021 12:18:37 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9538C061401 for ; Fri, 24 Dec 2021 09:18:36 -0800 (PST) Received: from localhost ([::1]:59094 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oDD-0004ww-3p; Fri, 24 Dec 2021 18:18:35 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 06/11] xtables: Do not pass nft_handle to do_parse() Date: Fri, 24 Dec 2021 18:17:49 +0100 Message-Id: <20211224171754.14210-7-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Make it fit for sharing with legacy iptables, drop nft-specific parameter. This requires to mirror proto_parse and post_parse callbacks from family_ops somewhere reachable - use xt_cmd_parse, it holds other "parser setup data" as well. Signed-off-by: Phil Sutter --- iptables/nft-shared.h | 35 +-------------------------------- iptables/xshared.h | 38 ++++++++++++++++++++++++++++++++++++ iptables/xtables-translate.c | 4 +++- iptables/xtables.c | 13 +++++++----- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 4948aef761d10..7396fa991439f 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -177,40 +177,7 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data); bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2); bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2); -struct addr_mask { - union { - struct in_addr *v4; - struct in6_addr *v6; - void *ptr; - } addr; - - unsigned int naddrs; - - union { - struct in_addr *v4; - struct in6_addr *v6; - void *ptr; - } mask; -}; - -struct xtables_args { - int family; - uint16_t proto; - uint8_t flags; - uint16_t invflags; - char iniface[IFNAMSIZ], outiface[IFNAMSIZ]; - unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ]; - bool goto_set; - const char *shostnetworkmask, *dhostnetworkmask; - const char *pcnt, *bcnt; - struct addr_mask s, d; - const char *src_mac, *dst_mac; - const char *arp_hlen, *arp_opcode; - const char *arp_htype, *arp_ptype; - unsigned long long pcnt_cnt, bcnt_cnt; -}; - -void do_parse(struct nft_handle *h, int argc, char *argv[], +void do_parse(int argc, char *argv[], struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args); diff --git a/iptables/xshared.h b/iptables/xshared.h index dde94b7335f6a..1954168f64058 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -262,6 +262,39 @@ int print_match_save(const struct xt_entry_match *e, const void *ip); void xtables_printhelp(const struct xtables_rule_match *matches); void exit_tryhelp(int status, int line) __attribute__((noreturn)); +struct addr_mask { + union { + struct in_addr *v4; + struct in6_addr *v6; + void *ptr; + } addr; + + unsigned int naddrs; + + union { + struct in_addr *v4; + struct in6_addr *v6; + void *ptr; + } mask; +}; + +struct xtables_args { + int family; + uint16_t proto; + uint8_t flags; + uint16_t invflags; + char iniface[IFNAMSIZ], outiface[IFNAMSIZ]; + unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ]; + bool goto_set; + const char *shostnetworkmask, *dhostnetworkmask; + const char *pcnt, *bcnt; + struct addr_mask s, d; + const char *src_mac, *dst_mac; + const char *arp_hlen, *arp_opcode; + const char *arp_htype, *arp_ptype; + unsigned long long pcnt_cnt, bcnt_cnt; +}; + struct xt_cmd_parse { unsigned int command; unsigned int rulenum; @@ -272,6 +305,11 @@ struct xt_cmd_parse { bool restore; int verbose; bool xlate; + void (*proto_parse)(struct iptables_command_state *cs, + struct xtables_args *args); + void (*post_parse)(int command, + struct iptables_command_state *cs, + struct xtables_args *args); }; #endif /* IPTABLES_XSHARED_H */ diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c index 9d312b244657e..b0b27695cbb8c 100644 --- a/iptables/xtables-translate.c +++ b/iptables/xtables-translate.c @@ -252,6 +252,8 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], .table = *table, .restore = restore, .xlate = true, + .proto_parse = h->ops->proto_parse, + .post_parse = h->ops->post_parse, }; struct iptables_command_state cs = { .jumpto = "", @@ -265,7 +267,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], if (h->ops->init_cs) h->ops->init_cs(&cs); - do_parse(h, argc, argv, &p, &cs, &args); + do_parse(argc, argv, &p, &cs, &args); cs.restore = restore; diff --git a/iptables/xtables.c b/iptables/xtables.c index 5e8c027b8471e..d7e22285e089e 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -186,7 +186,7 @@ static void check_inverse(struct xtables_args *args, const char option[], } } -void do_parse(struct nft_handle *h, int argc, char *argv[], +void do_parse(int argc, char *argv[], struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args) { @@ -382,8 +382,8 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], "rule would never match protocol"); /* This needs to happen here to parse extensions */ - if (h->ops->proto_parse) - h->ops->proto_parse(cs, args); + if (p->proto_parse) + p->proto_parse(cs, args); break; case 's': @@ -653,7 +653,8 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], xtables_error(PARAMETER_PROBLEM, "nothing appropriate following !"); - h->ops->post_parse(p->command, cs, args); + if (p->post_parse) + p->post_parse(p->command, cs, args); if (p->command == CMD_REPLACE && (args->s.naddrs != 1 || args->d.naddrs != 1)) @@ -702,6 +703,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, struct xt_cmd_parse p = { .table = *table, .restore = restore, + .proto_parse = h->ops->proto_parse, + .post_parse = h->ops->post_parse, }; struct iptables_command_state cs = { .jumpto = "", @@ -714,7 +717,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, if (h->ops->init_cs) h->ops->init_cs(&cs); - do_parse(h, argc, argv, &p, &cs, &args); + do_parse(argc, argv, &p, &cs, &args); if (!nft_table_builtin_find(h, p.table)) xtables_error(VERSION_PROBLEM, From patchwork Fri Dec 24 17:17:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573091 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDLh0k0Rz9sXS for ; Sat, 25 Dec 2021 04:19:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230158AbhLXRTH (ORCPT ); Fri, 24 Dec 2021 12:19:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRTG (ORCPT ); Fri, 24 Dec 2021 12:19:06 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E12BC061401 for ; Fri, 24 Dec 2021 09:19:06 -0800 (PST) Received: from localhost ([::1]:59104 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oDg-0004y6-Pj; Fri, 24 Dec 2021 18:19:04 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 07/11] xshared: Move do_parse to shared space Date: Fri, 24 Dec 2021 18:17:50 +0100 Message-Id: <20211224171754.14210-8-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Small adjustments were needed: - Pass line variable via xt_cmd_parse, xshared.c does not have it in namespace. - Replace opts, prog_name and prog_vers defines by the respective xt_params field reference. Signed-off-by: Phil Sutter --- iptables/nft-shared.h | 4 - iptables/xshared.c | 553 ++++++++++++++++++++++++++++++++++ iptables/xshared.h | 5 + iptables/xtables-translate.c | 1 + iptables/xtables.c | 556 +---------------------------------- 5 files changed, 560 insertions(+), 559 deletions(-) diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 7396fa991439f..a253dd70c335f 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -177,10 +177,6 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data); bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2); bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2); -void do_parse(int argc, char *argv[], - struct xt_cmd_parse *p, struct iptables_command_state *cs, - struct xtables_args *args); - struct nftnl_chain_list; struct nft_xt_restore_cb { diff --git a/iptables/xshared.c b/iptables/xshared.c index efee7a30b39fd..7702d899a3586 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1262,3 +1262,556 @@ void exit_tryhelp(int status, int line) xtables_free_opts(1); exit(status); } + +static void check_empty_interface(struct xtables_args *args, const char *arg) +{ + const char *msg = "Empty interface is likely to be undesired"; + + if (*arg != '\0') + return; + + if (args->family != NFPROTO_ARP) + xtables_error(PARAMETER_PROBLEM, msg); + + fprintf(stderr, "%s", msg); +} + +static void check_inverse(struct xtables_args *args, const char option[], + bool *invert, int *optidx, int argc) +{ + switch (args->family) { + case NFPROTO_ARP: + break; + default: + return; + } + + if (!option || strcmp(option, "!")) + return; + + fprintf(stderr, "Using intrapositioned negation (`--option ! this`) " + "is deprecated in favor of extrapositioned (`! --option this`).\n"); + + if (*invert) + xtables_error(PARAMETER_PROBLEM, + "Multiple `!' flags not allowed"); + *invert = true; + if (optidx) { + *optidx = *optidx + 1; + if (argc && *optidx > argc) + xtables_error(PARAMETER_PROBLEM, + "no argument following `!'"); + } +} + +void do_parse(int argc, char *argv[], + struct xt_cmd_parse *p, struct iptables_command_state *cs, + struct xtables_args *args) +{ + struct xtables_match *m; + struct xtables_rule_match *matchp; + bool wait_interval_set = false; + struct timeval wait_interval; + struct xtables_target *t; + bool table_set = false; + bool invert = false; + int wait = 0; + + /* re-set optind to 0 in case do_command4 gets called + * a second time */ + optind = 0; + + /* clear mflags in case do_command4 gets called a second time + * (we clear the global list of all matches for security)*/ + for (m = xtables_matches; m; m = m->next) + m->mflags = 0; + + for (t = xtables_targets; t; t = t->next) { + t->tflags = 0; + t->used = 0; + } + + /* Suppress error messages: we may add new options if we + demand-load a protocol. */ + opterr = 0; + + xt_params->opts = xt_params->orig_opts; + while ((cs->c = getopt_long(argc, argv, xt_params->optstring, + xt_params->opts, NULL)) != -1) { + switch (cs->c) { + /* + * Command selection + */ + case 'A': + add_command(&p->command, CMD_APPEND, CMD_NONE, invert); + p->chain = optarg; + break; + + case 'C': + add_command(&p->command, CMD_CHECK, CMD_NONE, invert); + p->chain = optarg; + break; + + case 'D': + add_command(&p->command, CMD_DELETE, CMD_NONE, invert); + p->chain = optarg; + if (xs_has_arg(argc, argv)) { + p->rulenum = parse_rulenumber(argv[optind++]); + p->command = CMD_DELETE_NUM; + } + break; + + case 'R': + add_command(&p->command, CMD_REPLACE, CMD_NONE, invert); + p->chain = optarg; + if (xs_has_arg(argc, argv)) + p->rulenum = parse_rulenumber(argv[optind++]); + else + xtables_error(PARAMETER_PROBLEM, + "-%c requires a rule number", + cmd2char(CMD_REPLACE)); + break; + + case 'I': + add_command(&p->command, CMD_INSERT, CMD_NONE, invert); + p->chain = optarg; + if (xs_has_arg(argc, argv)) + p->rulenum = parse_rulenumber(argv[optind++]); + else + p->rulenum = 1; + break; + + case 'L': + add_command(&p->command, CMD_LIST, + CMD_ZERO | CMD_ZERO_NUM, invert); + if (optarg) + p->chain = optarg; + else if (xs_has_arg(argc, argv)) + p->chain = argv[optind++]; + if (xs_has_arg(argc, argv)) + p->rulenum = parse_rulenumber(argv[optind++]); + break; + + case 'S': + add_command(&p->command, CMD_LIST_RULES, + CMD_ZERO|CMD_ZERO_NUM, invert); + if (optarg) + p->chain = optarg; + else if (xs_has_arg(argc, argv)) + p->chain = argv[optind++]; + if (xs_has_arg(argc, argv)) + p->rulenum = parse_rulenumber(argv[optind++]); + break; + + case 'F': + add_command(&p->command, CMD_FLUSH, CMD_NONE, invert); + if (optarg) + p->chain = optarg; + else if (xs_has_arg(argc, argv)) + p->chain = argv[optind++]; + break; + + case 'Z': + add_command(&p->command, CMD_ZERO, + CMD_LIST|CMD_LIST_RULES, invert); + if (optarg) + p->chain = optarg; + else if (xs_has_arg(argc, argv)) + p->chain = argv[optind++]; + if (xs_has_arg(argc, argv)) { + p->rulenum = parse_rulenumber(argv[optind++]); + p->command = CMD_ZERO_NUM; + } + break; + + case 'N': + parse_chain(optarg); + add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE, + invert); + p->chain = optarg; + break; + + case 'X': + add_command(&p->command, CMD_DELETE_CHAIN, CMD_NONE, + invert); + if (optarg) + p->chain = optarg; + else if (xs_has_arg(argc, argv)) + p->chain = argv[optind++]; + break; + + case 'E': + add_command(&p->command, CMD_RENAME_CHAIN, CMD_NONE, + invert); + p->chain = optarg; + if (xs_has_arg(argc, argv)) + p->newname = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, + "-%c requires old-chain-name and " + "new-chain-name", + cmd2char(CMD_RENAME_CHAIN)); + break; + + case 'P': + add_command(&p->command, CMD_SET_POLICY, CMD_NONE, + invert); + p->chain = optarg; + if (xs_has_arg(argc, argv)) + p->policy = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, + "-%c requires a chain and a policy", + cmd2char(CMD_SET_POLICY)); + break; + + case 'h': + if (!optarg) + optarg = argv[optind]; + + /* iptables -p icmp -h */ + if (!cs->matches && cs->protocol) + xtables_find_match(cs->protocol, + XTF_TRY_LOAD, &cs->matches); + + xt_params->print_help(cs->matches); + p->command = CMD_NONE; + return; + + /* + * Option selection + */ + case 'p': + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_PROTOCOL, + &args->invflags, invert); + + /* Canonicalize into lower case */ + for (cs->protocol = argv[optind - 1]; + *cs->protocol; cs->protocol++) + *cs->protocol = tolower(*cs->protocol); + + cs->protocol = argv[optind - 1]; + args->proto = xtables_parse_protocol(cs->protocol); + + if (args->proto == 0 && + (args->invflags & XT_INV_PROTO)) + xtables_error(PARAMETER_PROBLEM, + "rule would never match protocol"); + + /* This needs to happen here to parse extensions */ + if (p->proto_parse) + p->proto_parse(cs, args); + break; + + case 's': + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_SOURCE, + &args->invflags, invert); + args->shostnetworkmask = argv[optind - 1]; + break; + + case 'd': + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_DESTINATION, + &args->invflags, invert); + args->dhostnetworkmask = argv[optind - 1]; + break; + +#ifdef IPT_F_GOTO + case 'g': + set_option(&cs->options, OPT_JUMP, &args->invflags, + invert); + args->goto_set = true; + cs->jumpto = xt_parse_target(optarg); + break; +#endif + + case 2:/* src-mac */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_S_MAC, &args->invflags, + invert); + args->src_mac = argv[optind - 1]; + break; + + case 3:/* dst-mac */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_D_MAC, &args->invflags, + invert); + args->dst_mac = argv[optind - 1]; + break; + + case 'l':/* hardware length */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_H_LENGTH, &args->invflags, + invert); + args->arp_hlen = argv[optind - 1]; + break; + + case 8: /* was never supported, not even in arptables-legacy */ + xtables_error(PARAMETER_PROBLEM, "not supported"); + case 4:/* opcode */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_OPCODE, &args->invflags, + invert); + args->arp_opcode = argv[optind - 1]; + break; + + case 5:/* h-type */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_H_TYPE, &args->invflags, + invert); + args->arp_htype = argv[optind - 1]; + break; + + case 6:/* proto-type */ + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_P_TYPE, &args->invflags, + invert); + args->arp_ptype = argv[optind - 1]; + break; + + case 'j': + set_option(&cs->options, OPT_JUMP, &args->invflags, + invert); + command_jump(cs, argv[optind - 1]); + break; + + case 'i': + check_empty_interface(args, optarg); + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_VIANAMEIN, + &args->invflags, invert); + xtables_parse_interface(argv[optind - 1], + args->iniface, + args->iniface_mask); + break; + + case 'o': + check_empty_interface(args, optarg); + check_inverse(args, optarg, &invert, &optind, argc); + set_option(&cs->options, OPT_VIANAMEOUT, + &args->invflags, invert); + xtables_parse_interface(argv[optind - 1], + args->outiface, + args->outiface_mask); + break; + + case 'f': + if (args->family == AF_INET6) { + xtables_error(PARAMETER_PROBLEM, + "`-f' is not supported in IPv6, " + "use -m frag instead"); + } + set_option(&cs->options, OPT_FRAGMENT, &args->invflags, + invert); + args->flags |= IPT_F_FRAG; + break; + + case 'v': + if (!p->verbose) + set_option(&cs->options, OPT_VERBOSE, + &args->invflags, invert); + p->verbose++; + break; + + case 'm': + command_match(cs, invert); + break; + + case 'n': + set_option(&cs->options, OPT_NUMERIC, &args->invflags, + invert); + break; + + case 't': + if (invert) + xtables_error(PARAMETER_PROBLEM, + "unexpected ! flag before --table"); + if (p->restore && table_set) + xtables_error(PARAMETER_PROBLEM, + "The -t option cannot be used in %s.\n", + xt_params->program_name); + p->table = optarg; + table_set = true; + break; + + case 'x': + set_option(&cs->options, OPT_EXPANDED, &args->invflags, + invert); + break; + + case 'V': + if (invert) + printf("Not %s ;-)\n", + xt_params->program_version); + else + printf("%s v%s\n", + xt_params->program_name, + xt_params->program_version); + exit(0); + + case 'w': + if (p->restore) { + xtables_error(PARAMETER_PROBLEM, + "You cannot use `-w' from " + "iptables-restore"); + } + + wait = parse_wait_time(argc, argv); + break; + + case 'W': + if (p->restore) { + xtables_error(PARAMETER_PROBLEM, + "You cannot use `-W' from " + "iptables-restore"); + } + + parse_wait_interval(argc, argv, &wait_interval); + wait_interval_set = true; + break; + + case '0': + set_option(&cs->options, OPT_LINENUMBERS, + &args->invflags, invert); + break; + + case 'M': + xtables_modprobe_program = optarg; + break; + + case 'c': + set_option(&cs->options, OPT_COUNTERS, &args->invflags, + invert); + args->pcnt = optarg; + args->bcnt = strchr(args->pcnt + 1, ','); + if (args->bcnt) + args->bcnt++; + if (!args->bcnt && xs_has_arg(argc, argv)) + args->bcnt = argv[optind++]; + if (!args->bcnt) + xtables_error(PARAMETER_PROBLEM, + "-%c requires packet and byte counter", + opt2char(OPT_COUNTERS)); + + if (sscanf(args->pcnt, "%llu", &args->pcnt_cnt) != 1) + xtables_error(PARAMETER_PROBLEM, + "-%c packet counter not numeric", + opt2char(OPT_COUNTERS)); + + if (sscanf(args->bcnt, "%llu", &args->bcnt_cnt) != 1) + xtables_error(PARAMETER_PROBLEM, + "-%c byte counter not numeric", + opt2char(OPT_COUNTERS)); + break; + + case '4': + if (args->family == AF_INET) + break; + + if (p->restore && args->family == AF_INET6) + return; + + exit_tryhelp(2, p->line); + + case '6': + if (args->family == AF_INET6) + break; + + if (p->restore && args->family == AF_INET) + return; + + exit_tryhelp(2, p->line); + + case 1: /* non option */ + if (optarg[0] == '!' && optarg[1] == '\0') { + if (invert) + xtables_error(PARAMETER_PROBLEM, + "multiple consecutive ! not" + " allowed"); + invert = true; + optarg[0] = '\0'; + continue; + } + fprintf(stderr, "Bad argument `%s'\n", optarg); + exit_tryhelp(2, p->line); + + default: + if (command_default(cs, xt_params, invert)) + /* cf. ip6tables.c */ + continue; + break; + } + invert = false; + } + + if (strcmp(p->table, "nat") == 0 && + ((p->policy != NULL && strcmp(p->policy, "DROP") == 0) || + (cs->jumpto != NULL && strcmp(cs->jumpto, "DROP") == 0))) + xtables_error(PARAMETER_PROBLEM, + "\nThe \"nat\" table is not intended for filtering, " + "the use of DROP is therefore inhibited.\n\n"); + + if (!wait && wait_interval_set) + xtables_error(PARAMETER_PROBLEM, + "--wait-interval only makes sense with --wait\n"); + + for (matchp = cs->matches; matchp; matchp = matchp->next) + xtables_option_mfcall(matchp->match); + if (cs->target != NULL) + xtables_option_tfcall(cs->target); + + /* Fix me: must put inverse options checking here --MN */ + + if (optind < argc) + xtables_error(PARAMETER_PROBLEM, + "unknown arguments found on commandline"); + if (!p->command) + xtables_error(PARAMETER_PROBLEM, "no command specified"); + if (invert) + xtables_error(PARAMETER_PROBLEM, + "nothing appropriate following !"); + + if (p->post_parse) + p->post_parse(p->command, cs, args); + + if (p->command == CMD_REPLACE && + (args->s.naddrs != 1 || args->d.naddrs != 1)) + xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " + "specify a unique address"); + + generic_opt_check(p->command, cs->options); + + if (p->chain != NULL && strlen(p->chain) >= XT_EXTENSION_MAXNAMELEN) + xtables_error(PARAMETER_PROBLEM, + "chain name `%s' too long (must be under %u chars)", + p->chain, XT_EXTENSION_MAXNAMELEN); + + if (p->command == CMD_APPEND || + p->command == CMD_DELETE || + p->command == CMD_DELETE_NUM || + p->command == CMD_CHECK || + p->command == CMD_INSERT || + p->command == CMD_REPLACE) { + if (strcmp(p->chain, "PREROUTING") == 0 + || strcmp(p->chain, "INPUT") == 0) { + /* -o not valid with incoming packets. */ + if (cs->options & OPT_VIANAMEOUT) + xtables_error(PARAMETER_PROBLEM, + "Can't use -%c with %s\n", + opt2char(OPT_VIANAMEOUT), + p->chain); + } + + if (strcmp(p->chain, "POSTROUTING") == 0 + || strcmp(p->chain, "OUTPUT") == 0) { + /* -i not valid with outgoing packets */ + if (cs->options & OPT_VIANAMEIN) + xtables_error(PARAMETER_PROBLEM, + "Can't use -%c with %s\n", + opt2char(OPT_VIANAMEIN), + p->chain); + } + } +} diff --git a/iptables/xshared.h b/iptables/xshared.h index 1954168f64058..2737ba4b11c25 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -303,6 +303,7 @@ struct xt_cmd_parse { const char *newname; const char *policy; bool restore; + int line; int verbose; bool xlate; void (*proto_parse)(struct iptables_command_state *cs, @@ -312,4 +313,8 @@ struct xt_cmd_parse { struct xtables_args *args); }; +void do_parse(int argc, char *argv[], + struct xt_cmd_parse *p, struct iptables_command_state *cs, + struct xtables_args *args); + #endif /* IPTABLES_XSHARED_H */ diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c index b0b27695cbb8c..076b7249329bc 100644 --- a/iptables/xtables-translate.c +++ b/iptables/xtables-translate.c @@ -251,6 +251,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], struct xt_cmd_parse p = { .table = *table, .restore = restore, + .line = line, .xlate = true, .proto_parse = h->ops->proto_parse, .post_parse = h->ops->post_parse, diff --git a/iptables/xtables.c b/iptables/xtables.c index d7e22285e089e..6d79215755b3e 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -95,10 +95,6 @@ struct xtables_globals xtables_globals = { .print_help = xtables_printhelp, }; -#define opts xt_params->opts -#define prog_name xt_params->program_name -#define prog_vers xt_params->program_version - /* * All functions starting with "parse" should succeed, otherwise * the program fails. @@ -145,557 +141,6 @@ list_rules(struct nft_handle *h, const char *chain, const char *table, return nft_cmd_rule_list_save(h, chain, table, rulenum, counters); } -static void check_empty_interface(struct xtables_args *args, const char *arg) -{ - const char *msg = "Empty interface is likely to be undesired"; - - if (*arg != '\0') - return; - - if (args->family != NFPROTO_ARP) - xtables_error(PARAMETER_PROBLEM, msg); - - fprintf(stderr, "%s", msg); -} - -static void check_inverse(struct xtables_args *args, const char option[], - bool *invert, int *optidx, int argc) -{ - switch (args->family) { - case NFPROTO_ARP: - break; - default: - return; - } - - if (!option || strcmp(option, "!")) - return; - - fprintf(stderr, "Using intrapositioned negation (`--option ! this`) " - "is deprecated in favor of extrapositioned (`! --option this`).\n"); - - if (*invert) - xtables_error(PARAMETER_PROBLEM, - "Multiple `!' flags not allowed"); - *invert = true; - if (optidx) { - *optidx = *optidx + 1; - if (argc && *optidx > argc) - xtables_error(PARAMETER_PROBLEM, - "no argument following `!'"); - } -} - -void do_parse(int argc, char *argv[], - struct xt_cmd_parse *p, struct iptables_command_state *cs, - struct xtables_args *args) -{ - struct xtables_match *m; - struct xtables_rule_match *matchp; - bool wait_interval_set = false; - struct timeval wait_interval; - struct xtables_target *t; - bool table_set = false; - bool invert = false; - int wait = 0; - - /* re-set optind to 0 in case do_command4 gets called - * a second time */ - optind = 0; - - /* clear mflags in case do_command4 gets called a second time - * (we clear the global list of all matches for security)*/ - for (m = xtables_matches; m; m = m->next) - m->mflags = 0; - - for (t = xtables_targets; t; t = t->next) { - t->tflags = 0; - t->used = 0; - } - - /* Suppress error messages: we may add new options if we - demand-load a protocol. */ - opterr = 0; - - opts = xt_params->orig_opts; - while ((cs->c = getopt_long(argc, argv, xt_params->optstring, - opts, NULL)) != -1) { - switch (cs->c) { - /* - * Command selection - */ - case 'A': - add_command(&p->command, CMD_APPEND, CMD_NONE, invert); - p->chain = optarg; - break; - - case 'C': - add_command(&p->command, CMD_CHECK, CMD_NONE, invert); - p->chain = optarg; - break; - - case 'D': - add_command(&p->command, CMD_DELETE, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) { - p->rulenum = parse_rulenumber(argv[optind++]); - p->command = CMD_DELETE_NUM; - } - break; - - case 'R': - add_command(&p->command, CMD_REPLACE, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a rule number", - cmd2char(CMD_REPLACE)); - break; - - case 'I': - add_command(&p->command, CMD_INSERT, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - else - p->rulenum = 1; - break; - - case 'L': - add_command(&p->command, CMD_LIST, - CMD_ZERO | CMD_ZERO_NUM, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'S': - add_command(&p->command, CMD_LIST_RULES, - CMD_ZERO|CMD_ZERO_NUM, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'F': - add_command(&p->command, CMD_FLUSH, CMD_NONE, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - break; - - case 'Z': - add_command(&p->command, CMD_ZERO, - CMD_LIST|CMD_LIST_RULES, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) { - p->rulenum = parse_rulenumber(argv[optind++]); - p->command = CMD_ZERO_NUM; - } - break; - - case 'N': - parse_chain(optarg); - add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE, - invert); - p->chain = optarg; - break; - - case 'X': - add_command(&p->command, CMD_DELETE_CHAIN, CMD_NONE, - invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - break; - - case 'E': - add_command(&p->command, CMD_RENAME_CHAIN, CMD_NONE, - invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->newname = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires old-chain-name and " - "new-chain-name", - cmd2char(CMD_RENAME_CHAIN)); - break; - - case 'P': - add_command(&p->command, CMD_SET_POLICY, CMD_NONE, - invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->policy = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a chain and a policy", - cmd2char(CMD_SET_POLICY)); - break; - - case 'h': - if (!optarg) - optarg = argv[optind]; - - /* iptables -p icmp -h */ - if (!cs->matches && cs->protocol) - xtables_find_match(cs->protocol, - XTF_TRY_LOAD, &cs->matches); - - xt_params->print_help(cs->matches); - p->command = CMD_NONE; - return; - - /* - * Option selection - */ - case 'p': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_PROTOCOL, - &args->invflags, invert); - - /* Canonicalize into lower case */ - for (cs->protocol = argv[optind - 1]; - *cs->protocol; cs->protocol++) - *cs->protocol = tolower(*cs->protocol); - - cs->protocol = argv[optind - 1]; - args->proto = xtables_parse_protocol(cs->protocol); - - if (args->proto == 0 && - (args->invflags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, - "rule would never match protocol"); - - /* This needs to happen here to parse extensions */ - if (p->proto_parse) - p->proto_parse(cs, args); - break; - - case 's': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_SOURCE, - &args->invflags, invert); - args->shostnetworkmask = argv[optind - 1]; - break; - - case 'd': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_DESTINATION, - &args->invflags, invert); - args->dhostnetworkmask = argv[optind - 1]; - break; - -#ifdef IPT_F_GOTO - case 'g': - set_option(&cs->options, OPT_JUMP, &args->invflags, - invert); - args->goto_set = true; - cs->jumpto = xt_parse_target(optarg); - break; -#endif - - case 2:/* src-mac */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_S_MAC, &args->invflags, - invert); - args->src_mac = argv[optind - 1]; - break; - - case 3:/* dst-mac */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_D_MAC, &args->invflags, - invert); - args->dst_mac = argv[optind - 1]; - break; - - case 'l':/* hardware length */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_H_LENGTH, &args->invflags, - invert); - args->arp_hlen = argv[optind - 1]; - break; - - case 8: /* was never supported, not even in arptables-legacy */ - xtables_error(PARAMETER_PROBLEM, "not supported"); - case 4:/* opcode */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_OPCODE, &args->invflags, - invert); - args->arp_opcode = argv[optind - 1]; - break; - - case 5:/* h-type */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_H_TYPE, &args->invflags, - invert); - args->arp_htype = argv[optind - 1]; - break; - - case 6:/* proto-type */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_P_TYPE, &args->invflags, - invert); - args->arp_ptype = argv[optind - 1]; - break; - - case 'j': - set_option(&cs->options, OPT_JUMP, &args->invflags, - invert); - command_jump(cs, argv[optind - 1]); - break; - - case 'i': - check_empty_interface(args, optarg); - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_VIANAMEIN, - &args->invflags, invert); - xtables_parse_interface(argv[optind - 1], - args->iniface, - args->iniface_mask); - break; - - case 'o': - check_empty_interface(args, optarg); - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_VIANAMEOUT, - &args->invflags, invert); - xtables_parse_interface(argv[optind - 1], - args->outiface, - args->outiface_mask); - break; - - case 'f': - if (args->family == AF_INET6) { - xtables_error(PARAMETER_PROBLEM, - "`-f' is not supported in IPv6, " - "use -m frag instead"); - } - set_option(&cs->options, OPT_FRAGMENT, &args->invflags, - invert); - args->flags |= IPT_F_FRAG; - break; - - case 'v': - if (!p->verbose) - set_option(&cs->options, OPT_VERBOSE, - &args->invflags, invert); - p->verbose++; - break; - - case 'm': - command_match(cs, invert); - break; - - case 'n': - set_option(&cs->options, OPT_NUMERIC, &args->invflags, - invert); - break; - - case 't': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "unexpected ! flag before --table"); - if (p->restore && table_set) - xtables_error(PARAMETER_PROBLEM, - "The -t option cannot be used in %s.\n", - xt_params->program_name); - p->table = optarg; - table_set = true; - break; - - case 'x': - set_option(&cs->options, OPT_EXPANDED, &args->invflags, - invert); - break; - - case 'V': - if (invert) - printf("Not %s ;-)\n", prog_vers); - else - printf("%s v%s\n", - prog_name, prog_vers); - exit(0); - - case 'w': - if (p->restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-w' from " - "iptables-restore"); - } - - wait = parse_wait_time(argc, argv); - break; - - case 'W': - if (p->restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-W' from " - "iptables-restore"); - } - - parse_wait_interval(argc, argv, &wait_interval); - wait_interval_set = true; - break; - - case '0': - set_option(&cs->options, OPT_LINENUMBERS, - &args->invflags, invert); - break; - - case 'M': - xtables_modprobe_program = optarg; - break; - - case 'c': - set_option(&cs->options, OPT_COUNTERS, &args->invflags, - invert); - args->pcnt = optarg; - args->bcnt = strchr(args->pcnt + 1, ','); - if (args->bcnt) - args->bcnt++; - if (!args->bcnt && xs_has_arg(argc, argv)) - args->bcnt = argv[optind++]; - if (!args->bcnt) - xtables_error(PARAMETER_PROBLEM, - "-%c requires packet and byte counter", - opt2char(OPT_COUNTERS)); - - if (sscanf(args->pcnt, "%llu", &args->pcnt_cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c packet counter not numeric", - opt2char(OPT_COUNTERS)); - - if (sscanf(args->bcnt, "%llu", &args->bcnt_cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c byte counter not numeric", - opt2char(OPT_COUNTERS)); - break; - - case '4': - if (args->family == AF_INET) - break; - - if (p->restore && args->family == AF_INET6) - return; - - exit_tryhelp(2, line); - - case '6': - if (args->family == AF_INET6) - break; - - if (p->restore && args->family == AF_INET) - return; - - exit_tryhelp(2, line); - - case 1: /* non option */ - if (optarg[0] == '!' && optarg[1] == '\0') { - if (invert) - xtables_error(PARAMETER_PROBLEM, - "multiple consecutive ! not" - " allowed"); - invert = true; - optarg[0] = '\0'; - continue; - } - fprintf(stderr, "Bad argument `%s'\n", optarg); - exit_tryhelp(2, line); - - default: - if (command_default(cs, xt_params, invert)) - /* cf. ip6tables.c */ - continue; - break; - } - invert = false; - } - - if (strcmp(p->table, "nat") == 0 && - ((p->policy != NULL && strcmp(p->policy, "DROP") == 0) || - (cs->jumpto != NULL && strcmp(cs->jumpto, "DROP") == 0))) - xtables_error(PARAMETER_PROBLEM, - "\nThe \"nat\" table is not intended for filtering, " - "the use of DROP is therefore inhibited.\n\n"); - - if (!wait && wait_interval_set) - xtables_error(PARAMETER_PROBLEM, - "--wait-interval only makes sense with --wait\n"); - - for (matchp = cs->matches; matchp; matchp = matchp->next) - xtables_option_mfcall(matchp->match); - if (cs->target != NULL) - xtables_option_tfcall(cs->target); - - /* Fix me: must put inverse options checking here --MN */ - - if (optind < argc) - xtables_error(PARAMETER_PROBLEM, - "unknown arguments found on commandline"); - if (!p->command) - xtables_error(PARAMETER_PROBLEM, "no command specified"); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "nothing appropriate following !"); - - if (p->post_parse) - p->post_parse(p->command, cs, args); - - if (p->command == CMD_REPLACE && - (args->s.naddrs != 1 || args->d.naddrs != 1)) - xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " - "specify a unique address"); - - generic_opt_check(p->command, cs->options); - - if (p->chain != NULL && strlen(p->chain) >= XT_EXTENSION_MAXNAMELEN) - xtables_error(PARAMETER_PROBLEM, - "chain name `%s' too long (must be under %u chars)", - p->chain, XT_EXTENSION_MAXNAMELEN); - - if (p->command == CMD_APPEND || - p->command == CMD_DELETE || - p->command == CMD_DELETE_NUM || - p->command == CMD_CHECK || - p->command == CMD_INSERT || - p->command == CMD_REPLACE) { - if (strcmp(p->chain, "PREROUTING") == 0 - || strcmp(p->chain, "INPUT") == 0) { - /* -o not valid with incoming packets. */ - if (cs->options & OPT_VIANAMEOUT) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEOUT), - p->chain); - } - - if (strcmp(p->chain, "POSTROUTING") == 0 - || strcmp(p->chain, "OUTPUT") == 0) { - /* -i not valid with outgoing packets */ - if (cs->options & OPT_VIANAMEIN) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEIN), - p->chain); - } - } -} - int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore) { @@ -703,6 +148,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, struct xt_cmd_parse p = { .table = *table, .restore = restore, + .line = line, .proto_parse = h->ops->proto_parse, .post_parse = h->ops->post_parse, }; From patchwork Fri Dec 24 17:17:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573081 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDKd729Fz9sVq for ; Sat, 25 Dec 2021 04:18:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233289AbhLXRSJ (ORCPT ); Fri, 24 Dec 2021 12:18:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSI (ORCPT ); Fri, 24 Dec 2021 12:18:08 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40BE4C061401 for ; Fri, 24 Dec 2021 09:18:08 -0800 (PST) Received: from localhost ([::1]:59082 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oCh-0004vA-67; Fri, 24 Dec 2021 18:18:03 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 08/11] xshared: Store parsed wait and wait_interval in xtables_args Date: Fri, 24 Dec 2021 18:17:51 +0100 Message-Id: <20211224171754.14210-9-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org While nft-variants don't care, legacy ones do. Signed-off-by: Phil Sutter --- iptables/xshared.c | 8 +++----- iptables/xshared.h | 2 ++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iptables/xshared.c b/iptables/xshared.c index 7702d899a3586..021402ea6165e 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1311,11 +1311,9 @@ void do_parse(int argc, char *argv[], struct xtables_match *m; struct xtables_rule_match *matchp; bool wait_interval_set = false; - struct timeval wait_interval; struct xtables_target *t; bool table_set = false; bool invert = false; - int wait = 0; /* re-set optind to 0 in case do_command4 gets called * a second time */ @@ -1658,7 +1656,7 @@ void do_parse(int argc, char *argv[], "iptables-restore"); } - wait = parse_wait_time(argc, argv); + args->wait = parse_wait_time(argc, argv); break; case 'W': @@ -1668,7 +1666,7 @@ void do_parse(int argc, char *argv[], "iptables-restore"); } - parse_wait_interval(argc, argv, &wait_interval); + parse_wait_interval(argc, argv, &args->wait_interval); wait_interval_set = true; break; @@ -1753,7 +1751,7 @@ void do_parse(int argc, char *argv[], "\nThe \"nat\" table is not intended for filtering, " "the use of DROP is therefore inhibited.\n\n"); - if (!wait && wait_interval_set) + if (!args->wait && wait_interval_set) xtables_error(PARAMETER_PROBLEM, "--wait-interval only makes sense with --wait\n"); diff --git a/iptables/xshared.h b/iptables/xshared.h index 2737ba4b11c25..6ac1330537731 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -293,6 +293,8 @@ struct xtables_args { const char *arp_hlen, *arp_opcode; const char *arp_htype, *arp_ptype; unsigned long long pcnt_cnt, bcnt_cnt; + int wait; + struct timeval wait_interval; }; struct xt_cmd_parse { From patchwork Fri Dec 24 17:17:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573088 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDLR5CTSz9sVq for ; Sat, 25 Dec 2021 04:18:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353289AbhLXRSx (ORCPT ); Fri, 24 Dec 2021 12:18:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSv (ORCPT ); Fri, 24 Dec 2021 12:18:51 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F49CC061401 for ; Fri, 24 Dec 2021 09:18:50 -0800 (PST) Received: from localhost ([::1]:59096 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oDQ-0004xF-RF; Fri, 24 Dec 2021 18:18:48 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 09/11] nft: Move proto_parse and post_parse callbacks to xshared Date: Fri, 24 Dec 2021 18:17:52 +0100 Message-Id: <20211224171754.14210-10-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org They are not nft-variant-specific and may therefore be shared with legacy. Signed-off-by: Phil Sutter --- iptables/nft-ipv4.c | 59 +-------------------- iptables/nft-ipv6.c | 76 +------------------------- iptables/xshared.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ iptables/xshared.h | 9 ++++ 4 files changed, 139 insertions(+), 131 deletions(-) diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index f36260980e829..2588babd395a5 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -274,61 +274,6 @@ static void nft_ipv4_save_rule(const void *data, unsigned int format) &cs->fw, format); } -static void nft_ipv4_proto_parse(struct iptables_command_state *cs, - struct xtables_args *args) -{ - cs->fw.ip.proto = args->proto; - cs->fw.ip.invflags = args->invflags; -} - -static void nft_ipv4_post_parse(int command, - struct iptables_command_state *cs, - struct xtables_args *args) -{ - cs->fw.ip.flags = args->flags; - /* We already set invflags in proto_parse, but we need to refresh it - * to include new parsed options. - */ - cs->fw.ip.invflags = args->invflags; - - memcpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ); - memcpy(cs->fw.ip.iniface_mask, - args->iniface_mask, IFNAMSIZ*sizeof(unsigned char)); - - memcpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ); - memcpy(cs->fw.ip.outiface_mask, - args->outiface_mask, IFNAMSIZ*sizeof(unsigned char)); - - if (args->goto_set) - cs->fw.ip.flags |= IPT_F_GOTO; - - cs->counters.pcnt = args->pcnt_cnt; - cs->counters.bcnt = args->bcnt_cnt; - - if (command & (CMD_REPLACE | CMD_INSERT | - CMD_DELETE | CMD_APPEND | CMD_CHECK)) { - if (!(cs->options & OPT_DESTINATION)) - args->dhostnetworkmask = "0.0.0.0/0"; - if (!(cs->options & OPT_SOURCE)) - args->shostnetworkmask = "0.0.0.0/0"; - } - - if (args->shostnetworkmask) - xtables_ipparse_multiple(args->shostnetworkmask, - &args->s.addr.v4, &args->s.mask.v4, - &args->s.naddrs); - if (args->dhostnetworkmask) - xtables_ipparse_multiple(args->dhostnetworkmask, - &args->d.addr.v4, &args->d.mask.v4, - &args->d.naddrs); - - if ((args->s.naddrs > 1 || args->d.naddrs > 1) && - (cs->fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP))) - xtables_error(PARAMETER_PROBLEM, - "! not allowed with multiple" - " source or destination IP addresses"); -} - static void xlate_ipv4_addr(const char *selector, const struct in_addr *addr, const struct in_addr *mask, bool inv, struct xt_xlate *xl) @@ -510,8 +455,8 @@ struct nft_family_ops nft_family_ops_ipv4 = { .print_rule = nft_ipv4_print_rule, .save_rule = nft_ipv4_save_rule, .save_chain = nft_ipv46_save_chain, - .proto_parse = nft_ipv4_proto_parse, - .post_parse = nft_ipv4_post_parse, + .proto_parse = ipv4_proto_parse, + .post_parse = ipv4_post_parse, .parse_target = nft_ipv46_parse_target, .rule_to_cs = nft_rule_to_iptables_command_state, .clear_cs = nft_clear_iptables_command_state, diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index 132130880a43a..6d288112abbfa 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -236,78 +236,6 @@ static void nft_ipv6_save_rule(const void *data, unsigned int format) &cs->fw6, format); } -/* These are invalid numbers as upper layer protocol */ -static int is_exthdr(uint16_t proto) -{ - return (proto == IPPROTO_ROUTING || - proto == IPPROTO_FRAGMENT || - proto == IPPROTO_AH || - proto == IPPROTO_DSTOPTS); -} - -static void nft_ipv6_proto_parse(struct iptables_command_state *cs, - struct xtables_args *args) -{ - cs->fw6.ipv6.proto = args->proto; - cs->fw6.ipv6.invflags = args->invflags; - - if (is_exthdr(cs->fw6.ipv6.proto) - && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0) - fprintf(stderr, - "Warning: never matched protocol: %s. " - "use extension match instead.\n", - cs->protocol); -} - -static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs, - struct xtables_args *args) -{ - cs->fw6.ipv6.flags = args->flags; - /* We already set invflags in proto_parse, but we need to refresh it - * to include new parsed options. - */ - cs->fw6.ipv6.invflags = args->invflags; - - memcpy(cs->fw6.ipv6.iniface, args->iniface, IFNAMSIZ); - memcpy(cs->fw6.ipv6.iniface_mask, - args->iniface_mask, IFNAMSIZ*sizeof(unsigned char)); - - memcpy(cs->fw6.ipv6.outiface, args->outiface, IFNAMSIZ); - memcpy(cs->fw6.ipv6.outiface_mask, - args->outiface_mask, IFNAMSIZ*sizeof(unsigned char)); - - if (args->goto_set) - cs->fw6.ipv6.flags |= IP6T_F_GOTO; - - cs->fw6.counters.pcnt = args->pcnt_cnt; - cs->fw6.counters.bcnt = args->bcnt_cnt; - - if (command & (CMD_REPLACE | CMD_INSERT | - CMD_DELETE | CMD_APPEND | CMD_CHECK)) { - if (!(cs->options & OPT_DESTINATION)) - args->dhostnetworkmask = "::0/0"; - if (!(cs->options & OPT_SOURCE)) - args->shostnetworkmask = "::0/0"; - } - - if (args->shostnetworkmask) - xtables_ip6parse_multiple(args->shostnetworkmask, - &args->s.addr.v6, - &args->s.mask.v6, - &args->s.naddrs); - if (args->dhostnetworkmask) - xtables_ip6parse_multiple(args->dhostnetworkmask, - &args->d.addr.v6, - &args->d.mask.v6, - &args->d.naddrs); - - if ((args->s.naddrs > 1 || args->d.naddrs > 1) && - (cs->fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP))) - xtables_error(PARAMETER_PROBLEM, - "! not allowed with multiple" - " source or destination IP addresses"); -} - static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr, const struct in6_addr *mask, int invert, struct xt_xlate *xl) @@ -495,8 +423,8 @@ struct nft_family_ops nft_family_ops_ipv6 = { .print_rule = nft_ipv6_print_rule, .save_rule = nft_ipv6_save_rule, .save_chain = nft_ipv46_save_chain, - .proto_parse = nft_ipv6_proto_parse, - .post_parse = nft_ipv6_post_parse, + .proto_parse = ipv6_proto_parse, + .post_parse = ipv6_post_parse, .parse_target = nft_ipv46_parse_target, .rule_to_cs = nft_rule_to_iptables_command_state, .clear_cs = nft_clear_iptables_command_state, diff --git a/iptables/xshared.c b/iptables/xshared.c index 021402ea6165e..1993c89541527 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1813,3 +1813,129 @@ void do_parse(int argc, char *argv[], } } } + +void ipv4_proto_parse(struct iptables_command_state *cs, + struct xtables_args *args) +{ + cs->fw.ip.proto = args->proto; + cs->fw.ip.invflags = args->invflags; +} + +/* These are invalid numbers as upper layer protocol */ +static int is_exthdr(uint16_t proto) +{ + return (proto == IPPROTO_ROUTING || + proto == IPPROTO_FRAGMENT || + proto == IPPROTO_AH || + proto == IPPROTO_DSTOPTS); +} + +void ipv6_proto_parse(struct iptables_command_state *cs, + struct xtables_args *args) +{ + cs->fw6.ipv6.proto = args->proto; + cs->fw6.ipv6.invflags = args->invflags; + + if (is_exthdr(cs->fw6.ipv6.proto) + && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0) + fprintf(stderr, + "Warning: never matched protocol: %s. " + "use extension match instead.\n", + cs->protocol); +} + +void ipv4_post_parse(int command, struct iptables_command_state *cs, + struct xtables_args *args) +{ + cs->fw.ip.flags = args->flags; + /* We already set invflags in proto_parse, but we need to refresh it + * to include new parsed options. + */ + cs->fw.ip.invflags = args->invflags; + + memcpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ); + memcpy(cs->fw.ip.iniface_mask, + args->iniface_mask, IFNAMSIZ*sizeof(unsigned char)); + + memcpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ); + memcpy(cs->fw.ip.outiface_mask, + args->outiface_mask, IFNAMSIZ*sizeof(unsigned char)); + + if (args->goto_set) + cs->fw.ip.flags |= IPT_F_GOTO; + + cs->counters.pcnt = args->pcnt_cnt; + cs->counters.bcnt = args->bcnt_cnt; + + if (command & (CMD_REPLACE | CMD_INSERT | + CMD_DELETE | CMD_APPEND | CMD_CHECK)) { + if (!(cs->options & OPT_DESTINATION)) + args->dhostnetworkmask = "0.0.0.0/0"; + if (!(cs->options & OPT_SOURCE)) + args->shostnetworkmask = "0.0.0.0/0"; + } + + if (args->shostnetworkmask) + xtables_ipparse_multiple(args->shostnetworkmask, + &args->s.addr.v4, &args->s.mask.v4, + &args->s.naddrs); + if (args->dhostnetworkmask) + xtables_ipparse_multiple(args->dhostnetworkmask, + &args->d.addr.v4, &args->d.mask.v4, + &args->d.naddrs); + + if ((args->s.naddrs > 1 || args->d.naddrs > 1) && + (cs->fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP))) + xtables_error(PARAMETER_PROBLEM, + "! not allowed with multiple" + " source or destination IP addresses"); +} + +void ipv6_post_parse(int command, struct iptables_command_state *cs, + struct xtables_args *args) +{ + cs->fw6.ipv6.flags = args->flags; + /* We already set invflags in proto_parse, but we need to refresh it + * to include new parsed options. + */ + cs->fw6.ipv6.invflags = args->invflags; + + memcpy(cs->fw6.ipv6.iniface, args->iniface, IFNAMSIZ); + memcpy(cs->fw6.ipv6.iniface_mask, + args->iniface_mask, IFNAMSIZ*sizeof(unsigned char)); + + memcpy(cs->fw6.ipv6.outiface, args->outiface, IFNAMSIZ); + memcpy(cs->fw6.ipv6.outiface_mask, + args->outiface_mask, IFNAMSIZ*sizeof(unsigned char)); + + if (args->goto_set) + cs->fw6.ipv6.flags |= IP6T_F_GOTO; + + cs->fw6.counters.pcnt = args->pcnt_cnt; + cs->fw6.counters.bcnt = args->bcnt_cnt; + + if (command & (CMD_REPLACE | CMD_INSERT | + CMD_DELETE | CMD_APPEND | CMD_CHECK)) { + if (!(cs->options & OPT_DESTINATION)) + args->dhostnetworkmask = "::0/0"; + if (!(cs->options & OPT_SOURCE)) + args->shostnetworkmask = "::0/0"; + } + + if (args->shostnetworkmask) + xtables_ip6parse_multiple(args->shostnetworkmask, + &args->s.addr.v6, + &args->s.mask.v6, + &args->s.naddrs); + if (args->dhostnetworkmask) + xtables_ip6parse_multiple(args->dhostnetworkmask, + &args->d.addr.v6, + &args->d.mask.v6, + &args->d.naddrs); + + if ((args->s.naddrs > 1 || args->d.naddrs > 1) && + (cs->fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP))) + xtables_error(PARAMETER_PROBLEM, + "! not allowed with multiple" + " source or destination IP addresses"); +} diff --git a/iptables/xshared.h b/iptables/xshared.h index 6ac1330537731..296b3510226f3 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -319,4 +319,13 @@ void do_parse(int argc, char *argv[], struct xt_cmd_parse *p, struct iptables_command_state *cs, struct xtables_args *args); +void ipv4_proto_parse(struct iptables_command_state *cs, + struct xtables_args *args); +void ipv6_proto_parse(struct iptables_command_state *cs, + struct xtables_args *args); +void ipv4_post_parse(int command, struct iptables_command_state *cs, + struct xtables_args *args); +void ipv6_post_parse(int command, struct iptables_command_state *cs, + struct xtables_args *args); + #endif /* IPTABLES_XSHARED_H */ From patchwork Fri Dec 24 17:17:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573090 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDLZ6X3wz9sVq for ; Sat, 25 Dec 2021 04:19:02 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353291AbhLXRTB (ORCPT ); Fri, 24 Dec 2021 12:19:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRTB (ORCPT ); Fri, 24 Dec 2021 12:19:01 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28325C061401 for ; Fri, 24 Dec 2021 09:19:01 -0800 (PST) Received: from localhost ([::1]:59102 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oDb-0004xn-FC; Fri, 24 Dec 2021 18:18:59 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 10/11] iptables: Use xtables' do_parse() function Date: Fri, 24 Dec 2021 18:17:53 +0100 Message-Id: <20211224171754.14210-11-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org To do so, a few conversions are needed: - Make use of xt_params->optstring - Make use of xt_params->print_help callback - Switch to using a proto_parse callback Signed-off-by: Phil Sutter --- iptables/iptables.c | 484 +++----------------------------------------- iptables/xshared.c | 3 + 2 files changed, 36 insertions(+), 451 deletions(-) diff --git a/iptables/iptables.c b/iptables/iptables.c index 7dc4cbc1c9c22..d1bc73f5a2021 100644 --- a/iptables/iptables.c +++ b/iptables/iptables.c @@ -87,21 +87,12 @@ static struct option original_opts[] = { struct xtables_globals iptables_globals = { .option_offset = 0, .program_version = PACKAGE_VERSION " (legacy)", + .optstring = OPTSTRING_COMMON "R:S::W::" "46bfg:h::m:nvw::x", .orig_opts = original_opts, .compat_rev = xtables_compatible_revision, + .print_help = xtables_printhelp, }; -#define opts iptables_globals.opts -#define prog_name iptables_globals.program_name -#define prog_vers iptables_globals.program_version - -static void -exit_printhelp(const struct xtables_rule_match *matches) -{ - xtables_printhelp(matches); - exit(0); -} - /* * All functions starting with "parse" should succeed, otherwise * the program fails. @@ -699,10 +690,21 @@ generate_entry(const struct ipt_entry *fw, int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle, bool restore) { + struct xt_cmd_parse p = { + .table = *table, + .restore = restore, + .line = line, + .proto_parse = ipv4_proto_parse, + .post_parse = ipv4_post_parse, + }; struct iptables_command_state cs = { .jumpto = "", .argv = argv, }; + struct xtables_args args = { + .family = AF_INET, + .wait_interval.tv_sec = 1, + }; struct ipt_entry *e = NULL; unsigned int nsaddrs = 0, ndaddrs = 0; struct in_addr *saddrs = NULL, *smasks = NULL; @@ -710,433 +712,30 @@ int do_command4(int argc, char *argv[], char **table, struct timeval wait_interval = { .tv_sec = 1, }; - bool wait_interval_set = false; int verbose = 0; int wait = 0; const char *chain = NULL; - const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; const char *policy = NULL, *newname = NULL; unsigned int rulenum = 0, command = 0; - const char *pcnt = NULL, *bcnt = NULL; int ret = 1; - struct xtables_match *m; - struct xtables_rule_match *matchp; - struct xtables_target *t; - unsigned long long cnt; - bool table_set = false; - uint16_t invflags = 0; - bool invert = false; - - /* re-set optind to 0 in case do_command4 gets called - * a second time */ - optind = 0; - - /* clear mflags in case do_command4 gets called a second time - * (we clear the global list of all matches for security)*/ - for (m = xtables_matches; m; m = m->next) - m->mflags = 0; - - for (t = xtables_targets; t; t = t->next) { - t->tflags = 0; - t->used = 0; - } - - /* Suppress error messages: we may add new options if we - demand-load a protocol. */ - opterr = 0; - opts = xt_params->orig_opts; - while ((cs.c = getopt_long(argc, argv, - "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46", - opts, NULL)) != -1) { - switch (cs.c) { - /* - * Command selection - */ - case 'A': - add_command(&command, CMD_APPEND, CMD_NONE, invert); - chain = optarg; - break; - - case 'C': - add_command(&command, CMD_CHECK, CMD_NONE, invert); - chain = optarg; - break; - - case 'D': - add_command(&command, CMD_DELETE, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) { - rulenum = parse_rulenumber(argv[optind++]); - command = CMD_DELETE_NUM; - } - break; - - case 'R': - add_command(&command, CMD_REPLACE, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a rule number", - cmd2char(CMD_REPLACE)); - break; - - case 'I': - add_command(&command, CMD_INSERT, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - else rulenum = 1; - break; - - case 'L': - add_command(&command, CMD_LIST, - CMD_ZERO | CMD_ZERO_NUM, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'S': - add_command(&command, CMD_LIST_RULES, - CMD_ZERO|CMD_ZERO_NUM, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'F': - add_command(&command, CMD_FLUSH, CMD_NONE, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - break; - - case 'Z': - add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, - invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) { - rulenum = parse_rulenumber(argv[optind++]); - command = CMD_ZERO_NUM; - } - break; - - case 'N': - parse_chain(optarg); - add_command(&command, CMD_NEW_CHAIN, CMD_NONE, invert); - chain = optarg; - break; - - case 'X': - add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, - invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - break; - - case 'E': - add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, - invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - newname = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires old-chain-name and " - "new-chain-name", - cmd2char(CMD_RENAME_CHAIN)); - break; - - case 'P': - add_command(&command, CMD_SET_POLICY, CMD_NONE, - invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - policy = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a chain and a policy", - cmd2char(CMD_SET_POLICY)); - break; - - case 'h': - if (!optarg) - optarg = argv[optind]; - - /* iptables -p icmp -h */ - if (!cs.matches && cs.protocol) - xtables_find_match(cs.protocol, - XTF_TRY_LOAD, &cs.matches); - - exit_printhelp(cs.matches); - - /* - * Option selection - */ - case 'p': - set_option(&cs.options, OPT_PROTOCOL, &invflags, - invert); - - /* Canonicalize into lower case */ - for (cs.protocol = optarg; *cs.protocol; cs.protocol++) - *cs.protocol = tolower(*cs.protocol); - - cs.protocol = optarg; - cs.fw.ip.proto = xtables_parse_protocol(cs.protocol); - - if (cs.fw.ip.proto == 0 && (invflags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, - "rule would never match protocol"); - break; - - case 's': - set_option(&cs.options, OPT_SOURCE, &invflags, invert); - shostnetworkmask = optarg; - break; - - case 'd': - set_option(&cs.options, OPT_DESTINATION, &invflags, - invert); - dhostnetworkmask = optarg; - break; - -#ifdef IPT_F_GOTO - case 'g': - set_option(&cs.options, OPT_JUMP, &invflags, invert); - cs.fw.ip.flags |= IPT_F_GOTO; - cs.jumpto = xt_parse_target(optarg); - break; -#endif - - case 'j': - set_option(&cs.options, OPT_JUMP, &invflags, invert); - command_jump(&cs, optarg); - break; - - - case 'i': - if (*optarg == '\0') - xtables_error(PARAMETER_PROBLEM, - "Empty interface is likely to be " - "undesired"); - set_option(&cs.options, OPT_VIANAMEIN, &invflags, - invert); - xtables_parse_interface(optarg, - cs.fw.ip.iniface, - cs.fw.ip.iniface_mask); - break; - - case 'o': - if (*optarg == '\0') - xtables_error(PARAMETER_PROBLEM, - "Empty interface is likely to be " - "undesired"); - set_option(&cs.options, OPT_VIANAMEOUT, &invflags, - invert); - xtables_parse_interface(optarg, - cs.fw.ip.outiface, - cs.fw.ip.outiface_mask); - break; - - case 'f': - set_option(&cs.options, OPT_FRAGMENT, &invflags, - invert); - cs.fw.ip.flags |= IPT_F_FRAG; - break; - - case 'v': - if (!verbose) - set_option(&cs.options, OPT_VERBOSE, - &invflags, invert); - verbose++; - break; - - case 'w': - if (restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-w' from " - "iptables-restore"); - } - wait = parse_wait_time(argc, argv); - break; - case 'W': - if (restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-W' from " - "iptables-restore"); - } - parse_wait_interval(argc, argv, &wait_interval); - wait_interval_set = true; - break; - - case 'm': - command_match(&cs, invert); - break; - - case 'n': - set_option(&cs.options, OPT_NUMERIC, &invflags, - invert); - break; - - case 't': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "unexpected ! flag before --table"); - if (restore && table_set) - xtables_error(PARAMETER_PROBLEM, - "The -t option cannot be used in %s.\n", - xt_params->program_name); - *table = optarg; - table_set = true; - break; - - case 'x': - set_option(&cs.options, OPT_EXPANDED, &invflags, - invert); - break; - - case 'V': - if (invert) - printf("Not %s ;-)\n", prog_vers); - else - printf("%s v%s\n", - prog_name, prog_vers); - exit(0); - - case '0': - set_option(&cs.options, OPT_LINENUMBERS, &invflags, - invert); - break; - - case 'M': - xtables_modprobe_program = optarg; - break; - - case 'c': - - set_option(&cs.options, OPT_COUNTERS, &invflags, - invert); - pcnt = optarg; - bcnt = strchr(pcnt + 1, ','); - if (bcnt) - bcnt++; - if (!bcnt && xs_has_arg(argc, argv)) - bcnt = argv[optind++]; - if (!bcnt) - xtables_error(PARAMETER_PROBLEM, - "-%c requires packet and byte counter", - opt2char(OPT_COUNTERS)); - - if (sscanf(pcnt, "%llu", &cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c packet counter not numeric", - opt2char(OPT_COUNTERS)); - cs.fw.counters.pcnt = cnt; - - if (sscanf(bcnt, "%llu", &cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c byte counter not numeric", - opt2char(OPT_COUNTERS)); - cs.fw.counters.bcnt = cnt; - break; - - case '4': - /* This is indeed the IPv4 iptables */ - break; - - case '6': - /* This is not the IPv6 ip6tables */ - if (line != -1) - return 1; /* success: line ignored */ - fprintf(stderr, "This is the IPv4 version of iptables.\n"); - exit_tryhelp(2, line); - - case 1: /* non option */ - if (optarg[0] == '!' && optarg[1] == '\0') { - if (invert) - xtables_error(PARAMETER_PROBLEM, - "multiple consecutive ! not" - " allowed"); - invert = true; - optarg[0] = '\0'; - continue; - } - fprintf(stderr, "Bad argument `%s'\n", optarg); - exit_tryhelp(2, line); - - default: - if (command_default(&cs, &iptables_globals, invert)) - /* cf. ip6tables.c */ - continue; - break; - } - invert = false; - } - - if (!wait && wait_interval_set) - xtables_error(PARAMETER_PROBLEM, - "--wait-interval only makes sense with --wait\n"); - - if (strcmp(*table, "nat") == 0 && - ((policy != NULL && strcmp(policy, "DROP") == 0) || - (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0))) - xtables_error(PARAMETER_PROBLEM, - "\nThe \"nat\" table is not intended for filtering, " - "the use of DROP is therefore inhibited.\n\n"); - - for (matchp = cs.matches; matchp; matchp = matchp->next) - xtables_option_mfcall(matchp->match); - if (cs.target != NULL) - xtables_option_tfcall(cs.target); - - /* Fix me: must put inverse options checking here --MN */ - - if (optind < argc) - xtables_error(PARAMETER_PROBLEM, - "unknown arguments found on commandline"); - if (!command) - xtables_error(PARAMETER_PROBLEM, "no command specified"); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "nothing appropriate following !"); - - cs.fw.ip.invflags = invflags; - - if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) { - if (!(cs.options & OPT_DESTINATION)) - dhostnetworkmask = "0.0.0.0/0"; - if (!(cs.options & OPT_SOURCE)) - shostnetworkmask = "0.0.0.0/0"; - } - - if (shostnetworkmask) - xtables_ipparse_multiple(shostnetworkmask, &saddrs, - &smasks, &nsaddrs); - - if (dhostnetworkmask) - xtables_ipparse_multiple(dhostnetworkmask, &daddrs, - &dmasks, &ndaddrs); - - if ((nsaddrs > 1 || ndaddrs > 1) && - (cs.fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP))) - xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple" - " source or destination IP addresses"); - - if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1)) - xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " - "specify a unique address"); - - generic_opt_check(command, cs.options); + do_parse(argc, argv, &p, &cs, &args); + + command = p.command; + chain = p.chain; + *table = p.table; + rulenum = p.rulenum; + policy = p.policy; + newname = p.newname; + verbose = p.verbose; + wait = args.wait; + wait_interval = args.wait_interval; + nsaddrs = args.s.naddrs; + ndaddrs = args.d.naddrs; + saddrs = args.s.addr.v4; + daddrs = args.d.addr.v4; + smasks = args.s.mask.v4; + dmasks = args.d.mask.v4; /* Attempt to acquire the xtables lock */ if (!restore) @@ -1160,26 +759,6 @@ int do_command4(int argc, char *argv[], char **table, || command == CMD_CHECK || command == CMD_INSERT || command == CMD_REPLACE) { - if (strcmp(chain, "PREROUTING") == 0 - || strcmp(chain, "INPUT") == 0) { - /* -o not valid with incoming packets. */ - if (cs.options & OPT_VIANAMEOUT) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEOUT), - chain); - } - - if (strcmp(chain, "POSTROUTING") == 0 - || strcmp(chain, "OUTPUT") == 0) { - /* -i not valid with outgoing packets */ - if (cs.options & OPT_VIANAMEIN) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEIN), - chain); - } - if (cs.target && iptc_is_chain(cs.jumpto, *handle)) { fprintf(stderr, "Warning: using chain %s, not extension\n", @@ -1317,6 +896,9 @@ int do_command4(int argc, char *argv[], char **table, case CMD_SET_POLICY: ret = iptc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw.counters : NULL, *handle); break; + case CMD_NONE: + /* do_parse ignored the line (eg: -4 with ip6tables-restore) */ + break; default: /* We should never reach this... */ exit_tryhelp(2, line); diff --git a/iptables/xshared.c b/iptables/xshared.c index 1993c89541527..1bce6715c3a9a 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1864,8 +1864,11 @@ void ipv4_post_parse(int command, struct iptables_command_state *cs, if (args->goto_set) cs->fw.ip.flags |= IPT_F_GOTO; + /* nft-variants use cs->counters, legacy uses cs->fw.counters */ cs->counters.pcnt = args->pcnt_cnt; cs->counters.bcnt = args->bcnt_cnt; + cs->fw.counters.pcnt = args->pcnt_cnt; + cs->fw.counters.bcnt = args->bcnt_cnt; if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) { From patchwork Fri Dec 24 17:17:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1573082 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4JLDKf5Dztz9sXS for ; Sat, 25 Dec 2021 04:18:14 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344145AbhLXRSL (ORCPT ); Fri, 24 Dec 2021 12:18:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbhLXRSK (ORCPT ); Fri, 24 Dec 2021 12:18:10 -0500 Received: from orbyte.nwl.cc (orbyte.nwl.cc [IPv6:2001:41d0:e:133a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D41CC061401 for ; Fri, 24 Dec 2021 09:18:10 -0800 (PST) Received: from localhost ([::1]:59084 helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.94.2) (envelope-from ) id 1n0oCm-0004vG-GH; Fri, 24 Dec 2021 18:18:08 +0100 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH 11/11] ip6tables: Use the shared do_parse, too Date: Fri, 24 Dec 2021 18:17:54 +0100 Message-Id: <20211224171754.14210-12-phil@nwl.cc> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211224171754.14210-1-phil@nwl.cc> References: <20211224171754.14210-1-phil@nwl.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Same change as with iptables, merely have to set IP6T_F_PROTO flag in ipv6_proto_parse(). Signed-off-by: Phil Sutter --- iptables/ip6tables.c | 499 +++---------------------------------------- iptables/xshared.c | 4 + 2 files changed, 37 insertions(+), 466 deletions(-) diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c index b4604f83cf8a4..fa3e6c1506e71 100644 --- a/iptables/ip6tables.c +++ b/iptables/ip6tables.c @@ -90,21 +90,12 @@ static struct option original_opts[] = { struct xtables_globals ip6tables_globals = { .option_offset = 0, .program_version = PACKAGE_VERSION " (legacy)", + .optstring = OPTSTRING_COMMON "R:S::W::" "46bg:h::m:nvw::x", .orig_opts = original_opts, .compat_rev = xtables_compatible_revision, + .print_help = xtables_printhelp, }; -#define opts ip6tables_globals.opts -#define prog_name ip6tables_globals.program_name -#define prog_vers ip6tables_globals.program_version - -static void -exit_printhelp(const struct xtables_rule_match *matches) -{ - xtables_printhelp(matches); - exit(0); -} - /* * All functions starting with "parse" should succeed, otherwise * the program fails. @@ -114,15 +105,6 @@ exit_printhelp(const struct xtables_rule_match *matches) * return global static data. */ -/* These are invalid numbers as upper layer protocol */ -static int is_exthdr(uint16_t proto) -{ - return (proto == IPPROTO_ROUTING || - proto == IPPROTO_FRAGMENT || - proto == IPPROTO_AH || - proto == IPPROTO_DSTOPTS); -} - static int print_match(const struct xt_entry_match *m, const struct ip6t_ip6 *ip, @@ -714,10 +696,21 @@ generate_entry(const struct ip6t_entry *fw, int do_command6(int argc, char *argv[], char **table, struct xtc_handle **handle, bool restore) { + struct xt_cmd_parse p = { + .table = *table, + .restore = restore, + .line = line, + .proto_parse = ipv6_proto_parse, + .post_parse = ipv6_post_parse, + }; struct iptables_command_state cs = { .jumpto = "", .argv = argv, }; + struct xtables_args args = { + .family = AF_INET6, + .wait_interval.tv_sec = 1, + }; struct ip6t_entry *e = NULL; unsigned int nsaddrs = 0, ndaddrs = 0; struct in6_addr *saddrs = NULL, *daddrs = NULL; @@ -728,437 +721,28 @@ int do_command6(int argc, char *argv[], char **table, struct timeval wait_interval = { .tv_sec = 1, }; - bool wait_interval_set = false; const char *chain = NULL; - const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; const char *policy = NULL, *newname = NULL; unsigned int rulenum = 0, command = 0; - const char *pcnt = NULL, *bcnt = NULL; int ret = 1; - struct xtables_match *m; - struct xtables_rule_match *matchp; - struct xtables_target *t; - unsigned long long cnt; - bool table_set = false; - uint16_t invflags = 0; - bool invert = false; - - /* re-set optind to 0 in case do_command6 gets called - * a second time */ - optind = 0; - - /* clear mflags in case do_command6 gets called a second time - * (we clear the global list of all matches for security)*/ - for (m = xtables_matches; m; m = m->next) - m->mflags = 0; - - for (t = xtables_targets; t; t = t->next) { - t->tflags = 0; - t->used = 0; - } - - /* Suppress error messages: we may add new options if we - demand-load a protocol. */ - opterr = 0; - - opts = xt_params->orig_opts; - while ((cs.c = getopt_long(argc, argv, - "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::W::nt:m:xc:g:46", - opts, NULL)) != -1) { - switch (cs.c) { - /* - * Command selection - */ - case 'A': - add_command(&command, CMD_APPEND, CMD_NONE, invert); - chain = optarg; - break; - - case 'C': - add_command(&command, CMD_CHECK, CMD_NONE, invert); - chain = optarg; - break; - - case 'D': - add_command(&command, CMD_DELETE, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) { - rulenum = parse_rulenumber(argv[optind++]); - command = CMD_DELETE_NUM; - } - break; - - case 'R': - add_command(&command, CMD_REPLACE, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a rule number", - cmd2char(CMD_REPLACE)); - break; - - case 'I': - add_command(&command, CMD_INSERT, CMD_NONE, invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - else rulenum = 1; - break; - - case 'L': - add_command(&command, CMD_LIST, - CMD_ZERO | CMD_ZERO_NUM, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'S': - add_command(&command, CMD_LIST_RULES, - CMD_ZERO | CMD_ZERO_NUM, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'F': - add_command(&command, CMD_FLUSH, CMD_NONE, invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - break; - - case 'Z': - add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, - invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - if (xs_has_arg(argc, argv)) { - rulenum = parse_rulenumber(argv[optind++]); - command = CMD_ZERO_NUM; - } - break; - - case 'N': - parse_chain(optarg); - add_command(&command, CMD_NEW_CHAIN, CMD_NONE, invert); - chain = optarg; - break; - - case 'X': - add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, - invert); - if (optarg) chain = optarg; - else if (xs_has_arg(argc, argv)) - chain = argv[optind++]; - break; - - case 'E': - add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, - invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - newname = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires old-chain-name and " - "new-chain-name", - cmd2char(CMD_RENAME_CHAIN)); - break; - - case 'P': - add_command(&command, CMD_SET_POLICY, CMD_NONE, - invert); - chain = optarg; - if (xs_has_arg(argc, argv)) - policy = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a chain and a policy", - cmd2char(CMD_SET_POLICY)); - break; - - case 'h': - if (!optarg) - optarg = argv[optind]; - /* ip6tables -p icmp -h */ - if (!cs.matches && cs.protocol) - xtables_find_match(cs.protocol, XTF_TRY_LOAD, - &cs.matches); - - exit_printhelp(cs.matches); - - /* - * Option selection - */ - case 'p': - set_option(&cs.options, OPT_PROTOCOL, &invflags, - invert); - - /* Canonicalize into lower case */ - for (cs.protocol = optarg; *cs.protocol; cs.protocol++) - *cs.protocol = tolower(*cs.protocol); - - cs.protocol = optarg; - cs.fw6.ipv6.proto = xtables_parse_protocol(cs.protocol); - cs.fw6.ipv6.flags |= IP6T_F_PROTO; - - if (cs.fw6.ipv6.proto == 0 && (invflags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, - "rule would never match protocol"); - - if (is_exthdr(cs.fw6.ipv6.proto) - && (invflags & XT_INV_PROTO) == 0) - fprintf(stderr, - "Warning: never matched protocol: %s. " - "use extension match instead.\n", - cs.protocol); - break; - - case 's': - set_option(&cs.options, OPT_SOURCE, &invflags, invert); - shostnetworkmask = optarg; - break; - - case 'd': - set_option(&cs.options, OPT_DESTINATION, &invflags, - invert); - dhostnetworkmask = optarg; - break; - -#ifdef IP6T_F_GOTO - case 'g': - set_option(&cs.options, OPT_JUMP, &invflags, invert); - cs.fw6.ipv6.flags |= IP6T_F_GOTO; - cs.jumpto = xt_parse_target(optarg); - break; -#endif - - case 'j': - set_option(&cs.options, OPT_JUMP, &invflags, invert); - command_jump(&cs, optarg); - break; - - - case 'i': - if (*optarg == '\0') - xtables_error(PARAMETER_PROBLEM, - "Empty interface is likely to be " - "undesired"); - set_option(&cs.options, OPT_VIANAMEIN, &invflags, - invert); - xtables_parse_interface(optarg, - cs.fw6.ipv6.iniface, - cs.fw6.ipv6.iniface_mask); - break; - - case 'o': - if (*optarg == '\0') - xtables_error(PARAMETER_PROBLEM, - "Empty interface is likely to be " - "undesired"); - set_option(&cs.options, OPT_VIANAMEOUT, &invflags, - invert); - xtables_parse_interface(optarg, - cs.fw6.ipv6.outiface, - cs.fw6.ipv6.outiface_mask); - break; - - case 'v': - if (!verbose) - set_option(&cs.options, OPT_VERBOSE, - &invflags, invert); - verbose++; - break; - - case 'w': - if (restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-w' from " - "ip6tables-restore"); - } - wait = parse_wait_time(argc, argv); - break; - - case 'W': - if (restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-W' from " - "ip6tables-restore"); - } - parse_wait_interval(argc, argv, &wait_interval); - wait_interval_set = true; - break; - - case 'm': - command_match(&cs, invert); - break; - - case 'n': - set_option(&cs.options, OPT_NUMERIC, &invflags, invert); - break; - - case 't': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "unexpected ! flag before --table"); - if (restore && table_set) - xtables_error(PARAMETER_PROBLEM, - "The -t option cannot be used in %s.\n", - xt_params->program_name); - *table = optarg; - table_set = true; - break; - - case 'x': - set_option(&cs.options, OPT_EXPANDED, &invflags, - invert); - break; - - case 'V': - if (invert) - printf("Not %s ;-)\n", prog_vers); - else - printf("%s v%s\n", - prog_name, prog_vers); - exit(0); - - case '0': - set_option(&cs.options, OPT_LINENUMBERS, &invflags, - invert); - break; - - case 'M': - xtables_modprobe_program = optarg; - break; - - case 'c': - - set_option(&cs.options, OPT_COUNTERS, &invflags, - invert); - pcnt = optarg; - bcnt = strchr(pcnt + 1, ','); - if (bcnt) - bcnt++; - if (!bcnt && xs_has_arg(argc, argv)) - bcnt = argv[optind++]; - if (!bcnt) - xtables_error(PARAMETER_PROBLEM, - "-%c requires packet and byte counter", - opt2char(OPT_COUNTERS)); - - if (sscanf(pcnt, "%llu", &cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c packet counter not numeric", - opt2char(OPT_COUNTERS)); - cs.fw6.counters.pcnt = cnt; - - if (sscanf(bcnt, "%llu", &cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c byte counter not numeric", - opt2char(OPT_COUNTERS)); - cs.fw6.counters.bcnt = cnt; - break; - - case '4': - /* This is not the IPv4 iptables */ - if (line != -1) - return 1; /* success: line ignored */ - fprintf(stderr, "This is the IPv6 version of ip6tables.\n"); - exit_tryhelp(2, line); - - case '6': - /* This is indeed the IPv6 ip6tables */ - break; - - case 1: /* non option */ - if (optarg[0] == '!' && optarg[1] == '\0') { - if (invert) - xtables_error(PARAMETER_PROBLEM, - "multiple consecutive ! not" - " allowed"); - invert = true; - optarg[0] = '\0'; - continue; - } - fprintf(stderr, "Bad argument `%s'\n", optarg); - exit_tryhelp(2, line); - - default: - if (command_default(&cs, &ip6tables_globals, invert)) - /* - * If new options were loaded, we must retry - * getopt immediately and not allow - * invert=false to be executed. - */ - continue; - break; - } - invert = false; - } - - if (!wait && wait_interval_set) - xtables_error(PARAMETER_PROBLEM, - "--wait-interval only makes sense with --wait\n"); - - if (strcmp(*table, "nat") == 0 && - ((policy != NULL && strcmp(policy, "DROP") == 0) || - (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0))) - xtables_error(PARAMETER_PROBLEM, - "\nThe \"nat\" table is not intended for filtering, " - "the use of DROP is therefore inhibited.\n\n"); - - for (matchp = cs.matches; matchp; matchp = matchp->next) - xtables_option_mfcall(matchp->match); - if (cs.target != NULL) - xtables_option_tfcall(cs.target); - - /* Fix me: must put inverse options checking here --MN */ - - if (optind < argc) - xtables_error(PARAMETER_PROBLEM, - "unknown arguments found on commandline"); - if (!command) - xtables_error(PARAMETER_PROBLEM, "no command specified"); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "nothing appropriate following !"); - - cs.fw6.ipv6.invflags = invflags; - - if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) { - if (!(cs.options & OPT_DESTINATION)) - dhostnetworkmask = "::0/0"; - if (!(cs.options & OPT_SOURCE)) - shostnetworkmask = "::0/0"; - } - - if (shostnetworkmask) - xtables_ip6parse_multiple(shostnetworkmask, &saddrs, - &smasks, &nsaddrs); - - if (dhostnetworkmask) - xtables_ip6parse_multiple(dhostnetworkmask, &daddrs, - &dmasks, &ndaddrs); - - if ((nsaddrs > 1 || ndaddrs > 1) && - (cs.fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP))) - xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple" - " source or destination IP addresses"); - - if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1)) - xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " - "specify a unique address"); - - generic_opt_check(command, cs.options); + do_parse(argc, argv, &p, &cs, &args); + + command = p.command; + chain = p.chain; + *table = p.table; + rulenum = p.rulenum; + policy = p.policy; + newname = p.newname; + verbose = p.verbose; + wait = args.wait; + wait_interval = args.wait_interval; + nsaddrs = args.s.naddrs; + ndaddrs = args.d.naddrs; + saddrs = args.s.addr.v6; + daddrs = args.d.addr.v6; + smasks = args.s.mask.v6; + dmasks = args.d.mask.v6; /* Attempt to acquire the xtables lock */ if (!restore) @@ -1182,26 +766,6 @@ int do_command6(int argc, char *argv[], char **table, || command == CMD_CHECK || command == CMD_INSERT || command == CMD_REPLACE) { - if (strcmp(chain, "PREROUTING") == 0 - || strcmp(chain, "INPUT") == 0) { - /* -o not valid with incoming packets. */ - if (cs.options & OPT_VIANAMEOUT) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEOUT), - chain); - } - - if (strcmp(chain, "POSTROUTING") == 0 - || strcmp(chain, "OUTPUT") == 0) { - /* -i not valid with outgoing packets */ - if (cs.options & OPT_VIANAMEIN) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEIN), - chain); - } - if (cs.target && ip6tc_is_chain(cs.jumpto, *handle)) { fprintf(stderr, "Warning: using chain %s, not extension\n", @@ -1337,6 +901,9 @@ int do_command6(int argc, char *argv[], char **table, case CMD_SET_POLICY: ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw6.counters : NULL, *handle); break; + case CMD_NONE: + /* do_parse ignored the line (eg: -4 with ip6tables-restore) */ + break; default: /* We should never reach this... */ exit_tryhelp(2, line); diff --git a/iptables/xshared.c b/iptables/xshared.c index 1bce6715c3a9a..3b363e72361e0 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1836,6 +1836,10 @@ void ipv6_proto_parse(struct iptables_command_state *cs, cs->fw6.ipv6.proto = args->proto; cs->fw6.ipv6.invflags = args->invflags; + /* this is needed for ip6tables-legacy only */ + args->flags |= IP6T_F_PROTO; + cs->fw6.ipv6.flags |= IP6T_F_PROTO; + if (is_exthdr(cs->fw6.ipv6.proto) && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0) fprintf(stderr,