summaryrefslogtreecommitdiff
path: root/src/devices/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/nm-device.c')
-rw-r--r--src/devices/nm-device.c96
1 files changed, 71 insertions, 25 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index a5c13f6d88..997284878a 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -854,6 +854,22 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure,
return success;
}
+/**
+ * nm_device_finish_init:
+ * @self: the master device
+ *
+ * Whatever needs to be done post-initialization, when the device has a DBus
+ * object name.
+ */
+void
+nm_device_finish_init (NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (priv->master)
+ nm_device_enslave_slave (priv->master, self, NULL);
+}
+
static void
carrier_changed (NMDevice *device, gboolean carrier)
{
@@ -1018,6 +1034,27 @@ update_for_ip_ifname_change (NMDevice *device)
}
static void
+device_set_master (NMDevice *self, int ifindex)
+{
+ NMDevice *master;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ master = nm_manager_get_device_by_ifindex (nm_manager_get (), ifindex);
+ if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
+ g_clear_object (&priv->master);
+ priv->master = g_object_ref (master);
+ nm_device_master_add_slave (master, self, FALSE);
+ } else if (master) {
+ nm_log_info (LOGD_DEVICE, "(%s): enslaved to non-master-type device %s; ignoring",
+ nm_device_get_iface (self),
+ nm_device_get_iface (master));
+ } else {
+ nm_log_warn (LOGD_DEVICE, "(%s): enslaved to unknown device",
+ nm_device_get_iface (self));
+ }
+}
+
+static void
device_link_changed (NMDevice *device, NMPlatformLink *info)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device);
@@ -1060,27 +1097,13 @@ device_link_changed (NMDevice *device, NMPlatformLink *info)
}
/* Update slave status for external changes */
- if (info->master && !priv->enslaved) {
- NMDevice *master;
-
- master = nm_manager_get_device_by_ifindex (nm_manager_get (), info->master);
- if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
- g_clear_object (&priv->master);
- priv->master = g_object_ref (master);
- nm_device_master_add_slave (master, device, FALSE);
- nm_device_enslave_slave (master, device, NULL);
- } else if (master) {
- nm_log_info (LOGD_DEVICE, "(%s): enslaved to non-master-type device %s; ignoring",
- nm_device_get_iface (device),
- nm_device_get_iface (master));
- } else {
- nm_log_warn (LOGD_DEVICE, "(%s): enslaved to unknown device %d %s",
- nm_device_get_iface (device),
- info->master,
- nm_platform_link_get_name (info->master));
- }
- } else if (priv->enslaved && !info->master)
+ if (priv->enslaved && info->master != nm_device_get_ifindex (priv->master))
nm_device_release_one_slave (priv->master, device, FALSE, NM_DEVICE_STATE_REASON_NONE);
+ if (info->master && !priv->enslaved) {
+ device_set_master (device, info->master);
+ if (priv->master)
+ nm_device_enslave_slave (priv->master, device, NULL);
+ }
if (klass->link_changed)
klass->link_changed (device, info);
@@ -1252,6 +1275,7 @@ nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure)
G_CALLBACK (slave_state_changed), dev);
priv->slaves = g_slist_append (priv->slaves, info);
}
+ nm_device_queue_recheck_assume (dev);
return TRUE;
}
@@ -1471,11 +1495,16 @@ nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason)
master_status);
nm_device_queue_state (dev, new_state, reason);
- } else {
+ } else if (priv->master) {
nm_log_info (LOGD_DEVICE,
"(%s): released from master %s",
nm_device_get_iface (dev),
nm_device_get_iface (priv->master));
+ } else {
+ nm_log_info (LOGD_DEVICE,
+ "(%s): released from master%s",
+ nm_device_get_iface (dev),
+ priv->enslaved ? "" : " (was not enslaved)");
}
if (priv->enslaved) {
@@ -1760,8 +1789,9 @@ nm_device_generate_connection (NMDevice *device)
ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
&& g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0
- && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))) {
- nm_log_dbg (LOGD_DEVICE, "(%s): ignoring generated connection (no IP and not slave)", ifname);
+ && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
+ && !priv->slaves) {
+ nm_log_dbg (LOGD_DEVICE, "(%s): ignoring generated connection (no IP and not in master-slave relationship)", ifname);
g_object_unref (connection);
connection = NULL;
}
@@ -1971,7 +2001,7 @@ nm_device_emit_recheck_assume (gpointer self)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
priv->recheck_assume_id = 0;
- if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config))
+ if (!nm_device_get_act_request (self))
g_signal_emit (self, signals[RECHECK_ASSUME], 0);
return G_SOURCE_REMOVE;
}
@@ -6879,7 +6909,10 @@ _set_state_full (NMDevice *device,
nm_act_request_get_connection (req),
device);
} else {
- priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
+ if (nm_device_is_available (device))
+ priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
+ else
+ priv->dispatcher.post_state = NM_DEVICE_STATE_UNAVAILABLE;
priv->dispatcher.post_state_reason = reason;
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
nm_act_request_get_connection (req),
@@ -6915,6 +6948,13 @@ _set_state_full (NMDevice *device,
"Activation (%s) failed for connection '%s'",
nm_device_get_iface (device),
connection ? nm_connection_get_id (connection) : "<unknown>");
+ if (req && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (req))) {
+ /* Avoid tearing down assumed connection, assume it's connected */
+ nm_device_queue_state (device,
+ NM_DEVICE_STATE_ACTIVATED,
+ NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
+ break;
+ }
/* Notify any slaves of the unexpected failure */
nm_device_master_release_slaves (device);
@@ -7409,6 +7449,7 @@ constructed (GObject *object)
{
NMDevice *dev = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
+ int master;
nm_device_update_hw_address (dev);
@@ -7441,6 +7482,11 @@ constructed (GObject *object)
if (priv->ifindex > 0)
priv->mtu = nm_platform_link_get_mtu (priv->ifindex);
+ /* Enslave ourselves */
+ master = nm_platform_link_get_master (priv->ifindex);
+ if (master)
+ device_set_master (dev, master);
+
priv->con_provider = nm_connection_provider_get ();
g_assert (priv->con_provider);
g_signal_connect (priv->con_provider,