From 207c0f5f8163af9432d2f31c87a9974a765ff8e8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 21 Mar 2016 15:22:10 +0100 Subject: [PATCH 1/3] platform: add nm_platform_link_can_assume() --- src/platform/nm-linux-platform.c | 45 ++++++++++++++++++++++++++++++++ src/platform/nm-platform.c | 12 +++++++++ src/platform/nm-platform.h | 4 +++ 3 files changed, 61 insertions(+) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 14301598bf..3282e698ce 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -5128,6 +5128,49 @@ wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean ru /******************************************************************/ +static gboolean +link_can_assume (NMPlatform *platform, int ifindex) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + NMPCacheId cache_id; + const NMPlatformObject *const *objs; + guint i, len; + const NMPObject *link; + + if (ifindex <= 0) + return FALSE; + + link = cache_lookup_link (platform, ifindex); + if (!link) + return FALSE; + + if (!NM_FLAGS_HAS (link->link.n_ifi_flags, IFF_UP)) + return FALSE; + + if (link->link.master > 0) + return TRUE; + + if (nmp_cache_lookup_multi (priv->cache, + nmp_cache_id_init_addrroute_visible_by_ifindex (&cache_id, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex), + NULL)) + return TRUE; + + objs = nmp_cache_lookup_multi (priv->cache, + nmp_cache_id_init_addrroute_visible_by_ifindex (&cache_id, NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex), + &len); + if (objs) { + for (i = 0; i < len; i++) { + const NMPlatformIP6Address *a = (NMPlatformIP6Address *) objs[i]; + + if (!IN6_IS_ADDR_LINKLOCAL (&a->address)) + return TRUE; + } + } + return FALSE; +} + +/******************************************************************/ + static guint32 mesh_get_channel (NMPlatform *platform, int ifindex) { @@ -6218,6 +6261,8 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_enslave = link_enslave; platform_class->link_release = link_release; + platform_class->link_can_assume = link_can_assume; + platform_class->vlan_add = vlan_add; platform_class->link_vlan_change = link_vlan_change; platform_class->link_vxlan_add = link_vxlan_add; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index d5ee48d49f..5a399b316a 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1378,6 +1378,18 @@ nm_platform_link_get_master (NMPlatform *self, int slave) /*****************************************************************************/ +gboolean +nm_platform_link_can_assume (NMPlatform *self, int ifindex) +{ + _CHECK_SELF (self, klass, FALSE); + + if (klass->link_can_assume) + return klass->link_can_assume (self, ifindex); + g_return_val_if_reached (FALSE); +} + +/*****************************************************************************/ + /** * nm_platform_link_get_lnk: * @self: the platform instance diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 8c97f7668a..15bd2fdeef 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -528,6 +528,8 @@ typedef struct { gboolean (*link_enslave) (NMPlatform *, int master, int slave); gboolean (*link_release) (NMPlatform *, int master, int slave); + gboolean (*link_can_assume) (NMPlatform *, int ifindex); + gboolean (*vlan_add) (NMPlatform *, const char *name, int parent, int vlanid, guint32 vlanflags, const NMPlatformLink **out_link); gboolean (*link_vlan_change) (NMPlatform *self, int ifindex, @@ -717,6 +719,8 @@ gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length); int nm_platform_link_get_master (NMPlatform *self, int slave); +gboolean nm_platform_link_can_assume (NMPlatform *self, int ifindex); + gboolean nm_platform_link_get_unmanaged (NMPlatform *self, int ifindex, gboolean *unmanaged); gboolean nm_platform_link_supports_slaves (NMPlatform *self, int ifindex); const char *nm_platform_link_get_type_name (NMPlatform *self, int ifindex); From e1edcda317f2368b1a126a91da1383d676aebd63 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 21 Mar 2016 15:30:07 +0100 Subject: [PATCH 2/3] device: consider external devices as unmanaged until they have an IP address --- src/devices/nm-device.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 50858333aa..ff4f43d34e 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1210,20 +1210,26 @@ is_unmanaged_external_down (NMDevice *self, gboolean consider_can) /* Manage externally-created software interfaces only when they are IFF_UP */ if ( priv->ifindex <= 0 - || !priv->up) + || !priv->up + || !nm_platform_link_can_assume (NM_PLATFORM_GET, priv->ifindex)) return NM_UNMAN_FLAG_OP_SET_UNMANAGED; return NM_UNMAN_FLAG_OP_SET_MANAGED; } static void -set_unmanaged_external_down (NMDevice *self) +set_unmanaged_external_down (NMDevice *self, gboolean only_if_unmanaged) { NMUnmanFlagOp ext_flags; if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)) return; + if (only_if_unmanaged) { + if (!nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) + return; + } + ext_flags = is_unmanaged_external_down (self, FALSE); if (ext_flags != NM_UNMAN_FLAG_OP_SET_UNMANAGED) { /* Ensure the assume check is queued before any queued state changes @@ -1562,7 +1568,7 @@ device_link_changed (NMDevice *self) nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason); } - set_unmanaged_external_down (self); + set_unmanaged_external_down (self, FALSE); device_recheck_slave_status (self, &info); return G_SOURCE_REMOVE; @@ -8879,6 +8885,8 @@ queued_ip4_config_change (gpointer user_data) update_ip4_config (self, FALSE); g_object_unref (self); + set_unmanaged_external_down (self, TRUE); + return FALSE; } @@ -8933,6 +8941,8 @@ queued_ip6_config_change (gpointer user_data) g_object_unref (self); + set_unmanaged_external_down (self, TRUE); + return FALSE; } From 35059ed48e79e06a5f940230dbace1947db8cc34 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 11 Mar 2016 09:37:18 +0100 Subject: [PATCH 3/3] device: allow NM-owned device to be assumed Software devices created by NM should be kept up when quitting so that they can be assumed upon restart. But now we consider devices created by NM (those with the @is_nm_owned flag) not capable of assuming connections and therefore we tear them down and deconfigure when quitting. Change this and ignore @is_nm_owned when deciding if a device can be re-assumed. --- src/devices/nm-device.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ff4f43d34e..619eda9bba 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3066,8 +3066,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave static gboolean nm_device_can_assume_connections (NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (self)->update_connection - && !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned; + return !!NM_DEVICE_GET_CLASS (self)->update_connection; } /**