Kernel does not all allow to configure a route via a gateway, if the gateway is not directly reachable.
For non-manually added routes (e.g. from DHCP), we ignore them as a server configuration errors. For manually added routes, we try to work around them.
Note that if the user adds a manual route that references a gateway, maybe he should be required to also add a matching onlink route for the gateway (or an address that results in a device-route), otherwise the configuration could be considered invalid. That was however not done historically, and also, it seems a rather unhelpful behavior. NetworkManage should just make it work, not not assume anything is wrong with the configuration. Similarly, for IPv4, the user could configure the route as onlink, however, that still requires extra configuration of which the user might not be aware.
This would apply for example, when a connection has method=auto, and would obtain the routes automatically. It seems sensible to allow the user to add a route via the gateway, if he ~knows~ that this particular network will provide such a configuration via DHCP.
In the past however, we tried not to automatically add a device route, but instead see whether we will get a suitable route via DHCP. If we wouldn't get such a route, we would however fail the connection. However, this is really very hard to get right. We call ip_config_merge_and_apply() possibly before receiving automatic IP configuration (commit 7070d17cedd09d07f12ce977dd1e16cecf8d4b45, "device: reset @con_ip6_config on failure before RA"). In this case, we could not yet configure the route. Instead, we also cannot fail (yet), because we should wait whether we will receive a route that makes this configuration feasable. That is hard to get right. How long should we wait? If we get a DHCP lease and still cannot add the route, should we fail the IP configuration or wait longer for another lease? Worse, if we decide to fail the IP configuration, it might not fail the entire activation. Instead, we would only mark the current address family as failed. If we later get a DHCP lease, should we retry to add the route again? -- probably yes. If we still fail, we would need to keep the IP configuration in failed state, regardless that DHCP succeeded. Part of the problem is, that we are bad at tracking the failed state per IP method. So, if manual configuration fails but DHCP succeeds, we get the state wrong. That should be fixed separately, but it just shows how hard it is to have this route that we currently cannot add, and wanting to wait for something that might never come, but still fail at some point.
Instead, if we cannot add a route due to a missing onlink gateway, just retry and add the /32 or /128 direct route ourself.
Note that for IPv6 routes that have a "src" address which is still TENTATIVE, we also cannot currently add the route and retry later. However, that is fundamentally different, because:- the configuration here is correct, it's only that the address didn't yet pass IPv6 DAD and kernel is being unhelpful (rh#1457196).
- we only have to wait a few seconds for DAD to complete or fail. So, it's easy to implement this sensibly.
c9f89cafd platform: adding onlink gateway route for manual addresses
src/devices/nm-device.c | 4 +--
src/platform/nm-platform.c | 72 +++++++++++++++++++++++++++++++++++++---------
src/platform/nmp-object.c | 2 +-
src/platform/nmp-object.h | 2 +-
4 files changed, 62 insertions(+), 18 deletions(-)