netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Status of native NAT64/NAT46 in Netfilter?
@ 2025-06-08 20:37 Klaus Frank
  2025-06-12  9:56 ` Phil Sutter
  0 siblings, 1 reply; 11+ messages in thread
From: Klaus Frank @ 2025-06-08 20:37 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Pablo Neira Ayuso, Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

Hi,

I've been looking through the mailling list archives and couldn't find a clear anser.
So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?

All I was able to find so far:
* scanner patches related to "IPv4-Mapped IPv6" and "IPv4-compat IPv6"
* multiple people asking about this without replies
* "this is useful with DNS64/NAT64 networks for example" from 2023 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b308feb4fd2d1c06919445c65c8fbf8e9fd1781
* "in the future: in-kernel NAT64/NAT46 (Pablo)" from 2021 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42df6e1d221dddc0f2acf2be37e68d553ad65f96
* "This hook is also useful for NAT46/NAT64, tunneling and filtering of
locally generated af_packet traffic such as dhclient." from 2020 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8537f78647c072bdb1a5dbe32e1c7e5b13ff1258

It kinda looks like native NAT64/NAT46 was planned at some point in time but it just become quite silent afterwards.

Was there some technical limitation/blocker or some consensus to not move forward with it?

I'm kinda looking forward to such a feature and therefore would really like to know more about the current state of things.

Sincerely,
Klaus Frank


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-08 20:37 Status of native NAT64/NAT46 in Netfilter? Klaus Frank
@ 2025-06-12  9:56 ` Phil Sutter
  2025-06-12 13:34   ` Antonio Ojea
  0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2025-06-12  9:56 UTC (permalink / raw)
  To: Klaus Frank
  Cc: netfilter-devel, Pablo Neira Ayuso, Florian Westphal,
	Lukas Wunner, netfilter, Maciej Żenczykowski, netdev

Hi,

On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> I've been looking through the mailling list archives and couldn't find a clear anser.
> So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> 
> All I was able to find so far:
> * scanner patches related to "IPv4-Mapped IPv6" and "IPv4-compat IPv6"
> * multiple people asking about this without replies
> * "this is useful with DNS64/NAT64 networks for example" from 2023 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b308feb4fd2d1c06919445c65c8fbf8e9fd1781
> * "in the future: in-kernel NAT64/NAT46 (Pablo)" from 2021 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42df6e1d221dddc0f2acf2be37e68d553ad65f96
> * "This hook is also useful for NAT46/NAT64, tunneling and filtering of
> locally generated af_packet traffic such as dhclient." from 2020 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8537f78647c072bdb1a5dbe32e1c7e5b13ff1258
> 
> It kinda looks like native NAT64/NAT46 was planned at some point in time but it just become quite silent afterwards.
> 
> Was there some technical limitation/blocker or some consensus to not move forward with it?

Not to my knowledge. I had an implementation once in iptables, but it
never made it past the PoC stage. Nowadays this would need to be
implemented in nf_tables at least.

I'm not sure about some of the arguments you linked to above, my
implementation happily lived in forward hook for instance. It serves
well though in discovering the limitations of l3/l4 encapsulation, so
might turn into a can of worms. Implementing the icmp/icmpv6 translation
was fun, though!

> I'm kinda looking forward to such a feature and therefore would really like to know more about the current state of things.

AFAIK, this is currently not even planned to be implemented.

Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12  9:56 ` Phil Sutter
@ 2025-06-12 13:34   ` Antonio Ojea
  2025-06-12 13:56     ` Phil Sutter
  0 siblings, 1 reply; 11+ messages in thread
From: Antonio Ojea @ 2025-06-12 13:34 UTC (permalink / raw)
  To: Phil Sutter, Klaus Frank, netfilter-devel, Pablo Neira Ayuso,
	Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
>
> Hi,
>
> On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > I've been looking through the mailling list archives and couldn't find a clear anser.
> > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> >
> > All I was able to find so far:
> > * scanner patches related to "IPv4-Mapped IPv6" and "IPv4-compat IPv6"
> > * multiple people asking about this without replies
> > * "this is useful with DNS64/NAT64 networks for example" from 2023 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b308feb4fd2d1c06919445c65c8fbf8e9fd1781
> > * "in the future: in-kernel NAT64/NAT46 (Pablo)" from 2021 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42df6e1d221dddc0f2acf2be37e68d553ad65f96
> > * "This hook is also useful for NAT46/NAT64, tunneling and filtering of
> > locally generated af_packet traffic such as dhclient." from 2020 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8537f78647c072bdb1a5dbe32e1c7e5b13ff1258
> >
> > It kinda looks like native NAT64/NAT46 was planned at some point in time but it just become quite silent afterwards.
> >
> > Was there some technical limitation/blocker or some consensus to not move forward with it?
>
> Not to my knowledge. I had an implementation once in iptables, but it
> never made it past the PoC stage. Nowadays this would need to be
> implemented in nf_tables at least.
>
> I'm not sure about some of the arguments you linked to above, my
> implementation happily lived in forward hook for instance. It serves
> well though in discovering the limitations of l3/l4 encapsulation, so
> might turn into a can of worms. Implementing the icmp/icmpv6 translation
> was fun, though!
>
> > I'm kinda looking forward to such a feature and therefore would really like to know more about the current state of things.
>
> AFAIK, this is currently not even planned to be implemented.
>
> Cheers, Phil
>

we ended doing some "smart hack" , well, really a combination of them
to provide a nat64 alternative for kubernetes
https://github.com/kubernetes-sigs/nat64:
- a virtual dummy interface to "attract" the nat64 traffic with the
well known prefix
- ebpf tc filters to do the family conversion using static nat for
simplicity on the dummy interface
- and reusing nftables masquerading to avoid to reimplement conntrack

you can play with it using namespaces (without kubernetes), see
https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
for kind of selftest environment

phil point about icmp is really accurate :)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 13:34   ` Antonio Ojea
@ 2025-06-12 13:56     ` Phil Sutter
  2025-06-12 18:19       ` Antonio Ojea
  0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2025-06-12 13:56 UTC (permalink / raw)
  To: Antonio Ojea
  Cc: Klaus Frank, netfilter-devel, Pablo Neira Ayuso, Florian Westphal,
	Lukas Wunner, netfilter, Maciej Żenczykowski, netdev

Hi,

On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> > >
> > > All I was able to find so far:
> > > * scanner patches related to "IPv4-Mapped IPv6" and "IPv4-compat IPv6"
> > > * multiple people asking about this without replies
> > > * "this is useful with DNS64/NAT64 networks for example" from 2023 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b308feb4fd2d1c06919445c65c8fbf8e9fd1781
> > > * "in the future: in-kernel NAT64/NAT46 (Pablo)" from 2021 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42df6e1d221dddc0f2acf2be37e68d553ad65f96
> > > * "This hook is also useful for NAT46/NAT64, tunneling and filtering of
> > > locally generated af_packet traffic such as dhclient." from 2020 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8537f78647c072bdb1a5dbe32e1c7e5b13ff1258
> > >
> > > It kinda looks like native NAT64/NAT46 was planned at some point in time but it just become quite silent afterwards.
> > >
> > > Was there some technical limitation/blocker or some consensus to not move forward with it?
> >
> > Not to my knowledge. I had an implementation once in iptables, but it
> > never made it past the PoC stage. Nowadays this would need to be
> > implemented in nf_tables at least.
> >
> > I'm not sure about some of the arguments you linked to above, my
> > implementation happily lived in forward hook for instance. It serves
> > well though in discovering the limitations of l3/l4 encapsulation, so
> > might turn into a can of worms. Implementing the icmp/icmpv6 translation
> > was fun, though!
> >
> > > I'm kinda looking forward to such a feature and therefore would really like to know more about the current state of things.
> >
> > AFAIK, this is currently not even planned to be implemented.
> >
> > Cheers, Phil
> >
> 
> we ended doing some "smart hack" , well, really a combination of them
> to provide a nat64 alternative for kubernetes
> https://github.com/kubernetes-sigs/nat64:
> - a virtual dummy interface to "attract" the nat64 traffic with the
> well known prefix
> - ebpf tc filters to do the family conversion using static nat for
> simplicity on the dummy interface
> - and reusing nftables masquerading to avoid to reimplement conntrack

Oh, interesting! Would you benefit from a native implementation in
nftables?

> you can play with it using namespaces (without kubernetes), see
> https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> for kind of selftest environment

Refusing to look at the code: You didn't take care of the typical NAT
helper users like FTP or SIP, did you?

I also recall some loose ends regarding MTU since the packet size
increases when translating from v4 to v6.

Anyway, funny to see there is a public DNS64 run by Google. I had used a
DNS proxy named totd (the trick-or-treat daemon), but can't even find it
in the web anymore.

> phil point about icmp is really accurate :)

That wasn't ironic! Compared to other problems, getting ICMP working was
easy. :)

Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 13:56     ` Phil Sutter
@ 2025-06-12 18:19       ` Antonio Ojea
  2025-06-12 19:45         ` Phil Sutter
  0 siblings, 1 reply; 11+ messages in thread
From: Antonio Ojea @ 2025-06-12 18:19 UTC (permalink / raw)
  To: Phil Sutter, Antonio Ojea, Klaus Frank, netfilter-devel,
	Pablo Neira Ayuso, Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
>
> Hi,
>
> On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?

> > we ended doing some "smart hack" , well, really a combination of them
> > to provide a nat64 alternative for kubernetes
> > https://github.com/kubernetes-sigs/nat64:
> > - a virtual dummy interface to "attract" the nat64 traffic with the
> > well known prefix
> > - ebpf tc filters to do the family conversion using static nat for
> > simplicity on the dummy interface
> > - and reusing nftables masquerading to avoid to reimplement conntrack
>
> Oh, interesting! Would you benefit from a native implementation in
> nftables?

Indeed we'll benefit a lot, see what we have to do :)

> > you can play with it using namespaces (without kubernetes), see
> > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > for kind of selftest environment
>
> Refusing to look at the code: You didn't take care of the typical NAT
> helper users like FTP or SIP, did you?

The current approach does static NAT64 first, switching the IPv6 ips
to IPv4 and adapting the IPv4 packet, the "real nat" is done by
nftables on the ipv4 family after that, so ... it may work?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 18:19       ` Antonio Ojea
@ 2025-06-12 19:45         ` Phil Sutter
  2025-06-12 20:13           ` Klaus Frank
  0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2025-06-12 19:45 UTC (permalink / raw)
  To: Antonio Ojea
  Cc: Klaus Frank, netfilter-devel, Pablo Neira Ayuso, Florian Westphal,
	Lukas Wunner, netfilter, Maciej Żenczykowski, netdev

On Thu, Jun 12, 2025 at 08:19:53PM +0200, Antonio Ojea wrote:
> On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
> >
> > Hi,
> >
> > On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> 
> > > we ended doing some "smart hack" , well, really a combination of them
> > > to provide a nat64 alternative for kubernetes
> > > https://github.com/kubernetes-sigs/nat64:
> > > - a virtual dummy interface to "attract" the nat64 traffic with the
> > > well known prefix
> > > - ebpf tc filters to do the family conversion using static nat for
> > > simplicity on the dummy interface
> > > - and reusing nftables masquerading to avoid to reimplement conntrack
> >
> > Oh, interesting! Would you benefit from a native implementation in
> > nftables?
> 
> Indeed we'll benefit a lot, see what we have to do :)
> 
> > > you can play with it using namespaces (without kubernetes), see
> > > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > > for kind of selftest environment
> >
> > Refusing to look at the code: You didn't take care of the typical NAT
> > helper users like FTP or SIP, did you?
> 
> The current approach does static NAT64 first, switching the IPv6 ips
> to IPv4 and adapting the IPv4 packet, the "real nat" is done by
> nftables on the ipv4 family after that, so ... it may work?

That was my approach as well: The incoming IPv6 packet was translated to
IPv4 with an rfc1918 source address linked to the IPv6 source, then
MASQUERADE would translate to the external IP.

In reverse direction, iptables would use the right IPv6 destination
address from given rfc1918 destination address.

The above is a hack which limits the number of IPv6 clients to the size
of that IPv4 transfer net. Fixing it properly would probably require
conntrack integration, not sure if going that route is feasible (note
that I have no clue about conntrack internals).

The actual issue though with protocols like FTP is that they embed IP
addresses in their headers. Therefore it is not sufficient to swap the
l3 header and recalculate the TCP checksum, you end up manipulating l7
headers to keep things going. At least there's prior work in conntrack
helpers, not sure if that code could be reused or not.

Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 19:45         ` Phil Sutter
@ 2025-06-12 20:13           ` Klaus Frank
  2025-06-12 21:55             ` Phil Sutter
  0 siblings, 1 reply; 11+ messages in thread
From: Klaus Frank @ 2025-06-12 20:13 UTC (permalink / raw)
  To: Phil Sutter, Antonio Ojea, Klaus Frank, netfilter-devel,
	Pablo Neira Ayuso, Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Thu, Jun 12, 2025 at 09:45:00PM +0200, Phil Sutter wrote:
> On Thu, Jun 12, 2025 at 08:19:53PM +0200, Antonio Ojea wrote:
> > On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
> > >
> > > Hi,
> > >
> > > On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > > > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> > 
> > > > we ended doing some "smart hack" , well, really a combination of them
> > > > to provide a nat64 alternative for kubernetes
> > > > https://github.com/kubernetes-sigs/nat64:
> > > > - a virtual dummy interface to "attract" the nat64 traffic with the
> > > > well known prefix
> > > > - ebpf tc filters to do the family conversion using static nat for
> > > > simplicity on the dummy interface
> > > > - and reusing nftables masquerading to avoid to reimplement conntrack
> > >
> > > Oh, interesting! Would you benefit from a native implementation in
> > > nftables?
> > 
> > Indeed we'll benefit a lot, see what we have to do :)
> > 
> > > > you can play with it using namespaces (without kubernetes), see
> > > > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > > > for kind of selftest environment
> > >
> > > Refusing to look at the code: You didn't take care of the typical NAT
> > > helper users like FTP or SIP, did you?
> > 
> > The current approach does static NAT64 first, switching the IPv6 ips
> > to IPv4 and adapting the IPv4 packet, the "real nat" is done by
> > nftables on the ipv4 family after that, so ... it may work?
> 
> That was my approach as well: The incoming IPv6 packet was translated to
> IPv4 with an rfc1918 source address linked to the IPv6 source, then
> MASQUERADE would translate to the external IP.
> 
> In reverse direction, iptables would use the right IPv6 destination
> address from given rfc1918 destination address.
> 
> The above is a hack which limits the number of IPv6 clients to the size
> of that IPv4 transfer net. Fixing it properly would probably require
> conntrack integration, not sure if going that route is feasible (note
> that I have no clue about conntrack internals).

Well technically all that needs to be done is NAT66 instead of NAT44
within that hack and that limitation vanishes.
> 
> The actual issue though with protocols like FTP is that they embed IP
> addresses in their headers. Therefore it is not sufficient to swap the
> l3 header and recalculate the TCP checksum, you end up manipulating l7
> headers to keep things going. At least there's prior work in conntrack
> helpers, not sure if that code could be reused or not.

If nat64 functionality was added within conntrac itself then it would be
easy to reuse the l7 helpers. If it was anywhere else the l7 helpers
within conntrack would have to be re-implemented as conntrack wouldn't
know the mappings and therefor it probably would be quite hard to do the
rewrites.
Also in regards to FTP not just L7 headers but also payload needs to be
edited on the fly. As it often uses differnt commands for IPv4 and IPv6
(even though the IPv6 ones also support IPv4) and it embeds the IPs as
strings.

EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>

where "net-prt" is either 1 for IPv4 or 2 for IPv6. and net-addr is the
string representation.
However a client may send the "PORT" command instead...
Also RFC2428 may be helpful in this context.

I think if it was possible to get the nat64 into conntrack it should
also be possible to take care of this more easily as with external
"hacks".


Also in regards to the above code it looks like currently only tcp and
udp are supported. All other traffic appears to just dropped at the
moment instead of just passed through. Is there a particular reason for
this?

> 
> Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 20:13           ` Klaus Frank
@ 2025-06-12 21:55             ` Phil Sutter
  2025-06-12 22:19               ` webmaster
  2025-06-12 23:25               ` Jan Engelhardt
  0 siblings, 2 replies; 11+ messages in thread
From: Phil Sutter @ 2025-06-12 21:55 UTC (permalink / raw)
  To: Klaus Frank
  Cc: Antonio Ojea, netfilter-devel, Pablo Neira Ayuso,
	Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Thu, Jun 12, 2025 at 08:13:02PM +0000, Klaus Frank wrote:
> On Thu, Jun 12, 2025 at 09:45:00PM +0200, Phil Sutter wrote:
> > On Thu, Jun 12, 2025 at 08:19:53PM +0200, Antonio Ojea wrote:
> > > On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > > > > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > > > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> > > 
> > > > > we ended doing some "smart hack" , well, really a combination of them
> > > > > to provide a nat64 alternative for kubernetes
> > > > > https://github.com/kubernetes-sigs/nat64:
> > > > > - a virtual dummy interface to "attract" the nat64 traffic with the
> > > > > well known prefix
> > > > > - ebpf tc filters to do the family conversion using static nat for
> > > > > simplicity on the dummy interface
> > > > > - and reusing nftables masquerading to avoid to reimplement conntrack
> > > >
> > > > Oh, interesting! Would you benefit from a native implementation in
> > > > nftables?
> > > 
> > > Indeed we'll benefit a lot, see what we have to do :)
> > > 
> > > > > you can play with it using namespaces (without kubernetes), see
> > > > > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > > > > for kind of selftest environment
> > > >
> > > > Refusing to look at the code: You didn't take care of the typical NAT
> > > > helper users like FTP or SIP, did you?
> > > 
> > > The current approach does static NAT64 first, switching the IPv6 ips
> > > to IPv4 and adapting the IPv4 packet, the "real nat" is done by
> > > nftables on the ipv4 family after that, so ... it may work?
> > 
> > That was my approach as well: The incoming IPv6 packet was translated to
> > IPv4 with an rfc1918 source address linked to the IPv6 source, then
> > MASQUERADE would translate to the external IP.
> > 
> > In reverse direction, iptables would use the right IPv6 destination
> > address from given rfc1918 destination address.
> > 
> > The above is a hack which limits the number of IPv6 clients to the size
> > of that IPv4 transfer net. Fixing it properly would probably require
> > conntrack integration, not sure if going that route is feasible (note
> > that I have no clue about conntrack internals).
> 
> Well technically all that needs to be done is NAT66 instead of NAT44
> within that hack and that limitation vanishes.

I don't comprehend: I have to use an IPv4 transfer net because I need to
set a source address in the generated IPv4 header. The destination IPv4
address is extracted from the IPv6 destination address. Simple example:

IPv6-only internal:     fec0::/64
v6mapped:               cafe::/96
external IPv4:          1.2.3.4
internal transfer IPv4: 10.64.64.0/24

Client sends:       IPv6(fec0::1, cafe::8.8.8.8)
nat64 in fwd:       IPv4(10.64.64.1, 8.8.8.8)
nat in postrouting: IPv4(1.2.3.4, 8.8.8.8)

Google replies:     IPv4(8.8.8.8, 1.2.3.4)
nat in prerouting:  IPv4(8.8.8.8, 10.64.64.1)
nat64 in fwd:       IPv6(cafe::8.8.8.8, fec0::1)

> > The actual issue though with protocols like FTP is that they embed IP
> > addresses in their headers. Therefore it is not sufficient to swap the
> > l3 header and recalculate the TCP checksum, you end up manipulating l7
> > headers to keep things going. At least there's prior work in conntrack
> > helpers, not sure if that code could be reused or not.
> 
> If nat64 functionality was added within conntrac itself then it would be
> easy to reuse the l7 helpers. If it was anywhere else the l7 helpers
> within conntrack would have to be re-implemented as conntrack wouldn't
> know the mappings and therefor it probably would be quite hard to do the
> rewrites.
> Also in regards to FTP not just L7 headers but also payload needs to be
> edited on the fly. As it often uses differnt commands for IPv4 and IPv6
> (even though the IPv6 ones also support IPv4) and it embeds the IPs as
> strings.
> 
> EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>
> 
> where "net-prt" is either 1 for IPv4 or 2 for IPv6. and net-addr is the
> string representation.
> However a client may send the "PORT" command instead...
> Also RFC2428 may be helpful in this context.
> 
> I think if it was possible to get the nat64 into conntrack it should
> also be possible to take care of this more easily as with external
> "hacks".

I agree it would probably be the cleanest solution.

> Also in regards to the above code it looks like currently only tcp and
> udp are supported. All other traffic appears to just dropped at the
> moment instead of just passed through. Is there a particular reason for
> this?

I guess tcp and udp are simply sufficient in k8s.

Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 21:55             ` Phil Sutter
@ 2025-06-12 22:19               ` webmaster
  2025-06-13  8:42                 ` Antonio Ojea
  2025-06-12 23:25               ` Jan Engelhardt
  1 sibling, 1 reply; 11+ messages in thread
From: webmaster @ 2025-06-12 22:19 UTC (permalink / raw)
  To: Phil Sutter, Klaus Frank, Antonio Ojea, netfilter-devel,
	Pablo Neira Ayuso, Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Thu, Jun 12, 2025 at 11:55:06PM +0200, Phil Sutter wrote:
> On Thu, Jun 12, 2025 at 08:13:02PM +0000, Klaus Frank wrote:
> > On Thu, Jun 12, 2025 at 09:45:00PM +0200, Phil Sutter wrote:
> > > On Thu, Jun 12, 2025 at 08:19:53PM +0200, Antonio Ojea wrote:
> > > > On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > > > > > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > > > > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > > > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > > > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> > > > 
> > > > > > we ended doing some "smart hack" , well, really a combination of them
> > > > > > to provide a nat64 alternative for kubernetes
> > > > > > https://github.com/kubernetes-sigs/nat64:
> > > > > > - a virtual dummy interface to "attract" the nat64 traffic with the
> > > > > > well known prefix
> > > > > > - ebpf tc filters to do the family conversion using static nat for
> > > > > > simplicity on the dummy interface
> > > > > > - and reusing nftables masquerading to avoid to reimplement conntrack
> > > > >
> > > > > Oh, interesting! Would you benefit from a native implementation in
> > > > > nftables?
> > > > 
> > > > Indeed we'll benefit a lot, see what we have to do :)
> > > > 
> > > > > > you can play with it using namespaces (without kubernetes), see
> > > > > > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > > > > > for kind of selftest environment
> > > > >
> > > > > Refusing to look at the code: You didn't take care of the typical NAT
> > > > > helper users like FTP or SIP, did you?
> > > > 
> > > > The current approach does static NAT64 first, switching the IPv6 ips
> > > > to IPv4 and adapting the IPv4 packet, the "real nat" is done by
> > > > nftables on the ipv4 family after that, so ... it may work?
> > > 
> > > That was my approach as well: The incoming IPv6 packet was translated to
> > > IPv4 with an rfc1918 source address linked to the IPv6 source, then
> > > MASQUERADE would translate to the external IP.
> > > 
> > > In reverse direction, iptables would use the right IPv6 destination
> > > address from given rfc1918 destination address.
> > > 
> > > The above is a hack which limits the number of IPv6 clients to the size
> > > of that IPv4 transfer net. Fixing it properly would probably require
> > > conntrack integration, not sure if going that route is feasible (note
> > > that I have no clue about conntrack internals).
> > 
> > Well technically all that needs to be done is NAT66 instead of NAT44
> > within that hack and that limitation vanishes.
> 
> I don't comprehend: I have to use an IPv4 transfer net because I need to
> set a source address in the generated IPv4 header. The destination IPv4
> address is extracted from the IPv6 destination address. Simple example:
> 
> IPv6-only internal:     fec0::/64
> v6mapped:               cafe::/96
> external IPv4:          1.2.3.4
> internal transfer IPv4: 10.64.64.0/24
> 
> Client sends:       IPv6(fec0::1, cafe::8.8.8.8)
> nat64 in fwd:       IPv4(10.64.64.1, 8.8.8.8)
> nat in postrouting: IPv4(1.2.3.4, 8.8.8.8)
> 
> Google replies:     IPv4(8.8.8.8, 1.2.3.4)
> nat in prerouting:  IPv4(8.8.8.8, 10.64.64.1)
> nat64 in fwd:       IPv6(cafe::8.8.8.8, fec0::1)

The IPv6 subnet has more IPs than the internal transfer IPv4 network.
Therefore doing a NAT66 to condense all of them into one IPv6 address
means you only need 1 IPv4 in the internal transfer net. Therefore the
limitation stated above no longer applies. Admittedly if you do the
nat44 within a dedicated network namespace while sharing an IPv4 with
the host you'd still need to do NAT44 too.

> 
> > > The actual issue though with protocols like FTP is that they embed IP
> > > addresses in their headers. Therefore it is not sufficient to swap the
> > > l3 header and recalculate the TCP checksum, you end up manipulating l7
> > > headers to keep things going. At least there's prior work in conntrack
> > > helpers, not sure if that code could be reused or not.
> > 
> > If nat64 functionality was added within conntrac itself then it would be
> > easy to reuse the l7 helpers. If it was anywhere else the l7 helpers
> > within conntrack would have to be re-implemented as conntrack wouldn't
> > know the mappings and therefor it probably would be quite hard to do the
> > rewrites.
> > Also in regards to FTP not just L7 headers but also payload needs to be
> > edited on the fly. As it often uses differnt commands for IPv4 and IPv6
> > (even though the IPv6 ones also support IPv4) and it embeds the IPs as
> > strings.
> > 
> > EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>
> > 
> > where "net-prt" is either 1 for IPv4 or 2 for IPv6. and net-addr is the
> > string representation.
> > However a client may send the "PORT" command instead...
> > Also RFC2428 may be helpful in this context.
> > 
> > I think if it was possible to get the nat64 into conntrack it should
> > also be possible to take care of this more easily as with external
> > "hacks".
> 
> I agree it would probably be the cleanest solution.
> 
> > Also in regards to the above code it looks like currently only tcp and
> > udp are supported. All other traffic appears to just dropped at the
> > moment instead of just passed through. Is there a particular reason for
> > this?
> 
> I guess tcp and udp are simply sufficient in k8s.

doesn't k8s also support sctp? Also still no need to just drop
everything else, would have expected to just pass through it without
special handling...

> 
> Cheers, Phil

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 21:55             ` Phil Sutter
  2025-06-12 22:19               ` webmaster
@ 2025-06-12 23:25               ` Jan Engelhardt
  1 sibling, 0 replies; 11+ messages in thread
From: Jan Engelhardt @ 2025-06-12 23:25 UTC (permalink / raw)
  To: Phil Sutter
  Cc: Klaus Frank, Antonio Ojea, netfilter-devel, Pablo Neira Ayuso,
	Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev


On Thursday 2025-06-12 23:55, Phil Sutter wrote:
>
>I don't comprehend: I have to use an IPv4 transfer net because I need to
>set a source address in the generated IPv4 header. The destination IPv4
>address is extracted from the IPv6 destination address. Simple example:
>
>IPv6-only internal:     fec0::/64
>v6mapped:               cafe::/96
>external IPv4:          1.2.3.4
>internal transfer IPv4: 10.64.64.0/24

Here's a thought (experiment)...

 * make all conntrack entries and templates use IPPROTO_IPV6, even
   for IPv4 (i.e. by representing those as ::ffff:0:0/96)

 * at the time of NF_IP6_PRI_NAT_SRC or later, if a skbuff has a
   ::ffff:0:0/96 address in *both* srcaddr and dstaddr, replace the
   skbuff by one with an IPv4 header.

 * at the time of NF_IP_PRI_NAT_DST, if the ct entry is such that
   the replacement dstaddr contains one non-ffff address, replace the
   skbuff by one with an IPv6 header.

all in the hope of enabling

ip6tables -t nat -A POSTROUTING -s fec0::/64 -j SNAT --to ::ffff:1.2.3.4

so that you don't have to think about cafe::/96 or 10.64.64.0/24.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Status of native NAT64/NAT46 in Netfilter?
  2025-06-12 22:19               ` webmaster
@ 2025-06-13  8:42                 ` Antonio Ojea
  0 siblings, 0 replies; 11+ messages in thread
From: Antonio Ojea @ 2025-06-13  8:42 UTC (permalink / raw)
  To: webmaster
  Cc: Phil Sutter, Klaus Frank, netfilter-devel, Pablo Neira Ayuso,
	Florian Westphal, Lukas Wunner, netfilter,
	Maciej Żenczykowski, netdev

On Fri, 13 Jun 2025 at 00:19, <webmaster@agowa338.de> wrote:
>
> On Thu, Jun 12, 2025 at 11:55:06PM +0200, Phil Sutter wrote:
> > On Thu, Jun 12, 2025 at 08:13:02PM +0000, Klaus Frank wrote:
> > > On Thu, Jun 12, 2025 at 09:45:00PM +0200, Phil Sutter wrote:
> > > > On Thu, Jun 12, 2025 at 08:19:53PM +0200, Antonio Ojea wrote:
> > > > > On Thu, 12 Jun 2025 at 15:56, Phil Sutter <phil@nwl.cc> wrote:
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > On Thu, Jun 12, 2025 at 03:34:08PM +0200, Antonio Ojea wrote:
> > > > > > > On Thu, 12 Jun 2025 at 11:57, Phil Sutter <phil@nwl.cc> wrote:
> > > > > > > > On Sun, Jun 08, 2025 at 08:37:10PM +0000, Klaus Frank wrote:
> > > > > > > > > I've been looking through the mailling list archives and couldn't find a clear anser.
> > > > > > > > > So I wanted to ask here what the status of native NAT64/NAT46 support in netfilter is?
> > > > >
> > > > > > > we ended doing some "smart hack" , well, really a combination of them
> > > > > > > to provide a nat64 alternative for kubernetes
> > > > > > > https://github.com/kubernetes-sigs/nat64:
> > > > > > > - a virtual dummy interface to "attract" the nat64 traffic with the
> > > > > > > well known prefix
> > > > > > > - ebpf tc filters to do the family conversion using static nat for
> > > > > > > simplicity on the dummy interface
> > > > > > > - and reusing nftables masquerading to avoid to reimplement conntrack
> > > > > >
> > > > > > Oh, interesting! Would you benefit from a native implementation in
> > > > > > nftables?
> > > > >
> > > > > Indeed we'll benefit a lot, see what we have to do :)
> > > > >
> > > > > > > you can play with it using namespaces (without kubernetes), see
> > > > > > > https://github.com/kubernetes-sigs/nat64/blob/main/tests/integration/e2e.bats
> > > > > > > for kind of selftest environment
> > > > > >
> > > > > > Refusing to look at the code: You didn't take care of the typical NAT
> > > > > > helper users like FTP or SIP, did you?
> > > > >
> > > > > The current approach does static NAT64 first, switching the IPv6 ips
> > > > > to IPv4 and adapting the IPv4 packet, the "real nat" is done by
> > > > > nftables on the ipv4 family after that, so ... it may work?
> > > >
> > > > That was my approach as well: The incoming IPv6 packet was translated to
> > > > IPv4 with an rfc1918 source address linked to the IPv6 source, then
> > > > MASQUERADE would translate to the external IP.
> > > >
> > > > In reverse direction, iptables would use the right IPv6 destination
> > > > address from given rfc1918 destination address.
> > > >
> > > > The above is a hack which limits the number of IPv6 clients to the size
> > > > of that IPv4 transfer net. Fixing it properly would probably require
> > > > conntrack integration, not sure if going that route is feasible (note
> > > > that I have no clue about conntrack internals).
> > >
> > > Well technically all that needs to be done is NAT66 instead of NAT44
> > > within that hack and that limitation vanishes.
> >
> > I don't comprehend: I have to use an IPv4 transfer net because I need to
> > set a source address in the generated IPv4 header. The destination IPv4
> > address is extracted from the IPv6 destination address. Simple example:
> >

Yeah, my bad, I was thinking about the Service implementation and the
need to track multiple connections for the same DNAT, and this is
about embedded IPs.

> >
> > > Also in regards to the above code it looks like currently only tcp and
> > > udp are supported. All other traffic appears to just dropped at the
> > > moment instead of just passed through. Is there a particular reason for
> > > this?
> >
> > I guess tcp and udp are simply sufficient in k8s.
>
> doesn't k8s also support sctp? Also still no need to just drop
> everything else, would have expected to just pass through it without
> special handling...
>

Ok, k8s support, here by dragons, taking some licenses for keeping the
explanation simple:
k8s orchestrate containers with a flat network as model, as every
container needs to talk to other containers in the cluster without
NAT, there is nothing kubernetes mandates about protocols here, only
about how the network in the cluster should look like, this end to end
principle makes networking "simple" to think about and put the
complexity on the endpoints.

k8s also offers a mechanism for service discovery, the famous
kube-proxy that basically does DNAT to some virtual ip and Port
configured by the user, that is the thing that users can configure to
expose their containers, and this API only allow users to set TCP ,
UDP or SCTP protocols, this is what people traditional mean as
"kubernetes supports SCTP", although the use cases for this are very
niche.

The need for NAT64 in k8s is because unfortunately the world is not
IPv6 ready, so people deploy containers that pull images from
registries that are not reachable via IPv6 or use some git repository
that is IPv4 only, this traffic "from container to Internet" is the
traffic that needs a translation mechanism and is what this project
tries to solve, is a stopgap solution, just that.

The "mixing IP families inside the same cluster", so I have some
containers IPv4 and others IPv6 is something I heard people trying to
do, but that basically breaks the networking model of k8s, since means
some containers will only be able to reach other containers through
NAT, I really do not recommend that, as I do not see the benefit, is
something cool to work with, but not something I will use if I have my
company business on that cluster, you better use multiple clusters
with different network domains and ip families and communicate through
the "external to cluster" mechanisms

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-06-13  8:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-08 20:37 Status of native NAT64/NAT46 in Netfilter? Klaus Frank
2025-06-12  9:56 ` Phil Sutter
2025-06-12 13:34   ` Antonio Ojea
2025-06-12 13:56     ` Phil Sutter
2025-06-12 18:19       ` Antonio Ojea
2025-06-12 19:45         ` Phil Sutter
2025-06-12 20:13           ` Klaus Frank
2025-06-12 21:55             ` Phil Sutter
2025-06-12 22:19               ` webmaster
2025-06-13  8:42                 ` Antonio Ojea
2025-06-12 23:25               ` Jan Engelhardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).