summaryrefslogtreecommitdiff
path: root/src/nm-device-ethernet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-device-ethernet.c')
-rw-r--r--src/nm-device-ethernet.c486
1 files changed, 163 insertions, 323 deletions
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index c4f62f396..f470e090c 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -15,10 +15,11 @@
* 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 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
+#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <netinet/in.h>
@@ -34,7 +35,6 @@
#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,30 +78,17 @@ 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 {
@@ -929,67 +916,6 @@ 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 *
@@ -1030,30 +956,6 @@ 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);
@@ -1077,32 +979,40 @@ 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_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
+ nm_supplicant_manager_iface_release (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)
{
@@ -1145,10 +1055,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,
- TRUE,
- SECRETS_CALLER_ETHERNET,
+ NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW,
NULL,
- NULL);
+ wired_secrets_cb,
+ self);
return FALSE;
@@ -1160,77 +1070,6 @@ 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)
{
@@ -1257,20 +1096,33 @@ build_supplicant_config (NMDeviceEthernet *self)
return config;
}
-static gboolean
-supplicant_iface_state_cb_handler (gpointer user_data)
+static void
+supplicant_iface_state_cb (NMSupplicantInterface *iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
- NMDevice *device = NM_DEVICE (task->self);
+ 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));
- if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
- NMSupplicantConfig *config;
- const char *iface;
- gboolean success = FALSE;
+ devstate = nm_device_get_state (device);
- iface = nm_device_get_iface (device);
- config = build_supplicant_config (task->self);
+ switch (new_state) {
+ case NM_SUPPLICANT_INTERFACE_STATE_READY:
+ config = build_supplicant_config (self);
if (config) {
success = nm_supplicant_interface_set_config (priv->supplicant.iface, config);
g_object_unref (config);
@@ -1279,99 +1131,54 @@ supplicant_iface_state_cb_handler (gpointer user_data)
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't send security "
"configuration to the supplicant.",
- iface);
+ nm_device_get_iface (device));
}
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't build security configuration.",
- iface);
+ nm_device_get_iface (device));
}
- 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 (!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 this is the initial association during device activation,
* schedule the next activation stage.
*/
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
+ if (devstate == 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 (dev));
- nm_device_activate_schedule_stage3_ip_config_start (dev);
+ nm_device_get_iface (device));
+ nm_device_activate_schedule_stage3_ip_config_start (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);
-
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
+ if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
/* 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, dev);
+ priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
}
- }
-
- 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));
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
+ supplicant_interface_release (self);
+ remove_supplicant_timeouts (self);
- schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
- supplicant_iface_connection_state_cb_handler,
- new_state,
- old_state,
- FALSE);
+ 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);
+ }
+ break;
+ default:
+ break;
+ }
}
static gboolean
@@ -1429,18 +1236,14 @@ handle_auth_or_fail (NMDeviceEthernet *self,
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) {
- gboolean get_new;
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
/* If the caller doesn't necessarily want completely new secrets,
* only ask for new secrets after the first failure.
*/
- get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
- nm_act_request_get_secrets (req,
- setting_name,
- get_new,
- SECRETS_CALLER_ETHERNET,
- NULL,
- NULL);
+ 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);
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else {
@@ -1489,38 +1292,26 @@ supplicant_interface_init (NMDeviceEthernet *self)
iface = nm_device_get_iface (NM_DEVICE (self));
/* Create supplicant interface */
- priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr, iface, FALSE);
+ priv->supplicant.iface = nm_supplicant_manager_iface_get (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);
-
- 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);
+ "connection-error",
+ G_CALLBACK (supplicant_iface_connection_error_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);
@@ -1558,7 +1349,6 @@ 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;
@@ -1572,7 +1362,6 @@ 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);
@@ -1581,7 +1370,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_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
ret = handle_auth_or_fail (self, req, FALSE);
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
@@ -1589,7 +1378,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_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
if (supplicant_interface_init (self))
ret = NM_ACT_STAGE_RETURN_POSTPONE;
@@ -1779,7 +1568,7 @@ real_act_stage4_get_ip4_config (NMDevice *device,
}
static void
-real_deactivate_quickly (NMDevice *device)
+real_deactivate (NMDevice *device)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -1864,6 +1653,68 @@ 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);
@@ -1945,7 +1796,6 @@ 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;
@@ -1957,10 +1807,6 @@ 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;
@@ -1979,7 +1825,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_setting_connection_get_uuid (s_con));
+ nm_connection_get_uuid (connection));
g_object_unref (dhcp_mgr);
method = nm_setting_ip4_config_get_method (s_ip4);
@@ -2083,12 +1929,6 @@ 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;
@@ -2177,14 +2017,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_quickly = real_deactivate_quickly;
+ parent_class->deactivate = real_deactivate;
parent_class->spec_match_list = spec_match_list;
parent_class->connection_match_config = connection_match_config;
@@ -2317,7 +2157,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 0;
+ return FALSE;
}
memset (&ifr, 0, sizeof (struct ifreq));