[Bug 268241] broken handling of icmp needfrag packets with libalias/ipfw_nat and smaller wan mtu
Date: Thu, 08 Dec 2022 11:31:26 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=268241 Bug ID: 268241 Summary: broken handling of icmp needfrag packets with libalias/ipfw_nat and smaller wan mtu Product: Base System Version: 13.1-RELEASE Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: john@sanren.ac.za Created attachment 238625 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=238625&action=edit patch to make needfrag packets work with nat and an interface with a smaller mtu on the same device. When using ipfw + nat on the same device as the wan interface and the mtu of the wan interface is smaller than the default, the created needfrag packets are not handled correctly. The problem is if a packet is received from the lan it will go through nat and gets translated to use the ip address of the outgoing interface as source ip. If it then tries to send it out, the output part of the stack will realize that it is too big and create the needfrag icmp packet. It will use the source ip as the destination and realize that is a local address and use 127.0.0.1 as the source address and route it on lo0. Currently libalias has no way to fix the source ip of 127.0.0.1. Using firewall rules like this: ##### wan="vtnet0" lan="vtnet1" ${fwcmd} nat 123 config if ${wan} log ${fwcmd} add 1000 count log all from any to any ${fwcmd} add 5000 nat 123 ip4 from any to any via ${wan} ${fwcmd} add 5050 nat 123 ip4 from any to not 127.0.0.1 via lo0 ${fwcmd} add 6000 allow log all from any to any ##### Results in the ipfw logs like this. (The client is 10.10.1.3, the wan interface/nat address is 10.10.2.2 and the test target is 10.10.5.5) ##### Dec 7 14:17:31 rtr kernel: ipfw: 1000 Count ICMP:8.0 10.10.1.3 10.10.5.5 in via vtnet1 Dec 7 14:17:31 rtr kernel: ipfw: 6000 Accept ICMP:8.0 10.10.1.3 10.10.5.5 in via vtnet1 Dec 7 14:17:31 rtr kernel: ipfw: 1000 Count ICMP:8.0 10.10.1.3 10.10.5.5 out via vtnet0 Dec 7 14:17:31 rtr kernel: ipfw: 6000 Accept ICMP:8.0 10.10.2.2 10.10.5.5 out via vtnet0 Dec 7 14:17:31 rtr kernel: ipfw: 1000 Count ICMP:3.4 127.0.0.1 10.10.2.2 out via lo0 Dec 7 14:17:31 rtr kernel: ipfw: 6000 Accept ICMP:3.4 127.0.0.1 10.10.2.2 out via lo0 Dec 7 14:17:31 rtr kernel: ipfw: 1000 Count ICMP:3.4 127.0.0.1 10.10.2.2 in via lo0 Dec 7 14:17:31 rtr kernel: ipfw: 6000 Accept ICMP:3.4 127.0.0.1 10.10.1.3 in via lo0 Dec 7 14:17:31 rtr kernel: ipfw: 1000 Count ICMP:3.4 127.0.0.1 10.10.1.3 out via vtnet1 Dec 7 14:17:31 rtr kernel: ipfw: 6000 Accept ICMP:3.4 127.0.0.1 10.10.1.3 out via vtnet1 ###### I have made a patch to libalias/alias.c in IcmpAliasIn2() to check if the source ip is IN_LOOPBACK() and the destination is not IN_LOOPBACK() and then just copy the destination to the source address. There might be better ways and it might be better to use the ip address of the outgoing interface as the source, but it did not seem easy to retrieve that from inside libalias. With this ping and ssh works as expected. Regards John -- You are receiving this mail because: You are the assignee for the bug.