From patchwork Mon May 28 21:21:00 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: 921699 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 40vqXn1xVMz9s16 for ; Tue, 29 May 2018 07:21:12 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934145AbeE1VVL (ORCPT ); Mon, 28 May 2018 17:21:11 -0400 Received: from mail.us.es ([193.147.175.20]:55610 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934139AbeE1VVL (ORCPT ); Mon, 28 May 2018 17:21:11 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 663C4114817 for ; Mon, 28 May 2018 23:20:02 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 534D9DA729 for ; Mon, 28 May 2018 23:20:02 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id 489FADA7E9; Mon, 28 May 2018 23:20:02 +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 560FEDA737 for ; Mon, 28 May 2018 23:20:00 +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 23:20:00 +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 365B24265A4E for ; Mon, 28 May 2018 23:20:00 +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 23:21:00 +0200 Message-Id: <20180528212104.8431-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 21:21:02 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: 921701 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 40vqXr5wy6z9s16 for ; Tue, 29 May 2018 07:21:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934150AbeE1VVP (ORCPT ); Mon, 28 May 2018 17:21:15 -0400 Received: from mail.us.es ([193.147.175.20]:55616 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934139AbeE1VVN (ORCPT ); Mon, 28 May 2018 17:21:13 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 43241114817 for ; Mon, 28 May 2018 23:20:04 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 2A829DA729 for ; Mon, 28 May 2018 23:20:04 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id 1FC3BDA727; Mon, 28 May 2018 23:20:04 +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 E068DDA73F for ; Mon, 28 May 2018 23:20:01 +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 23:20:01 +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 C52A44265A4E for ; Mon, 28 May 2018 23:20:01 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH v2,xtables 2/4] xtables: add chain cache Date: Mon, 28 May 2018 23:21:02 +0200 Message-Id: <20180528212104.8431-3-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528212104.8431-1-pablo@netfilter.org> References: <20180528212104.8431-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 --- v2: no changes. 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 ba98230f1006..6940b30dedf1 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -601,7 +601,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 */ @@ -614,8 +614,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) @@ -692,8 +690,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); } @@ -1091,14 +1116,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) { @@ -1108,15 +1134,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) { @@ -1125,12 +1142,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] = { @@ -1184,7 +1203,6 @@ next: } nftnl_chain_list_iter_destroy(iter); - nftnl_chain_list_free(list); return 1; } @@ -1357,7 +1375,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; @@ -1391,8 +1409,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; } @@ -1417,6 +1433,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; } @@ -1436,7 +1456,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; @@ -1467,6 +1487,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; @@ -1525,7 +1546,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; @@ -1691,6 +1712,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; } @@ -2062,7 +2085,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) @@ -2116,8 +2139,6 @@ next: nftnl_chain_list_iter_destroy(iter); err: - nftnl_chain_list_free(list); - return 1; } @@ -2186,7 +2207,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) @@ -2221,8 +2242,6 @@ next: nftnl_chain_list_iter_destroy(iter); err: - nftnl_chain_list_free(list); - return ret; } @@ -2283,7 +2302,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, @@ -2665,7 +2683,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; @@ -2810,7 +2828,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; @@ -2831,7 +2849,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 d4a78b088940..e6a7636387dc 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; int8_t config_done; @@ -68,7 +69,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 21:21:03 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: 921702 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 40vqXx0xpKz9s16 for ; Tue, 29 May 2018 07:21:21 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934153AbeE1VVT (ORCPT ); Mon, 28 May 2018 17:21:19 -0400 Received: from mail.us.es ([193.147.175.20]:55654 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934139AbeE1VVS (ORCPT ); Mon, 28 May 2018 17:21:18 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id E08FB114817 for ; Mon, 28 May 2018 23:20:09 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id C8255DA727 for ; Mon, 28 May 2018 23:20:09 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id BD5DFDA840; Mon, 28 May 2018 23:20:09 +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 972B1DA727 for ; Mon, 28 May 2018 23:20:07 +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 23:20:07 +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 F10F44082CA0 for ; Mon, 28 May 2018 23:20:02 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH v2,xtables 3/4] xtables: rework rule cache logic Date: Mon, 28 May 2018 23:21:03 +0200 Message-Id: <20180528212104.8431-4-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528212104.8431-1-pablo@netfilter.org> References: <20180528212104.8431-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 --- v2: set built-in table initialization to false on *tablename. iptables/nft.c | 87 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 6940b30dedf1..03a9f29df0ee 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -681,13 +681,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) @@ -719,7 +736,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); } @@ -1036,6 +1053,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) @@ -1062,7 +1081,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; } @@ -1405,9 +1427,8 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) next: c = nftnl_chain_list_iter_next(iter); } - nftnl_chain_list_iter_destroy(iter); - flush_rule_cache(h); + flush_rule_cache(h, table); err: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; @@ -1702,6 +1723,7 @@ int nft_for_each_table(struct nft_handle *h, static int __nft_table_flush(struct nft_handle *h, const char *table) { + struct builtin_table *_t; struct nftnl_table *t; t = nftnl_table_alloc(); @@ -1712,7 +1734,12 @@ static int __nft_table_flush(struct nft_handle *h, const char *table) batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, t); + _t = nft_table_builtin_find(h, table); + assert(t); + _t->initialized = false; + flush_chain_cache(h, table); + flush_rule_cache(h, table); return 0; } @@ -1753,6 +1780,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: @@ -1864,12 +1895,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) @@ -1878,25 +1907,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 */ @@ -1917,11 +1945,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; @@ -1929,13 +1955,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; } @@ -1963,8 +1997,6 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, } else errno = ENOENT; - flush_rule_cache(h); - return ret; } @@ -1987,14 +2019,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; } @@ -2275,8 +2307,6 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, false); error: - flush_rule_cache(h); - return ret; } @@ -2314,7 +2344,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 21:21:04 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: 921703 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 40vqY914Sbz9s16 for ; Tue, 29 May 2018 07:21:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934185AbeE1VVZ (ORCPT ); Mon, 28 May 2018 17:21:25 -0400 Received: from mail.us.es ([193.147.175.20]:55740 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934166AbeE1VVW (ORCPT ); Mon, 28 May 2018 17:21:22 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 2E25A114817 for ; Mon, 28 May 2018 23:20:14 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 1C0F5DA729 for ; Mon, 28 May 2018 23:20:14 +0200 (CEST) Received: by antivirus1-rhel7.int (Postfix, from userid 99) id 11625DA727; Mon, 28 May 2018 23:20:14 +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 16111DA7B9 for ; Mon, 28 May 2018 23:20:12 +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 23:20:12 +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 ECA7C4265A4E for ; Mon, 28 May 2018 23:20:11 +0200 (CEST) X-SMTPAUTHUS: auth mail.us.es From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH v2, xtables 4/4] xtables: initialize basechains for rule flush command too Date: Mon, 28 May 2018 23:21:04 +0200 Message-Id: <20180528212104.8431-5-pablo@netfilter.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180528212104.8431-1-pablo@netfilter.org> References: <20180528212104.8431-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 --- v2: no changes. iptables/nft.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iptables/nft.c b/iptables/nft.c index 03a9f29df0ee..ec9dd13b4031 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1395,6 +1395,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);