From patchwork Thu Sep 6 14:26:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 967033 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 425jZB36y5z9rxp for ; Fri, 7 Sep 2018 00:26:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729978AbeIFTCo (ORCPT ); Thu, 6 Sep 2018 15:02:44 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:33256 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729073AbeIFTCo (ORCPT ); Thu, 6 Sep 2018 15:02:44 -0400 Received: from localhost ([::1]:40790 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fxvFH-0006pu-A4; Thu, 06 Sep 2018 16:26:55 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [iptables PATCH] xtables-restore: Fix flushing referenced custom chains Date: Thu, 6 Sep 2018 16:26:45 +0200 Message-Id: <20180906142645.1869-1-phil@nwl.cc> X-Mailer: git-send-email 2.18.0 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The logic to replicate 'iptables-restore --noflush' behaviour of flushing custom chains if listed in the dump was broken for chains being referenced. A minimal dump reproducing the issue is: | *filter | :foobar - [0:0] | -I INPUT -j foobar | -A foobar -j ACCEPT | COMMIT With --noflush, this can be restored just once in iptables-nft-restore. Consecutive attempts return an error since xtables tries to delete the referenced chain and recreate it instead of performing a real flush. Fix this by really flushing the custom chain in 'chain_user_flush' callback and calling 'chain_user_add' callback only if 'noflush' is not set. Fixes: df3d92bec6007 ("xtables-compat-restore: flush user-defined chains with -n") Signed-off-by: Phil Sutter --- iptables/nft.c | 10 ++-------- iptables/xtables-restore.c | 3 ++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 7123060b34ef5..77ad38bea5211 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1491,7 +1491,6 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data) struct nft_handle *h = d->handle; const char *table = d->table; const char *chain = d->chain; - int ret; if (strcmp(table, table_name) != 0) return 0; @@ -1499,13 +1498,8 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data) if (strcmp(chain, chain_name) != 0) return 0; - if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_FLUSH, c); - if (ret < 0) - return ret; - - nftnl_chain_list_del(c); - } + if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) + __nft_rule_flush(h, table, chain); return 0; } diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 3274543677329..5e22e74bb190f 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -246,7 +246,8 @@ void xtables_restore_parse(struct nft_handle *h, ret = 1; } else { - if (cb->chain_user_add && + if (noflush == 0 && + cb->chain_user_add && cb->chain_user_add(h, chain, curtable->name) < 0) { if (errno == EEXIST)