summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-01-11 14:57:10 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2016-01-11 14:57:10 +0100
commit82134792470a1e8e860acea2e3623984975fb37c (patch)
treec8846962b5e042440def3fa99d98c0912d2be35e
parent49107121ab03be766f3f930333cc4b362d40c7ea (diff)
parent8d5eeda5ebe981898308db1f969c74e3b55aea69 (diff)
downloadNetworkManager-82134792470a1e8e860acea2e3623984975fb37c.tar.gz
device: merge branch 'bg/device-zero-mac-fix-rh1288110'
https://bugzilla.redhat.com/show_bug.cgi?id=1288110
-rw-r--r--src/devices/nm-device-ethernet.c35
-rw-r--r--src/devices/nm-device.c69
-rw-r--r--src/devices/nm-device.h3
-rw-r--r--src/nm-manager.c17
4 files changed, 77 insertions, 47 deletions
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 2dda84b3e8..b281d03859 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -1598,10 +1598,44 @@ link_changed (NMDevice *device, NMPlatformLink *info)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+ static const guint8 zero_hwaddr[ETH_ALEN];
+ const guint8 *hwaddr;
+ gsize hwaddrlen = 0;
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->link_changed (device, info);
if (!priv->subchan1 && info->initialized)
_update_s390_subchannels (self);
+
+ if (!nm_device_get_initial_hw_address (device)) {
+ hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET,
+ nm_device_get_ifindex (self),
+ &hwaddrlen);
+ if (!nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, ETH_ALEN)) {
+ _LOGD (LOGD_DEVICE, "device got a valid hw address");
+ nm_device_update_hw_address (self);
+ nm_device_update_initial_hw_address (self);
+ if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
+ /*
+ * If the device is UNAVAILABLE, any previous try to
+ * bring it up probably has failed because of the
+ * invalid hardware address; try again.
+ */
+ nm_device_bring_up (self, TRUE, NULL);
+ nm_device_queue_recheck_available (device,
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
+ }
+ }
+ }
+}
+
+static gboolean
+is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
+{
+ if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->is_available (device, flags))
+ return FALSE;
+
+ return !!nm_device_get_initial_hw_address (device);
}
static void
@@ -1700,6 +1734,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->update_connection = update_connection;
parent_class->carrier_changed = carrier_changed;
parent_class->link_changed = link_changed;
+ parent_class->is_available = is_available;
parent_class->state_changed = device_state_changed;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 4413e92836..494e90772a 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -95,7 +95,6 @@ enum {
REMOVED,
RECHECK_AUTO_ACTIVATE,
RECHECK_ASSUME,
- LINK_INITIALIZED,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -389,8 +388,6 @@ static void _set_state_full (NMDevice *self,
NMDeviceStateReason reason,
gboolean quitting);
-static void nm_device_update_hw_address (NMDevice *self);
-
/***********************************************************/
#define QUEUED_PREFIX "queued state change to "
@@ -1515,9 +1512,6 @@ device_link_changed (NMDevice *self)
}
}
- if (emit_link_initialized)
- g_signal_emit (self, signals[LINK_INITIALIZED], 0);
-
return G_SOURCE_REMOVE;
}
@@ -8865,19 +8859,24 @@ nm_device_get_hw_address (NMDevice *self)
return priv->hw_addr_len ? priv->hw_addr : NULL;
}
-static void
+void
nm_device_update_hw_address (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
int ifindex = nm_device_get_ifindex (self);
const guint8 *hwaddr;
gsize hwaddrlen = 0;
+ static const guint8 zero_hwaddr[ETH_ALEN];
if (ifindex <= 0)
return;
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen);
+ if ( priv->type == NM_DEVICE_TYPE_ETHERNET
+ && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, sizeof (zero_hwaddr)))
+ hwaddrlen = 0;
+
if (hwaddrlen) {
if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
g_free (priv->hw_addr);
@@ -8898,6 +8897,33 @@ nm_device_update_hw_address (NMDevice *self)
priv->hw_addr_len = hwaddrlen;
}
+void
+nm_device_update_initial_hw_address (NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (priv->hw_addr_len) {
+ priv->initial_hw_addr = g_strdup (priv->hw_addr);
+ _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
+
+ if (priv->ifindex > 0) {
+ guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
+ size_t len = 0;
+
+ if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
+ g_warn_if_fail (len == priv->hw_addr_len);
+ priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
+ _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
+ priv->perm_hw_addr);
+ } else {
+ /* Fall back to current address */
+ _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
+ priv->perm_hw_addr = g_strdup (priv->hw_addr);
+ }
+ }
+ }
+}
+
gboolean
nm_device_set_hw_addr (NMDevice *self, const char *addr,
const char *detail, guint64 hw_log_domain)
@@ -9133,27 +9159,7 @@ constructed (GObject *object)
int master;
nm_device_update_hw_address (self);
-
- if (priv->hw_addr_len) {
- priv->initial_hw_addr = g_strdup (priv->hw_addr);
- _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
-
- if (priv->ifindex > 0) {
- guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
- size_t len = 0;
-
- if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
- g_warn_if_fail (len == priv->hw_addr_len);
- priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
- _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
- priv->perm_hw_addr);
- } else {
- /* Fall back to current address */
- _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
- priv->perm_hw_addr = g_strdup (priv->hw_addr);
- }
- }
- }
+ nm_device_update_initial_hw_address (self);
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
@@ -9879,13 +9885,6 @@ nm_device_class_init (NMDeviceClass *klass)
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
- signals[LINK_INITIALIZED] =
- g_signal_new (NM_DEVICE_LINK_INITIALIZED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_object_info);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 49cef8e19c..0ba1c1f08d 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -441,6 +441,9 @@ const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gbool
void nm_device_spawn_iface_helper (NMDevice *self);
+void nm_device_update_hw_address (NMDevice *self);
+void nm_device_update_initial_hw_address (NMDevice *self);
+
G_END_DECLS
/* For testing only */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index a1e4fb4f17..26e2127354 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -717,6 +717,7 @@ manager_device_state_changed (NMDevice *device,
gpointer user_data)
{
NMManager *self = NM_MANAGER (user_data);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
switch (new_state) {
case NM_DEVICE_STATE_UNMANAGED:
@@ -729,6 +730,10 @@ manager_device_state_changed (NMDevice *device,
default:
break;
}
+
+ if ( new_state == NM_DEVICE_STATE_UNAVAILABLE
+ || new_state == NM_DEVICE_STATE_DISCONNECTED)
+ nm_settings_device_added (priv->settings, device);
}
static void device_has_pending_action_changed (NMDevice *device,
@@ -853,14 +858,6 @@ device_removed_cb (NMDevice *device, gpointer user_data)
}
static void
-device_link_initialized_cb (NMDevice *device, gpointer user_data)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data);
-
- nm_settings_device_added (priv->settings, device);
-}
-
-static void
aipd_handle_event (DBusGProxy *proxy,
const char *event,
const char *iface,
@@ -1821,10 +1818,6 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume)
G_CALLBACK (device_removed_cb),
self);
- g_signal_connect (device, NM_DEVICE_LINK_INITIALIZED,
- G_CALLBACK (device_link_initialized_cb),
- self);
-
g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
G_CALLBACK (device_ip_iface_changed),
self);