From mboxrd@z Thu Jan 1 00:00:00 1970 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 1133A3C2790 for ; Tue, 12 May 2026 20:58:28 +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=1778619511; cv=none; b=RoeVL3oaFWvBnCgjaKGKWyBPxilUq2+WJbWo3JqRWa9+yDTL0d/AcH5N9ss+d42b8v9cNnFQ9kmYBxOdal/n3AbciLMtByPa+7pSKcN7dQxnkBh6APJcrkVceGuWxIMpWimieM63PLZ6CEL7YKII7d501J/YrRACgHNWzilb4wg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778619511; c=relaxed/simple; bh=VWJl54B0stNPSu/ZeijIJ290Ax2X5J+LWZeIekwe+QM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=qPVabRMTKD3oRuzNFs6mFwE0SZCvBgjLjYW6aZqpKFTKlL2xlUybkxsvyI2hxyoGpTYOLB9CxPILQ+b2fmMLgZoUvmRzxpkPMv1O1xYQzFeMsYR1IWu8+o+CuUiT6nJfKU6VK98ErPrV74dYNvERiFWkTT8HJD2+C43wfiJ8aP0= 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=MPwOETlX; 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="MPwOETlX" Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id C3618601B2; Tue, 12 May 2026 22:58:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1778619507; bh=9xpYvLpcTgRA+W3E7+Tpr9u5mnrwDrrRsSLkXn1jQRo=; h=From:To:Cc:Subject:Date:From; b=MPwOETlXMZHuvA6h6Rzcek9pjYb9PZ+dmkhyIucca1cQSblck/TUHD17YGFLy0NhG I19/rImYs3KMODDrpJHFZF/XHnLq9EY/Nx6BIKPTGvIpuY0JQ04dlKxtQeapovhjzb Tke2l5PfYl9k8CoTwL4HKU/mis0fsTvZtZ7WLzD9Vo0OLxRK7e7fOu2svFkfffV9O2 dViIBDz1LH4jpdFULW4ddWlb1JnfgtgQhkc1WiekoOBkf5QIxdkm9He84Z+2jiat6n 4FxtsJ7QgkiJDSsJs6OiN5WS2PxuiRPYpqe/7I0KSIC7NoQqsdGzZSeJGqHnhK65/e ZhBh0vBD/HX7g== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: fw@strlen.de Subject: [PATCH nf] netfilter: conntrack: add dead flag to helpers Date: Tue, 12 May 2026 22:58:23 +0200 Message-ID: <20260512205823.803476-1-pablo@netfilter.org> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add a new NF_CT_HELPER_F_DEAD helper flag to notify the packet path that this helper is going away. Thus, helpers are effectively disabled and no new expectations are created while removing the expectations created by this helper as well as unhelping the existing conntrack entries. Add the check for NF_CT_HELPER_F_DEAD in the packet path to: - Conntrack confirmation path which invokes the helper callback. - Propagation of helper to conntrack via expectation. - OVS ct helper invocation. Fixes: 12f7a505331e ("netfilter: add user-space connection tracking helper infrastructure") Reported-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_helper.h | 6 ++++++ net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_helper.c | 5 ++++- net/netfilter/nf_conntrack_ovs.c | 3 +++ net/netfilter/nf_conntrack_proto.c | 2 +- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index de2f956abf34..1faa42efe42e 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -25,6 +25,7 @@ struct module; enum nf_ct_helper_flags { NF_CT_HELPER_F_USERSPACE = (1 << 0), NF_CT_HELPER_F_CONFIGURED = (1 << 1), + NF_CT_HELPER_F_DEAD = (1 << 2), }; #define NF_CT_HELPER_NAME_LEN 16 @@ -63,6 +64,11 @@ struct nf_conntrack_helper { char nat_mod_name[NF_CT_HELPER_NAME_LEN]; }; +static inline bool nf_ct_helper_alive(const struct nf_conntrack_helper *helper) +{ + return likely(!(helper->flags & NF_CT_HELPER_F_DEAD)); +} + /* Must be kept in sync with the classes defined by helpers */ #define NF_CT_MAX_EXPECT_CLASSES 4 diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 8ba5b22a1eef..d54da6babcfe 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1818,7 +1818,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, /* exp->master safe, refcnt bumped in nf_ct_find_expectation */ ct->master = exp->master; assign_helper = rcu_dereference(exp->assign_helper); - if (assign_helper) { + if (assign_helper && nf_ct_helper_alive(assign_helper)) { help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); if (help) rcu_assign_pointer(help->helper, assign_helper); diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index b594cd244fe1..b3752ccca75e 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -415,8 +415,11 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) nf_ct_helper_count--; mutex_unlock(&nf_ct_helper_mutex); + me->flags |= NF_CT_HELPER_F_DEAD; + /* Make sure every nothing is still using the helper unless its a - * connection in the hash. + * connection in the hash, no more expectations are created after + * this rcu grace period. */ synchronize_rcu(); diff --git a/net/netfilter/nf_conntrack_ovs.c b/net/netfilter/nf_conntrack_ovs.c index a6988eeb1579..eeeb85c18a84 100644 --- a/net/netfilter/nf_conntrack_ovs.c +++ b/net/netfilter/nf_conntrack_ovs.c @@ -28,6 +28,9 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct, if (!helper) return NF_ACCEPT; + if (!nf_ct_helper_alive(helper)) + return NF_ACCEPT; + if (helper->tuple.src.l3num != NFPROTO_UNSPEC && helper->tuple.src.l3num != proto) return NF_ACCEPT; diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 50ddd3d613e1..b2ac5bd491cb 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -174,7 +174,7 @@ unsigned int nf_confirm(void *priv, /* rcu_read_lock()ed by nf_hook */ helper = rcu_dereference(help->helper); - if (helper) { + if (helper && nf_ct_helper_alive(helper)) { ret = helper->help(skb, protoff, ct, ctinfo); -- 2.47.3