Google did not help me. Easy to repeat: 2 gateways: 1. rl0=1.2.3.2/30, gateway 1.2.3.1 2. rl1 PPPoE (/usr/sbin/ppp) tun0 5.6.7.8 --> 9.10.11.12 netmask 0xffffffff 2 rules: fwd 9.10.11.12 ip from 5.6.7.8 to not 192.168.0.0/16 out fwd 1.2.3.1 ip from 1.2.3.2 to not 192.168.0.0/16 out script: gwvo=$(/sbin/ifconfig | grep "inet 5.6.7.8" | awk '{print $4}') usualy give me '9.10.11.12' if PPPoE provider had been in down before router booted, then $(gwvo) took on empty value and /sbin/route change default ${gwvo} result default route is absent and ping -S 1.2.3.2 8.8.8.8 answer me "no route to host" and fwd 1.2.3.1 ip from 1.2.3.2 to not 192.168.0.0/16 out stop forward (and count) packets
If ipfw rule's counter didn't increased, this means a packet doesn't matched the rule. Since you don't have gateway, system couldn't determine outbound interface. So, "out" opcode in the rule is cause, why it didn't matched.
Also it is possible that a packet didn't reached ipfw and dropped before pfil processing. You need enable verbose logging in the rules to see what happens. Also look at the `netstat -sp ip | grep discard` counter.
Thank You for answer! netstat -sp ip | grep discard is incremeting while pinging without default gateway. I opened thread https://forums.freebsd.org/threads/57456/ I understood that router must try to router packet through the any interface (even with status "no carrier" like in experiment was described in forum) and only in such case ipfw fwd external_ip begins to work. "The reason it probably works with a "fake" gateway is because it's sending a bunch of ICMP redirects, directing it to the proper gateway."