From 2079f8361c4c50ac9ef416acb19bc3a23054d877 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 17:01:02 +0200 Subject: device: fix wrongly deleting default-route on exit We must preserve the default-route on shutdown. Thus it must first be announced as "assumed", and only removed in a second step. Fixes: 9498ea507eb1d5042736c4351337e91b9c13bdf6 --- src/devices/nm-device.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4bc1b1079d..0acc22f063 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2634,11 +2634,20 @@ nm_device_removed (NMDevice *self) * is reacting via NM_DEVICE_IP4_CONFIG_CHANGED/NM_DEVICE_IP6_CONFIG_CHANGED * signal. As NMPolicy registered the NMIPxConfig instances in NMDnsManager, * these would be leaked otherwise. */ + if ( priv->default_route.v4_has + && !priv->default_route.v4_is_assumed) { + priv->default_route.v4_is_assumed = TRUE; + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + } + if ( priv->default_route.v6_has + && !priv->default_route.v6_is_assumed) { + priv->default_route.v6_is_assumed = TRUE; + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + } + priv->default_route.v4_has = FALSE; - priv->default_route.v4_is_assumed = TRUE; nm_device_set_ip4_config (self, NULL, 0, FALSE, FALSE, NULL); priv->default_route.v6_has = FALSE; - priv->default_route.v6_is_assumed = TRUE; nm_device_set_ip6_config (self, NULL, FALSE, FALSE, NULL); } -- cgit v1.2.1 From b2f794fe1e9adc5e9e6a1b55769169d1e2abac28 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 17:43:17 +0200 Subject: device: refactor clearing default-route in NMDevice Add a function _update_default_route() to set the default_route flags and call update() in one step. Also, if there are no changes, skip the call to NMDefaultRouteManager's update(). --- src/devices/nm-device.c | 69 ++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 0acc22f063..70aa2a1485 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -280,11 +280,11 @@ typedef struct _NMDevicePrivate { NMIP4Config * wwan_ip4_config; /* WWAN configuration */ GSList * vpn4_configs; /* VPNs which use this device */ struct { - gboolean v4_has; - gboolean v4_is_assumed; + bool v4_has; + bool v4_is_assumed; + bool v6_has; + bool v6_is_assumed; NMPlatformIP4Route v4; - gboolean v6_has; - gboolean v6_is_assumed; NMPlatformIP6Route v6; } default_route; @@ -879,6 +879,34 @@ nm_device_get_ip6_route_metric (NMDevice *self) return _get_ipx_route_metric (self, FALSE); } +static void +_update_default_route (NMDevice *self, int addr_family, gboolean has, gboolean is_assumed) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + bool *p_has, *p_is_assumed; + + nm_assert (NM_IN_SET (addr_family, 0, AF_INET, AF_INET6)); + + if (addr_family == AF_INET) { + p_has = &priv->default_route.v4_has; + p_is_assumed = &priv->default_route.v4_is_assumed; + } else { + p_has = &priv->default_route.v6_has; + p_is_assumed = &priv->default_route.v6_is_assumed; + } + + if (*p_has == has && *p_is_assumed == is_assumed) + return; + + *p_has = has; + *p_is_assumed = is_assumed; + + if (addr_family == AF_INET) + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + else + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); +} + const NMPlatformIP4Route * nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed) { @@ -2634,20 +2662,11 @@ nm_device_removed (NMDevice *self) * is reacting via NM_DEVICE_IP4_CONFIG_CHANGED/NM_DEVICE_IP6_CONFIG_CHANGED * signal. As NMPolicy registered the NMIPxConfig instances in NMDnsManager, * these would be leaked otherwise. */ - if ( priv->default_route.v4_has - && !priv->default_route.v4_is_assumed) { - priv->default_route.v4_is_assumed = TRUE; - nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); - } - if ( priv->default_route.v6_has - && !priv->default_route.v6_is_assumed) { - priv->default_route.v6_is_assumed = TRUE; - nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); - } - - priv->default_route.v4_has = FALSE; + _update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE); + _update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE); + _update_default_route (self, AF_INET, FALSE, TRUE); + _update_default_route (self, AF_INET6, FALSE, TRUE); nm_device_set_ip4_config (self, NULL, 0, FALSE, FALSE, NULL); - priv->default_route.v6_has = FALSE; nm_device_set_ip6_config (self, NULL, FALSE, FALSE, NULL); } @@ -10045,20 +10064,12 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - priv->default_route.v4_has = FALSE; - priv->default_route.v6_has = FALSE; - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - priv->default_route.v4_is_assumed = FALSE; - priv->default_route.v6_is_assumed = FALSE; - 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); + _update_default_route (self, AF_INET, FALSE, FALSE); + _update_default_route (self, AF_INET6, FALSE, FALSE); } - - priv->default_route.v4_is_assumed = TRUE; - priv->default_route.v6_is_assumed = TRUE; - 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); + _update_default_route (self, AF_INET, FALSE, TRUE); + _update_default_route (self, AF_INET6, FALSE, TRUE); priv->v4_commit_first_time = TRUE; priv->v6_commit_first_time = TRUE; -- cgit v1.2.1 From 4697376f990fdfe048b1978aaf64205da826f412 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 17:43:17 +0200 Subject: device: fix preserving the default-route during _cleanup_generic_post() When we want to preserve the default-route on cleanup, we must first set it to assumed, before clearing it. Otherwise, NMDefaultRouteManager's update() will delete the default route. This is the oposite of the deconfigure case, where we first set it to !has && !assumed, to force the route-manager to delete the route. --- src/devices/nm-device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 70aa2a1485..1c6612df8f 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -10067,6 +10067,9 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { _update_default_route (self, AF_INET, FALSE, FALSE); _update_default_route (self, AF_INET6, FALSE, FALSE); + } else { + _update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE); + _update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE); } _update_default_route (self, AF_INET, FALSE, TRUE); _update_default_route (self, AF_INET6, FALSE, TRUE); -- cgit v1.2.1