mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-08 08:20:28 +01:00
core: merge branch 'bg/device-zero-mac-fix-rh1288110'
Fix activation for ethernet devices that appear with a zero initial MAC address. https://bugzilla.redhat.com/show_bug.cgi?id=1288110
This commit is contained in:
commit
3b35bf0ad7
4 changed files with 77 additions and 47 deletions
|
|
@ -1607,10 +1607,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
|
||||
|
|
@ -1711,6 +1745,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ enum {
|
|||
REMOVED,
|
||||
RECHECK_AUTO_ACTIVATE,
|
||||
RECHECK_ASSUME,
|
||||
LINK_INITIALIZED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
|
@ -403,8 +402,6 @@ static void _set_state_full (NMDevice *self,
|
|||
NMDeviceStateReason reason,
|
||||
gboolean quitting);
|
||||
|
||||
static void nm_device_update_hw_address (NMDevice *self);
|
||||
|
||||
static gboolean queued_ip4_config_change (gpointer user_data);
|
||||
static gboolean queued_ip6_config_change (gpointer user_data);
|
||||
|
||||
|
|
@ -1589,9 +1586,6 @@ device_link_changed (NMDevice *self)
|
|||
}
|
||||
}
|
||||
|
||||
if (just_initialized)
|
||||
g_signal_emit (self, signals[LINK_INITIALIZED], 0);
|
||||
|
||||
device_recheck_slave_status (self, &info);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
|
@ -1904,27 +1898,7 @@ setup_start (NMDevice *self, const NMPlatformLink *plink)
|
|||
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
|
||||
|
||||
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)) {
|
||||
|
|
@ -9883,19 +9857,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) {
|
||||
priv->hw_addr_len = hwaddrlen;
|
||||
if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
|
||||
|
|
@ -9917,6 +9896,33 @@ nm_device_update_hw_address (NMDevice *self)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -10897,13 +10903,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_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
|
||||
NMDBUS_TYPE_DEVICE_SKELETON,
|
||||
"Disconnect", impl_device_disconnect,
|
||||
|
|
|
|||
|
|
@ -567,6 +567,9 @@ void nm_device_reapply_settings_immediately (NMDevice *self);
|
|||
void nm_device_update_firewall_zone (NMDevice *self);
|
||||
void nm_device_update_metered (NMDevice *self);
|
||||
|
||||
void nm_device_update_hw_address (NMDevice *self);
|
||||
void nm_device_update_initial_hw_address (NMDevice *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_DEVICE_H */
|
||||
|
|
|
|||
|
|
@ -721,6 +721,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:
|
||||
|
|
@ -733,6 +734,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,
|
||||
|
|
@ -859,14 +864,6 @@ device_removed_cb (NMDevice *device, gpointer user_data)
|
|||
remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
NMState
|
||||
nm_manager_get_state (NMManager *manager)
|
||||
{
|
||||
|
|
@ -1830,10 +1827,6 @@ add_device (NMManager *self, NMDevice *device, GError **error)
|
|||
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, NM_DEVICE_RECHECK_ASSUME,
|
||||
G_CALLBACK (recheck_assume_connection_cb),
|
||||
self);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue