CFE-4723: Fixed default route selection to pick the lowest-metric route - #6302
Open
djbclark wants to merge 1 commit into
Open
CFE-4723: Fixed default route selection to pick the lowest-metric route#6302djbclark wants to merge 1 commit into
djbclark wants to merge 1 commit into
Conversation
GetNetworkingInfo() declared `long lowest_metric = 0;` and never assigned it again, so once any candidate had been chosen the guard `JsonPrimitiveGetAsInteger(metric) < lowest_metric` compared each later route's metric against 0 and could never be true for the non-negative metrics the kernel prints. The first active default route in /proc/net/route therefore always won, regardless of metric, ever since the loop was introduced (CFE-1991, first released in 3.9.0). The metric of the selected route is now recorded, so a later route with a strictly lower metric replaces the earlier choice; equal metrics keep the earlier entry, as before. On hosts with several active default routes where a lower-metric route appears after a higher-metric one, this changes the reported sys.inet.default_route and sys.inet.default_gateway to the lower-metric route. The selection loop moved into FindLowestMetricDefaultRoute() so that the new tests/unit/unix_iface_test.c can drive it with constructed route data; its lowest-metric-last case fails against the previous logic. Ticket: CFE-4723 Changelog: Title
|
Thanks for submitting a pull request! Maybe @larsewi can review this? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GetNetworkingInfo()inlibenv/unix_iface.cdeclaredlong lowest_metric = 0;and never assigned it again, so the guard
JsonPrimitiveGetAsInteger(metric) < lowest_metriccompared every later routeagainst 0 and could not be true for the non-negative metrics the kernel prints.
The first active default route in
/proc/net/routealways won. Present sincethe loop was introduced (CFE-1991, 3.9.0).
The fix records the selected route's metric so a strictly lower one replaces it;
equal metrics keep the earlier entry, as before.
Scope
Smaller than it sounds. The kernel emits default routes in ascending metric
order, so on most hosts the first route is the lowest and the reported
sys.inet.default_route/sys.inet.default_gatewaydo not change. It biteswhere a lower-metric default route appears after a higher-metric one.
What this does not fix
fib_priorityisu32butnet/ipv4/fib_trie.cprints it with%d, so ametric ≥ 2^31 renders with a leading
-, which the[[:xdigit:]]+capturecannot match. Those route lines are dropped before selection ever runs.
Pre-existing, orthogonal to this change, and deliberately not addressed here.
(Relatedly,
metricandirttare decimal fields captured as[[:xdigit:]]+while
refcnt/use/mtu/windowuse\d+. Over-permissive rather thanwrong — decimal is a subset of xdigit — so it is left alone.)
Tests
The selection loop moved into a static
FindLowestMetricDefaultRoute()sotests/unit/unix_iface_test.ccan drive it with constructed route data, via the#include <unix_iface.c>patternsysinfo_testalready uses, guarded byif !NT. 7 cases.Discrimination: deleting only the line
lowest_metric = metric_value;buildsclean and fails exactly
test_lowest_metric_last(
"192.168.0.1" != "192.168.0.3"— first route winning instead of lowest).test_lowest_metric_firstis a deliberate control and passes against theunfixed code too. The file restores byte-identical (sha256
4e6bd587…9e843)and all 7 pass again.
This is a Linux
/proc/net/routepath and it was developed on macOS 26.6.1arm64. The unit tests feed constructed route data, so they run anywhere; there
is no end-to-end test crossing a real
/proc/net/route. Worth a Linux eye.Cut from master
17eb78e6d. Tracked asCFE-4723.