From patchwork Thu Mar 6 15:34:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 14004713 X-Patchwork-Delegate: kuba@kernel.org Received: from mail.netfilter.org (mail.netfilter.org [217.70.190.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 87DE71990D9; Thu, 6 Mar 2025 15:34:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.190.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275302; cv=none; b=D+LqyqOptIpcL+oG/r3A35EWK331ORacSOhbO+eg5+WgpmzClc7cP29NbAVkEVw/5vrA3yRsNo9/DsJhrLjCYDQ2RWHP5bcGypZJEFRUMFtkbpl6PeVV8nlCvWN7rzdap11sVH1sb/P/tCJ9wV5g5/Po5vQKYAMk72aW+7Ac5tY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275302; c=relaxed/simple; bh=vpy/1a0310/A6O1uLdZCzoCsT6lCRgdx6V5eVdwIgV4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gdtF9R6SWsJOUjsuNvR3q6sDFz01wHFPfphQr4AHB8jY99XWvH8Ge8oFqGNC2iZ51XJehYTFhMcPafpDU/enPyINy2vUkZ+3lZFfsS76Lf2yz4mQh8fJvNQ6HSutZAbEH+BI+vVIGPdixpEJ5KVBlhslqWZHDnEGlRYHQ+M+YLc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org; spf=pass smtp.mailfrom=netfilter.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=uGb8HMU6; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=tf0YzabV; arc=none smtp.client-ip=217.70.190.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=netfilter.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="uGb8HMU6"; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="tf0YzabV" Received: by mail.netfilter.org (Postfix, from userid 109) id 002C760308; Thu, 6 Mar 2025 16:34:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275294; bh=mkon9fs8xRiDE8tH3lMwSu4uXP3e+5V3rBY5SY2y3MA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uGb8HMU6nujod37W1e0HX3vaPb3rWfygpCXXDOHhqJclAo4WG9quilzMarqf08zgp 4ILITLtfDZU6nmrKCX//T0ETdBgTvjKC7rIC6lvhfTN0RxIQsjW8nIjUQKJtktyYEQ IzggAdExTdFVfzC3o7t82sIAKDT0upg2yHjtPkvKqtLsuhA35hq1EsaCi46EFVJEvs wLdH8esL+CLtkPCzfOOU97JNGXi7+WVmD3V4d8j34F/l4HHitkeIvT6oQntNNEE/so mC7ZwHh7+KI/TwiEEibl6OddCIotf2wFtT1BnPKCDSkgDc7qLxqd/W+Pl+m9sUju1y Svm5K1EtLmG5A== X-Spam-Level: Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id 186E960306; Thu, 6 Mar 2025 16:34:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275292; bh=mkon9fs8xRiDE8tH3lMwSu4uXP3e+5V3rBY5SY2y3MA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tf0YzabVdE4fScL4S/sPpwfNhWNULcF2izUhQxWwd+Go3hEoCEthYfJv9pSPtdXKH yn01icir5Hu6BNk2Q+oT9H6ofqU7i1PmS7hpVCy5VI1TL5xGcRNVcI+7ApZWTFHH0f KZ0RbH2PLwprSxk19qyvMPswNzbJJK/bhbXOQM6NLBDSqZGW1lMnGvaev1yQ1P2ihk ECYeYSeoVj5VH6/R3y6ZNeYnB35TryUl+KhI4+BYf6yHwS5gM5/AyVuLfykUc4AJ19 jr1/53/Av6dbQ8nNKkfRCdh0b4+mAGlyyHTNCdI6sdEExZyK24YkuvrgTVpxLXI5aS 6uJHieKqzNUow== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org, pabeni@redhat.com, edumazet@google.com, fw@strlen.de, horms@kernel.org Subject: [PATCH net 1/3] netfilter: nft_ct: Use __refcount_inc() for per-CPU nft_ct_pcpu_template. Date: Thu, 6 Mar 2025 16:34:44 +0100 Message-Id: <20250306153446.46712-2-pablo@netfilter.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20250306153446.46712-1-pablo@netfilter.org> References: <20250306153446.46712-1-pablo@netfilter.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Sebastian Andrzej Siewior nft_ct_pcpu_template is a per-CPU variable and relies on disabled BH for its locking. The refcounter is read and if its value is set to one then the refcounter is incremented and variable is used - otherwise it is already in use and left untouched. Without per-CPU locking in local_bh_disable() on PREEMPT_RT the read-then-increment operation is not atomic and therefore racy. This can be avoided by using unconditionally __refcount_inc() which will increment counter and return the old value as an atomic operation. In case the returned counter is not one, the variable is in use and we need to decrement counter. Otherwise we can use it. Use __refcount_inc() instead of read and a conditional increment. Fixes: edee4f1e9245 ("netfilter: nft_ct: add zone id set support") Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_ct.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 2e59aba681a1..d526e69a2a2b 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -230,6 +230,7 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr, enum ip_conntrack_info ctinfo; u16 value = nft_reg_load16(®s->data[priv->sreg]); struct nf_conn *ct; + int oldcnt; ct = nf_ct_get(skb, &ctinfo); if (ct) /* already tracked */ @@ -250,10 +251,11 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr, ct = this_cpu_read(nft_ct_pcpu_template); - if (likely(refcount_read(&ct->ct_general.use) == 1)) { - refcount_inc(&ct->ct_general.use); + __refcount_inc(&ct->ct_general.use, &oldcnt); + if (likely(oldcnt == 1)) { nf_ct_zone_add(ct, &zone); } else { + refcount_dec(&ct->ct_general.use); /* previous skb got queued to userspace, allocate temporary * one until percpu template can be reused. */ From patchwork Thu Mar 6 15:34:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 14004712 X-Patchwork-Delegate: kuba@kernel.org Received: from mail.netfilter.org (mail.netfilter.org [217.70.190.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF3141A08A6; Thu, 6 Mar 2025 15:34:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.190.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275302; cv=none; b=Xoa6UjMfYP4O4U+vzHTLxb54b/lVsp67in8iTcgbj8mFXEjYpt+niPVM9kE59vFSNW0OiWvj4RSUM3PEHFOC35W38TYkoeq51reIiO7o3zYG/xfdb8Dqg6bjU6RCguZq+PgsicGrClAdLZgNSMhhx7bphe0JoyYN4763OZmqUzM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275302; c=relaxed/simple; bh=3eBta4NdUVZpRQY7Rd3tvYxIeT60lB9yGt8iGAOE7UE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I3gYWzkC9A0T3S0j0s+DZ6/mrI81X7ZMwn0xYAxVacQ0tmvme6Qk2aTgtO2fte4ogPf2w16DRhZHYUPuIZ7lmHsstRGCAmRdmSaPqgSXW/q+njkv0fZcnc95B3vcy6qWec8koq/uCXt5fE0e/rgrid5G28BssA5tuRELC7LT3x0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org; spf=pass smtp.mailfrom=netfilter.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=XqVnGBrV; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=DuoMAnnd; arc=none smtp.client-ip=217.70.190.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=netfilter.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="XqVnGBrV"; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="DuoMAnnd" Received: by mail.netfilter.org (Postfix, from userid 109) id DDC1560303; Thu, 6 Mar 2025 16:34:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275295; bh=AUsdUETtDieRadQMe+F2JvPGgnSvRnKzF1g3M1QVQD4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XqVnGBrVjCX+1ihlLNuRlTLc/9CYNByPnwaxx5Qabg4pc3G4yGenBgVM6Rcjii2ID 2m9xGL5Dbe7KCyT9Q+NOQoPEvsfsdxnjqOpn54ZvKtOfvc9fjYc/d1SWQmfKb8NpZb 2GLJAmZxAb7BekXJwIh0CS4iKDyGl7ZrG2DVbBYUPCsMCeiWcxeNa1thG+hHSmPaqS GmUVKXQpCXi/II4yCOnEGPd06i+X6m+vZ0XHNTaFsi/HeJO4ZH9fp8tlmLYjuO7tYE oCMHB5durRErkh0N4VqBUb6PUQISrIaDR1tlN45s15f7K9nCVE2n4jjattrLGU1I0B mEE4/Uky4tvxA== X-Spam-Level: Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id DC2E860307; Thu, 6 Mar 2025 16:34:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275293; bh=AUsdUETtDieRadQMe+F2JvPGgnSvRnKzF1g3M1QVQD4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DuoMAnndoZP/7x6XZoK0Czte1bWmUCS1lCrv2iLMPIz4gnxEchZR7vh6RxJ4GaC0s SYIssdQfkW3TwVcySUvTQ0akjIOFEa/FvC4tW2ckh5lZPpcG+ZiXAvLWqBH5MDDF/j 4ovNN1afCD6+pfxI2mZy9nAOab2tq8Ia/xeMymyjiMbWtq8jP1p5ixRrBq0vAWWZqC nRBDScMzTqwwyQ7ZwyopxwKylBLkGAETRA9tkzFHUi8wt3j+iRctCBqLHoKjSy/cuX cI1F8KKBzYQ06Mp/GzFpaR9E48htQBLXH6KADT6AlHXTHmF/5N0jGVdS63HrJUnBj3 nrRcRMgmQMRvQ== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org, pabeni@redhat.com, edumazet@google.com, fw@strlen.de, horms@kernel.org Subject: [PATCH net 2/3] netfilter: nf_conncount: garbage collection is not skipped when jiffies wrap around Date: Thu, 6 Mar 2025 16:34:45 +0100 Message-Id: <20250306153446.46712-3-pablo@netfilter.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20250306153446.46712-1-pablo@netfilter.org> References: <20250306153446.46712-1-pablo@netfilter.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Nicklas Bo Jensen nf_conncount is supposed to skip garbage collection if it has already run garbage collection in the same jiffy. Unfortunately, this is broken when jiffies wrap around which this patch fixes. The problem is that last_gc in the nf_conncount_list struct is an u32, but jiffies is an unsigned long which is 8 bytes on my systems. When those two are compared it only works until last_gc wraps around. See bug report: https://bugzilla.netfilter.org/show_bug.cgi?id=1778 for more details. Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") Signed-off-by: Nicklas Bo Jensen Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conncount.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index 4890af4dc263..ebe38ed2e6f4 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -132,7 +132,7 @@ static int __nf_conncount_add(struct net *net, struct nf_conn *found_ct; unsigned int collect = 0; - if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) + if ((u32)jiffies == list->last_gc) goto add_new_node; /* check the saved connections */ @@ -234,7 +234,7 @@ bool nf_conncount_gc_list(struct net *net, bool ret = false; /* don't bother if we just did GC */ - if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc))) + if ((u32)jiffies == READ_ONCE(list->last_gc)) return false; /* don't bother if other cpu is already doing GC */ From patchwork Thu Mar 6 15:34:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 14004715 X-Patchwork-Delegate: kuba@kernel.org Received: from mail.netfilter.org (mail.netfilter.org [217.70.190.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBC5E20C46A; Thu, 6 Mar 2025 15:34:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.190.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275303; cv=none; b=lXbOMW5miVcZRs1VIms+mtLnvA6OhY3u2GyqXqfA+oFbRJzMOqsT6JOVy9kN+hmdbv/85g+zMLuVOm6ke0pRM+DU6MUp95v2+aMdi5sbG7tywIUd19ZuK6/1+XuBB0Y8K2CfCABz+3qtlBkARkN7EsWmIKTBgkzmVc+MZtGHe6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741275303; c=relaxed/simple; bh=jpeCnE3HJfsofmxO8W9m3xNHL3wARCCkrvgT3AbdNvU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NBYpnxnjSyFkIFaPmE+GpGkKWbHGa7jU1y7vWsOCC5UCsrGQTycCpy1vgcFbYpR/Vzzso8r2x7ucyRVs3Di0Lax1CujG7bK+ZBFOifPKvSPuwh5vbSvBPyPN7n28iLcqMqZyInpZg0GVng0D8sFU9DurzAFH4ECqq3nu/SDfHpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org; spf=pass smtp.mailfrom=netfilter.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=PPhxYtUA; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=vcGpmHj+; arc=none smtp.client-ip=217.70.190.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=netfilter.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="PPhxYtUA"; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="vcGpmHj+" Received: by mail.netfilter.org (Postfix, from userid 109) id 4A09860309; Thu, 6 Mar 2025 16:34:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275298; bh=a8cWGaq49n2A6fXIPbnph0hjKXtxxbdOlnnG+dTzH2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PPhxYtUAsJqiStl5SaOQ3Em9LllALgz/93EkcSw905lieTnySqpH8aXSuy19i+TZR QC2YKrPVNmgJkHQUlGSF70o15RbY63qd19pjRkbkM2E8N7tCKlmkYMOv69gp6Mjxkt yLwgCDLJqcc9QXqHXtrMwLADQuoVZSivKk6HzxAq3+GyWACMhJwdbQSUGFnyGlogO2 /ueO5W/WLrTvXbTrDFPoConNc0Xfm/eM1y75yFcg6/m3s6Vwp0Q8eD7nGCzysXUFz5 MoDLJCNPHNlfmssCT/vLGut/cprkDqCEK0Wa2N8tN9mlEt2pDheMX0rL2tanzq/nNV BzTQWryHTJVeQ== X-Spam-Level: Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id 88F4160301; Thu, 6 Mar 2025 16:34:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1741275293; bh=a8cWGaq49n2A6fXIPbnph0hjKXtxxbdOlnnG+dTzH2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vcGpmHj+qcm5VyWBZwf1zOlIiXe7/CtSs2zoojhEwoNITtF2Z06cszNR8w2lPG0Az oT+ndQRuvZ2fRDzs8TySKyKE/SQlQq0arcfpQibNxX0EFLAIdeINpMuUeAQlKLDKek MwjRROXZhwjoPCBexrKAE6TkbJZyNX/i+s2leMiMyHe/N2HY55ueiM8oO+/fuNzX+j tX8V9spi7FLehaO8tOBl9ErfSMt0gEkvRswajoiW3fL7t0fyHRFolVpFn6nZEe1+z8 NJtyVcMANSYaC4jk8+WPePIKVp8m76yNTh5fe2ydaTr2ekuL+RcxQtHKGoz4vZAT6H SqQuK2uGDQaLQ== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org, pabeni@redhat.com, edumazet@google.com, fw@strlen.de, horms@kernel.org Subject: [PATCH net 3/3] netfilter: nf_tables: make destruction work queue pernet Date: Thu, 6 Mar 2025 16:34:46 +0100 Message-Id: <20250306153446.46712-4-pablo@netfilter.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20250306153446.46712-1-pablo@netfilter.org> References: <20250306153446.46712-1-pablo@netfilter.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Florian Westphal The call to flush_work before tearing down a table from the netlink notifier was supposed to make sure that all earlier updates (e.g. rule add) that might reference that table have been processed. Unfortunately, flush_work() waits for the last queued instance. This could be an instance that is different from the one that we must wait for. This is because transactions are protected with a pernet mutex, but the work item is global, so holding the transaction mutex doesn't prevent another netns from queueing more work. Make the work item pernet so that flush_work() will wait for all transactions queued from this netns. A welcome side effect is that we no longer need to wait for transaction objects from foreign netns. The gc work queue is still global. This seems to be ok because nft_set structures are reference counted and each container structure owns a reference on the net namespace. The destroy_list is still protected by a global spinlock rather than pernet one but the hold time is very short anyway. v2: call cancel_work_sync before reaping the remaining tables (Pablo). Fixes: 9f6958ba2e90 ("netfilter: nf_tables: unconditionally flush pending work before notifier") Reported-by: syzbot+5d8c5789c8cb076b2c25@syzkaller.appspotmail.com Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 4 +++- net/netfilter/nf_tables_api.c | 24 ++++++++++++++---------- net/netfilter/nft_compat.c | 8 ++++---- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 60d5dcdb289c..803d5f1601f9 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1891,7 +1891,7 @@ void nft_chain_filter_fini(void); void __init nft_chain_route_init(void); void nft_chain_route_fini(void); -void nf_tables_trans_destroy_flush_work(void); +void nf_tables_trans_destroy_flush_work(struct net *net); int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result); __be64 nf_jiffies64_to_msecs(u64 input); @@ -1905,6 +1905,7 @@ static inline int nft_request_module(struct net *net, const char *fmt, ...) { re struct nftables_pernet { struct list_head tables; struct list_head commit_list; + struct list_head destroy_list; struct list_head commit_set_list; struct list_head binding_list; struct list_head module_list; @@ -1915,6 +1916,7 @@ struct nftables_pernet { unsigned int base_seq; unsigned int gc_seq; u8 validate_state; + struct work_struct destroy_work; }; extern unsigned int nf_tables_net_id; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index a34de9c17cf1..c2df81b7e950 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -34,7 +34,6 @@ unsigned int nf_tables_net_id __read_mostly; static LIST_HEAD(nf_tables_expressions); static LIST_HEAD(nf_tables_objects); static LIST_HEAD(nf_tables_flowtables); -static LIST_HEAD(nf_tables_destroy_list); static LIST_HEAD(nf_tables_gc_list); static DEFINE_SPINLOCK(nf_tables_destroy_list_lock); static DEFINE_SPINLOCK(nf_tables_gc_list_lock); @@ -125,7 +124,6 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s table->validate_state = new_validate_state; } static void nf_tables_trans_destroy_work(struct work_struct *w); -static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work); static void nft_trans_gc_work(struct work_struct *work); static DECLARE_WORK(trans_gc_work, nft_trans_gc_work); @@ -10006,11 +10004,12 @@ static void nft_commit_release(struct nft_trans *trans) static void nf_tables_trans_destroy_work(struct work_struct *w) { + struct nftables_pernet *nft_net = container_of(w, struct nftables_pernet, destroy_work); struct nft_trans *trans, *next; LIST_HEAD(head); spin_lock(&nf_tables_destroy_list_lock); - list_splice_init(&nf_tables_destroy_list, &head); + list_splice_init(&nft_net->destroy_list, &head); spin_unlock(&nf_tables_destroy_list_lock); if (list_empty(&head)) @@ -10024,9 +10023,11 @@ static void nf_tables_trans_destroy_work(struct work_struct *w) } } -void nf_tables_trans_destroy_flush_work(void) +void nf_tables_trans_destroy_flush_work(struct net *net) { - flush_work(&trans_destroy_work); + struct nftables_pernet *nft_net = nft_pernet(net); + + flush_work(&nft_net->destroy_work); } EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work); @@ -10484,11 +10485,11 @@ static void nf_tables_commit_release(struct net *net) trans->put_net = true; spin_lock(&nf_tables_destroy_list_lock); - list_splice_tail_init(&nft_net->commit_list, &nf_tables_destroy_list); + list_splice_tail_init(&nft_net->commit_list, &nft_net->destroy_list); spin_unlock(&nf_tables_destroy_list_lock); nf_tables_module_autoload_cleanup(net); - schedule_work(&trans_destroy_work); + schedule_work(&nft_net->destroy_work); mutex_unlock(&nft_net->commit_mutex); } @@ -11853,7 +11854,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, gc_seq = nft_gc_seq_begin(nft_net); - nf_tables_trans_destroy_flush_work(); + nf_tables_trans_destroy_flush_work(net); again: list_for_each_entry(table, &nft_net->tables, list) { if (nft_table_has_owner(table) && @@ -11895,6 +11896,7 @@ static int __net_init nf_tables_init_net(struct net *net) INIT_LIST_HEAD(&nft_net->tables); INIT_LIST_HEAD(&nft_net->commit_list); + INIT_LIST_HEAD(&nft_net->destroy_list); INIT_LIST_HEAD(&nft_net->commit_set_list); INIT_LIST_HEAD(&nft_net->binding_list); INIT_LIST_HEAD(&nft_net->module_list); @@ -11903,6 +11905,7 @@ static int __net_init nf_tables_init_net(struct net *net) nft_net->base_seq = 1; nft_net->gc_seq = 0; nft_net->validate_state = NFT_VALIDATE_SKIP; + INIT_WORK(&nft_net->destroy_work, nf_tables_trans_destroy_work); return 0; } @@ -11931,14 +11934,17 @@ static void __net_exit nf_tables_exit_net(struct net *net) if (!list_empty(&nft_net->module_list)) nf_tables_module_autoload_cleanup(net); + cancel_work_sync(&nft_net->destroy_work); __nft_release_tables(net); nft_gc_seq_end(nft_net, gc_seq); mutex_unlock(&nft_net->commit_mutex); + WARN_ON_ONCE(!list_empty(&nft_net->tables)); WARN_ON_ONCE(!list_empty(&nft_net->module_list)); WARN_ON_ONCE(!list_empty(&nft_net->notify_list)); + WARN_ON_ONCE(!list_empty(&nft_net->destroy_list)); } static void nf_tables_exit_batch(struct list_head *net_exit_list) @@ -12029,10 +12035,8 @@ static void __exit nf_tables_module_exit(void) unregister_netdevice_notifier(&nf_tables_flowtable_notifier); nft_chain_filter_fini(); nft_chain_route_fini(); - nf_tables_trans_destroy_flush_work(); unregister_pernet_subsys(&nf_tables_net_ops); cancel_work_sync(&trans_gc_work); - cancel_work_sync(&trans_destroy_work); rcu_barrier(); rhltable_destroy(&nft_objname_ht); nf_tables_core_module_exit(); diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 7ca4f0d21fe2..72711d62fddf 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -228,7 +228,7 @@ static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) return 0; } -static void nft_compat_wait_for_destructors(void) +static void nft_compat_wait_for_destructors(struct net *net) { /* xtables matches or targets can have side effects, e.g. * creation/destruction of /proc files. @@ -236,7 +236,7 @@ static void nft_compat_wait_for_destructors(void) * work queue. If we have pending invocations we thus * need to wait for those to finish. */ - nf_tables_trans_destroy_flush_work(); + nf_tables_trans_destroy_flush_work(net); } static int @@ -262,7 +262,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); - nft_compat_wait_for_destructors(); + nft_compat_wait_for_destructors(ctx->net); ret = xt_check_target(&par, size, proto, inv); if (ret < 0) { @@ -515,7 +515,7 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); - nft_compat_wait_for_destructors(); + nft_compat_wait_for_destructors(ctx->net); return xt_check_match(&par, size, proto, inv); }