I'm trying to forward protocol 41 (ipv6-in-ipv4) for an HE tunnel through a WRT54G running Tomato 1.28. Tomato 1.28 is running a 2.4 kernel that knows absolutely nothing about protocol 41, except that it is named "ipv6". Having a 2.4 kernel also appears to mean that conntrack can't just be disabled: there are no "raw" iptables rules.
I can set up rules so that incoming packets are DNAT-ed to the correct internal host. If the remote host sends something over the tunnel first, everything works fine. Packets can flow over the tunnel in both directions with proper NATing, and I get a
/proc/net/ip_conntrack entry like this:
unknown 41 599 src=184.108.40.206 dst=220.127.116.11 src=10.1.0.3 dst=18.104.22.168 use=1 mark=0
The entry says it's for the unknown protocol 41, has a timeout of 599 more seconds if no more traffic is received, and has one pair of source and destination addresses on the initiating side (which is the WAN side) and another on the receiving side (which is the LAN side).
But if my system tries to send a packet out over the tunnel first, the source address does not get translated to the address of the router like it should, and I get a conntrack entry like this:
unknown 41 589 src=10.1.0.3 dst=22.214.171.124 [UNREPLIED] src=126.96.36.199 dst=10.1.0.3 use=1 mark=0
As long as my machine keeps trying to use the tunnel, it keeps this bogus conntrack entry alive, and I can see the packets leaving my router for the cable modem with the internal source address still attached, causing them to be dropped and never get where they're going.
To get my tunnel to come up, I have to bring down the tunnel interface on my end, use the HE ping tool to induce some IPv6 traffic to come down the pipe, and, while the 10-minute timeout is still active on the correct conntrack entry, bring my end of the tunnel back up again--and then ensure it is never idle for 10 minutes at a stretch. I can do that, but it's pretty stupid.
Right now I have my forwarding rules set up like this:
# Send incoming ipv6-in-ipv4 packets to the correct host iptables -t nat -A PREROUTING -p 41 -s 188.8.131.52 -j DNAT --to 10.1.0.3 # Allow those packets through the firewall iptables -I FORWARD -p 41 -d 10.1.0.3 -j ACCEPT # Things I have added to try and solve my problem, which didn't work: # Remove the default masquerade-everything rule iptables -t nat -D POSTROUTING 10 # Masquerade only protocols other than 41. Conntrack still gets its bogus entries, # and if I get the correct entry in it still works. iptables -t nat -A POSTROUTING -p ! 41 -j MASQUERADE
I also at one point tried setting up an SNAT rule like this:
iptables -t nat -I POSTROUTING -p 41 -s 10.1.0.3 -j SNAT --to 184.108.40.206
But as far as I could tell, that was no help either.
So my question is:
1) Has anyone ever gotten protocol 41 to forward through a WRT54G running Tomato successfully? If so, what special firewall rules did you use?
2) Why does the router think it doesn't have to do source address translation on outgoing protocol 41?