464xlat bug? (missing ipv4)

I have an OpenWRT 25.12.2 “Dumb AP” device which is running ipv6 only with a single lan6 interface, and it sits on a LAN with a nat64 at the gateway. I can ping ipv4 sites using the well known prefix just fine, and so the remote PLAT is functioning. All is good for ipv6. For example:

root@openwrt:~# ping6 64:ff9b::8.8.8.8
PING 64:ff9b::8.8.8.8 (64:ff9b::808:808): 56 data bytes
64 bytes from 64:ff9b::808:808: seq=0 ttl=64 time=6.670 ms
64 bytes from 64:ff9b::808:808: seq=1 ttl=64 time=3.006 ms

I would like a CLAT on the AP, to provide seamless ipv4 locally so I install the 464xlat package and reboot. This automatically gives a new interface lan6_4 with protocol Virtual dynamic interface (464XLAT (CLAT)). I do not change any other configuration. I can now see:

root@openwrt:~# cat /proc/net/nat46/control
add 464-lan6_4
config 464-lan6_4 local.v4 192.0.0.1/32 local.v6 2600:bbbb:bbbb:bbbb:aaaa:aaaa:aaaa:aaaa/128 local.style NONE local.ea-len 0 local.psid-offset 0 remote.v4 0.0.0.0/0 remote.v6 64:ff9b::c000:aa/96 remote.style RFC6052 r

root@openwrt:~# ip addr show dev 464-lan6_4
2: 464-lan6_4: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 16384 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet6 fe80::cccc:cccc:cccc:ccc/64 scope link stable-privacy proto kernel_ll
       valid_lft forever preferred_lft forever

However it doesn’t function unless I manually add the ipv4 address to it:

root@openwrt:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss


root@openwrt:~# ip addr add 192.0.0.1/32 dev 464-lan6_4
root@openwrt:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=63 time=4.435 ms
64 bytes from 8.8.8.8: seq=1 ttl=63 time=3.595 ms
64 bytes from 8.8.8.8: seq=2 ttl=63 time=5.078 ms
64 bytes from 8.8.8.8: seq=3 ttl=63 time=7.447 ms
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 3.595/5.138/7.447 ms

I wonder if there is a bug in the /lib/netifd/proto/464xlat.sh script?

Note, the ip routes, ip rules, firewall, snat, etc are all correctly configured automatically. It’s simply missing the address on the automatically created interface itself.

Did you configure DNS64, too?

I'd start at the gateway. Later look into packaging it, so OpenWRT can do CLAT if its on a IPv6-only or IPv6-preferred network.

Remote DNS64 and NAT64 is working, for example:

# 1. IPv6 -> IPv4 (using DNS64 and NAT64 on the remote PLAT)
root@openwrt:~# ping -6 -c1 ipv4.google.com
PING ipv4.google.com (64:ff9b::8efb:d3ae): 56 data bytes
64 bytes from 64:ff9b::8efb:d3ae: seq=0 ttl=64 time=3.615 ms

--- ipv4.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss

But the default auto-generated local CLAT won’t work unless I manually add the NAT46 address to the auto-generated CLAT interface:

# 2. Using local IPv4 (via the CLAT's NAT46)
root@openwrt:~# ping -4 -c1 ipv4.google.com
PING ipv4.google.com (142.251.211.174): 56 data bytes
^C
--- ipv4.google.com ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss


# 3. Again, with the local CLAT interface now having the NAT46 address
root@openwrt:~# ip addr add 192.0.0.1/32 dev 464-lan6_4
root@openwrt:~# ping -4 -c1 ipv4.google.com
PING ipv4.google.com (142.251.211.174): 56 data bytes
64 bytes from 142.251.211.174: seq=0 ttl=63 time=3.896 ms

--- ipv4.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss

In all three ping tests above I see icmp6 echo and echo-reply pairs in tcpdump on the wire, but when the CLAT interface is missing the NAT46 address (scenario 2 above) I believe the kernel filters out the replies as the de-translated packets don’t match any local interface.

tl;dr I suspect there’s a bug in the CLAT setup script.