* [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows
@ 2026-06-30 6:03 Florian Westphal
2026-06-30 10:08 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2026-06-30 6:03 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
This feature only works for connections originating from the host
and only if there no source address rewrite.
Add the needed nat glue to have the expectation follow the original
nat binding.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
v2:
add missing nf_ct_expect_iterate_destroy() in exit handler
fix buld with CONFIG_NF_NAT=n
net/netfilter/nft_ct.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 03a88c77e0f0..95fc3d7c1edb 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,
return 0;
}
+#if IS_ENABLED(CONFIG_NF_NAT)
+static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)
+{
+ const struct nf_ct_helper_expectfn *expfn;
+
+ expfn = nf_ct_helper_expectfn_find_by_name("nat-follow-master");
+ if (expfn)
+ expfn->expectfn(ct, this);
+}
+#endif
+
static void nft_ct_expect_obj_eval(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
@@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
priv->l4proto, NULL, &priv->dport);
exp->timeout += priv->timeout;
+#if IS_ENABLED(CONFIG_NF_NAT)
+ if (ct->status & IPS_NAT_MASK) {
+ exp->saved_proto.tcp.port = priv->dport;
+ exp->dir = !dir;
+ exp->expectfn = nft_ct_nat_follow_master;
+ }
+#endif
if (nf_ct_expect_related(exp, 0) != 0)
regs->verdict.code = NF_DROP;
@@ -1416,6 +1434,13 @@ static int __init nft_ct_module_init(void)
return err;
}
+#if IS_ENABLED(CONFIG_NF_NAT)
+static bool __exit expect_iter_nat(struct nf_conntrack_expect *exp, void *data)
+{
+ return exp->expectfn == nft_ct_nat_follow_master;
+}
+#endif
+
static void __exit nft_ct_module_exit(void)
{
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
@@ -1425,6 +1450,11 @@ static void __exit nft_ct_module_exit(void)
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
+
+#if IS_ENABLED(CONFIG_NF_NAT)
+ nf_ct_expect_iterate_destroy(expect_iter_nat, NULL);
+ synchronize_rcu();
+#endif
}
module_init(nft_ct_module_init);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows
2026-06-30 6:03 [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows Florian Westphal
@ 2026-06-30 10:08 ` Pablo Neira Ayuso
2026-06-30 11:04 ` Florian Westphal
0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2026-06-30 10:08 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
Hi Florian,
On Tue, Jun 30, 2026 at 08:03:08AM +0200, Florian Westphal wrote:
> This feature only works for connections originating from the host
> and only if there no source address rewrite.
>
> Add the needed nat glue to have the expectation follow the original
> nat binding.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> v2:
> add missing nf_ct_expect_iterate_destroy() in exit handler
> fix buld with CONFIG_NF_NAT=n
>
> net/netfilter/nft_ct.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> index 03a88c77e0f0..95fc3d7c1edb 100644
> --- a/net/netfilter/nft_ct.c
> +++ b/net/netfilter/nft_ct.c
> @@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,
> return 0;
> }
>
> +#if IS_ENABLED(CONFIG_NF_NAT)
> +static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)
> +{
> + const struct nf_ct_helper_expectfn *expfn;
> +
> + expfn = nf_ct_helper_expectfn_find_by_name("nat-follow-master");
> + if (expfn)
> + expfn->expectfn(ct, this);
> +}
> +#endif
> +
> static void nft_ct_expect_obj_eval(struct nft_object *obj,
> struct nft_regs *regs,
> const struct nft_pktinfo *pkt)
> @@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
> priv->l4proto, NULL, &priv->dport);
> exp->timeout += priv->timeout;
>
> +#if IS_ENABLED(CONFIG_NF_NAT)
> + if (ct->status & IPS_NAT_MASK) {
> + exp->saved_proto.tcp.port = priv->dport;
> + exp->dir = !dir;
> + exp->expectfn = nft_ct_nat_follow_master;
> + }
> +#endif
> if (nf_ct_expect_related(exp, 0) != 0)
> regs->verdict.code = NF_DROP;
>
> @@ -1416,6 +1434,13 @@ static int __init nft_ct_module_init(void)
> return err;
> }
>
> +#if IS_ENABLED(CONFIG_NF_NAT)
> +static bool __exit expect_iter_nat(struct nf_conntrack_expect *exp, void *data)
> +{
> + return exp->expectfn == nft_ct_nat_follow_master;
> +}
> +#endif
> +
> static void __exit nft_ct_module_exit(void)
> {
> #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
> @@ -1425,6 +1450,11 @@ static void __exit nft_ct_module_exit(void)
> nft_unregister_obj(&nft_ct_helper_obj_type);
> nft_unregister_expr(&nft_notrack_type);
> nft_unregister_expr(&nft_ct_type);
> +
> +#if IS_ENABLED(CONFIG_NF_NAT)
> + nf_ct_expect_iterate_destroy(expect_iter_nat, NULL);
> + synchronize_rcu();
> +#endif
Not sure sashiko is signalling a real issue here.
static void __exit nf_nat_cleanup(void)
{
struct nf_nat_proto_clean clean = {};
nf_ct_iterate_destroy(nf_nat_proto_clean, &clean);
all NATted master conntracks are destroyed here, including their
expectations, which might have the expectations using
nat_follow_master.
nf_ct_iterate_cleanup()
nf_ct_delete()
clean_from_lists()
nf_ct_remove_expectation()
And nf_nat_cleanup() can only be called if all there is no more nat
chains in place, correct?
If so, no new expectations can be created using nat_follow_master and
this nf_ct_iterate_destroy() is implicitly removing the remaining
expectations using nat_follow_master.
Sorry for the long writing, I don't see it where the issue is.
> }
>
> module_init(nft_ct_module_init);
> --
> 2.53.0
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows
2026-06-30 10:08 ` Pablo Neira Ayuso
@ 2026-06-30 11:04 ` Florian Westphal
2026-06-30 14:20 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2026-06-30 11:04 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > +#if IS_ENABLED(CONFIG_NF_NAT)
> > + nf_ct_expect_iterate_destroy(expect_iter_nat, NULL);
> > + synchronize_rcu();
> > +#endif
>
> Not sure sashiko is signalling a real issue here.
I could use the nf_nat_helper_register/unregister interface which would
support dump/restore via ctnetlink / conntrackd.
Not sure its worth it.
This isn't using nat-follow-master directly to avoid a module dependency
on the nat core.
> static void __exit nf_nat_cleanup(void)
> {
> struct nf_nat_proto_clean clean = {};
>
> nf_ct_iterate_destroy(nf_nat_proto_clean, &clean);
>
> all NATted master conntracks are destroyed here, including their
> expectations, which might have the expectations using
> nat_follow_master.
Yes, but users can remove nft_ct and leave nf nat core loaded,
so above function won't run. The expect_iter_nat cb will zap
expectations that are still in the table that point to the
internal expectfn (i.e. into the module thats going away).
The alternative to the manual nf_ct_iterate_destroy() is to use
nf_ct_helper_expectfn_destroy() and a real struct nf_ct_helper_expectfn.
> And nf_nat_cleanup() can only be called if all there is no more nat
> chains in place, correct?
Yes, but I don't think thats related to the sashiko comment at
https://sashiko.dev/#/patchset/20260630060311.2504-1-fw%40strlen.de
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows
2026-06-30 11:04 ` Florian Westphal
@ 2026-06-30 14:20 ` Pablo Neira Ayuso
0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2026-06-30 14:20 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
On Tue, Jun 30, 2026 at 01:04:42PM +0200, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > > +#if IS_ENABLED(CONFIG_NF_NAT)
> > > + nf_ct_expect_iterate_destroy(expect_iter_nat, NULL);
> > > + synchronize_rcu();
> > > +#endif
> >
> > Not sure sashiko is signalling a real issue here.
>
> I could use the nf_nat_helper_register/unregister interface which would
> support dump/restore via ctnetlink / conntrackd.
> Not sure its worth it.
>
> This isn't using nat-follow-master directly to avoid a module dependency
> on the nat core.
>
> > static void __exit nf_nat_cleanup(void)
> > {
> > struct nf_nat_proto_clean clean = {};
> >
> > nf_ct_iterate_destroy(nf_nat_proto_clean, &clean);
> >
> > all NATted master conntracks are destroyed here, including their
> > expectations, which might have the expectations using
> > nat_follow_master.
>
> Yes, but users can remove nft_ct and leave nf nat core loaded,
> so above function won't run. The expect_iter_nat cb will zap
> expectations that are still in the table that point to the
> internal expectfn (i.e. into the module thats going away).
Right.
> The alternative to the manual nf_ct_iterate_destroy() is to use
> nf_ct_helper_expectfn_destroy() and a real struct nf_ct_helper_expectfn.
For the scenario you describe, I think it should be possible to
register a dummy helper for this expectation type, with a NULL
callback. Helper unregistration should deal with removing the pending
expectations that are left behind on module removal.
By adding this dummy helper, this special type of expectations gets
aligned with the existing helpers.
I can take a look if you busy with something else, let me know.
Thanks Florian.
> > And nf_nat_cleanup() can only be called if all there is no more nat
> > chains in place, correct?
>
> Yes, but I don't think thats related to the sashiko comment at
> https://sashiko.dev/#/patchset/20260630060311.2504-1-fw%40strlen.de
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-30 14:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30 6:03 [PATCH nf-next v2] netfilter: nft_ct: support expectation creation for natted flows Florian Westphal
2026-06-30 10:08 ` Pablo Neira Ayuso
2026-06-30 11:04 ` Florian Westphal
2026-06-30 14:20 ` Pablo Neira Ayuso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.