Page MenuHomeFreeBSD

Remove remnants of classful behavior in route(8).

Authored by melifaro on Apr 13 2020, 8:06 PM.



As reported in bin/237391, route(8) treats some addresses as network addresses:

route -nv get
RTA_DST: inet; RTA_NETMASK: inet; 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> 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
RTA_DST: inet; RTA_IFP: link ; RTM_GET: Report Metrics: len 224, pid: 0, seq 1, errno 0, flags:<UP,GATEWAY,HOST,STATIC>
   route to:

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):

  1. add GW (treated as a host)
  2. add GW (treated as a network)
  3. add GW (DNS resolve for a host)
  4. add some_network GW (getnetbyname() reading /etc/networks and auto-guessing mask)
  5. add some_network GW OR some_netmask
  6. add 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..

Diff Detail

R10 FreeBSD src repository
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.