As reported in bin/237391, route(8) treats some addresses as network addresses:
route -nv get 10.0.0.0
RTA_DST: inet 10.0.0.0; RTA_NETMASK: inet 255.0.0.0; RTA_IFP: link ; RTM_GET: Report Metrics: len 240, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,STATIC> locks: inits: sockaddrs: <DST,NETMASK,IFP> 10.0.0.0 255.0.0.0 link#0 route: route has not been found
Note added RTA_NETMASK in the request.
Host address from the same network is ok:
route -nv get 10.0.0.1
RTA_DST: inet 10.0.0.1; RTA_IFP: link ; RTM_GET: Report Metrics: len 224, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,HOST,STATIC> ... route to: 10.0.0.1 destination: 10.0.0.0 mask: 255.255.255.0
This is due to the logic that tries to "guess" netmask for the network-looking adresses by using long-forgotten functions like inet_lnaof().
The proposed change is simple: eliminate the entire guessing part and simplify the whole part.
route(8) manual suggests the following syntax variations are permitted (permutations with *-host* or *-net* flags skipped):
- add 1.1.1.1 GW (treated as a host)
- add 1.1.1.1 GW 255.255.0.0 (treated as a network)
- add somehost.com GW (DNS resolve for a host)
- add some_network GW (getnetbyname() reading /etc/networks and auto-guessing mask)
- add some_network GW 255.255.255.0 OR some_netmask
- add 1.1.1.1/32 GW
I propose to eliminate (4), (5) for the following reasons:
- rc.conf seem to be the master source of data for interface networks and static routes
- Again, modern way of storing static routes is either variations of rc.conf or the routing daemon.
- getnetbyname() does not support IPv6
- default handling assumes classful approach, which was deprecated 10+ years ago
The interesting part is how can we backport (any) of similar changes to solve the original problem, though..