summaryrefslogtreecommitdiff
path: root/src/nm-device-ethernet.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-04-21 10:42:53 +0200
committerMichael Biebl <biebl@debian.org>2011-04-21 10:42:53 +0200
commit8baa1aca8dfd35e3190d7d5655eb83b5b901e263 (patch)
treea9ac1e67d0c22a48330c76f08fc5291f85307055 /src/nm-device-ethernet.c
parentf75dd6fd1975146623052b843b182dc32c3fbe46 (diff)
Imported Upstream version 0.8.4.0upstream/0.8.4.0
Diffstat (limited to 'src/nm-device-ethernet.c')
-rw-r--r--src/nm-device-ethernet.c486
1 files changed, 323 insertions, 163 deletions
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index f470e090c..c4f62f396 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -15,11 +15,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2011 Red Hat, Inc.
+ * Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
-#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <netinet/in.h>
@@ -35,6 +34,7 @@
#include <linux/if.h>
#include <errno.h>
+#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include <netlink/route/addr.h>
@@ -78,17 +78,30 @@ typedef enum
#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ())
#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
+typedef struct SupplicantStateTask {
+ NMDeviceEthernet *self;
+ guint32 new_state;
+ guint32 old_state;
+ gboolean mgr_task;
+ guint source_id;
+} SupplicantStateTask;
+
typedef struct Supplicant {
NMSupplicantManager *mgr;
NMSupplicantInterface *iface;
/* signal handler ids */
+ guint mgr_state_id;
guint iface_error_id;
guint iface_state_id;
+ guint iface_con_state_id;
/* Timeouts and idles */
guint iface_con_error_cb_id;
guint con_timeout_id;
+
+ GSList *iface_tasks;
+ GSList *mgr_tasks;
} Supplicant;
typedef struct {
@@ -916,6 +929,67 @@ real_get_best_auto_connection (NMDevice *dev,
return NULL;
}
+static void
+real_connection_secrets_updated (NMDevice *dev,
+ NMConnection *connection,
+ GSList *updated_settings,
+ RequestSecretsCaller caller)
+{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (dev);
+ NMActRequest *req;
+ gboolean valid = FALSE;
+ GSList *iter;
+
+ g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (dev)));
+
+ /* PPPoE? */
+ if (caller == SECRETS_CALLER_PPP) {
+ NMSettingPPPOE *s_pppoe;
+
+ g_assert (priv->ppp_manager);
+
+ s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
+ if (!s_pppoe) {
+ nm_ppp_manager_update_secrets (priv->ppp_manager,
+ nm_device_get_iface (dev),
+ NULL,
+ NULL,
+ "missing PPPoE setting; no secrets could be found.");
+ } else {
+ const char *pppoe_username = nm_setting_pppoe_get_username (s_pppoe);
+ const char *pppoe_password = nm_setting_pppoe_get_password (s_pppoe);
+
+ nm_ppp_manager_update_secrets (priv->ppp_manager,
+ nm_device_get_iface (dev),
+ pppoe_username ? pppoe_username : "",
+ pppoe_password ? pppoe_password : "",
+ NULL);
+ }
+ return;
+ }
+
+ /* Only caller could be ourselves for 802.1x */
+ g_return_if_fail (caller == SECRETS_CALLER_ETHERNET);
+ g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
+
+ for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
+ const char *setting_name = (const char *) iter->data;
+
+ if (!strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
+ valid = TRUE;
+ } else {
+ nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.",
+ setting_name);
+ }
+ }
+
+ req = nm_device_get_act_request (dev);
+ g_assert (req);
+
+ g_return_if_fail (nm_act_request_get_connection (req) == connection);
+ nm_device_activate_schedule_stage1_device_prepare (dev);
+}
+
/* FIXME: Move it to nm-device.c and then get rid of all foo_device_get_setting() all around.
It's here now to keep the patch short. */
static NMSetting *
@@ -956,6 +1030,30 @@ remove_supplicant_timeouts (NMDeviceEthernet *self)
}
static void
+finish_supplicant_task (SupplicantStateTask *task, gboolean remove_source)
+{
+ NMDeviceEthernet *self = task->self;
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+
+ /* idle/timeout handlers should pass FALSE for remove_source, since they
+ * will tell glib to remove their source from the mainloop by returning
+ * FALSE when they exit. When called from this NMDevice's dispose handler,
+ * remove_source should be TRUE to cancel all outstanding idle/timeout
+ * handlers asynchronously.
+ */
+ if (task->source_id && remove_source)
+ g_source_remove (task->source_id);
+
+ if (task->mgr_task)
+ priv->supplicant.mgr_tasks = g_slist_remove (priv->supplicant.mgr_tasks, task);
+ else
+ priv->supplicant.iface_tasks = g_slist_remove (priv->supplicant.iface_tasks, task);
+
+ memset (task, 0, sizeof (SupplicantStateTask));
+ g_slice_free (SupplicantStateTask, task);
+}
+
+static void
remove_supplicant_interface_error_handler (NMDeviceEthernet *self)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -979,40 +1077,32 @@ supplicant_interface_release (NMDeviceEthernet *self)
remove_supplicant_timeouts (self);
remove_supplicant_interface_error_handler (self);
+ /* Clean up all pending supplicant interface state idle tasks */
+ while (priv->supplicant.iface_tasks)
+ finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
+
+ if (priv->supplicant.iface_con_state_id) {
+ g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_con_state_id);
+ priv->supplicant.iface_con_state_id = 0;
+ }
+
if (priv->supplicant.iface_state_id > 0) {
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
priv->supplicant.iface_state_id = 0;
}
+ if (priv->supplicant.mgr_state_id) {
+ g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
+ priv->supplicant.mgr_state_id = 0;
+ }
+
if (priv->supplicant.iface) {
nm_supplicant_interface_disconnect (priv->supplicant.iface);
- nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
+ nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
priv->supplicant.iface = NULL;
}
}
-static void
-wired_secrets_cb (NMActRequest *req,
- guint32 call_id,
- NMConnection *connection,
- GError *error,
- gpointer user_data)
-{
- NMDevice *dev = NM_DEVICE (user_data);
-
- g_return_if_fail (req == nm_device_get_act_request (dev));
- g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
- g_return_if_fail (nm_act_request_get_connection (req) == connection);
-
- if (error) {
- nm_log_warn (LOGD_ETHER, "%s", error->message);
- nm_device_state_changed (dev,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_NO_SECRETS);
- } else
- nm_device_activate_schedule_stage1_device_prepare (dev);
-}
-
static gboolean
link_timeout_cb (gpointer user_data)
{
@@ -1055,10 +1145,10 @@ link_timeout_cb (gpointer user_data)
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
setting_name,
- NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW,
+ TRUE,
+ SECRETS_CALLER_ETHERNET,
NULL,
- wired_secrets_cb,
- self);
+ NULL);
return FALSE;
@@ -1070,6 +1160,77 @@ time_out:
return FALSE;
}
+static gboolean
+schedule_state_handler (NMDeviceEthernet *self,
+ GSourceFunc handler,
+ guint32 new_state,
+ guint32 old_state,
+ gboolean mgr_task)
+{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+ SupplicantStateTask *task;
+
+ if (new_state == old_state)
+ return TRUE;
+
+ task = g_slice_new0 (SupplicantStateTask);
+ if (!task) {
+ nm_log_err (LOGD_DEVICE, "Not enough memory to process supplicant manager state change.");
+ return FALSE;
+ }
+
+ task->self = self;
+ task->new_state = new_state;
+ task->old_state = old_state;
+ task->mgr_task = mgr_task;
+
+ task->source_id = g_idle_add (handler, task);
+ if (mgr_task)
+ priv->supplicant.mgr_tasks = g_slist_append (priv->supplicant.mgr_tasks, task);
+ else
+ priv->supplicant.iface_tasks = g_slist_append (priv->supplicant.iface_tasks, task);
+ return TRUE;
+}
+
+static gboolean
+supplicant_mgr_state_cb_handler (gpointer user_data)
+{
+ SupplicantStateTask *task = (SupplicantStateTask *) user_data;
+ NMDevice *device = NM_DEVICE (task->self);
+
+ /* If the supplicant went away, release the supplicant interface */
+ if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
+ supplicant_interface_release (task->self);
+
+ if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
+ nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ }
+ }
+
+ finish_supplicant_task (task, FALSE);
+ return FALSE;
+}
+
+static void
+supplicant_mgr_state_cb (NMSupplicantInterface * iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
+{
+ nm_log_info (LOGD_DEVICE | LOGD_ETHER,
+ "(%s): supplicant manager state: %s -> %s",
+ nm_device_get_iface (NM_DEVICE (user_data)),
+ nm_supplicant_manager_state_to_string (old_state),
+ nm_supplicant_manager_state_to_string (new_state));
+
+ schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
+ supplicant_mgr_state_cb_handler,
+ new_state,
+ old_state,
+ TRUE);
+}
+
static NMSupplicantConfig *
build_supplicant_config (NMDeviceEthernet *self)
{
@@ -1096,33 +1257,20 @@ build_supplicant_config (NMDeviceEthernet *self)
return config;
}
-static void
-supplicant_iface_state_cb (NMSupplicantInterface *iface,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data)
+static gboolean
+supplicant_iface_state_cb_handler (gpointer user_data)
{
- NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
- NMDevice *device = NM_DEVICE (self);
- NMSupplicantConfig *config;
- gboolean success = FALSE;
- NMDeviceState devstate;
-
- if (new_state == old_state)
- return;
-
- nm_log_info (LOGD_DEVICE | LOGD_ETHER,
- "(%s): supplicant interface state: %s -> %s",
- nm_device_get_iface (device),
- nm_supplicant_interface_state_to_string (old_state),
- nm_supplicant_interface_state_to_string (new_state));
+ SupplicantStateTask *task = (SupplicantStateTask *) user_data;
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
+ NMDevice *device = NM_DEVICE (task->self);
- devstate = nm_device_get_state (device);
+ if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
+ NMSupplicantConfig *config;
+ const char *iface;
+ gboolean success = FALSE;
- switch (new_state) {
- case NM_SUPPLICANT_INTERFACE_STATE_READY:
- config = build_supplicant_config (self);
+ iface = nm_device_get_iface (device);
+ config = build_supplicant_config (task->self);
if (config) {
success = nm_supplicant_interface_set_config (priv->supplicant.iface, config);
g_object_unref (config);
@@ -1131,54 +1279,99 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't send security "
"configuration to the supplicant.",
- nm_device_get_iface (device));
+ iface);
}
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't build security configuration.",
- nm_device_get_iface (device));
+ iface);
}
- if (!success) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
- }
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
- remove_supplicant_interface_error_handler (self);
- remove_supplicant_timeouts (self);
+ if (!success)
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
+ } else if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
+ NMDeviceState state = nm_device_get_state (device);
+
+ supplicant_interface_release (task->self);
+
+ if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ }
+
+ finish_supplicant_task (task, FALSE);
+ return FALSE;
+}
+
+static void
+supplicant_iface_state_cb (NMSupplicantInterface * iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
+{
+
+ nm_log_info (LOGD_DEVICE | LOGD_ETHER,
+ "(%s): supplicant interface state: %s -> %s",
+ nm_device_get_iface (NM_DEVICE (user_data)),
+ nm_supplicant_interface_state_to_string (old_state),
+ nm_supplicant_interface_state_to_string (new_state));
+
+ schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
+ supplicant_iface_state_cb_handler,
+ new_state,
+ old_state,
+ FALSE);
+}
+
+static gboolean
+supplicant_iface_connection_state_cb_handler (gpointer user_data)
+{
+ SupplicantStateTask *task = (SupplicantStateTask *) user_data;
+ NMDevice *dev = NM_DEVICE (task->self);
+
+ if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
+ remove_supplicant_interface_error_handler (task->self);
+ remove_supplicant_timeouts (task->self);
/* If this is the initial association during device activation,
* schedule the next activation stage.
*/
- if (devstate == NM_DEVICE_STATE_CONFIG) {
+ if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.",
- nm_device_get_iface (device));
- nm_device_activate_schedule_stage3_ip_config_start (device);
+ nm_device_get_iface (dev));
+ nm_device_activate_schedule_stage3_ip_config_start (dev);
}
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
- if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
+ } else if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
+ if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
+
/* Start the link timeout so we allow some time for reauthentication */
if (!priv->supplicant_timeout_id)
- priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
- }
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
- supplicant_interface_release (self);
- remove_supplicant_timeouts (self);
-
- if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
- nm_device_state_changed (device,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, dev);
}
- break;
- default:
- break;
}
+
+ finish_supplicant_task (task, FALSE);
+ return FALSE;
+}
+
+static void
+supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
+{
+ nm_log_info (LOGD_DEVICE | LOGD_ETHER,
+ "(%s) supplicant connection state: %s -> %s",
+ nm_device_get_iface (NM_DEVICE (user_data)),
+ nm_supplicant_interface_connection_state_to_string (old_state),
+ nm_supplicant_interface_connection_state_to_string (new_state));
+
+ schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
+ supplicant_iface_connection_state_cb_handler,
+ new_state,
+ old_state,
+ FALSE);
}
static gboolean
@@ -1236,14 +1429,18 @@ handle_auth_or_fail (NMDeviceEthernet *self,
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) {
- NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+ gboolean get_new;
/* If the caller doesn't necessarily want completely new secrets,
* only ask for new secrets after the first failure.
*/
- if (new_secrets || tries)
- flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
- nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self);
+ get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
+ nm_act_request_get_secrets (req,
+ setting_name,
+ get_new,
+ SECRETS_CALLER_ETHERNET,
+ NULL,
+ NULL);
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else {
@@ -1292,26 +1489,38 @@ supplicant_interface_init (NMDeviceEthernet *self)
iface = nm_device_get_iface (NM_DEVICE (self));
/* Create supplicant interface */
- priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, iface, FALSE);
+ priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr, iface, FALSE);
if (!priv->supplicant.iface) {
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
"Couldn't initialize supplicant interface for %s.",
iface);
supplicant_interface_release (self);
+
return FALSE;
}
/* Listen for it's state signals */
priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface,
- "state",
- G_CALLBACK (supplicant_iface_state_cb),
- self);
+ "state",
+ G_CALLBACK (supplicant_iface_state_cb),
+ self);
/* Hook up error signal handler to capture association errors */
priv->supplicant.iface_error_id = g_signal_connect (priv->supplicant.iface,
- "connection-error",
- G_CALLBACK (supplicant_iface_connection_error_cb),
- self);
+ "connection-error",
+ G_CALLBACK (supplicant_iface_connection_error_cb),
+ self);
+
+ priv->supplicant.iface_con_state_id = g_signal_connect (priv->supplicant.iface,
+ "connection-state",
+ G_CALLBACK (supplicant_iface_connection_state_cb),
+ self);
+
+ /* Listen for supplicant manager state changes */
+ priv->supplicant.mgr_state_id = g_signal_connect (priv->supplicant.mgr,
+ "state",
+ G_CALLBACK (supplicant_mgr_state_cb),
+ self);
/* Set up a timeout on the connection attempt to fail it after 25 seconds */
priv->supplicant.con_timeout_id = g_timeout_add_seconds (25, supplicant_connection_timeout_cb, self);
@@ -1349,6 +1558,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{
NMConnection *connection;
NMSetting8021x *security;
+ NMSettingConnection *s_connection;
const char *setting_name;
const char *iface;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
@@ -1362,6 +1572,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
}
iface = nm_device_get_iface (NM_DEVICE (self));
+ s_connection = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
/* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL);
@@ -1370,7 +1581,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): connection '%s' has security, but secrets are required.",
- iface, nm_connection_get_id (connection));
+ iface, nm_setting_connection_get_id (s_connection));
ret = handle_auth_or_fail (self, req, FALSE);
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
@@ -1378,7 +1589,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
} else {
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): connection '%s' requires no security. No secrets needed.",
- iface, nm_connection_get_id (connection));
+ iface, nm_setting_connection_get_id (s_connection));
if (supplicant_interface_init (self))
ret = NM_ACT_STAGE_RETURN_POSTPONE;
@@ -1568,7 +1779,7 @@ real_act_stage4_get_ip4_config (NMDevice *device,
}
static void
-real_deactivate (NMDevice *device)
+real_deactivate_quickly (NMDevice *device)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -1653,68 +1864,6 @@ real_check_connection_compatible (NMDevice *device,
}
static gboolean
-real_complete_connection (NMDevice *device,
- NMConnection *connection,
- const char *specific_object,
- const GSList *existing_connections,
- GError **error)
-{
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
- NMSettingWired *s_wired;
- NMSettingPPPOE *s_pppoe;
- const GByteArray *setting_mac;
-
- s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
-
- /* We can't telepathically figure out the service name or username, so if
- * those weren't given, we can't complete the connection.
- */
- if (s_pppoe && !nm_setting_verify (NM_SETTING (s_pppoe), NULL, error))
- return FALSE;
-
- /* Default to an ethernet-only connection, but if a PPPoE setting was given
- * then PPPoE should be our connection type.
- */
- nm_utils_complete_generic (connection,
- s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME,
- existing_connections,
- s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"),
- NULL,
- s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */
-
- s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
- if (!s_wired) {
- s_wired = (NMSettingWired *) nm_setting_wired_new ();
- nm_connection_add_setting (connection, NM_SETTING (s_wired));
- }
-
- setting_mac = nm_setting_wired_get_mac_address (s_wired);
- if (setting_mac) {
- /* Make sure the setting MAC (if any) matches the device's permanent MAC */
- if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) {
- g_set_error_literal (error,
- NM_SETTING_WIRED_ERROR,
- NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
- NM_SETTING_WIRED_MAC_ADDRESS);
- return FALSE;
- }
- } else {
- GByteArray *mac;
- const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
- /* Lock the connection to this device by default */
- if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) {
- mac = g_byte_array_sized_new (ETH_ALEN);
- g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN);
- g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
- g_byte_array_free (mac, TRUE);
- }
- }
-
- return TRUE;
-}
-
-static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
@@ -1796,6 +1945,7 @@ static gboolean
ip4_match_config (NMDevice *self, NMConnection *connection)
{
NMSettingIP4Config *s_ip4;
+ NMSettingConnection *s_con;
struct nl_handle *nlh = NULL;
struct nl_cache *addr_cache = NULL;
int i, num;
@@ -1807,6 +1957,10 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
ifindex = nm_device_get_ifindex (self);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ g_assert (nm_setting_connection_get_uuid (s_con));
+
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
if (!s_ip4)
return FALSE;
@@ -1825,7 +1979,7 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
dhcp_mgr = nm_dhcp_manager_get ();
leases = nm_dhcp_manager_get_lease_config (dhcp_mgr,
nm_device_get_iface (self),
- nm_connection_get_uuid (connection));
+ nm_setting_connection_get_uuid (s_con));
g_object_unref (dhcp_mgr);
method = nm_setting_ip4_config_get_method (s_ip4);
@@ -1929,6 +2083,12 @@ dispose (GObject *object)
priv->disposed = TRUE;
+ /* Clean up all pending supplicant tasks */
+ while (priv->supplicant.iface_tasks)
+ finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
+ while (priv->supplicant.mgr_tasks)
+ finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.mgr_tasks->data, TRUE);
+
if (priv->link_connected_id) {
g_signal_handler_disconnect (priv->monitor, priv->link_connected_id);
priv->link_connected_id = 0;
@@ -2017,14 +2177,14 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->update_initial_hw_address = real_update_initial_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
+ parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
- parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
parent_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
- parent_class->deactivate = real_deactivate;
+ parent_class->deactivate_quickly = real_deactivate_quickly;
parent_class->spec_match_list = spec_match_list;
parent_class->connection_match_config = connection_match_config;
@@ -2157,7 +2317,7 @@ supports_mii_carrier_detect (NMDeviceEthernet *self)
fd = socket (PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
nm_log_err (LOGD_HW, "couldn't open control socket.");
- return FALSE;
+ return 0;
}
memset (&ifr, 0, sizeof (struct ifreq));