From patchwork Mon May 28 19:27:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 921670 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netfilter.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vn1w56y0z9s2k for ; Tue, 29 May 2018 05:27:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933498AbeE1T1q (ORCPT ); Mon, 28 May 2018 15:27:46 -0400 Received: from mail.us.es ([193.147.175.20]:59190 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933098AbeE1T1p (ORCPT ); Mon, 28 May 2018 15:27:45 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id F3F88114814 for ; Mon, 28 May 2018 21:27:12 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 0646CDA727 for ; Mon, 28 May 2018 21:26:37 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id EFEA1DA792; Mon, 28 May 2018 21:26:36 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on antivirus1-rhel7.int X-Spam-Level: X-Spam-Status: No, score=-108.2 required=7.5 tests=ALL_TRUSTED,BAYES_50, SMTPAUTH_US2,USER_IN_WHITELIST autolearn=disabled version=3.4.1 Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id CB7A1DA727 for ; Mon, 28 May 2018 21:26:34 +0200 (CEST) Received: from 192.168.1.97 (192.168.1.97) by antivirus1-rhel7.int (F-Secure/fsigk_smtp/550/antivirus1-rhel7.int); Mon, 28 May 2018 21:26:34 +0200 (CEST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int) Received: from salvia.here (sys.soleta.eu [212.170.55.40]) (Authenticated sender: pneira@us.es) by entrada.int (Postfix) with ESMTPA id AB4C14082CA0 for ; Mon, 28 May 2018 21:26:34 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH xtables 1/4] xtables: always initialize basechains on ruleset restore Date: Mon, 28 May 2018 21:27:36 +0200 Message-Id: <20180528192739.10414-1-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 X-Virus-Scanned: ClamAV using ClamSMTP Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org We cannot assume iptables-restore files always come with explicit basechain definition, eg. :PREROUTING ACCEPT incremental ruleset updates may deliberately skip this. Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 37aa0b2ee8c5..a04aa350a074 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -2551,9 +2551,6 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, uint32_t table_family, chain_family; bool found = false; - if (h->restore) - return 0; - table_list = nftnl_table_list_alloc(); chain_list = nftnl_chain_list_alloc(); From patchwork Mon May 28 19:27:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 921671 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netfilter.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vn1y2TnFz9s31 for ; Tue, 29 May 2018 05:27:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933514AbeE1T1s (ORCPT ); Mon, 28 May 2018 15:27:48 -0400 Received: from mail.us.es ([193.147.175.20]:59192 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933506AbeE1T1r (ORCPT ); Mon, 28 May 2018 15:27:47 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 2209A114815 for ; Mon, 28 May 2018 21:27:14 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 22E93DA80C for ; Mon, 28 May 2018 21:26:38 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id 18757DA7F1; Mon, 28 May 2018 21:26:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on antivirus1-rhel7.int X-Spam-Level: X-Spam-Status: No, score=-108.2 required=7.5 tests=ALL_TRUSTED,BAYES_50, SMTPAUTH_US2,USER_IN_WHITELIST autolearn=disabled version=3.4.1 Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id C9C94DA782 for ; Mon, 28 May 2018 21:26:35 +0200 (CEST) Received: from 192.168.1.97 (192.168.1.97) by antivirus1-rhel7.int (F-Secure/fsigk_smtp/550/antivirus1-rhel7.int); Mon, 28 May 2018 21:26:35 +0200 (CEST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int) Received: from salvia.here (sys.soleta.eu [212.170.55.40]) (Authenticated sender: pneira@us.es) by entrada.int (Postfix) with ESMTPA id AE9614082CA0 for ; Mon, 28 May 2018 21:26:35 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH xtables 2/4] xtables: add chain cache Date: Mon, 28 May 2018 21:27:37 +0200 Message-Id: <20180528192739.10414-2-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528192739.10414-1-pablo@netfilter.org> References: <20180528192739.10414-1-pablo@netfilter.org> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org So we don't have to dump the chain cache content over and over again. Moreover, perform incremental updates on the chain cache to add and to delete non-base chains. Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 82 ++++++++++++++++++++++++++++------------------ iptables/nft.h | 3 +- iptables/xtables-restore.c | 5 +-- iptables/xtables-save.c | 2 +- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index a04aa350a074..07801f973176 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -604,7 +604,7 @@ static void nft_chain_builtin_init(struct nft_handle *h, struct builtin_table *table) { int i; - struct nftnl_chain_list *list = nft_chain_dump(h, NULL); + struct nftnl_chain_list *list = nft_chain_dump(h); struct nftnl_chain *c; /* Initialize built-in chains if they don't exist yet */ @@ -617,8 +617,6 @@ static void nft_chain_builtin_init(struct nft_handle *h, nft_chain_builtin_add(h, table, &table->chains[i]); } - - nftnl_chain_list_free(list); } static int nft_xt_builtin_init(struct nft_handle *h, const char *table) @@ -694,8 +692,35 @@ static void flush_rule_cache(struct nft_handle *h) h->rule_cache = NULL; } +static int __flush_chain_cache(struct nftnl_chain *c, void *data) +{ + const char *tablename = data; + + if (!strcmp(nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), tablename)) { + nftnl_chain_list_del(c); + nftnl_chain_free(c); + } + + return 0; +} + +static void flush_chain_cache(struct nft_handle *h, const char *tablename) +{ + if (!h->chain_cache) + return; + + if (tablename) { + nftnl_chain_list_foreach(h->chain_cache, __flush_chain_cache, + (void *)tablename); + } else { + nftnl_chain_list_free(h->chain_cache); + h->chain_cache = NULL; + } +} + void nft_fini(struct nft_handle *h) { + flush_chain_cache(h, NULL); flush_rule_cache(h); mnl_socket_close(h->nl); } @@ -1093,14 +1118,15 @@ err: return MNL_CB_OK; } -static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h, - const char *tablename) +static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h) { char buf[16536]; struct nlmsghdr *nlh; struct nftnl_chain_list *list; int ret; + if (h->chain_cache) + return h->chain_cache; retry: list = nftnl_chain_list_alloc(); if (list == NULL) { @@ -1110,15 +1136,6 @@ retry: nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, NLM_F_DUMP, h->seq); - if (tablename) { - struct nftnl_chain *t = nftnl_chain_alloc(); - - if (t) { - nftnl_chain_set(t, NFTNL_CHAIN_TABLE, tablename); - nftnl_chain_nlmsg_build_payload(nlh, t); - nftnl_chain_free(t); - } - } ret = mnl_talk(h, nlh, nftnl_chain_list_cb, list); if (ret < 0 && errno == EINTR) { @@ -1127,12 +1144,14 @@ retry: goto retry; } + h->chain_cache = list; + return list; } -struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h, const char *tablename) +struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h) { - return nftnl_chain_list_get(h, tablename); + return nftnl_chain_list_get(h); } static const char *policy_name[NF_ACCEPT+1] = { @@ -1186,7 +1205,6 @@ next: } nftnl_chain_list_iter_destroy(iter); - nftnl_chain_list_free(list); return 1; } @@ -1359,7 +1377,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) nft_fn = nft_rule_flush; - list = nftnl_chain_list_get(h, table); + list = nftnl_chain_list_get(h); if (list == NULL) { ret = 0; goto err; @@ -1393,8 +1411,6 @@ next: nftnl_chain_list_iter_destroy(iter); flush_rule_cache(h); err: - nftnl_chain_list_free(list); - /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; } @@ -1419,6 +1435,10 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); + nft_chain_dump(h); + + nftnl_chain_list_add(c, h->chain_cache); + /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; } @@ -1438,7 +1458,7 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl nft_fn = nft_chain_user_del; - list = nftnl_chain_list_get(h, table); + list = nftnl_chain_list_get(h); if (list == NULL) goto err; @@ -1469,6 +1489,7 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl break; deleted_ctr++; + nftnl_chain_list_del(c); if (chain != NULL) break; @@ -1527,7 +1548,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain) { struct nftnl_chain_list *list; - list = nftnl_chain_list_get(h, table); + list = nftnl_chain_list_get(h); if (list == NULL) return NULL; @@ -1693,6 +1714,8 @@ static int __nft_table_flush(struct nft_handle *h, const char *table) batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, t); + flush_chain_cache(h, table); + return 0; } @@ -2064,7 +2087,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, return 1; } - list = nft_chain_dump(h, table); + list = nft_chain_dump(h); iter = nftnl_chain_list_iter_create(list); if (iter == NULL) @@ -2118,8 +2141,6 @@ next: nftnl_chain_list_iter_destroy(iter); err: - nftnl_chain_list_free(list); - return 1; } @@ -2188,7 +2209,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, struct nftnl_chain *c; int ret = 1; - list = nft_chain_dump(h, table); + list = nft_chain_dump(h); /* Dump policies and custom chains first */ if (!rulenum) @@ -2223,8 +2244,6 @@ next: nftnl_chain_list_iter_destroy(iter); err: - nftnl_chain_list_free(list); - return ret; } @@ -2285,7 +2304,6 @@ static void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type, type, h->family, flags, seq); nftnl_chain_nlmsg_build_payload(nlh, chain); nft_chain_print_debug(chain, nlh); - nftnl_chain_free(chain); } static void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type, @@ -2654,7 +2672,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, struct nftnl_chain *c; int ret = 0; - list = nftnl_chain_list_get(h, table); + list = nftnl_chain_list_get(h); if (list == NULL) goto err; @@ -2799,7 +2817,7 @@ static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename struct nftnl_chain *chain; int ret = 0; - list = nftnl_chain_list_get(h, tablename); + list = nftnl_chain_list_get(h); if (list == NULL) return -1; @@ -2820,7 +2838,7 @@ next: } nftnl_chain_list_iter_destroy(iter); - nftnl_chain_list_free(list); + return ret; } diff --git a/iptables/nft.h b/iptables/nft.h index 515832d7e37b..7a775a8db7a2 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -36,6 +36,7 @@ struct nft_handle { struct list_head err_list; struct nft_family_ops *ops; struct builtin_table *tables; + struct nftnl_chain_list *chain_cache; struct nftnl_rule_list *rule_cache; bool restore; }; @@ -67,7 +68,7 @@ int nft_table_flush(struct nft_handle *h, const char *table); struct nftnl_chain; int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters); -struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h, const char *table); +struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h); struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain); int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table); int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table); diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index d977dabfae50..db199218027b 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -169,7 +169,7 @@ static struct nftnl_chain_list *get_chain_list(struct nft_handle *h) { struct nftnl_chain_list *chain_list; - chain_list = nft_chain_dump(h, NULL); + chain_list = nft_chain_dump(h); if (chain_list == NULL) xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n"); @@ -447,9 +447,6 @@ void xtables_restore_parse(struct nft_handle *h, xt_params->program_name, line + 1); exit(1); } - - if (chain_list) - nftnl_chain_list_free(chain_list); } static int diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index be98b8350aaa..8bcc31fd9d48 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -57,7 +57,7 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) return 0; } - chain_list = nft_chain_dump(h, tablename); + chain_list = nft_chain_dump(h); time_t now = time(NULL); From patchwork Mon May 28 19:27:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 921672 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netfilter.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vn1z2JsNz9s3D for ; Tue, 29 May 2018 05:27:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933517AbeE1T1t (ORCPT ); Mon, 28 May 2018 15:27:49 -0400 Received: from mail.us.es ([193.147.175.20]:59194 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933511AbeE1T1r (ORCPT ); Mon, 28 May 2018 15:27:47 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id C80D9114814 for ; Mon, 28 May 2018 21:27:14 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id C9679DA80C for ; Mon, 28 May 2018 21:26:38 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id BEDC5DA7F1; Mon, 28 May 2018 21:26:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on antivirus1-rhel7.int X-Spam-Level: X-Spam-Status: No, score=-108.2 required=7.5 tests=ALL_TRUSTED,BAYES_50, SMTPAUTH_US2,USER_IN_WHITELIST autolearn=disabled version=3.4.1 Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id A0755DA786 for ; Mon, 28 May 2018 21:26:36 +0200 (CEST) Received: from 192.168.1.97 (192.168.1.97) by antivirus1-rhel7.int (F-Secure/fsigk_smtp/550/antivirus1-rhel7.int); Mon, 28 May 2018 21:26:36 +0200 (CEST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int) Received: from salvia.here (sys.soleta.eu [212.170.55.40]) (Authenticated sender: pneira@us.es) by entrada.int (Postfix) with ESMTPA id 832A34082CA0 for ; Mon, 28 May 2018 21:26:36 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH xtables 3/4] xtables: rework rule cache logic Date: Mon, 28 May 2018 21:27:38 +0200 Message-Id: <20180528192739.10414-3-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528192739.10414-1-pablo@netfilter.org> References: <20180528192739.10414-1-pablo@netfilter.org> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Perform incremental tracking on rule cache updates, instead of flushing and resynchronizing with the kernel over and over again. Note that there is no need to call flush_rule_cache() from nft_rule_delete() and nft_rule_delete_num(), since __nft_rule_del() already deletes the rule from the list. Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 81 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 07801f973176..3cfd23c7cdab 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -683,13 +683,30 @@ int nft_init(struct nft_handle *h, struct builtin_table *t) return 0; } -static void flush_rule_cache(struct nft_handle *h) +static int __flush_rule_cache(struct nftnl_rule *r, void *data) +{ + const char *tablename = data; + + if (!strcmp(nftnl_rule_get_str(r, NFTNL_RULE_TABLE), tablename)) { + nftnl_rule_list_del(r); + nftnl_rule_free(r); + } + + return 0; +} + +static void flush_rule_cache(struct nft_handle *h, const char *tablename) { if (!h->rule_cache) return; - nftnl_rule_list_free(h->rule_cache); - h->rule_cache = NULL; + if (tablename) { + nftnl_rule_list_foreach(h->rule_cache, __flush_rule_cache, + (void *)tablename); + } else { + nftnl_rule_list_free(h->rule_cache); + h->rule_cache = NULL; + } } static int __flush_chain_cache(struct nftnl_chain *c, void *data) @@ -721,7 +738,7 @@ static void flush_chain_cache(struct nft_handle *h, const char *tablename) void nft_fini(struct nft_handle *h) { flush_chain_cache(h, NULL); - flush_rule_cache(h); + flush_rule_cache(h, NULL); mnl_socket_close(h->nl); } @@ -1038,6 +1055,8 @@ err: return NULL; } +static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h); + int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose) @@ -1064,7 +1083,10 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, if (batch_rule_add(h, type, r) < 0) nftnl_rule_free(r); - flush_rule_cache(h); + nft_rule_list_get(h); + + nftnl_rule_list_add_tail(r, h->rule_cache); + return 1; } @@ -1407,9 +1429,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) next: c = nftnl_chain_list_iter_next(iter); } + flush_rule_cache(h, table); nftnl_chain_list_iter_destroy(iter); - flush_rule_cache(h); err: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; @@ -1715,6 +1737,7 @@ static int __nft_table_flush(struct nft_handle *h, const char *table) batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, t); flush_chain_cache(h, table); + flush_rule_cache(h, table); return 0; } @@ -1755,6 +1778,10 @@ next: t = nftnl_table_list_iter_next(iter); } + h->rule_cache = nftnl_rule_list_alloc(); + if (h->rule_cache == NULL) + return -1; + err_table_iter: nftnl_table_list_iter_destroy(iter); err_table_list: @@ -1866,12 +1893,10 @@ int nft_rule_delete(struct nft_handle *h, const char *chain, } else errno = ENOENT; - flush_rule_cache(h); - return ret; } -static int +static struct nftnl_rule * nft_rule_add(struct nft_handle *h, const char *chain, const char *table, struct iptables_command_state *cs, uint64_t handle, bool verbose) @@ -1880,25 +1905,24 @@ nft_rule_add(struct nft_handle *h, const char *chain, r = nft_rule_new(h, chain, table, cs); if (r == NULL) - return 0; + return NULL; if (handle > 0) nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle); if (batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r) < 0) { nftnl_rule_free(r); - return 0; + return NULL; } - flush_rule_cache(h); - return 1; + return r; } int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose) { + struct nftnl_rule *r, *new_rule; struct nftnl_rule_list *list; - struct nftnl_rule *r; uint64_t handle = 0; /* If built-in chains don't exist for this table, create them */ @@ -1919,11 +1943,9 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, */ r = nft_rule_find(h, list, chain, table, data, rulenum - 1); - if (r != NULL) { - flush_rule_cache(h); + if (r != NULL) return nft_rule_append(h, chain, table, data, 0, verbose); - } errno = ENOENT; goto err; @@ -1931,13 +1953,21 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE); DEBUGP("adding after rule handle %"PRIu64"\n", handle); - - flush_rule_cache(h); + } else { + nft_rule_list_get(h); } - return nft_rule_add(h, chain, table, data, handle, verbose); + new_rule = nft_rule_add(h, chain, table, data, handle, verbose); + if (!new_rule) + goto err; + + if (handle) + nftnl_rule_list_insert_at(new_rule, r); + else + nftnl_rule_list_add(new_rule, h->rule_cache); + + return 1; err: - flush_rule_cache(h); return 0; } @@ -1965,8 +1995,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, } else errno = ENOENT; - flush_rule_cache(h); - return ret; } @@ -1989,14 +2017,14 @@ int nft_rule_replace(struct nft_handle *h, const char *chain, (unsigned long long) nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE)); + nftnl_rule_list_del(r); + ret = nft_rule_append(h, chain, table, data, nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE), verbose); } else errno = ENOENT; - flush_rule_cache(h); - return ret; } @@ -2277,8 +2305,6 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, false); error: - flush_rule_cache(h); - return ret; } @@ -2316,7 +2342,6 @@ static void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type, type, h->family, flags, seq); nftnl_rule_nlmsg_build_payload(nlh, rule); nft_rule_print_debug(rule, nlh); - nftnl_rule_free(rule); } static int nft_action(struct nft_handle *h, int action) From patchwork Mon May 28 19:27:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 921673 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netfilter.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40vn201cR4z9s1p for ; Tue, 29 May 2018 05:27:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933522AbeE1T1v (ORCPT ); Mon, 28 May 2018 15:27:51 -0400 Received: from mail.us.es ([193.147.175.20]:59202 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933098AbeE1T1r (ORCPT ); Mon, 28 May 2018 15:27:47 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 2440111481A for ; Mon, 28 May 2018 21:27:15 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 2AE51DA817 for ; Mon, 28 May 2018 21:26:39 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id 205D3DA814; Mon, 28 May 2018 21:26:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on antivirus1-rhel7.int X-Spam-Level: X-Spam-Status: No, score=-108.2 required=7.5 tests=ALL_TRUSTED,BAYES_50, SMTPAUTH_US2,USER_IN_WHITELIST autolearn=disabled version=3.4.1 Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 320F1DA727 for ; Mon, 28 May 2018 21:26:37 +0200 (CEST) Received: from 192.168.1.97 (192.168.1.97) by antivirus1-rhel7.int (F-Secure/fsigk_smtp/550/antivirus1-rhel7.int); Mon, 28 May 2018 21:26:37 +0200 (CEST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int) Received: from salvia.here (sys.soleta.eu [212.170.55.40]) (Authenticated sender: pneira@us.es) by entrada.int (Postfix) with ESMTPA id 123F84082CA0 for ; Mon, 28 May 2018 21:26:37 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH xtables 4/4] xtables: initialize basechains for rule flush command too Date: Mon, 28 May 2018 21:27:39 +0200 Message-Id: <20180528192739.10414-4-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528192739.10414-1-pablo@netfilter.org> References: <20180528192739.10414-1-pablo@netfilter.org> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Otherwise, flush commands on not-yet-initialized basechains hit ENOENT. Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iptables/nft.c b/iptables/nft.c index 3cfd23c7cdab..851073fb4a44 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1397,6 +1397,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) struct nftnl_chain_list_iter *iter; struct nftnl_chain *c; + if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) + nft_xt_builtin_init(h, table); + nft_fn = nft_rule_flush; list = nftnl_chain_list_get(h);