Commit 5338178d authored by Thomas Haller's avatar Thomas Haller

policy: merge branch 'th/bgo735512_route_metric_v2'

Further fixes to NMDefaultRouteManager.

https://bugzilla.gnome.org/show_bug.cgi?id=735512
parents 9f5cff0b a0f81f26
......@@ -238,11 +238,14 @@ typedef struct {
IpState ip4_state;
NMIP4Config * dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */
NMIP4Config * ext_ip4_config; /* Stuff added outside NM */
gboolean ext_ip4_config_had_any_addresses;
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;
......@@ -273,6 +276,7 @@ typedef struct {
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
NMIP6Config * wwan_ip6_config;
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
gboolean ext_ip6_config_had_any_addresses;
gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */
NMRDisc * rdisc;
......@@ -724,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;
......@@ -732,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_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;
......@@ -744,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_is_assumed;
return priv->default_route.v6_has ? &priv->default_route.v6 : NULL;
}
......@@ -2782,8 +2792,10 @@ ip4_config_merge_and_apply (NMDevice *self,
*/
connection = nm_device_get_connection (self);
priv->default_route.v4_has = FALSE;
priv->default_route.v4_is_assumed = TRUE;
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,
......@@ -2802,13 +2814,17 @@ 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 {
priv->default_route.v4_is_assumed = FALSE;
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
* addresses for the route. */
gateway = nm_ip4_config_get_gateway (composite);
if ( gateway
|| nm_device_get_device_type (self) == NM_DEVICE_TYPE_MODEM) {
......@@ -2832,6 +2848,10 @@ 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);
}
}
......@@ -3331,8 +3351,10 @@ ip6_config_merge_and_apply (NMDevice *self,
*/
connection = nm_device_get_connection (self);
priv->default_route.v6_has = FALSE;
priv->default_route.v6_is_assumed = TRUE;
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,
......@@ -3351,13 +3373,17 @@ 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 {
priv->default_route.v6_is_assumed = FALSE;
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
* addresses for the route. */
gateway = nm_ip6_config_get_gateway (composite);
if (gateway) {
memset (route, 0, sizeof (*route));
......@@ -3380,6 +3406,10 @@ 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);
}
}
......@@ -6336,7 +6366,8 @@ update_ip_config (NMDevice *self, gboolean initial)
/* IPv4 */
g_clear_object (&priv->ext_ip4_config);
priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf);
priv->ext_ip4_config_had_any_addresses = ( priv->ext_ip4_config
&& nm_ip4_config_get_num_addresses (priv->ext_ip4_config) > 0);
if (priv->ext_ip4_config) {
if (initial) {
g_clear_object (&priv->dev_ip4_config);
......@@ -6355,6 +6386,8 @@ update_ip_config (NMDevice *self, gboolean initial)
/* IPv6 */
g_clear_object (&priv->ext_ip6_config);
priv->ext_ip6_config = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
priv->ext_ip6_config_had_any_addresses = ( priv->ext_ip6_config
&& nm_ip6_config_get_num_addresses (priv->ext_ip6_config) > 0);
if (priv->ext_ip6_config) {
/* Check this before modifying ext_ip6_config */
......@@ -6933,10 +6966,12 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure)
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
priv->default_route.v4_has = FALSE;
priv->default_route.v4_is_assumed = TRUE;
priv->default_route.v6_has = FALSE;
priv->default_route.v6_is_assumed = TRUE;
nm_default_route_manager_ip4_remove_default_route (nm_default_route_manager_get (), self);
nm_default_route_manager_ip6_remove_default_route (nm_default_route_manager_get (), self);
nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
/* Clean up IP configs; this does not actually deconfigure the
* interface; the caller must flush routes and addresses explicitly.
......@@ -6954,6 +6989,9 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure)
g_clear_object (&priv->wwan_ip6_config);
g_clear_object (&priv->ip6_config);
priv->ext_ip4_config_had_any_addresses = FALSE;
priv->ext_ip6_config_had_any_addresses = FALSE;
clear_act_request (self);
/* Clear legacy IPv4 address property */
......@@ -7730,6 +7768,9 @@ nm_device_init (NMDevice *self)
priv->unmanaged_flags = NM_UNMANAGED_INTERNAL;
priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
priv->default_route.v4_is_assumed = TRUE;
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);
......
This diff is collapsed.
......@@ -51,9 +51,6 @@ NMDefaultRouteManager *nm_default_route_manager_get (void);
void nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *manager, gpointer source);
void nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *manager, gpointer source);
void nm_default_route_manager_ip4_remove_default_route (NMDefaultRouteManager *manager, gpointer source);
void nm_default_route_manager_ip6_remove_default_route (NMDefaultRouteManager *manager, gpointer source);
gboolean nm_default_route_manager_ip4_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection);
gboolean nm_default_route_manager_ip6_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection);
......
......@@ -175,6 +175,12 @@ struct _NMPlatformIP6Address {
};
G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Address, address));
typedef union {
NMPlatformIPAddress ax;
NMPlatformIP4Address a4;
NMPlatformIP6Address a6;
} NMPlatformIPXAddress;
#undef __NMPlatformIPAddress_COMMON
......@@ -215,6 +221,12 @@ struct _NMPlatformIP6Route {
};
G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Route, network));
typedef union {
NMPlatformIPRoute rx;
NMPlatformIP4Route r4;
NMPlatformIP6Route r6;
} NMPlatformIPXRoute;
#undef __NMPlatformIPRoute_COMMON
......
......@@ -237,9 +237,6 @@ vpn_cleanup (NMVpnConnection *connection, NMDevice *parent_dev)
nm_platform_address_flush (priv->ip_ifindex);
}
nm_default_route_manager_ip4_remove_default_route (nm_default_route_manager_get (), connection);
nm_default_route_manager_ip6_remove_default_route (nm_default_route_manager_get (), connection);
nm_device_set_vpn4_config (parent_dev, NULL);
nm_device_set_vpn6_config (parent_dev, NULL);
......@@ -327,10 +324,8 @@ _set_vpn_state (NMVpnConnection *connection,
dispatcher_cleanup (connection);
if (vpn_state >= STATE_DISCONNECTED && vpn_state <= STATE_FAILED) {
nm_default_route_manager_ip4_remove_default_route (nm_default_route_manager_get (), connection);
nm_default_route_manager_ip6_remove_default_route (nm_default_route_manager_get (), connection);
}
nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), connection);
nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), connection);
/* The connection gets destroyed by the VPN manager when it enters the
* disconnected/failed state, but we need to keep it around for a bit
......
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