mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-07 21:18:09 +02:00
core: move permanent and initial MAC address reading to NMDevice and NMPlatform
Ethernet, WiFi, and VLAN used the same implementation for initial address. Ethernet and WiFi used the same implementation (and duplicated code) for permanent MAC address, plus they both used ethtool in what should be generic code, which is better done in the platform.
This commit is contained in:
parent
ddaea22332
commit
aba250a7d4
9 changed files with 209 additions and 253 deletions
|
|
@ -99,9 +99,6 @@ typedef enum {
|
||||||
} DcbWait;
|
} DcbWait;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char * perm_hw_addr; /* Permanent MAC address */
|
|
||||||
char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */
|
|
||||||
|
|
||||||
guint32 speed;
|
guint32 speed;
|
||||||
|
|
||||||
Supplicant supplicant;
|
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);
|
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
|
static NMDeviceCapabilities
|
||||||
get_generic_capabilities (NMDevice *device)
|
get_generic_capabilities (NMDevice *device)
|
||||||
{
|
{
|
||||||
|
|
@ -421,7 +358,6 @@ static gboolean
|
||||||
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
{
|
{
|
||||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
|
||||||
NMSettingWired *s_wired;
|
NMSettingWired *s_wired;
|
||||||
|
|
||||||
if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->check_connection_compatible (device, connection))
|
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;
|
return FALSE;
|
||||||
|
|
||||||
if (s_wired) {
|
if (s_wired) {
|
||||||
const char *mac;
|
const char *mac, *perm_hw_addr;
|
||||||
gboolean try_mac = TRUE;
|
gboolean try_mac = TRUE;
|
||||||
const char * const *mac_blacklist;
|
const char * const *mac_blacklist;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -446,21 +382,25 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
if (!match_subchans (self, s_wired, &try_mac))
|
if (!match_subchans (self, s_wired, &try_mac))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||||
mac = nm_setting_wired_get_mac_address (s_wired);
|
mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1))
|
if (perm_hw_addr) {
|
||||||
return FALSE;
|
if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||||
|
|
||||||
/* 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;
|
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)
|
||||||
if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -1391,8 +1331,8 @@ deactivate (NMDevice *device)
|
||||||
NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s ();
|
NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s ();
|
||||||
|
|
||||||
/* Reset MAC address back to initial address */
|
/* Reset MAC address back to initial address */
|
||||||
if (priv->initial_hw_addr)
|
if (nm_device_get_initial_hw_address (device))
|
||||||
nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER);
|
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_ETHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
@ -1402,10 +1342,10 @@ complete_connection (NMDevice *device,
|
||||||
const GSList *existing_connections,
|
const GSList *existing_connections,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
|
||||||
NMSettingWired *s_wired;
|
NMSettingWired *s_wired;
|
||||||
NMSettingPppoe *s_pppoe;
|
NMSettingPppoe *s_pppoe;
|
||||||
const char *setting_mac;
|
const char *setting_mac;
|
||||||
|
const char *perm_hw_addr;
|
||||||
|
|
||||||
s_pppoe = nm_connection_get_setting_pppoe (connection);
|
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));
|
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||||
}
|
}
|
||||||
|
|
||||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||||
if (setting_mac) {
|
if (perm_hw_addr) {
|
||||||
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
|
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) {
|
if (setting_mac) {
|
||||||
g_set_error_literal (error,
|
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
|
||||||
NM_CONNECTION_ERROR,
|
if (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) {
|
||||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
g_set_error_literal (error,
|
||||||
_("connection does not match device"));
|
NM_CONNECTION_ERROR,
|
||||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
return FALSE;
|
_("connection does not match device"));
|
||||||
}
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
|
||||||
} else {
|
return FALSE;
|
||||||
if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) {
|
}
|
||||||
|
} else {
|
||||||
g_object_set (G_OBJECT (s_wired),
|
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);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1515,6 +1456,7 @@ update_connection (NMDevice *device, NMConnection *connection)
|
||||||
{
|
{
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||||
NMSettingWired *s_wired = nm_connection_get_setting_wired (connection);
|
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 = nm_device_get_hw_address (device);
|
||||||
const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
|
const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
|
||||||
GHashTableIter iter;
|
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
|
/* If the device reports a permanent address, use that for the MAC address
|
||||||
* and the current MAC, if different, is the cloned MAC.
|
* and the current MAC, if different, is the cloned MAC.
|
||||||
*/
|
*/
|
||||||
if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) {
|
if (perm_hw_addr) {
|
||||||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, NULL);
|
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL);
|
||||||
|
|
||||||
mac_prop = 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;
|
mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1649,8 +1591,6 @@ finalize (GObject *object)
|
||||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
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_clear_object (&priv->supplicant.mgr);
|
||||||
g_free (priv->subchan1);
|
g_free (priv->subchan1);
|
||||||
g_free (priv->subchan2);
|
g_free (priv->subchan2);
|
||||||
|
|
@ -1671,7 +1611,7 @@ get_property (GObject *object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PERM_HW_ADDRESS:
|
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;
|
break;
|
||||||
case PROP_SPEED:
|
case PROP_SPEED:
|
||||||
g_value_set_uint (value, priv->speed);
|
g_value_set_uint (value, priv->speed);
|
||||||
|
|
@ -1711,8 +1651,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
|
|
||||||
parent_class->get_generic_capabilities = get_generic_capabilities;
|
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->check_connection_compatible = check_connection_compatible;
|
||||||
parent_class->complete_connection = complete_connection;
|
parent_class->complete_connection = complete_connection;
|
||||||
parent_class->new_default_connection = new_default_connection;
|
parent_class->new_default_connection = new_default_connection;
|
||||||
|
|
|
||||||
|
|
@ -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))
|
#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *initial_hw_addr;
|
|
||||||
|
|
||||||
gboolean disposed;
|
gboolean disposed;
|
||||||
gboolean invalid;
|
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
|
static NMDeviceCapabilities
|
||||||
get_generic_capabilities (NMDevice *dev)
|
get_generic_capabilities (NMDevice *dev)
|
||||||
{
|
{
|
||||||
|
|
@ -461,12 +449,9 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
|
||||||
static void
|
static void
|
||||||
deactivate (NMDevice *device)
|
deactivate (NMDevice *device)
|
||||||
{
|
{
|
||||||
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
|
|
||||||
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
/* Reset MAC address back to initial address */
|
/* Reset MAC address back to initial address */
|
||||||
if (priv->initial_hw_addr)
|
if (nm_device_get_initial_hw_address (device))
|
||||||
nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN);
|
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_VLAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
@ -582,17 +567,6 @@ dispose (GObject *object)
|
||||||
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
|
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (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
|
static void
|
||||||
nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
||||||
{
|
{
|
||||||
|
|
@ -608,9 +582,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
object_class->dispose = dispose;
|
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->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->bring_up = bring_up;
|
parent_class->bring_up = bring_up;
|
||||||
parent_class->act_stage1_prepare = act_stage1_prepare;
|
parent_class->act_stage1_prepare = act_stage1_prepare;
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ typedef struct {
|
||||||
GHashTable * available_connections;
|
GHashTable * available_connections;
|
||||||
char * hw_addr;
|
char * hw_addr;
|
||||||
guint hw_addr_len;
|
guint hw_addr_len;
|
||||||
|
char * perm_hw_addr;
|
||||||
|
char * initial_hw_addr;
|
||||||
char * physical_port_id;
|
char * physical_port_id;
|
||||||
guint dev_id;
|
guint dev_id;
|
||||||
|
|
||||||
|
|
@ -8408,6 +8410,22 @@ nm_device_set_hw_addr (NMDevice *self, const char *addr,
|
||||||
return success;
|
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:
|
* nm_device_spec_match_list:
|
||||||
* @self: an #NMDevice
|
* @self: an #NMDevice
|
||||||
|
|
@ -8579,13 +8597,29 @@ constructed (GObject *object)
|
||||||
|
|
||||||
nm_device_update_hw_address (self);
|
nm_device_update_hw_address (self);
|
||||||
|
|
||||||
if (NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address)
|
if (priv->hw_addr_len) {
|
||||||
NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address (self);
|
priv->initial_hw_addr = g_strdup (priv->hw_addr);
|
||||||
|
_LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
|
||||||
|
|
||||||
if (NM_DEVICE_GET_CLASS (self)->update_initial_hw_address)
|
if (priv->ifindex > 0) {
|
||||||
NM_DEVICE_GET_CLASS (self)->update_initial_hw_address (self);
|
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
/* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
|
||||||
if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
|
if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
|
||||||
NMConfig *config = nm_config_get ();
|
NMConfig *config = nm_config_get ();
|
||||||
|
|
||||||
|
|
@ -8718,6 +8752,8 @@ finalize (GObject *object)
|
||||||
_LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
|
_LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
|
||||||
|
|
||||||
g_free (priv->hw_addr);
|
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_slist_free_full (priv->pending_actions, g_free);
|
||||||
g_clear_pointer (&priv->physical_port_id, g_free);
|
g_clear_pointer (&priv->physical_port_id, g_free);
|
||||||
g_free (priv->udi);
|
g_free (priv->udi);
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,6 @@ typedef struct {
|
||||||
/* Carrier state (IFF_LOWER_UP) */
|
/* Carrier state (IFF_LOWER_UP) */
|
||||||
void (*carrier_changed) (NMDevice *, gboolean carrier);
|
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);
|
gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid);
|
||||||
|
|
||||||
NMDeviceCapabilities (* get_generic_capabilities) (NMDevice *self);
|
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_ip4_route_metric (NMDevice *dev);
|
||||||
guint32 nm_device_get_ip6_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);
|
NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev);
|
||||||
NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev);
|
NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev);
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,7 @@
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/sockios.h>
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "nm-glib-compat.h"
|
#include "nm-glib-compat.h"
|
||||||
|
|
@ -117,9 +111,6 @@ enum {
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
struct _NMDeviceWifiPrivate {
|
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;
|
gint8 invalid_strength_counter;
|
||||||
|
|
||||||
GHashTable * aps;
|
GHashTable * aps;
|
||||||
|
|
@ -533,8 +524,8 @@ deactivate (NMDevice *device)
|
||||||
nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE);
|
nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE);
|
||||||
|
|
||||||
/* Reset MAC address back to initial address */
|
/* Reset MAC address back to initial address */
|
||||||
if (priv->initial_hw_addr)
|
if (nm_device_get_initial_hw_address (device))
|
||||||
nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_WIFI);
|
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);
|
nm_platform_wifi_set_powersave (NM_PLATFORM_GET, ifindex, 0);
|
||||||
|
|
||||||
|
|
@ -600,6 +591,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
const char * const *mac_blacklist;
|
const char * const *mac_blacklist;
|
||||||
int i;
|
int i;
|
||||||
const char *mode;
|
const char *mode;
|
||||||
|
const char *perm_hw_addr;
|
||||||
|
|
||||||
if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection))
|
if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -614,21 +606,25 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
if (!s_wireless)
|
if (!s_wireless)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||||
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
||||||
if (mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1))
|
if (perm_hw_addr) {
|
||||||
return FALSE;
|
if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||||
|
|
||||||
/* 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;
|
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)
|
||||||
if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_adhoc_wpa (connection))
|
if (is_adhoc_wpa (connection))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -767,7 +763,6 @@ complete_connection (NMDevice *device,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
|
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
|
||||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
|
||||||
NMSettingWireless *s_wifi;
|
NMSettingWireless *s_wifi;
|
||||||
NMSettingWirelessSecurity *s_wsec;
|
NMSettingWirelessSecurity *s_wsec;
|
||||||
NMSetting8021x *s_8021x;
|
NMSetting8021x *s_8021x;
|
||||||
|
|
@ -778,6 +773,7 @@ complete_connection (NMDevice *device,
|
||||||
GByteArray *tmp_ssid = NULL;
|
GByteArray *tmp_ssid = NULL;
|
||||||
GBytes *setting_ssid = NULL;
|
GBytes *setting_ssid = NULL;
|
||||||
gboolean hidden = FALSE;
|
gboolean hidden = FALSE;
|
||||||
|
const char *perm_hw_addr;
|
||||||
|
|
||||||
s_wifi = nm_connection_get_setting_wireless (connection);
|
s_wifi = nm_connection_get_setting_wireless (connection);
|
||||||
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
||||||
|
|
@ -908,29 +904,31 @@ complete_connection (NMDevice *device,
|
||||||
if (hidden)
|
if (hidden)
|
||||||
g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL);
|
g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL);
|
||||||
|
|
||||||
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||||
if (setting_mac) {
|
if (perm_hw_addr) {
|
||||||
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
|
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
||||||
if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) {
|
if (setting_mac) {
|
||||||
g_set_error_literal (error,
|
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
|
||||||
NM_CONNECTION_ERROR,
|
if (!nm_utils_hwaddr_matches (setting_mac, -1, perm_hw_addr, -1)) {
|
||||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
g_set_error_literal (error,
|
||||||
_("connection does not match device"));
|
NM_CONNECTION_ERROR,
|
||||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS);
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
return FALSE;
|
_("connection does not match device"));
|
||||||
}
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS);
|
||||||
} else {
|
return FALSE;
|
||||||
guint8 perm_hw_addr[ETH_ALEN];
|
}
|
||||||
|
} else {
|
||||||
|
guint8 tmp[ETH_ALEN];
|
||||||
|
|
||||||
/* Lock the connection to this device by default if it uses a
|
/* Lock the connection to this device by default if it uses a
|
||||||
* permanent MAC address (ie not a 'locally administered' one)
|
* permanent MAC address (ie not a 'locally administered' one)
|
||||||
*/
|
*/
|
||||||
nm_utils_hwaddr_aton (priv->perm_hw_addr, perm_hw_addr, ETH_ALEN);
|
nm_utils_hwaddr_aton (perm_hw_addr, tmp, ETH_ALEN);
|
||||||
if ( !(perm_hw_addr[0] & 0x02)
|
if (!(tmp[0] & 0x02)) {
|
||||||
&& !nm_utils_hwaddr_matches (perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) {
|
g_object_set (G_OBJECT (s_wifi),
|
||||||
g_object_set (G_OBJECT (s_wifi),
|
NM_SETTING_WIRELESS_MAC_ADDRESS, perm_hw_addr,
|
||||||
NM_SETTING_WIRELESS_MAC_ADDRESS, priv->perm_hw_addr,
|
NULL);
|
||||||
NULL);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2241,62 +2239,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
|
static NMActStageReturn
|
||||||
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
|
|
@ -2950,12 +2892,7 @@ dispose (GObject *object)
|
||||||
static void
|
static void
|
||||||
finalize (GObject *object)
|
finalize (GObject *object)
|
||||||
{
|
{
|
||||||
NMDeviceWifi *self = NM_DEVICE_WIFI (object);
|
g_clear_pointer (&NM_DEVICE_WIFI_GET_PRIVATE (object)->aps, g_hash_table_unref);
|
||||||
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_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
@ -2972,7 +2909,7 @@ get_property (GObject *object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PERM_HW_ADDRESS:
|
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;
|
break;
|
||||||
case PROP_MODE:
|
case PROP_MODE:
|
||||||
g_value_set_uint (value, priv->mode);
|
g_value_set_uint (value, priv->mode);
|
||||||
|
|
@ -3028,8 +2965,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
|
|
||||||
parent_class->bring_up = bring_up;
|
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->can_auto_connect = can_auto_connect;
|
||||||
parent_class->is_available = is_available;
|
parent_class->is_available = is_available;
|
||||||
parent_class->check_connection_compatible = check_connection_compatible;
|
parent_class->check_connection_compatible = check_connection_compatible;
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,12 @@ link_get_address (NMPlatform *platform, int ifindex, size_t *length)
|
||||||
return g_bytes_get_data (device->address, length);
|
return g_bytes_get_data (device->address, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_get_permanent_address (NMPlatform *platform, int ifindex, guint8 *buf, size_t *length)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
|
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
|
||||||
{
|
{
|
||||||
|
|
@ -1432,6 +1438,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
||||||
|
|
||||||
platform_class->link_set_address = link_set_address;
|
platform_class->link_set_address = link_set_address;
|
||||||
platform_class->link_get_address = link_get_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_get_mtu = link_get_mtu;
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,31 @@ ethtool_get_driver_info (const char *ifname,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
ethtool_get_permanent_address (const char *ifname,
|
||||||
|
guint8 *buf,
|
||||||
|
size_t *length)
|
||||||
|
{
|
||||||
|
gs_free struct ethtool_perm_addr *epaddr = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* udev
|
* udev
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
@ -2854,6 +2879,15 @@ link_get_address (NMPlatform *platform, int ifindex, size_t *length)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_get_permanent_address (NMPlatform *platform,
|
||||||
|
int ifindex,
|
||||||
|
guint8 *buf,
|
||||||
|
size_t *length)
|
||||||
|
{
|
||||||
|
return ethtool_get_permanent_address (nm_platform_link_get_name (platform, ifindex), buf, length);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
|
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
|
||||||
{
|
{
|
||||||
|
|
@ -4787,6 +4821,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
||||||
|
|
||||||
platform_class->link_get_address = link_get_address;
|
platform_class->link_get_address = link_get_address;
|
||||||
platform_class->link_set_address = link_set_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_get_mtu = link_get_mtu;
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1012,7 +1012,8 @@ nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer addre
|
||||||
* @ifindex: Interface index
|
* @ifindex: Interface index
|
||||||
* @length: Pointer to a variable to store address length
|
* @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
|
gconstpointer
|
||||||
nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length)
|
nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length)
|
||||||
|
|
@ -1029,6 +1030,34 @@ nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length)
|
||||||
return klass->link_get_address (self, ifindex, 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
|
gboolean
|
||||||
nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex)
|
nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,10 @@ typedef struct {
|
||||||
gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
|
gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
|
||||||
|
|
||||||
gconstpointer (*link_get_address) (NMPlatform *, int ifindex, size_t *length);
|
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);
|
gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
|
||||||
guint32 (*link_get_mtu) (NMPlatform *, int ifindex);
|
guint32 (*link_get_mtu) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
||||||
|
|
@ -568,6 +572,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);
|
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);
|
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);
|
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);
|
guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex);
|
||||||
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
|
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue