diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b505f3ed74..2a93f3e0dc 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -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; } } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 840a19c08b..64687f7cbe 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -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); diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index ec1d07c741..e5aa9b1eee 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -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 */;