To read the routing table, we call sysctl() with a NULL pointer to get the size of the result (needed), then allocate a buffer that large, and then call sysctl() for real.
However, if you are operating a large router, like a BGP full feed, your routing table is changing constantly, and the routing table may grow by one or more entries between the estimate, and the actual read.
Currently, this results in the confusing error message:
# netstat -rnf inet Routing tables netstat: sysctl: net.route.0.2.dump.0: Cannot allocate memory
On a router with 12GB of free memory. Memory allocation did not fail, rather the buffer we passed to sysctl() was insufficient because some additional routes were added in the mean time.
This patch will expand needed by 25% over the most recent estimate and try again, up to 10 times.
During convergence, when 100s of thousands of routes are being added rapidly, this can be the difference between being able to read the routing table, and not.
This patch was inspired by one Hiroki offered on the mailing list in 2014.
https://lists.freebsd.org/pipermail/freebsd-current/2014-February/thread.html#48412
That version of the patch only grew the buffer by 4kb, however the routing table in this case is over 180 MB, and the churn may be more than the ~16 additional routes that would fit in an extra 4kb of memory.