Commit 1f5f576c authored by Thomas Haller's avatar Thomas Haller

policy: pick up externally configured default routes for managed interfaces

The previous commit made NM enforce the default route on interfaces for
which NM manages a default route.

For interfaces that are configured never-default, NM will now pick up
any externally configured default route, as if it was managed by NM.
This is important, because NMDefaultRouteManager needs a notion of which
is the best device. Without this change, it was agnostic to default routes
on managed, never-default interfaces.
Signed-off-by: Thomas Haller's avatarThomas Haller <thaller@redhat.com>
parent 16b0ddb6
......@@ -242,8 +242,10 @@ typedef struct {
NMIP4Config * wwan_ip4_config; /* WWAN configuration */
struct {
gboolean v4_has;
gboolean v4_is_assumed;
NMPlatformIP4Route v4;
gboolean v6_has;
gboolean v6_is_assumed;
NMPlatformIP6Route v6;
} default_route;
......@@ -726,7 +728,7 @@ nm_device_get_ip6_route_metric (NMDevice *self)
}
const NMPlatformIP4Route *
nm_device_get_ip4_default_route (NMDevice *self)
nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed)
{
NMDevicePrivate *priv;
......@@ -734,11 +736,14 @@ nm_device_get_ip4_default_route (NMDevice *self)
priv = NM_DEVICE_GET_PRIVATE (self);
if (out_is_assumed)
*out_is_assumed = priv->default_route.v4_has && priv->default_route.v4_is_assumed;
return priv->default_route.v4_has ? &priv->default_route.v4 : NULL;
}
const NMPlatformIP6Route *
nm_device_get_ip6_default_route (NMDevice *self)
nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed)
{
NMDevicePrivate *priv;
......@@ -746,6 +751,9 @@ nm_device_get_ip6_default_route (NMDevice *self)
priv = NM_DEVICE_GET_PRIVATE (self);
if (out_is_assumed)
*out_is_assumed = priv->default_route.v6_has && priv->default_route.v6_is_assumed;
return priv->default_route.v6_has ? &priv->default_route.v6 : NULL;
}
......@@ -2786,6 +2794,7 @@ ip4_config_merge_and_apply (NMDevice *self,
priv->default_route.v4_has = FALSE;
if (connection) {
gboolean assumed = nm_device_uses_assumed_connection (self);
NMPlatformIP4Route *route = &priv->default_route.v4;
if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) {
nm_ip4_config_merge_setting (composite,
......@@ -2804,14 +2813,12 @@ ip4_config_merge_and_apply (NMDevice *self,
* NMDefaultRouteManager eventually configures (because the it might
* tweak the effective metric).
*/
if (nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection)) {
if ( !assumed
&& nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection)) {
guint32 gateway = 0;
NMPlatformIP4Route *route = &priv->default_route.v4;
if (assumed)
priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) route);
else if ( (!commit && priv->ext_ip4_config_had_any_addresses)
|| ( commit && nm_ip4_config_get_num_addresses (composite))) {
if ( (!commit && priv->ext_ip4_config_had_any_addresses)
|| ( commit && nm_ip4_config_get_num_addresses (composite))) {
/* For managed interfaces, we can only configure a gateway, if either the external config indicates
* that we already have addresses, or if we are about to commit any addresses.
* Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any
......@@ -2825,6 +2832,7 @@ ip4_config_merge_and_apply (NMDevice *self,
route->metric = nm_device_get_ip4_route_metric (self);
route->mss = nm_ip4_config_get_mss (composite);
priv->default_route.v4_has = TRUE;
priv->default_route.v4_is_assumed = FALSE;
if ( gateway
&& !nm_ip4_config_get_subnet_for_host (composite, gateway)
......@@ -2839,6 +2847,11 @@ ip4_config_merge_and_apply (NMDevice *self,
}
}
}
} else {
/* For interfaces that are assumed and that have no default-route by configuration, we assume
* the default connection and pick up whatever is configured. */
priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) route);
priv->default_route.v4_is_assumed = TRUE;
}
}
......@@ -3340,6 +3353,7 @@ ip6_config_merge_and_apply (NMDevice *self,
priv->default_route.v6_has = FALSE;
if (connection) {
gboolean assumed = nm_device_uses_assumed_connection (self);
NMPlatformIP6Route *route = &priv->default_route.v6;
if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) {
nm_ip6_config_merge_setting (composite,
......@@ -3358,14 +3372,12 @@ ip6_config_merge_and_apply (NMDevice *self,
* NMDefaultRouteManager eventually configures (because the it might
* tweak the effective metric).
*/
if (nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection)) {
if ( !assumed
&& nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection)) {
const struct in6_addr *gateway = NULL;
NMPlatformIP6Route *route = &priv->default_route.v6;
if (assumed)
priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) route);
else if ( (!commit && priv->ext_ip6_config_had_any_addresses)
|| ( commit && nm_ip6_config_get_num_addresses (composite))) {
if ( (!commit && priv->ext_ip6_config_had_any_addresses)
|| ( commit && nm_ip6_config_get_num_addresses (composite))) {
/* For managed interfaces, we can only configure a gateway, if either the external config indicates
* that we already have addresses, or if we are about to commit any addresses.
* Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any
......@@ -3378,6 +3390,7 @@ ip6_config_merge_and_apply (NMDevice *self,
route->metric = nm_device_get_ip6_route_metric (self);
route->mss = nm_ip6_config_get_mss (composite);
priv->default_route.v6_has = TRUE;
priv->default_route.v6_is_assumed = FALSE;
if ( gateway
&& !nm_ip6_config_get_subnet_for_host (composite, gateway)
......@@ -3392,6 +3405,11 @@ ip6_config_merge_and_apply (NMDevice *self,
}
}
}
} else {
/* For interfaces that are assumed and that have no default-route by configuration, we assume
* the default connection and pick up whatever is configured. */
priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) route);
priv->default_route.v6_is_assumed = TRUE;
}
}
......
......@@ -362,8 +362,8 @@ gboolean nm_device_owns_iface (NMDevice *device, const char *iface);
NMConnection *nm_device_new_default_connection (NMDevice *self);
const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self);
const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self);
const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed);
const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed);
void nm_device_spawn_iface_helper (NMDevice *self);
......
......@@ -600,6 +600,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
NMVpnConnection *vpn = NULL;
gboolean never_default = FALSE;
gboolean synced;
gboolean is_assumed = FALSE;
g_return_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self));
if (NM_IS_DEVICE (source))
......@@ -646,9 +647,9 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
if (ip_ifindex > 0) {
if (device) {
if (VTABLE_IS_IP4)
default_route = (const NMPlatformIPRoute *) nm_device_get_ip4_default_route (device);
default_route = (const NMPlatformIPRoute *) nm_device_get_ip4_default_route (device, &is_assumed);
else
default_route = (const NMPlatformIPRoute *) nm_device_get_ip6_default_route (device);
default_route = (const NMPlatformIPRoute *) nm_device_get_ip6_default_route (device, &is_assumed);
} else {
NMConnection *connection = nm_active_connection_get_connection ((NMActiveConnection *) vpn);
......@@ -692,7 +693,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
/* if the source is never_default or the device uses an assumed connection,
* we don't sync the route. */
synced = !never_default && (!device || !nm_device_uses_assumed_connection (device));
synced = !never_default && !is_assumed;
if (!entry && !default_route)
/* nothing to do */;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment