So, I bothered to play around with these addresses. I find myself a little confused by what you wrote.
> If you machine is on say 2001::1, then when an application attempts to listen on an ipv4 address it opens a socket listening on 2001::1 instead, and when an application writes a packet to 1.0.0.1, your OS translates it to ::ffff:100:1. ...
> Your network then has a route to ::ffff:0:0/96 via a gateway (typically just the default router), with a source of 2001::1
What's the name of this translation mechanism that you're talking about? It seems to be the important part of the system.
I ask because when I visit [0] in Firefox on a Linux system with both globally-routable IPv6 and locally-routable IPv4 addresses configured, I see a TCP conversation with the remote IPv4 address 192.168.2.2. When I remove the IPv4 address (and the IPv4 default route) from the local host, I get immediate failures... neither v4 nor v6 traffic is made.
When I add the route it looks like you suggested I add
ip route add ::ffff:0:0/96 dev eth0 via <$DEFAULT_IPV6_GATEWAY_IP>
I see the route in my routing table, but I get exactly the same results... no IPv4 or IPv6 traffic.Based on my testing, it looks like this is only a way to represent IPv4 addresses as IPv6 addresses, as ::ffff:192.168.2.2 gets translated into ::ffff:c0a8:202, but the OS uses that to create IPv4 traffic. If your system doesn't have an IPv4 address configured on it, then this doesn't seem to help you at all. What am I missing?
You make Nat46 part of the OS network stack.
You make nat64 part of the typical router.
> I ask because when I visit [0] in Firefox on a Linux system with both globally-routable IPv6 and locally-routable IPv4 addresses configured, I see a TCP conversation with the remote IPv4 address 192.168.2.2. When I remove the IPv4 address (and the IPv4 default route) from the local host, I get immediate failures... neither v4 nor v6 traffic is made.
Yes, that's the failure of ipv6 deployment.
Imagine you have two vlans, one ipv4 only, one ipv6 only. There's a router sitting across both vlans.
VLAN1 - ipv6 only
Router 2001::1
Device A 2001::1234
VLAN2 - ipv4 only
Router 192.168.1.1
Device B 192.168.1.2
Device A pings 192.168.1.2, the OS converts that transparently to ::ffff:192.168.1.2, it sends it to its default router 2001::1
That router does a 6>4 translation, converting the destination to 192.168.1.2 and the source to 192.168.1.1 (or however it's configured)
It maintains the protocol/port/address in its state as any ipv4 natting router would do, and the response is "unnatted" as an "established connection" (with connection also applying for icmp/udp as v4 nat does today)
An application on Device A has no need to be ipv6 aware. The A record in DNS which resolves to 192.168.1.2 is reachable from device A despite it not having a V4 address. The hard coded IP database in it works fine.
Now if Device B wants to reach Device A, it uses traditional port forwarding on the router, where 192.168.1.1:80 is forwarded to [2001::1234]:80, with source of ::ffff:192.168.1.2
With this in place, there is no need to update any applications, and certainly no need for dual stack.
The missing bits are the lack of common 64/46 natting -- I don't believe it's built into the normal linux network chain like v4 nat is, and the lack of transparent upgrading of v4 handling on an OS level.