I would have expected to see an ESRCH if the provided gateway does not match the destination specified. See log below. root@lgbsd:~/Desktop # netstat -r Routing tables Internet: Destination Gateway Flags Netif Expire default 192.168.180.2 UGS em0 localhost link#2 UH lo0 192.168.180.0/24 link#1 U em0 192.168.180.128 link#1 UHS lo0 Internet6: Destination Gateway Flags Netif Expire ::/96 localhost UGRS lo0 localhost link#2 UH lo0 ::ffff:0.0.0.0/96 localhost UGRS lo0 fe80::/10 localhost UGRS lo0 fe80::%lo0/64 link#2 U lo0 fe80::1%lo0 link#2 UHS lo0 ff02::/16 localhost UGRS lo0 root@lgbsd:~/Desktop # route delete -net default 10.11.12.13 delete net default: gateway 10.11.12.13 root@lgbsd:~/Desktop # netstat -r Routing tables Internet: Destination Gateway Flags Netif Expire localhost link#2 UH lo0 192.168.180.0/24 link#1 U em0 192.168.180.128 link#1 UHS lo0 Internet6: Destination Gateway Flags Netif Expire ::/96 localhost UGRS lo0 localhost link#2 UH lo0 ::ffff:0.0.0.0/96 localhost UGRS lo0 fe80::/10 localhost UGRS lo0 fe80::%lo0/64 link#2 U lo0 fe80::1%lo0 link#2 UHS lo0 ff02::/16 localhost UGRS lo0 I can then also delete the destination subnet route and that causes all traffic to fail. root@lgbsd:~/Desktop # route delete -net 192.168.180.0/24 10.11.12.13 delete net 192.168.180.0: gateway 10.11.12.13 root@lgbsd:~/Desktop # ping 192.168.180.1 PING 192.168.180.1 (192.168.180.1): 56 data bytes ping: sendto: No route to host
IIRC gateway value is simply ignored in GENERIC kernel - the only thing that code checks is the prefix. This part has been changed in 13 - if a gateway is specified, then the route gateway(s) are checked for the match. I agree that 12 behaviour may look weird, however, that's what existed historically. I'm not sure if we can change it in FreeBSD 12, as we need to preserve compatibility any people may rely on this behaviour. Re interface route: could you please clarify what do you think should be the expected behaviour?
I'll close this PR on Jun 5 if there are no other questions.