* [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match
@ 2026-10-08 18:23 Phil Sutter
2026-10-21 10:17 ` Phil Sutter
0 siblings, 1 reply; 4+ messages in thread
From: Phil Sutter @ 2026-10-08 18:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Balazs Gulacsi
Iptables' conntrack match supports combined matching on ct->state bits
as well as the NAT bits in ct->status. The kernel extension matches if
any of the bits is set, i.e. '-m conntrack --ctstate NEW,DNAT' matches
packets in either NEW state or DNAT status or both. Therefore,
translating this sample match into 'ct status dnat ct state new' is
wrong: The nftables rule matches only if both statements match.
The only way to achieve this in nftables seems to be by duplicating the
rule which is not feasible within the xlate infrastructure. So instead
just abort the translation.
This is a partial revert of commit 1a13277f88099 ("extensions:
libxt_conntrack: Fix for ignored ctstates in translation") which turned
an incomplete translation into an incorrect one.
Cc: Balazs Gulacsi <m2gulbal@gmail.com>
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1826
Fixes: 26ec09bf6b9b6 ("extensions: libxt_conntrack: provide translation for DNAT and SNAT --ctstate")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Sorry for the back'n'forth here. While updating nfbz#1826 after pushing
the "fix", I noticed my comment explaining why I didn't submit the patch
back in January. This patch tidies up the loose ends.
---
extensions/libxt_conntrack.c | 12 ++++++++----
extensions/libxt_conntrack.txlate | 15 ---------------
2 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c
index 4ac4fba00c9c5..ebf8d6ebbee86 100644
--- a/extensions/libxt_conntrack.c
+++ b/extensions/libxt_conntrack.c
@@ -1201,6 +1201,9 @@ static void addr_xlate_print(struct xt_xlate *xl,
}
}
+#define XT_CONNTRACK_STATE_SDNAT ( XT_CONNTRACK_STATE_SNAT | \
+ XT_CONNTRACK_STATE_DNAT )
+
static int _conntrack3_mt_xlate(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params,
int family)
@@ -1227,15 +1230,16 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl,
}
if (sinfo->match_flags & XT_CONNTRACK_STATE) {
- if ((sinfo->state_mask & XT_CONNTRACK_STATE_SNAT) ||
- (sinfo->state_mask & XT_CONNTRACK_STATE_DNAT)) {
+ if (sinfo->state_mask & XT_CONNTRACK_STATE_SDNAT) {
+ if (sinfo->state_mask & ~XT_CONNTRACK_STATE_SDNAT)
+ return 0;
+
xt_xlate_add(xl, "%sct status %s%s", space,
sinfo->invert_flags & XT_CONNTRACK_STATE ? "!= " : "",
sinfo->state_mask & XT_CONNTRACK_STATE_SNAT ? "snat" : "dnat");
space = " ";
}
- if (sinfo->state_mask & ~(XT_CONNTRACK_STATE_SNAT |
- XT_CONNTRACK_STATE_DNAT)) {
+ if (sinfo->state_mask & ~XT_CONNTRACK_STATE_SDNAT) {
xt_xlate_add(xl, "%sct state ", space);
state_xlate_print(xl, sinfo->state_mask,
sinfo->invert_flags & XT_CONNTRACK_STATE);
diff --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate
index e7255e2a516fd..eeb1b1a53d66b 100644
--- a/extensions/libxt_conntrack.txlate
+++ b/extensions/libxt_conntrack.txlate
@@ -63,18 +63,3 @@ nft 'add rule ip filter INPUT ct status dnat counter accept'
iptables-translate -t filter -A INPUT -m conntrack ! --ctstate DNAT -j ACCEPT
nft 'add rule ip filter INPUT ct status != dnat counter accept'
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT
-nft 'add rule ip filter INPUT ct status dnat ct state related,established counter accept'
-
-iptables-translate -t filter -A INPUT -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT
-nft 'add rule ip filter INPUT ct status != dnat ct state ! related,established counter accept'
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstate ESTABLISHED,DNAT --ctstatus CONFIRMED -j ACCEPT
-nft 'add rule ip filter INPUT ct status dnat ct state established ct status confirmed counter accept'
-
-iptables-translate -t filter -A INPUT -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT --ctstatus CONFIRMED -j ACCEPT
-nft 'add rule ip filter INPUT ct status != dnat ct state ! related,established ct status confirmed counter accept'
-
-iptables-translate -t filter -A INPUT -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT ! --ctstatus CONFIRMED -j ACCEPT
-nft 'add rule ip filter INPUT ct status != dnat ct state ! related,established ct status ! confirmed counter accept'
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match
2026-10-08 18:23 [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match Phil Sutter
@ 2026-10-21 10:17 ` Phil Sutter
2026-10-21 10:31 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Phil Sutter @ 2026-10-21 10:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Balazs Gulacsi
On Thu, Oct 08, 2026 at 08:23:51PM +0200, Phil Sutter wrote:
> Iptables' conntrack match supports combined matching on ct->state bits
> as well as the NAT bits in ct->status. The kernel extension matches if
> any of the bits is set, i.e. '-m conntrack --ctstate NEW,DNAT' matches
> packets in either NEW state or DNAT status or both. Therefore,
> translating this sample match into 'ct status dnat ct state new' is
> wrong: The nftables rule matches only if both statements match.
>
> The only way to achieve this in nftables seems to be by duplicating the
> rule which is not feasible within the xlate infrastructure. So instead
> just abort the translation.
>
> This is a partial revert of commit 1a13277f88099 ("extensions:
> libxt_conntrack: Fix for ignored ctstates in translation") which turned
> an incomplete translation into an incorrect one.
>
> Cc: Balazs Gulacsi <m2gulbal@gmail.com>
> Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1826
> Fixes: 26ec09bf6b9b6 ("extensions: libxt_conntrack: provide translation for DNAT and SNAT --ctstate")
> Signed-off-by: Phil Sutter <phil@nwl.cc>
Patch applied.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match
2026-10-21 10:17 ` Phil Sutter
@ 2026-10-21 10:31 ` Pablo Neira Ayuso
2026-10-21 13:40 ` Phil Sutter
0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2026-10-21 10:31 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel, Balazs Gulacsi
Hi Phil,
On Wed, Oct 21, 2026 at 12:17:25PM +0200, Phil Sutter wrote:
> On Thu, Oct 08, 2026 at 08:23:51PM +0200, Phil Sutter wrote:
> > Iptables' conntrack match supports combined matching on ct->state bits
> > as well as the NAT bits in ct->status. The kernel extension matches if
> > any of the bits is set, i.e. '-m conntrack --ctstate NEW,DNAT' matches
> > packets in either NEW state or DNAT status or both. Therefore,
> > translating this sample match into 'ct status dnat ct state new' is
> > wrong: The nftables rule matches only if both statements match.
> >
> > The only way to achieve this in nftables seems to be by duplicating the
> > rule which is not feasible within the xlate infrastructure. So instead
> > just abort the translation.
> >
> > This is a partial revert of commit 1a13277f88099 ("extensions:
> > libxt_conntrack: Fix for ignored ctstates in translation") which turned
> > an incomplete translation into an incorrect one.
> >
> > Cc: Balazs Gulacsi <m2gulbal@gmail.com>
> > Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1826
> > Fixes: 26ec09bf6b9b6 ("extensions: libxt_conntrack: provide translation for DNAT and SNAT --ctstate")
> > Signed-off-by: Phil Sutter <phil@nwl.cc>
>
> Patch applied.
Thanks.
I wonder if it is worth filling the gap and expose snat and dnat
through ct state in nftables.
This will take time to propagate before we can expose it via userspace
(we have here the dilemma of exposing a feature which would be not
available in old kernel, but it would in newer ones... without having
an easy way to reject from control plane given the cmp and lookup
expressions do not have context on the acceptables values.
Such patch should be relatively small.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match
2026-10-21 10:31 ` Pablo Neira Ayuso
@ 2026-10-21 13:40 ` Phil Sutter
0 siblings, 0 replies; 4+ messages in thread
From: Phil Sutter @ 2026-10-21 13:40 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, Balazs Gulacsi
Hi Pablo,
On Wed, Oct 21, 2026 at 12:31:08PM +0200, Pablo Neira Ayuso wrote:
> On Wed, Oct 21, 2026 at 12:17:25PM +0200, Phil Sutter wrote:
> > On Thu, Oct 08, 2026 at 08:23:51PM +0200, Phil Sutter wrote:
> > > Iptables' conntrack match supports combined matching on ct->state bits
> > > as well as the NAT bits in ct->status. The kernel extension matches if
> > > any of the bits is set, i.e. '-m conntrack --ctstate NEW,DNAT' matches
> > > packets in either NEW state or DNAT status or both. Therefore,
> > > translating this sample match into 'ct status dnat ct state new' is
> > > wrong: The nftables rule matches only if both statements match.
> > >
> > > The only way to achieve this in nftables seems to be by duplicating the
> > > rule which is not feasible within the xlate infrastructure. So instead
> > > just abort the translation.
> > >
> > > This is a partial revert of commit 1a13277f88099 ("extensions:
> > > libxt_conntrack: Fix for ignored ctstates in translation") which turned
> > > an incomplete translation into an incorrect one.
> > >
> > > Cc: Balazs Gulacsi <m2gulbal@gmail.com>
> > > Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1826
> > > Fixes: 26ec09bf6b9b6 ("extensions: libxt_conntrack: provide translation for DNAT and SNAT --ctstate")
> > > Signed-off-by: Phil Sutter <phil@nwl.cc>
> >
> > Patch applied.
>
> Thanks.
>
> I wonder if it is worth filling the gap and expose snat and dnat
> through ct state in nftables.
If it's only for the purpose of providing a translation, I don't think
it's worth the effort. IMO it's just a niche feature of iptables and we
don't know how many people actually use it at all.
> This will take time to propagate before we can expose it via userspace
> (we have here the dilemma of exposing a feature which would be not
> available in old kernel, but it would in newer ones... without having
> an easy way to reject from control plane given the cmp and lookup
> expressions do not have context on the acceptables values.
>
> Such patch should be relatively small.
I would rather spend the effort on a more fundamental issue in nftables
I found while searching for a fix, namely the lack of an OR operation.
When looking at that ticket for the first time, I assumed a(n anonymous)
helper chain could solve it, but it seems not. To implement an "a OR b"
rule, we would need verdicts which tell the calling chain it should
continue with the next statement or break. Let's try with an example:
chain c {
jump { a return; b return; drop; } next_match verdict
next_rule
}
This serves the 'a || b' requirement in that if either a or b (or both)
are true, evaluation continues at next_match. But the failing case does
not work: instead of continuing at next_rule, packet is dropped. Using
'accept' as the final anonymous chain's rule, we jump to the next hook.
Do we have to introduce a new verdict (possibly reactivating an existing
NF_* kernel value)?
Cheers, Phil
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-21 13:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 18:23 [iptables PATCH] extensions: libxt_conntrack: Fail on untranslatable state match Phil Sutter
2026-10-21 10:17 ` Phil Sutter
2026-10-21 10:31 ` Pablo Neira Ayuso
2026-10-21 13:40 ` Phil Sutter
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.