summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/nm-device-ethernet.c142
-rw-r--r--src/devices/nm-device-vlan.c32
-rw-r--r--src/devices/nm-device.c48
-rw-r--r--src/devices/nm-device.h7
-rw-r--r--src/devices/wifi/nm-device-wifi.c157
-rw-r--r--src/platform/nm-fake-platform.c7
-rw-r--r--src/platform/nm-linux-platform.c29
-rw-r--r--src/platform/nm-platform.c31
-rw-r--r--src/platform/nm-platform.h5
9 files changed, 204 insertions, 254 deletions
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index c498219928..0f2a2f9784 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -99,9 +99,6 @@ typedef enum {
} DcbWait;
typedef struct {
- char * perm_hw_addr; /* Permanent MAC address */
- char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */
-
guint32 speed;
Supplicant supplicant;
@@ -310,66 +307,6 @@ nm_device_ethernet_init (NMDeviceEthernet *self)
priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
-static void
-update_permanent_hw_address (NMDevice *dev)
-{
- NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
- struct ifreq req;
- struct ethtool_perm_addr *epaddr = NULL;
- int fd, ret, errsv;
- const char *mac;
-
- g_return_if_fail (priv->perm_hw_addr == NULL);
-
- fd = socket (PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- _LOGW (LOGD_HW, "couldn't open control socket.");
- return;
- }
-
- /* Get permanent MAC address */
- memset (&req, 0, sizeof (struct ifreq));
- strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
-
- epaddr = g_malloc0 (sizeof (struct ethtool_perm_addr) + ETH_ALEN);
- epaddr->cmd = ETHTOOL_GPERMADDR;
- epaddr->size = ETH_ALEN;
- req.ifr_data = (void *) epaddr;
-
- errno = 0;
- ret = ioctl (fd, SIOCETHTOOL, &req);
- errsv = errno;
- if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) {
- _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)", errsv);
- /* Fall back to current address */
- mac = nm_device_get_hw_address (dev);
- if (mac)
- nm_utils_hwaddr_aton (mac, epaddr->data, ETH_ALEN);
- else
- memset (epaddr->data, 0, ETH_ALEN);
- }
-
- priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN);
-
- g_free (epaddr);
- close (fd);
-}
-
-static void
-update_initial_hw_address (NMDevice *dev)
-{
- NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
-
- /* This sets initial MAC address from current MAC address. It should only
- * be called from NMDevice constructor() to really get the initial address.
- */
- priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev));
-
- _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr);
-}
-
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
@@ -421,7 +358,6 @@ static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMSettingWired *s_wired;
if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->check_connection_compatible (device, connection))
@@ -438,7 +374,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
return FALSE;
if (s_wired) {
- const char *mac;
+ const char *mac, *perm_hw_addr;
gboolean try_mac = TRUE;
const char * const *mac_blacklist;
int i;
@@ -446,21 +382,25 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!match_subchans (self, s_wired, &try_mac))
return FALSE;
+ perm_hw_addr = nm_device_get_permanent_hw_address (device);
mac = nm_setting_wired_get_mac_address (s_wired);
- if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1))
- return FALSE;
-
- /* Check for MAC address blacklist */
- mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
- for (i = 0; mac_blacklist[i]; i++) {
- if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
- g_warn_if_reached ();
+ if (perm_hw_addr) {
+ if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
return FALSE;
- }
- if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1))
- return FALSE;
- }
+ /* Check for MAC address blacklist */
+ mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
+ for (i = 0; mac_blacklist[i]; i++) {
+ if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
+ g_warn_if_reached ();
+ return FALSE;
+ }
+
+ if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1))
+ return FALSE;
+ }
+ } else if (mac)
+ return FALSE;
}
return TRUE;
@@ -1391,8 +1331,8 @@ deactivate (NMDevice *device)
NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s ();
/* Reset MAC address back to initial address */
- if (priv->initial_hw_addr)
- nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER);
+ if (nm_device_get_initial_hw_address (device))
+ nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_ETHER);
}
static gboolean
@@ -1402,10 +1342,10 @@ complete_connection (NMDevice *device,
const GSList *existing_connections,
GError **error)
{
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
NMSettingWired *s_wired;
NMSettingPppoe *s_pppoe;
const char *setting_mac;
+ const char *perm_hw_addr;
s_pppoe = nm_connection_get_setting_pppoe (connection);
@@ -1432,21 +1372,22 @@ complete_connection (NMDevice *device,
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 (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) {
- g_set_error_literal (error,
- NM_CONNECTION_ERROR,
- NM_CONNECTION_ERROR_INVALID_PROPERTY,
- _("connection does not match device"));
- g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
- return FALSE;
- }
- } else {
- if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) {
+ perm_hw_addr = nm_device_get_permanent_hw_address (device);
+ if (perm_hw_addr) {
+ 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 (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("connection does not match device"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
+ return FALSE;
+ }
+ } else {
g_object_set (G_OBJECT (s_wired),
- NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr,
+ NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr,
NULL);
}
}
@@ -1515,6 +1456,7 @@ update_connection (NMDevice *device, NMConnection *connection)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
NMSettingWired *s_wired = nm_connection_get_setting_wired (connection);
+ const char *perm_hw_addr = nm_device_get_permanent_hw_address (device);
const char *mac = nm_device_get_hw_address (device);
const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
GHashTableIter iter;
@@ -1528,11 +1470,11 @@ update_connection (NMDevice *device, NMConnection *connection)
/* If the device reports a permanent address, use that for the MAC address
* and the current MAC, if different, is the cloned MAC.
*/
- if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) {
- g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, NULL);
+ if (perm_hw_addr) {
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL);
mac_prop = NULL;
- if (mac && !nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, mac, -1))
+ if (mac && !nm_utils_hwaddr_matches (perm_hw_addr, -1, mac, -1))
mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS;
}
@@ -1638,8 +1580,6 @@ finalize (GObject *object)
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
- g_free (priv->perm_hw_addr);
- g_free (priv->initial_hw_addr);
g_clear_object (&priv->supplicant.mgr);
g_free (priv->subchan1);
g_free (priv->subchan2);
@@ -1660,7 +1600,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_PERM_HW_ADDRESS:
- g_value_set_string (value, priv->perm_hw_addr);
+ g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (object)));
break;
case PROP_SPEED:
g_value_set_uint (value, priv->speed);
@@ -1700,8 +1640,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
object_class->set_property = set_property;
parent_class->get_generic_capabilities = get_generic_capabilities;
- parent_class->update_permanent_hw_address = update_permanent_hw_address;
- parent_class->update_initial_hw_address = update_initial_hw_address;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
parent_class->new_default_connection = new_default_connection;
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 19c20b8bbc..9f2cb6d9a6 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -52,8 +52,6 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate))
typedef struct {
- char *initial_hw_addr;
-
gboolean disposed;
gboolean invalid;
@@ -75,16 +73,6 @@ enum {
/******************************************************************/
-static void
-update_initial_hw_address (NMDevice *dev)
-{
- NMDeviceVlan *self = NM_DEVICE_VLAN (dev);
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
-
- priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev));
- _LOGD (LOGD_DEVICE | LOGD_VLAN, "read initial MAC address %s", priv->initial_hw_addr);
-}
-
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
@@ -464,12 +452,9 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
static void
deactivate (NMDevice *device)
{
- NMDeviceVlan *self = NM_DEVICE_VLAN (device);
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
-
/* Reset MAC address back to initial address */
- if (priv->initial_hw_addr)
- nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN);
+ if (nm_device_get_initial_hw_address (device))
+ nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_VLAN);
}
/******************************************************************/
@@ -586,17 +571,6 @@ dispose (GObject *object)
}
static void
-finalize (GObject *object)
-{
- NMDeviceVlan *self = NM_DEVICE_VLAN (object);
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
-
- g_free (priv->initial_hw_addr);
-
- G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object);
-}
-
-static void
nm_device_vlan_class_init (NMDeviceVlanClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -611,9 +585,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->dispose = dispose;
- object_class->finalize = finalize;
- parent_class->update_initial_hw_address = update_initial_hw_address;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->bring_up = bring_up;
parent_class->act_stage1_prepare = act_stage1_prepare;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index bcda3122fd..6c69610b87 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -200,6 +200,8 @@ typedef struct {
GHashTable * available_connections;
char * hw_addr;
guint hw_addr_len;
+ char * perm_hw_addr;
+ char * initial_hw_addr;
char * physical_port_id;
guint dev_id;
@@ -8321,6 +8323,22 @@ nm_device_set_hw_addr (NMDevice *self, const char *addr,
return success;
}
+const char *
+nm_device_get_permanent_hw_address (NMDevice *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
+
+ return NM_DEVICE_GET_PRIVATE (self)->perm_hw_addr;
+}
+
+const char *
+nm_device_get_initial_hw_address (NMDevice *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
+
+ return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr;
+}
+
/**
* nm_device_spec_match_list:
* @self: an #NMDevice
@@ -8478,13 +8496,29 @@ constructed (GObject *object)
nm_device_update_hw_address (self);
- if (NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address)
- NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address (self);
-
- if (NM_DEVICE_GET_CLASS (self)->update_initial_hw_address)
- NM_DEVICE_GET_CLASS (self)->update_initial_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 (error %d)",
+ nm_platform_get_error (NM_PLATFORM_GET));
+ priv->perm_hw_addr = g_strdup (priv->hw_addr);
+ }
+ }
+ }
- /* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
+ /* Note: initial hardware address must be read before calling get_ignore_carrier() */
if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), self);
@@ -8604,6 +8638,8 @@ finalize (GObject *object)
_LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
g_free (priv->hw_addr);
+ g_free (priv->perm_hw_addr);
+ g_free (priv->initial_hw_addr);
g_slist_free_full (priv->pending_actions, g_free);
g_clear_pointer (&priv->physical_port_id, g_free);
g_free (priv->udi);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 28503ff155..78dccdb0bd 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -139,9 +139,6 @@ typedef struct {
/* Carrier state (IFF_LOWER_UP) */
void (*carrier_changed) (NMDevice *, gboolean carrier);
- void (* update_permanent_hw_address) (NMDevice *self);
- void (* update_initial_hw_address) (NMDevice *self);
-
gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid);
NMDeviceCapabilities (* get_generic_capabilities) (NMDevice *self);
@@ -287,7 +284,9 @@ int nm_device_get_priority (NMDevice *dev);
guint32 nm_device_get_ip4_route_metric (NMDevice *dev);
guint32 nm_device_get_ip6_route_metric (NMDevice *dev);
-const char * nm_device_get_hw_address (NMDevice *dev);
+const char * nm_device_get_hw_address (NMDevice *dev);
+const char * nm_device_get_permanent_hw_address (NMDevice *dev);
+const char * nm_device_get_initial_hw_address (NMDevice *dev);
NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev);
NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev);
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index feba9bbea7..6f8d8ec19c 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -26,13 +26,7 @@
#include <dbus/dbus.h>
#include <netinet/in.h>
#include <string.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <signal.h>
#include <unistd.h>
-#include <linux/sockios.h>
-#include <linux/ethtool.h>
-#include <sys/ioctl.h>
#include <errno.h>
#include "nm-glib-compat.h"
@@ -117,9 +111,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
struct _NMDeviceWifiPrivate {
- char * perm_hw_addr; /* Permanent MAC address */
- char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */
-
gint8 invalid_strength_counter;
GHashTable * aps;
@@ -537,8 +528,8 @@ deactivate (NMDevice *device)
nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE);
/* Reset MAC address back to initial address */
- if (priv->initial_hw_addr)
- nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_WIFI);
+ if (nm_device_get_initial_hw_address (device))
+ nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_WIFI);
nm_platform_wifi_set_powersave (NM_PLATFORM_GET, ifindex, 0);
@@ -604,6 +595,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
const char * const *mac_blacklist;
int i;
const char *mode;
+ const char *perm_hw_addr;
if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection))
return FALSE;
@@ -618,21 +610,25 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_wireless)
return FALSE;
+ perm_hw_addr = nm_device_get_permanent_hw_address (device);
mac = nm_setting_wireless_get_mac_address (s_wireless);
- if (mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1))
- return FALSE;
-
- /* Check for MAC address blacklist */
- mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
- for (i = 0; mac_blacklist[i]; i++) {
- if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
- g_warn_if_reached ();
+ if (perm_hw_addr) {
+ if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
return FALSE;
- }
- if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1))
- return FALSE;
- }
+ /* Check for MAC address blacklist */
+ mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
+ for (i = 0; mac_blacklist[i]; i++) {
+ if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
+ g_warn_if_reached ();
+ return FALSE;
+ }
+
+ if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1))
+ return FALSE;
+ }
+ } else if (mac)
+ return FALSE;
if (is_adhoc_wpa (connection))
return FALSE;
@@ -771,7 +767,6 @@ complete_connection (NMDevice *device,
GError **error)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSetting8021x *s_8021x;
@@ -782,6 +777,7 @@ complete_connection (NMDevice *device,
GByteArray *tmp_ssid = NULL;
GBytes *setting_ssid = NULL;
gboolean hidden = FALSE;
+ const char *perm_hw_addr;
s_wifi = nm_connection_get_setting_wireless (connection);
s_wsec = nm_connection_get_setting_wireless_security (connection);
@@ -912,29 +908,31 @@ complete_connection (NMDevice *device,
if (hidden)
g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL);
- setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
- if (setting_mac) {
- /* Make sure the setting MAC (if any) matches the device's permanent MAC */
- if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) {
- g_set_error_literal (error,
- NM_CONNECTION_ERROR,
- NM_CONNECTION_ERROR_INVALID_PROPERTY,
- _("connection does not match device"));
- g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS);
- return FALSE;
- }
- } else {
- guint8 perm_hw_addr[ETH_ALEN];
+ perm_hw_addr = nm_device_get_permanent_hw_address (device);
+ if (perm_hw_addr) {
+ setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
+ if (setting_mac) {
+ /* Make sure the setting MAC (if any) matches the device's permanent MAC */
+ if (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("connection does not match device"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS);
+ return FALSE;
+ }
+ } else {
+ guint8 tmp[ETH_ALEN];
- /* Lock the connection to this device by default if it uses a
- * permanent MAC address (ie not a 'locally administered' one)
- */
- nm_utils_hwaddr_aton (priv->perm_hw_addr, perm_hw_addr, ETH_ALEN);
- if ( !(perm_hw_addr[0] & 0x02)
- && !nm_utils_hwaddr_matches (perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) {
- g_object_set (G_OBJECT (s_wifi),
- NM_SETTING_WIRELESS_MAC_ADDRESS, priv->perm_hw_addr,
- NULL);
+ /* Lock the connection to this device by default if it uses a
+ * permanent MAC address (ie not a 'locally administered' one)
+ */
+ nm_utils_hwaddr_aton (perm_hw_addr, tmp, ETH_ALEN);
+ if (!(tmp[0] & 0x02)) {
+ g_object_set (G_OBJECT (s_wifi),
+ NM_SETTING_WIRELESS_MAC_ADDRESS, perm_hw_addr,
+ NULL);
+ }
}
}
@@ -2348,62 +2346,6 @@ error:
/****************************************************************************/
-static void
-update_permanent_hw_address (NMDevice *device)
-{
- NMDeviceWifi *self = NM_DEVICE_WIFI (device);
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- struct ifreq req;
- struct ethtool_perm_addr *epaddr = NULL;
- int fd, ret, errsv;
-
- g_return_if_fail (priv->perm_hw_addr == NULL);
-
- fd = socket (PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- _LOGE (LOGD_HW, "could not open control socket.");
- return;
- }
-
- /* Get permanent MAC address */
- memset (&req, 0, sizeof (struct ifreq));
- strncpy (req.ifr_name, nm_device_get_iface (device), IFNAMSIZ);
-
- epaddr = g_malloc0 (sizeof (struct ethtool_perm_addr) + ETH_ALEN);
- epaddr->cmd = ETHTOOL_GPERMADDR;
- epaddr->size = ETH_ALEN;
- req.ifr_data = (void *) epaddr;
-
- errno = 0;
- ret = ioctl (fd, SIOCETHTOOL, &req);
- errsv = errno;
- if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) {
- _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)",
- errsv);
- /* Fall back to current address */
- nm_utils_hwaddr_aton (nm_device_get_hw_address (device), epaddr->data, ETH_ALEN);
- }
-
- priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN);
-
- g_free (epaddr);
- close (fd);
-}
-
-static void
-update_initial_hw_address (NMDevice *device)
-{
- NMDeviceWifi *self = NM_DEVICE_WIFI (device);
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- /* This sets initial MAC address from current MAC address. It should only
- * be called from NMDevice constructor() to really get the initial address.
- */
- priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (device));
-
- _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr);
-}
-
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
@@ -3057,12 +2999,7 @@ dispose (GObject *object)
static void
finalize (GObject *object)
{
- NMDeviceWifi *self = NM_DEVICE_WIFI (object);
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- g_free (priv->perm_hw_addr);
- g_free (priv->initial_hw_addr);
- g_clear_pointer (&priv->aps, g_hash_table_unref);
+ g_clear_pointer (&NM_DEVICE_WIFI_GET_PRIVATE (object)->aps, g_hash_table_unref);
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
}
@@ -3079,7 +3016,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_PERM_HW_ADDRESS:
- g_value_set_string (value, priv->perm_hw_addr);
+ g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (device)));
break;
case PROP_MODE:
g_value_set_uint (value, priv->mode);
@@ -3135,8 +3072,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
object_class->finalize = finalize;
parent_class->bring_up = bring_up;
- parent_class->update_permanent_hw_address = update_permanent_hw_address;
- parent_class->update_initial_hw_address = update_initial_hw_address;
parent_class->can_auto_connect = can_auto_connect;
parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index ed7a3e6c8a..553aae5051 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -480,6 +480,12 @@ link_get_address (NMPlatform *platform, int ifindex, size_t *length)
}
static gboolean
+link_get_permanent_address (NMPlatform *platform, int ifindex, guint8 *buf, size_t *length)
+{
+ return FALSE;
+}
+
+static gboolean
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
{
NMFakePlatformLink *device = link_get (platform, ifindex);
@@ -1457,6 +1463,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->link_set_address = link_set_address;
platform_class->link_get_address = link_get_address;
+ platform_class->link_get_permanent_address = link_get_permanent_address;
platform_class->link_get_mtu = link_get_mtu;
platform_class->link_set_mtu = link_set_mtu;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 71bc4a8a62..025d29ed63 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -2861,6 +2861,34 @@ link_get_address (NMPlatform *platform, int ifindex, size_t *length)
}
static gboolean
+link_get_permanent_address (NMPlatform *platform,
+ int ifindex,
+ guint8 *buf,
+ size_t *length)
+{
+ gs_free struct ethtool_perm_addr *epaddr = NULL;
+ const char *ifname;
+
+ ifname = nm_platform_link_get_name (platform, ifindex);
+ if (!ifname)
+ return FALSE;
+
+ epaddr = g_malloc0 (sizeof (*epaddr) + NM_UTILS_HWADDR_LEN_MAX);
+ epaddr->cmd = ETHTOOL_GPERMADDR;
+ epaddr->size = NM_UTILS_HWADDR_LEN_MAX;
+
+ if (!ethtool_get (ifname, epaddr))
+ return FALSE;
+ if (!nm_ethernet_address_is_valid (epaddr->data, epaddr->size))
+ return FALSE;
+
+ g_assert (epaddr->size <= NM_UTILS_HWADDR_LEN_MAX);
+ memcpy (buf, epaddr->data, epaddr->size);
+ *length = epaddr->size;
+ return TRUE;
+}
+
+static gboolean
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
{
auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL);
@@ -4788,6 +4816,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_get_address = link_get_address;
platform_class->link_set_address = link_set_address;
+ platform_class->link_get_permanent_address = link_get_permanent_address;
platform_class->link_get_mtu = link_get_mtu;
platform_class->link_set_mtu = link_set_mtu;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 097eb96404..ba5a7f3bf6 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -976,7 +976,8 @@ nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer addre
* @ifindex: Interface index
* @length: Pointer to a variable to store address length
*
- * Saves interface hardware address to @address.
+ * Returns: the interface hardware address as an array of bytes of
+ * length @length.
*/
gconstpointer
nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length)
@@ -993,6 +994,34 @@ nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length)
return klass->link_get_address (self, ifindex, length);
}
+/**
+ * nm_platform_link_get_permanent_address:
+ * @self: platform instance
+ * @ifindex: Interface index
+ * @buf: buffer of at least %NM_UTILS_HWADDR_LEN_MAX bytes, on success
+ * the permanent hardware address
+ * @length: Pointer to a variable to store address length
+ *
+ * Returns: %TRUE on success, %FALSE on failure to read the permanent hardware
+ * address.
+ */
+gboolean
+nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length)
+{
+ _CHECK_SELF (self, klass, FALSE);
+ reset_error (self);
+
+ if (length)
+ *length = 0;
+
+ g_return_val_if_fail (ifindex > 0, FALSE);
+ g_return_val_if_fail (klass->link_get_permanent_address, FALSE);
+ g_return_val_if_fail (buf, FALSE);
+ g_return_val_if_fail (length, FALSE);
+
+ return klass->link_get_permanent_address (self, ifindex, buf, length);
+}
+
gboolean
nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex)
{
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 5e5f6fe6d4..f7be4ab0ee 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -393,6 +393,10 @@ typedef struct {
gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
gconstpointer (*link_get_address) (NMPlatform *, int ifindex, size_t *length);
+ gboolean (*link_get_permanent_address) (NMPlatform *,
+ int ifindex,
+ guint8 *buf,
+ size_t *length);
gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
guint32 (*link_get_mtu) (NMPlatform *, int ifindex);
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
@@ -552,6 +556,7 @@ gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex
gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled);
gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length);
+gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex);
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);