device/wifi: properly reset the initial hardware address on shutdown

During shutdown, we unmanage Wi-Fi devices, and during NMDevice:deactivate()
we would reset to initial MAC address.

However, NMDeviceWifi:deactivate() would reset it again to the scanning one.

Fix that to properly restore the initial MAC address on the device
when NetworkManager exits.

Fixes: 4b2e375b33
This commit is contained in:
Thomas Haller
2016-06-30 11:42:28 +02:00
parent 5ce62dccc5
commit c5c9f0aad7
3 changed files with 31 additions and 5 deletions

View File

@@ -10653,8 +10653,6 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean
nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
} }
nm_device_hw_addr_reset (self, "deactivate");
/* Call device type-specific deactivation */ /* Call device type-specific deactivation */
if (NM_DEVICE_GET_CLASS (self)->deactivate) if (NM_DEVICE_GET_CLASS (self)->deactivate)
NM_DEVICE_GET_CLASS (self)->deactivate (self); NM_DEVICE_GET_CLASS (self)->deactivate (self);
@@ -10678,9 +10676,30 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean
nm_lldp_listener_stop (priv->lldp_listener); nm_lldp_listener_stop (priv->lldp_listener);
nm_device_update_metered (self); nm_device_update_metered (self);
/* during device cleanup, we want to reset the MAC address of the device
* to the initial state.
*
* We certainly want to do that when reaching the UNMANAGED state... */
if (nm_device_get_state (self) <= NM_DEVICE_STATE_UNMANAGED)
nm_device_hw_addr_reset (self, "unmanage");
else {
/* for other device states (UNAVAILABLE, DISCONNECTED), allow the
* device to overwrite the reset behavior, so that Wi-Fi can set
* a randomized MAC address used during scanning. */
NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self);
}
_cleanup_generic_post (self, cleanup_type); _cleanup_generic_post (self, cleanup_type);
} }
static void
deactivate_reset_hw_addr (NMDevice *self)
{
nm_device_hw_addr_reset (self, "deactivate");
}
static char * static char *
bin2hexstr (const char *bytes, gsize len) bin2hexstr (const char *bytes, gsize len)
{ {
@@ -12445,6 +12464,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->carrier_changed = carrier_changed; klass->carrier_changed = carrier_changed;
klass->get_ip_iface_identifier = get_ip_iface_identifier; klass->get_ip_iface_identifier = get_ip_iface_identifier;
klass->unmanaged_on_quit = unmanaged_on_quit; klass->unmanaged_on_quit = unmanaged_on_quit;
klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr;
/* Properties */ /* Properties */
obj_properties[PROP_UDI] = obj_properties[PROP_UDI] =

View File

@@ -279,6 +279,8 @@ typedef struct {
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
void (* deactivate_reset_hw_addr) (NMDevice *self);
/* Sync deactivating (in the DISCONNECTED phase) */ /* Sync deactivating (in the DISCONNECTED phase) */
void (* deactivate) (NMDevice *self); void (* deactivate) (NMDevice *self);

View File

@@ -501,9 +501,6 @@ deactivate (NMDevice *device)
/* Clear any critical protocol notification in the Wi-Fi stack */ /* Clear any critical protocol notification in the Wi-Fi stack */
nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE); nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE);
g_clear_pointer (&priv->hw_addr_scan, g_free);
_hw_addr_set_scanning (self, TRUE);
/* Ensure we're in infrastructure mode after deactivation; some devices /* Ensure we're in infrastructure mode after deactivation; some devices
* (usually older ones) don't scan well in adhoc mode. * (usually older ones) don't scan well in adhoc mode.
*/ */
@@ -525,6 +522,12 @@ deactivate (NMDevice *device)
} }
} }
static void
deactivate_reset_hw_addr (NMDevice *device)
{
_hw_addr_set_scanning ((NMDeviceWifi *) device, TRUE);
}
static gboolean static gboolean
is_adhoc_wpa (NMConnection *connection) is_adhoc_wpa (NMConnection *connection)
{ {
@@ -3117,6 +3120,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout; parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout;
parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout; parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
parent_class->deactivate = deactivate; parent_class->deactivate = deactivate;
parent_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr;
parent_class->unmanaged_on_quit = unmanaged_on_quit; parent_class->unmanaged_on_quit = unmanaged_on_quit;
parent_class->state_changed = device_state_changed; parent_class->state_changed = device_state_changed;