mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 07:38:20 +02:00
device: wait for valid MAC before making ethernet devices available
In certain situations, ethernet links first appear with a zero MAC
address and then the MAC changes some time later. Currently NM does
not deal correctly with this scenario since it initializes wrong
@initial_hwaddr and @permanent_hwaddr on the device and tries to
immediately activate it.
To fix this, initialize the device's addresses only when the MAC
becomes valid and make the device available only at that point.
(cherry picked from commit 92149f223f)
This commit is contained in:
parent
7296a88c3c
commit
8d5eeda5eb
3 changed files with 45 additions and 5 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -388,9 +388,6 @@ static void _set_state_full (NMDevice *self,
|
|||
NMDeviceStateReason reason,
|
||||
gboolean quitting);
|
||||
|
||||
static void nm_device_update_hw_address (NMDevice *self);
|
||||
static void nm_device_update_initial_hw_address (NMDevice *self);
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
#define QUEUED_PREFIX "queued state change to "
|
||||
|
|
@ -8862,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);
|
||||
|
|
@ -8895,7 +8897,7 @@ nm_device_update_hw_address (NMDevice *self)
|
|||
priv->hw_addr_len = hwaddrlen;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
nm_device_update_initial_hw_address (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue