mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-04 15:21:12 +00:00
device: merge branch 'th/device-inital-mac-addr-bgo708820'
https://bugzilla.gnome.org/show_bug.cgi?id=705545 https://bugzilla.gnome.org/show_bug.cgi?id=708820 https://bugzilla.gnome.org/show_bug.cgi?id=758301
This commit is contained in:
commit
9a354cdc90
|
@ -24,6 +24,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "nm-common-macros.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "nm-vpn-helpers.h"
|
#include "nm-vpn-helpers.h"
|
||||||
|
@ -44,26 +45,28 @@ NmcOutputField nmc_fields_setting_connection[] = {
|
||||||
SETTING_FIELD ("name"), /* 0 */
|
SETTING_FIELD ("name"), /* 0 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_ID), /* 1 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_ID), /* 1 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_UUID), /* 2 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_UUID), /* 2 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_INTERFACE_NAME), /* 3 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_STABLE_ID), /* 3 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_TYPE), /* 4 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_INTERFACE_NAME), /* 4 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT), /* 5 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_TYPE), /* 5 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY), /* 6 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT), /* 6 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP), /* 7 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY), /* 7 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY), /* 8 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP), /* 8 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS), /* 9 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY), /* 9 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_ZONE), /* 10 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS), /* 10 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_MASTER), /* 11 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_ZONE), /* 11 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE), /* 12 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_MASTER), /* 12 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES), /* 13 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE), /* 13 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES), /* 14 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES), /* 14 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT), /* 15 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES), /* 15 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_METERED), /* 16 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT), /* 16 */
|
||||||
SETTING_FIELD (NM_SETTING_CONNECTION_LLDP), /* 17 */
|
SETTING_FIELD (NM_SETTING_CONNECTION_METERED), /* 17 */
|
||||||
|
SETTING_FIELD (NM_SETTING_CONNECTION_LLDP), /* 18 */
|
||||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||||
};
|
};
|
||||||
#define NMC_FIELDS_SETTING_CONNECTION_ALL "name"","\
|
#define NMC_FIELDS_SETTING_CONNECTION_ALL "name"","\
|
||||||
NM_SETTING_CONNECTION_ID","\
|
NM_SETTING_CONNECTION_ID","\
|
||||||
NM_SETTING_CONNECTION_UUID","\
|
NM_SETTING_CONNECTION_UUID","\
|
||||||
|
NM_SETTING_CONNECTION_STABLE_ID","\
|
||||||
NM_SETTING_CONNECTION_INTERFACE_NAME","\
|
NM_SETTING_CONNECTION_INTERFACE_NAME","\
|
||||||
NM_SETTING_CONNECTION_TYPE","\
|
NM_SETTING_CONNECTION_TYPE","\
|
||||||
NM_SETTING_CONNECTION_AUTOCONNECT","\
|
NM_SETTING_CONNECTION_AUTOCONNECT","\
|
||||||
|
@ -89,13 +92,14 @@ NmcOutputField nmc_fields_setting_wired[] = {
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE), /* 4 */
|
SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE), /* 4 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS), /* 5 */
|
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS), /* 5 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS), /* 6 */
|
SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS), /* 6 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST), /* 7 */
|
SETTING_FIELD (NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK), /* 7 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_MTU), /* 8 */
|
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST), /* 8 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS), /* 9 */
|
SETTING_FIELD (NM_SETTING_WIRED_MTU), /* 9 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE), /* 10 */
|
SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS), /* 10 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS), /* 11 */
|
SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE), /* 11 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN), /* 12 */
|
SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS), /* 12 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD), /* 13 */
|
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN), /* 13 */
|
||||||
|
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD), /* 14 */
|
||||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||||
};
|
};
|
||||||
#define NMC_FIELDS_SETTING_WIRED_ALL "name"","\
|
#define NMC_FIELDS_SETTING_WIRED_ALL "name"","\
|
||||||
|
@ -105,6 +109,7 @@ NmcOutputField nmc_fields_setting_wired[] = {
|
||||||
NM_SETTING_WIRED_AUTO_NEGOTIATE","\
|
NM_SETTING_WIRED_AUTO_NEGOTIATE","\
|
||||||
NM_SETTING_WIRED_MAC_ADDRESS","\
|
NM_SETTING_WIRED_MAC_ADDRESS","\
|
||||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
|
||||||
|
NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK","\
|
||||||
NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST","\
|
NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST","\
|
||||||
NM_SETTING_WIRED_MTU","\
|
NM_SETTING_WIRED_MTU","\
|
||||||
NM_SETTING_WIRED_S390_SUBCHANNELS","\
|
NM_SETTING_WIRED_S390_SUBCHANNELS","\
|
||||||
|
@ -200,12 +205,13 @@ NmcOutputField nmc_fields_setting_wireless[] = {
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER), /* 7 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER), /* 7 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS), /* 8 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS), /* 8 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS), /* 9 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS), /* 9 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST), /* 10 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK), /* 10 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION), /* 11 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST), /* 11 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_MTU), /* 12 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION), /* 12 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS), /* 13 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_MTU), /* 13 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_HIDDEN), /* 14 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS), /* 14 */
|
||||||
SETTING_FIELD (NM_SETTING_WIRELESS_POWERSAVE), /* 15 */
|
SETTING_FIELD (NM_SETTING_WIRELESS_HIDDEN), /* 15 */
|
||||||
|
SETTING_FIELD (NM_SETTING_WIRELESS_POWERSAVE), /* 16 */
|
||||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||||
};
|
};
|
||||||
#define NMC_FIELDS_SETTING_WIRELESS_ALL "name"","\
|
#define NMC_FIELDS_SETTING_WIRELESS_ALL "name"","\
|
||||||
|
@ -218,6 +224,7 @@ NmcOutputField nmc_fields_setting_wireless[] = {
|
||||||
NM_SETTING_WIRELESS_TX_POWER","\
|
NM_SETTING_WIRELESS_TX_POWER","\
|
||||||
NM_SETTING_WIRELESS_MAC_ADDRESS","\
|
NM_SETTING_WIRELESS_MAC_ADDRESS","\
|
||||||
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS","\
|
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS","\
|
||||||
|
NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK","\
|
||||||
NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST","\
|
NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST","\
|
||||||
NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION","\
|
NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION","\
|
||||||
NM_SETTING_WIRELESS_MTU","\
|
NM_SETTING_WIRELESS_MTU","\
|
||||||
|
@ -1252,6 +1259,7 @@ DEFINE_SECRET_FLAGS_GETTER (nmc_property_cdma_get_password_flags, NM_SETTING_CDM
|
||||||
/* --- NM_SETTING_CONNECTION_SETTING_NAME property get functions --- */
|
/* --- NM_SETTING_CONNECTION_SETTING_NAME property get functions --- */
|
||||||
DEFINE_GETTER (nmc_property_connection_get_id, NM_SETTING_CONNECTION_ID)
|
DEFINE_GETTER (nmc_property_connection_get_id, NM_SETTING_CONNECTION_ID)
|
||||||
DEFINE_GETTER (nmc_property_connection_get_uuid, NM_SETTING_CONNECTION_UUID)
|
DEFINE_GETTER (nmc_property_connection_get_uuid, NM_SETTING_CONNECTION_UUID)
|
||||||
|
DEFINE_GETTER (nmc_property_connection_get_stable_id, NM_SETTING_CONNECTION_STABLE_ID)
|
||||||
DEFINE_GETTER (nmc_property_connection_get_interface_name, NM_SETTING_CONNECTION_INTERFACE_NAME)
|
DEFINE_GETTER (nmc_property_connection_get_interface_name, NM_SETTING_CONNECTION_INTERFACE_NAME)
|
||||||
DEFINE_GETTER (nmc_property_connection_get_type, NM_SETTING_CONNECTION_TYPE)
|
DEFINE_GETTER (nmc_property_connection_get_type, NM_SETTING_CONNECTION_TYPE)
|
||||||
DEFINE_GETTER (nmc_property_connection_get_autoconnect, NM_SETTING_CONNECTION_AUTOCONNECT)
|
DEFINE_GETTER (nmc_property_connection_get_autoconnect, NM_SETTING_CONNECTION_AUTOCONNECT)
|
||||||
|
@ -1761,6 +1769,7 @@ DEFINE_GETTER (nmc_property_wired_get_duplex, NM_SETTING_WIRED_DUPLEX)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_auto_negotiate, NM_SETTING_WIRED_AUTO_NEGOTIATE)
|
DEFINE_GETTER (nmc_property_wired_get_auto_negotiate, NM_SETTING_WIRED_AUTO_NEGOTIATE)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_mac_address, NM_SETTING_WIRED_MAC_ADDRESS)
|
DEFINE_GETTER (nmc_property_wired_get_mac_address, NM_SETTING_WIRED_MAC_ADDRESS)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_cloned_mac_address, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)
|
DEFINE_GETTER (nmc_property_wired_get_cloned_mac_address, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)
|
||||||
|
DEFINE_GETTER (nmc_property_wired_get_generate_mac_address_mask, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_mac_address_blacklist, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST)
|
DEFINE_GETTER (nmc_property_wired_get_mac_address_blacklist, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_s390_subchannels, NM_SETTING_WIRED_S390_SUBCHANNELS)
|
DEFINE_GETTER (nmc_property_wired_get_s390_subchannels, NM_SETTING_WIRED_S390_SUBCHANNELS)
|
||||||
DEFINE_GETTER (nmc_property_wired_get_s390_nettype, NM_SETTING_WIRED_S390_NETTYPE)
|
DEFINE_GETTER (nmc_property_wired_get_s390_nettype, NM_SETTING_WIRED_S390_NETTYPE)
|
||||||
|
@ -1887,6 +1896,7 @@ DEFINE_GETTER (nmc_property_wireless_get_rate, NM_SETTING_WIRELESS_RATE)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_tx_power, NM_SETTING_WIRELESS_TX_POWER)
|
DEFINE_GETTER (nmc_property_wireless_get_tx_power, NM_SETTING_WIRELESS_TX_POWER)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_mac_address, NM_SETTING_WIRELESS_MAC_ADDRESS)
|
DEFINE_GETTER (nmc_property_wireless_get_mac_address, NM_SETTING_WIRELESS_MAC_ADDRESS)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_cloned_mac_address, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)
|
DEFINE_GETTER (nmc_property_wireless_get_cloned_mac_address, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)
|
||||||
|
DEFINE_GETTER (nmc_property_wireless_get_generate_mac_address_mask, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_mac_address_blacklist, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST)
|
DEFINE_GETTER (nmc_property_wireless_get_mac_address_blacklist, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_seen_bssids, NM_SETTING_WIRELESS_SEEN_BSSIDS)
|
DEFINE_GETTER (nmc_property_wireless_get_seen_bssids, NM_SETTING_WIRELESS_SEEN_BSSIDS)
|
||||||
DEFINE_GETTER (nmc_property_wireless_get_hidden, NM_SETTING_WIRELESS_HIDDEN)
|
DEFINE_GETTER (nmc_property_wireless_get_hidden, NM_SETTING_WIRELESS_HIDDEN)
|
||||||
|
@ -2886,11 +2896,12 @@ nmc_property_set_ssid (NMSetting *setting, const char *prop, const char *val, GE
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GError **error)
|
_property_set_mac (NMSetting *setting, const char *prop, const char *val, gboolean cloned_mac_addr, GError **error)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||||
|
|
||||||
if (!nm_utils_hwaddr_valid (val, ETH_ALEN)) {
|
if ( (!cloned_mac_addr || !NM_CLONED_MAC_IS_SPECIAL (val))
|
||||||
|
&& !nm_utils_hwaddr_valid (val, ETH_ALEN)) {
|
||||||
g_set_error (error, 1, 0, _("'%s' is not a valid Ethernet MAC"), val);
|
g_set_error (error, 1, 0, _("'%s' is not a valid Ethernet MAC"), val);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2899,6 +2910,18 @@ nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GEr
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GError **error)
|
||||||
|
{
|
||||||
|
return _property_set_mac (setting, prop, val, FALSE, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nmc_property_set_mac_cloned (NMSetting *setting, const char *prop, const char *val, GError **error)
|
||||||
|
{
|
||||||
|
return _property_set_mac (setting, prop, val, TRUE, error);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
nmc_property_set_mtu (NMSetting *setting, const char *prop, const char *val, GError **error)
|
nmc_property_set_mtu (NMSetting *setting, const char *prop, const char *val, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -6217,6 +6240,13 @@ nmc_properties_init (void)
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
nmc_add_prop_funcs (GLUE (CONNECTION, STABLE_ID),
|
||||||
|
nmc_property_connection_get_stable_id,
|
||||||
|
nmc_property_set_string,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
nmc_add_prop_funcs (GLUE (CONNECTION, INTERFACE_NAME),
|
nmc_add_prop_funcs (GLUE (CONNECTION, INTERFACE_NAME),
|
||||||
nmc_property_connection_get_interface_name,
|
nmc_property_connection_get_interface_name,
|
||||||
nmc_property_set_ifname,
|
nmc_property_set_ifname,
|
||||||
|
@ -7188,7 +7218,14 @@ nmc_properties_init (void)
|
||||||
NULL);
|
NULL);
|
||||||
nmc_add_prop_funcs (GLUE (WIRED, CLONED_MAC_ADDRESS),
|
nmc_add_prop_funcs (GLUE (WIRED, CLONED_MAC_ADDRESS),
|
||||||
nmc_property_wired_get_cloned_mac_address,
|
nmc_property_wired_get_cloned_mac_address,
|
||||||
nmc_property_set_mac,
|
nmc_property_set_mac_cloned,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
nmc_add_prop_funcs (GLUE (WIRED, GENERATE_MAC_ADDRESS_MASK),
|
||||||
|
nmc_property_wired_get_generate_mac_address_mask,
|
||||||
|
nmc_property_set_string,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -7306,7 +7343,14 @@ nmc_properties_init (void)
|
||||||
NULL);
|
NULL);
|
||||||
nmc_add_prop_funcs (GLUE (WIRELESS, CLONED_MAC_ADDRESS),
|
nmc_add_prop_funcs (GLUE (WIRELESS, CLONED_MAC_ADDRESS),
|
||||||
nmc_property_wireless_get_cloned_mac_address,
|
nmc_property_wireless_get_cloned_mac_address,
|
||||||
nmc_property_set_mac,
|
nmc_property_set_mac_cloned,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
nmc_add_prop_funcs (GLUE (WIRELESS, GENERATE_MAC_ADDRESS_MASK),
|
||||||
|
nmc_property_wireless_get_generate_mac_address_mask,
|
||||||
|
nmc_property_set_string,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -8063,21 +8107,22 @@ setting_connection_details (NMSetting *setting, NmCli *nmc, const char *one_pro
|
||||||
set_val_str (arr, 0, g_strdup (nm_setting_get_name (setting)));
|
set_val_str (arr, 0, g_strdup (nm_setting_get_name (setting)));
|
||||||
set_val_str (arr, 1, nmc_property_connection_get_id (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 1, nmc_property_connection_get_id (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 2, nmc_property_connection_get_uuid (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 2, nmc_property_connection_get_uuid (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 3, nmc_property_connection_get_interface_name (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 3, nmc_property_connection_get_stable_id (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 4, nmc_property_connection_get_type (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 4, nmc_property_connection_get_interface_name (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 5, nmc_property_connection_get_autoconnect (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 5, nmc_property_connection_get_type (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 6, nmc_property_connection_get_autoconnect_priority (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 6, nmc_property_connection_get_autoconnect (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 7, nmc_property_connection_get_timestamp (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 7, nmc_property_connection_get_autoconnect_priority (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 8, nmc_property_connection_get_read_only (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 8, nmc_property_connection_get_timestamp (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 9, nmc_property_connection_get_permissions (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 9, nmc_property_connection_get_read_only (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 10, nmc_property_connection_get_zone (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 10, nmc_property_connection_get_permissions (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 11, nmc_property_connection_get_master (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 11, nmc_property_connection_get_zone (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 12, nmc_property_connection_get_slave_type (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 12, nmc_property_connection_get_master (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 13, nmc_property_connection_get_autoconnect_slaves (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 13, nmc_property_connection_get_slave_type (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 14, nmc_property_connection_get_secondaries (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 14, nmc_property_connection_get_autoconnect_slaves (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 15, nmc_property_connection_get_gateway_ping_timeout (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 15, nmc_property_connection_get_secondaries (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 16, nmc_property_connection_get_metered (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 16, nmc_property_connection_get_gateway_ping_timeout (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 17, nmc_property_connection_get_lldp (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 17, nmc_property_connection_get_metered (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
|
set_val_str (arr, 18, nmc_property_connection_get_lldp (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
g_ptr_array_add (nmc->output_data, arr);
|
g_ptr_array_add (nmc->output_data, arr);
|
||||||
|
|
||||||
print_data (nmc); /* Print all data */
|
print_data (nmc); /* Print all data */
|
||||||
|
@ -8109,13 +8154,14 @@ setting_wired_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gb
|
||||||
set_val_str (arr, 4, nmc_property_wired_get_auto_negotiate (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 4, nmc_property_wired_get_auto_negotiate (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 5, nmc_property_wired_get_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 5, nmc_property_wired_get_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 6, nmc_property_wired_get_cloned_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 6, nmc_property_wired_get_cloned_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 7, nmc_property_wired_get_mac_address_blacklist (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 7, nmc_property_wired_get_generate_mac_address_mask (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 8, nmc_property_wired_get_mtu (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 8, nmc_property_wired_get_mac_address_blacklist (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 9, nmc_property_wired_get_s390_subchannels (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 9, nmc_property_wired_get_mtu (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 10, nmc_property_wired_get_s390_nettype (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 10, nmc_property_wired_get_s390_subchannels (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 11, nmc_property_wired_get_s390_options (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 11, nmc_property_wired_get_s390_nettype (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 12, nmc_property_wired_get_wake_on_lan (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 12, nmc_property_wired_get_s390_options (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 13, nmc_property_wired_get_wake_on_lan_password (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 13, nmc_property_wired_get_wake_on_lan (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
|
set_val_str (arr, 14, nmc_property_wired_get_wake_on_lan_password (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
g_ptr_array_add (nmc->output_data, arr);
|
g_ptr_array_add (nmc->output_data, arr);
|
||||||
|
|
||||||
print_data (nmc); /* Print all data */
|
print_data (nmc); /* Print all data */
|
||||||
|
@ -8209,12 +8255,13 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc, const char *one_prop,
|
||||||
set_val_str (arr, 7, nmc_property_wireless_get_tx_power (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 7, nmc_property_wireless_get_tx_power (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 8, nmc_property_wireless_get_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 8, nmc_property_wireless_get_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 9, nmc_property_wireless_get_cloned_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 9, nmc_property_wireless_get_cloned_mac_address (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 10, nmc_property_wireless_get_mac_address_blacklist (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 10, nmc_property_wireless_get_generate_mac_address_mask (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 11, nmc_property_wireless_get_mac_address_randomization (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 11, nmc_property_wireless_get_mac_address_blacklist (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 12, nmc_property_wireless_get_mtu (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 12, nmc_property_wireless_get_mac_address_randomization (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 13, nmc_property_wireless_get_seen_bssids (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 13, nmc_property_wireless_get_mtu (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 14, nmc_property_wireless_get_hidden (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 14, nmc_property_wireless_get_seen_bssids (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
set_val_str (arr, 15, nmc_property_wireless_get_powersave (setting, NMC_PROPERTY_GET_PRETTY));
|
set_val_str (arr, 15, nmc_property_wireless_get_hidden (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
|
set_val_str (arr, 16, nmc_property_wireless_get_powersave (setting, NMC_PROPERTY_GET_PRETTY));
|
||||||
g_ptr_array_add (nmc->output_data, arr);
|
g_ptr_array_add (nmc->output_data, arr);
|
||||||
|
|
||||||
print_data (nmc); /* Print all data */
|
print_data (nmc); /* Print all data */
|
||||||
|
|
|
@ -28,11 +28,13 @@
|
||||||
|
|
||||||
#include "nm-default.h"
|
#include "nm-default.h"
|
||||||
|
|
||||||
|
#include "nmt-mac-entry.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
|
#include "nm-common-macros.h"
|
||||||
|
|
||||||
#include "nmt-mac-entry.h"
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
|
G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
|
||||||
|
|
||||||
|
@ -41,6 +43,7 @@ G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int mac_length;
|
int mac_length;
|
||||||
int mac_str_length;
|
int mac_str_length;
|
||||||
|
NmtMacEntryType entry_type;
|
||||||
|
|
||||||
} NmtMacEntryPrivate;
|
} NmtMacEntryPrivate;
|
||||||
|
|
||||||
|
@ -48,6 +51,7 @@ enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_MAC_LENGTH,
|
PROP_MAC_LENGTH,
|
||||||
PROP_MAC_ADDRESS,
|
PROP_MAC_ADDRESS,
|
||||||
|
PROP_ENTRY_TYPE,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
@ -57,6 +61,7 @@ enum {
|
||||||
* @width: the width in characters of the entry
|
* @width: the width in characters of the entry
|
||||||
* @mac_length: the length in bytes of the hardware address
|
* @mac_length: the length in bytes of the hardware address
|
||||||
* (either %ETH_ALEN or %INFINIBAND_ALEN)
|
* (either %ETH_ALEN or %INFINIBAND_ALEN)
|
||||||
|
* @entry_type: the type of the entry.
|
||||||
*
|
*
|
||||||
* Creates a new #NmtMacEntry.
|
* Creates a new #NmtMacEntry.
|
||||||
*
|
*
|
||||||
|
@ -64,11 +69,13 @@ enum {
|
||||||
*/
|
*/
|
||||||
NmtNewtWidget *
|
NmtNewtWidget *
|
||||||
nmt_mac_entry_new (int width,
|
nmt_mac_entry_new (int width,
|
||||||
int mac_length)
|
int mac_length,
|
||||||
|
NmtMacEntryType entry_type)
|
||||||
{
|
{
|
||||||
return g_object_new (NMT_TYPE_MAC_ENTRY,
|
return g_object_new (NMT_TYPE_MAC_ENTRY,
|
||||||
"width", width,
|
"width", width,
|
||||||
"mac-length", mac_length,
|
"mac-length", mac_length,
|
||||||
|
"entry-type", (int) entry_type,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +88,9 @@ mac_filter (NmtNewtEntry *entry,
|
||||||
{
|
{
|
||||||
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry);
|
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry);
|
||||||
|
|
||||||
|
if (priv->entry_type != NMT_MAC_ENTRY_TYPE_MAC)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (position >= priv->mac_str_length)
|
if (position >= priv->mac_str_length)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -98,6 +108,11 @@ mac_validator (NmtNewtEntry *entry,
|
||||||
if (!*text)
|
if (!*text)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if (priv->entry_type == NMT_MAC_ENTRY_TYPE_CLONED) {
|
||||||
|
if (NM_CLONED_MAC_IS_SPECIAL (text))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
p = text;
|
p = text;
|
||||||
while ( g_ascii_isxdigit (p[0])
|
while ( g_ascii_isxdigit (p[0])
|
||||||
&& g_ascii_isxdigit (p[1])
|
&& g_ascii_isxdigit (p[1])
|
||||||
|
@ -112,7 +127,9 @@ mac_validator (NmtNewtEntry *entry,
|
||||||
if (!*p)
|
if (!*p)
|
||||||
return (p - text == priv->mac_str_length);
|
return (p - text == priv->mac_str_length);
|
||||||
|
|
||||||
if (g_ascii_isxdigit (p[0]) && !p[1]) {
|
if ( g_ascii_isxdigit (p[0])
|
||||||
|
&& !p[1]
|
||||||
|
&& p - text < priv->mac_str_length) {
|
||||||
char *fixed = g_strdup_printf ("%.*s:%c", (int)(p - text), text, *p);
|
char *fixed = g_strdup_printf ("%.*s:%c", (int)(p - text), text, *p);
|
||||||
|
|
||||||
nmt_newt_entry_set_text (entry, fixed);
|
nmt_newt_entry_set_text (entry, fixed);
|
||||||
|
@ -161,6 +178,10 @@ nmt_mac_entry_set_property (GObject *object,
|
||||||
case PROP_MAC_ADDRESS:
|
case PROP_MAC_ADDRESS:
|
||||||
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), g_value_get_string (value));
|
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), g_value_get_string (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENTRY_TYPE:
|
||||||
|
/* construct-only */
|
||||||
|
priv->entry_type = g_value_get_int (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -182,6 +203,9 @@ nmt_mac_entry_get_property (GObject *object,
|
||||||
case PROP_MAC_ADDRESS:
|
case PROP_MAC_ADDRESS:
|
||||||
g_value_set_string (value, nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)));
|
g_value_set_string (value, nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)));
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENTRY_TYPE:
|
||||||
|
g_value_set_int (value, priv->entry_type);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -224,4 +248,17 @@ nmt_mac_entry_class_init (NmtMacEntryClass *entry_class)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
/**
|
||||||
|
* NmtMacEntry:entry-type:
|
||||||
|
*
|
||||||
|
* The type of the #NmtMacEntry. Can be either used for plain
|
||||||
|
* MAC addresses or for the extended format for cloned MAC addresses.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_ENTRY_TYPE,
|
||||||
|
g_param_spec_int ("entry-type", "", "",
|
||||||
|
NMT_MAC_ENTRY_TYPE_MAC, NMT_MAC_ENTRY_TYPE_CLONED, NMT_MAC_ENTRY_TYPE_MAC,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum { /*< skip >*/
|
||||||
|
NMT_MAC_ENTRY_TYPE_MAC,
|
||||||
|
NMT_MAC_ENTRY_TYPE_CLONED,
|
||||||
|
} NmtMacEntryType;
|
||||||
|
|
||||||
#define NMT_TYPE_MAC_ENTRY (nmt_mac_entry_get_type ())
|
#define NMT_TYPE_MAC_ENTRY (nmt_mac_entry_get_type ())
|
||||||
#define NMT_MAC_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_MAC_ENTRY, NmtMacEntry))
|
#define NMT_MAC_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_MAC_ENTRY, NmtMacEntry))
|
||||||
#define NMT_MAC_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_MAC_ENTRY, NmtMacEntryClass))
|
#define NMT_MAC_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_MAC_ENTRY, NmtMacEntryClass))
|
||||||
|
@ -45,7 +50,8 @@ typedef struct {
|
||||||
GType nmt_mac_entry_get_type (void);
|
GType nmt_mac_entry_get_type (void);
|
||||||
|
|
||||||
NmtNewtWidget *nmt_mac_entry_new (int width,
|
NmtNewtWidget *nmt_mac_entry_new (int width,
|
||||||
int mac_length);
|
int mac_length,
|
||||||
|
NmtMacEntryType type);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ nmt_page_ethernet_constructed (GObject *object)
|
||||||
section = nmt_editor_section_new (_("ETHERNET"), NULL, FALSE);
|
section = nmt_editor_section_new (_("ETHERNET"), NULL, FALSE);
|
||||||
grid = nmt_editor_section_get_body (section);
|
grid = nmt_editor_section_get_body (section);
|
||||||
|
|
||||||
widget = nmt_mac_entry_new (40, ETH_ALEN);
|
widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
|
||||||
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||||
widget, "mac-address",
|
widget, "mac-address",
|
||||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||||
|
|
|
@ -115,7 +115,7 @@ nmt_page_vlan_constructed (GObject *object)
|
||||||
|
|
||||||
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
|
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
|
||||||
|
|
||||||
widget = nmt_mac_entry_new (40, ETH_ALEN);
|
widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
|
||||||
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||||
widget, "mac-address",
|
widget, "mac-address",
|
||||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||||
|
|
|
@ -351,13 +351,13 @@ nmt_page_wifi_constructed (GObject *object)
|
||||||
|
|
||||||
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
|
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
|
||||||
|
|
||||||
widget = nmt_mac_entry_new (40, ETH_ALEN);
|
widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_MAC);
|
||||||
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_BSSID,
|
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_BSSID,
|
||||||
widget, "mac-address",
|
widget, "mac-address",
|
||||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||||
nmt_editor_grid_append (grid, _("BSSID"), widget, NULL);
|
nmt_editor_grid_append (grid, _("BSSID"), widget, NULL);
|
||||||
|
|
||||||
widget = nmt_mac_entry_new (40, ETH_ALEN);
|
widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
|
||||||
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||||
widget, "mac-address",
|
widget, "mac-address",
|
||||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||||
|
|
|
@ -847,6 +847,52 @@ _normalize_bond_mode (NMConnection *self, GHashTable *parameters)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_normalize_wireless_mac_address_randomization (NMConnection *self, GHashTable *parameters)
|
||||||
|
{
|
||||||
|
NMSettingWireless *s_wifi = nm_connection_get_setting_wireless (self);
|
||||||
|
const char *cloned_mac_address;
|
||||||
|
NMSettingMacRandomization mac_address_randomization;
|
||||||
|
|
||||||
|
if (!s_wifi)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
mac_address_randomization = nm_setting_wireless_get_mac_address_randomization (s_wifi);
|
||||||
|
if (!NM_IN_SET (mac_address_randomization,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_NEVER,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_ALWAYS))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cloned_mac_address = nm_setting_wireless_get_cloned_mac_address (s_wifi);
|
||||||
|
if (cloned_mac_address) {
|
||||||
|
if (nm_streq (cloned_mac_address, "random")) {
|
||||||
|
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS)
|
||||||
|
return FALSE;
|
||||||
|
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS;
|
||||||
|
} else if (nm_streq (cloned_mac_address, "permanent")) {
|
||||||
|
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER)
|
||||||
|
return FALSE;
|
||||||
|
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
|
||||||
|
} else {
|
||||||
|
if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
|
||||||
|
return FALSE;
|
||||||
|
mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
|
||||||
|
}
|
||||||
|
g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, mac_address_randomization, NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
|
||||||
|
g_object_set (s_wifi,
|
||||||
|
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||||
|
mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS
|
||||||
|
? "random" : "permanent",
|
||||||
|
NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_connection_verify:
|
* nm_connection_verify:
|
||||||
* @connection: the #NMConnection to verify
|
* @connection: the #NMConnection to verify
|
||||||
|
@ -1089,6 +1135,7 @@ nm_connection_normalize (NMConnection *connection,
|
||||||
was_modified |= _normalize_ip_config (connection, parameters);
|
was_modified |= _normalize_ip_config (connection, parameters);
|
||||||
was_modified |= _normalize_infiniband_mtu (connection, parameters);
|
was_modified |= _normalize_infiniband_mtu (connection, parameters);
|
||||||
was_modified |= _normalize_bond_mode (connection, parameters);
|
was_modified |= _normalize_bond_mode (connection, parameters);
|
||||||
|
was_modified |= _normalize_wireless_mac_address_randomization (connection, parameters);
|
||||||
|
|
||||||
/* Verify anew. */
|
/* Verify anew. */
|
||||||
success = _nm_connection_verify (connection, error);
|
success = _nm_connection_verify (connection, error);
|
||||||
|
|
|
@ -124,6 +124,8 @@ guint32 _nm_setting_get_setting_priority (NMSetting *setting);
|
||||||
|
|
||||||
gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value);
|
gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value);
|
||||||
|
|
||||||
|
guint _nm_utils_hwaddr_length (const char *asc);
|
||||||
|
|
||||||
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
||||||
|
|
||||||
GHashTable *_nm_utils_copy_strdict (GHashTable *strdict);
|
GHashTable *_nm_utils_copy_strdict (GHashTable *strdict);
|
||||||
|
@ -281,6 +283,16 @@ void _nm_setting_vlan_get_priorities (NMSettingVlan *setting,
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
|
||||||
|
struct ether_addr;
|
||||||
|
|
||||||
|
gboolean _nm_utils_generate_mac_address_mask_parse (const char *value,
|
||||||
|
struct ether_addr *out_mask,
|
||||||
|
struct ether_addr **out_ouis,
|
||||||
|
gsize *out_ouis_len,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NM_BOND_OPTION_TYPE_INT,
|
NM_BOND_OPTION_TYPE_INT,
|
||||||
NM_BOND_OPTION_TYPE_STRING,
|
NM_BOND_OPTION_TYPE_STRING,
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "nm-common-macros.h"
|
||||||
#include "nm-core-internal.h"
|
#include "nm-core-internal.h"
|
||||||
#include "nm-keyfile-utils.h"
|
#include "nm-keyfile-utils.h"
|
||||||
|
|
||||||
|
@ -581,19 +582,28 @@ ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize enforce_length)
|
mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize enforce_length, gboolean cloned_mac_addr)
|
||||||
{
|
{
|
||||||
const char *setting_name = nm_setting_get_name (setting);
|
const char *setting_name = nm_setting_get_name (setting);
|
||||||
char *tmp_string = NULL, *p, *mac_str;
|
gs_free char *tmp_string = NULL;
|
||||||
gint *tmp_list;
|
const char *p, *mac_str;
|
||||||
GByteArray *array = NULL;
|
gs_free guint8 *buf_arr = NULL;
|
||||||
|
guint buf_len;
|
||||||
gsize length;
|
gsize length;
|
||||||
|
|
||||||
p = tmp_string = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
|
tmp_string = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
|
||||||
|
|
||||||
|
if ( cloned_mac_addr
|
||||||
|
&& NM_CLONED_MAC_IS_SPECIAL (tmp_string)) {
|
||||||
|
mac_str = tmp_string;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp_string && tmp_string[0]) {
|
if (tmp_string && tmp_string[0]) {
|
||||||
/* Look for enough ':' characters to signify a MAC address */
|
/* Look for enough ':' characters to signify a MAC address */
|
||||||
guint i = 0;
|
guint i = 0;
|
||||||
|
|
||||||
|
p = tmp_string;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (*p == ':')
|
if (*p == ':')
|
||||||
i++;
|
i++;
|
||||||
|
@ -602,23 +612,24 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
|
||||||
|
|
||||||
if (enforce_length == 0 || enforce_length == i+1) {
|
if (enforce_length == 0 || enforce_length == i+1) {
|
||||||
/* If we found enough it's probably a string-format MAC address */
|
/* If we found enough it's probably a string-format MAC address */
|
||||||
array = g_byte_array_sized_new (i+1);
|
buf_len = i + 1;
|
||||||
g_byte_array_set_size (array, i+1);
|
buf_arr = g_new (guint8, buf_len);
|
||||||
if (!nm_utils_hwaddr_aton (tmp_string, array->data, array->len)) {
|
if (!nm_utils_hwaddr_aton (tmp_string, buf_arr, buf_len))
|
||||||
g_byte_array_unref (array);
|
g_clear_pointer (&buf_arr, g_free);
|
||||||
array = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_free (tmp_string);
|
g_clear_pointer (&tmp_string, g_free);
|
||||||
|
|
||||||
|
if (!buf_arr) {
|
||||||
|
gs_free int *tmp_list = NULL;
|
||||||
|
|
||||||
if (array == NULL) {
|
|
||||||
/* Old format; list of ints */
|
/* Old format; list of ints */
|
||||||
tmp_list = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL);
|
tmp_list = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL);
|
||||||
if (length > 0 && (enforce_length == 0 || enforce_length == length)) {
|
if (length > 0 && (enforce_length == 0 || enforce_length == length)) {
|
||||||
gsize i;
|
gsize i;
|
||||||
|
|
||||||
array = g_byte_array_sized_new (length);
|
buf_len = length;
|
||||||
|
buf_arr = g_new (guint8, buf_len);
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
int val = tmp_list[i];
|
int val = tmp_list[i];
|
||||||
const guint8 v = (guint8) (val & 0xFF);
|
const guint8 v = (guint8) (val & 0xFF);
|
||||||
|
@ -627,38 +638,42 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
|
||||||
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
|
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
|
||||||
_("ignoring invalid byte element '%d' (not between 0 and 255 inclusive)"),
|
_("ignoring invalid byte element '%d' (not between 0 and 255 inclusive)"),
|
||||||
val);
|
val);
|
||||||
g_byte_array_free (array, TRUE);
|
|
||||||
g_free (tmp_list);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_byte_array_append (array, &v, 1);
|
buf_arr[i] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_free (tmp_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!array) {
|
if (!buf_arr) {
|
||||||
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
|
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
|
||||||
_("ignoring invalid MAC address"));
|
_("ignoring invalid MAC address"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_str = nm_utils_hwaddr_ntoa (array->data, array->len);
|
tmp_string = nm_utils_hwaddr_ntoa (buf_arr, buf_len);
|
||||||
|
mac_str = tmp_string;
|
||||||
|
|
||||||
|
out:
|
||||||
g_object_set (setting, key, mac_str, NULL);
|
g_object_set (setting, key, mac_str, NULL);
|
||||||
g_free (mac_str);
|
|
||||||
g_byte_array_free (array, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mac_address_parser_ETHER (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
mac_address_parser_ETHER (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||||
{
|
{
|
||||||
mac_address_parser (info, setting, key, ETH_ALEN);
|
mac_address_parser (info, setting, key, ETH_ALEN, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mac_address_parser_ETHER_cloned (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||||
|
{
|
||||||
|
mac_address_parser (info, setting, key, ETH_ALEN, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mac_address_parser_INFINIBAND (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
mac_address_parser_INFINIBAND (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||||
{
|
{
|
||||||
mac_address_parser (info, setting, key, INFINIBAND_ALEN);
|
mac_address_parser (info, setting, key, INFINIBAND_ALEN, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1209,7 +1224,7 @@ static KeyParser key_parsers[] = {
|
||||||
{ NM_SETTING_WIRED_SETTING_NAME,
|
{ NM_SETTING_WIRED_SETTING_NAME,
|
||||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||||
TRUE,
|
TRUE,
|
||||||
mac_address_parser_ETHER },
|
mac_address_parser_ETHER_cloned },
|
||||||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||||
NM_SETTING_WIRELESS_MAC_ADDRESS,
|
NM_SETTING_WIRELESS_MAC_ADDRESS,
|
||||||
TRUE,
|
TRUE,
|
||||||
|
@ -1217,7 +1232,7 @@ static KeyParser key_parsers[] = {
|
||||||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||||
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||||
TRUE,
|
TRUE,
|
||||||
mac_address_parser_ETHER },
|
mac_address_parser_ETHER_cloned },
|
||||||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||||
NM_SETTING_WIRELESS_BSSID,
|
NM_SETTING_WIRELESS_BSSID,
|
||||||
TRUE,
|
TRUE,
|
||||||
|
|
|
@ -63,6 +63,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *id;
|
char *id;
|
||||||
char *uuid;
|
char *uuid;
|
||||||
|
char *stable_id;
|
||||||
char *interface_name;
|
char *interface_name;
|
||||||
char *type;
|
char *type;
|
||||||
char *master;
|
char *master;
|
||||||
|
@ -99,6 +100,7 @@ enum {
|
||||||
PROP_GATEWAY_PING_TIMEOUT,
|
PROP_GATEWAY_PING_TIMEOUT,
|
||||||
PROP_METERED,
|
PROP_METERED,
|
||||||
PROP_LLDP,
|
PROP_LLDP,
|
||||||
|
PROP_STABLE_ID,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
@ -230,6 +232,24 @@ nm_setting_connection_get_uuid (NMSettingConnection *setting)
|
||||||
return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->uuid;
|
return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_setting_connection_get_stable_id:
|
||||||
|
* @setting: the #NMSettingConnection
|
||||||
|
*
|
||||||
|
* Returns the #NMSettingConnection:stable_id property of the connection.
|
||||||
|
*
|
||||||
|
* Returns: the stable-id for the connection
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
**/
|
||||||
|
const char *
|
||||||
|
nm_setting_connection_get_stable_id (NMSettingConnection *setting)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
|
||||||
|
|
||||||
|
return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->stable_id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_setting_connection_get_interface_name:
|
* nm_setting_connection_get_interface_name:
|
||||||
* @setting: the #NMSettingConnection
|
* @setting: the #NMSettingConnection
|
||||||
|
@ -1128,6 +1148,7 @@ finalize (GObject *object)
|
||||||
|
|
||||||
g_free (priv->id);
|
g_free (priv->id);
|
||||||
g_free (priv->uuid);
|
g_free (priv->uuid);
|
||||||
|
g_free (priv->stable_id);
|
||||||
g_free (priv->interface_name);
|
g_free (priv->interface_name);
|
||||||
g_free (priv->type);
|
g_free (priv->type);
|
||||||
g_free (priv->zone);
|
g_free (priv->zone);
|
||||||
|
@ -1174,6 +1195,10 @@ set_property (GObject *object, guint prop_id,
|
||||||
g_free (priv->uuid);
|
g_free (priv->uuid);
|
||||||
priv->uuid = g_value_dup_string (value);
|
priv->uuid = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_STABLE_ID:
|
||||||
|
g_free (priv->stable_id);
|
||||||
|
priv->stable_id = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
case PROP_INTERFACE_NAME:
|
case PROP_INTERFACE_NAME:
|
||||||
g_free (priv->interface_name);
|
g_free (priv->interface_name);
|
||||||
priv->interface_name = g_value_dup_string (value);
|
priv->interface_name = g_value_dup_string (value);
|
||||||
|
@ -1260,6 +1285,9 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_UUID:
|
case PROP_UUID:
|
||||||
g_value_set_string (value, nm_setting_connection_get_uuid (setting));
|
g_value_set_string (value, nm_setting_connection_get_uuid (setting));
|
||||||
break;
|
break;
|
||||||
|
case PROP_STABLE_ID:
|
||||||
|
g_value_set_string (value, nm_setting_connection_get_stable_id (setting));
|
||||||
|
break;
|
||||||
case PROP_INTERFACE_NAME:
|
case PROP_INTERFACE_NAME:
|
||||||
g_value_set_string (value, nm_setting_connection_get_interface_name (setting));
|
g_value_set_string (value, nm_setting_connection_get_interface_name (setting));
|
||||||
break;
|
break;
|
||||||
|
@ -1368,7 +1396,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
|
||||||
* property: uuid
|
* property: uuid
|
||||||
* variable: UUID(+)
|
* variable: UUID(+)
|
||||||
* description: UUID for the connection profile. When missing, NetworkManager
|
* description: UUID for the connection profile. When missing, NetworkManager
|
||||||
* creates the UUID itself (by hashing the file).
|
* creates the UUID itself (by hashing the filename).
|
||||||
* ---end---
|
* ---end---
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
|
@ -1379,6 +1407,33 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
|
||||||
NM_SETTING_PARAM_FUZZY_IGNORE |
|
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMSettingConnection:stable-id:
|
||||||
|
*
|
||||||
|
* This token to generate stable IDs for the connection. If unset,
|
||||||
|
* the UUID will be used instead.
|
||||||
|
*
|
||||||
|
* The stable-id is used instead of the connection UUID for generating
|
||||||
|
* IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy.
|
||||||
|
* It is also used to seed the generated cloned MAC address for
|
||||||
|
* ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
**/
|
||||||
|
/* ---ifcfg-rh---
|
||||||
|
* property: stable-id
|
||||||
|
* variable: STABLE_ID(+)
|
||||||
|
* description: Token to generate stable IDs.
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_STABLE_ID,
|
||||||
|
g_param_spec_string (NM_SETTING_CONNECTION_STABLE_ID, "", "",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMSettingConnection:interface-name:
|
* NMSettingConnection:interface-name:
|
||||||
*
|
*
|
||||||
|
|
|
@ -46,6 +46,7 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
#define NM_SETTING_CONNECTION_ID "id"
|
#define NM_SETTING_CONNECTION_ID "id"
|
||||||
#define NM_SETTING_CONNECTION_UUID "uuid"
|
#define NM_SETTING_CONNECTION_UUID "uuid"
|
||||||
|
#define NM_SETTING_CONNECTION_STABLE_ID "stable-id"
|
||||||
#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name"
|
#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name"
|
||||||
#define NM_SETTING_CONNECTION_TYPE "type"
|
#define NM_SETTING_CONNECTION_TYPE "type"
|
||||||
#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect"
|
#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect"
|
||||||
|
@ -116,6 +117,8 @@ GType nm_setting_connection_get_type (void);
|
||||||
NMSetting * nm_setting_connection_new (void);
|
NMSetting * nm_setting_connection_new (void);
|
||||||
const char *nm_setting_connection_get_id (NMSettingConnection *setting);
|
const char *nm_setting_connection_get_id (NMSettingConnection *setting);
|
||||||
const char *nm_setting_connection_get_uuid (NMSettingConnection *setting);
|
const char *nm_setting_connection_get_uuid (NMSettingConnection *setting);
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
const char *nm_setting_connection_get_stable_id (NMSettingConnection *setting);
|
||||||
const char *nm_setting_connection_get_interface_name (NMSettingConnection *setting);
|
const char *nm_setting_connection_get_interface_name (NMSettingConnection *setting);
|
||||||
const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting);
|
const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting);
|
||||||
gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting);
|
gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting);
|
||||||
|
|
|
@ -299,6 +299,52 @@ nm_ip_address_unref (NMIPAddress *address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _nm_ip_address_equal:
|
||||||
|
* @address: the #NMIPAddress
|
||||||
|
* @other: the #NMIPAddress to compare @address to.
|
||||||
|
* @consider_attributes: whether to check for equality of attributes too.
|
||||||
|
*
|
||||||
|
* Determines if two #NMIPAddress objects are equal.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
|
||||||
|
**/
|
||||||
|
static gboolean
|
||||||
|
_nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other, gboolean consider_attributes)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (address != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (address->refcount > 0, FALSE);
|
||||||
|
|
||||||
|
g_return_val_if_fail (other != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (other->refcount > 0, FALSE);
|
||||||
|
|
||||||
|
if ( address->family != other->family
|
||||||
|
|| address->prefix != other->prefix
|
||||||
|
|| strcmp (address->address, other->address) != 0)
|
||||||
|
return FALSE;
|
||||||
|
if (consider_attributes) {
|
||||||
|
GHashTableIter iter;
|
||||||
|
const char *key;
|
||||||
|
GVariant *value, *value2;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
n = address->attributes ? g_hash_table_size (address->attributes) : 0;
|
||||||
|
if (n != (other->attributes ? g_hash_table_size (other->attributes) : 0))
|
||||||
|
return FALSE;
|
||||||
|
if (n) {
|
||||||
|
g_hash_table_iter_init (&iter, address->attributes);
|
||||||
|
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
|
||||||
|
value2 = g_hash_table_lookup (other->attributes, key);
|
||||||
|
if (!value2)
|
||||||
|
return FALSE;
|
||||||
|
if (!g_variant_equal (value, value2))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_ip_address_equal:
|
* nm_ip_address_equal:
|
||||||
* @address: the #NMIPAddress
|
* @address: the #NMIPAddress
|
||||||
|
@ -312,17 +358,7 @@ nm_ip_address_unref (NMIPAddress *address)
|
||||||
gboolean
|
gboolean
|
||||||
nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
|
nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (address != NULL, FALSE);
|
return _nm_ip_address_equal (address, other, FALSE);
|
||||||
g_return_val_if_fail (address->refcount > 0, FALSE);
|
|
||||||
|
|
||||||
g_return_val_if_fail (other != NULL, FALSE);
|
|
||||||
g_return_val_if_fail (other->refcount > 0, FALSE);
|
|
||||||
|
|
||||||
if ( address->family != other->family
|
|
||||||
|| address->prefix != other->prefix
|
|
||||||
|| strcmp (address->address, other->address) != 0)
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -717,17 +753,18 @@ nm_ip_route_unref (NMIPRoute *route)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_ip_route_equal:
|
* _nm_ip_route_equal:
|
||||||
* @route: the #NMIPRoute
|
* @route: the #NMIPRoute
|
||||||
* @other: the #NMIPRoute to compare @route to.
|
* @other: the #NMIPRoute to compare @route to.
|
||||||
|
* @consider_attributes: whether to compare attributes too
|
||||||
*
|
*
|
||||||
* Determines if two #NMIPRoute objects contain the same destination, prefix,
|
* Determines if two #NMIPRoute objects contain the same destination, prefix,
|
||||||
* next hop, and metric. (Attributes are not compared.)
|
* next hop, and metric.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
|
* Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
|
||||||
**/
|
**/
|
||||||
gboolean
|
static gboolean
|
||||||
nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
|
_nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other, gboolean consider_attributes)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (route != NULL, FALSE);
|
g_return_val_if_fail (route != NULL, FALSE);
|
||||||
g_return_val_if_fail (route->refcount > 0, FALSE);
|
g_return_val_if_fail (route->refcount > 0, FALSE);
|
||||||
|
@ -740,9 +777,45 @@ nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
|
||||||
|| strcmp (route->dest, other->dest) != 0
|
|| strcmp (route->dest, other->dest) != 0
|
||||||
|| g_strcmp0 (route->next_hop, other->next_hop) != 0)
|
|| g_strcmp0 (route->next_hop, other->next_hop) != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (consider_attributes) {
|
||||||
|
GHashTableIter iter;
|
||||||
|
const char *key;
|
||||||
|
GVariant *value, *value2;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
n = route->attributes ? g_hash_table_size (route->attributes) : 0;
|
||||||
|
if (n != (other->attributes ? g_hash_table_size (other->attributes) : 0))
|
||||||
|
return FALSE;
|
||||||
|
if (n) {
|
||||||
|
g_hash_table_iter_init (&iter, route->attributes);
|
||||||
|
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
|
||||||
|
value2 = g_hash_table_lookup (other->attributes, key);
|
||||||
|
if (!value2)
|
||||||
|
return FALSE;
|
||||||
|
if (!g_variant_equal (value, value2))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip_route_equal:
|
||||||
|
* @route: the #NMIPRoute
|
||||||
|
* @other: the #NMIPRoute to compare @route to.
|
||||||
|
*
|
||||||
|
* Determines if two #NMIPRoute objects contain the same destination, prefix,
|
||||||
|
* next hop, and metric. (Attributes are not compared.)
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
|
||||||
|
{
|
||||||
|
return _nm_ip_route_equal (route, other, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_ip_route_dup:
|
* nm_ip_route_dup:
|
||||||
* @route: the #NMIPRoute
|
* @route: the #NMIPRoute
|
||||||
|
@ -2306,6 +2379,48 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
compare_property (NMSetting *setting,
|
||||||
|
NMSetting *other,
|
||||||
|
const GParamSpec *prop_spec,
|
||||||
|
NMSettingCompareFlags flags)
|
||||||
|
{
|
||||||
|
NMSettingIPConfigPrivate *a_priv, *b_priv;
|
||||||
|
NMSettingClass *parent_class;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ADDRESSES)) {
|
||||||
|
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||||
|
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||||
|
|
||||||
|
if (a_priv->addresses->len != b_priv->addresses->len)
|
||||||
|
return FALSE;
|
||||||
|
for (i = 0; i < a_priv->addresses->len; i++) {
|
||||||
|
if (!_nm_ip_address_equal (a_priv->addresses->pdata[i], b_priv->addresses->pdata[i], TRUE))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ROUTES)) {
|
||||||
|
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
|
||||||
|
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
|
||||||
|
|
||||||
|
if (a_priv->routes->len != b_priv->routes->len)
|
||||||
|
return FALSE;
|
||||||
|
for (i = 0; i < a_priv->routes->len; i++) {
|
||||||
|
if (!_nm_ip_route_equal (a_priv->routes->pdata[i], b_priv->routes->pdata[i], TRUE))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise chain up to parent to handle generic compare */
|
||||||
|
parent_class = NM_SETTING_CLASS (nm_setting_ip_config_parent_class);
|
||||||
|
return parent_class->compare_property (setting, other, prop_spec, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_setting_ip_config_init (NMSettingIPConfig *setting)
|
nm_setting_ip_config_init (NMSettingIPConfig *setting)
|
||||||
|
@ -2536,6 +2651,7 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
parent_class->verify = verify;
|
parent_class->verify = verify;
|
||||||
|
parent_class->compare_property = compare_property;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
|
#include "nm-common-macros.h"
|
||||||
#include "nm-utils-private.h"
|
#include "nm-utils-private.h"
|
||||||
#include "nm-setting-private.h"
|
#include "nm-setting-private.h"
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ typedef struct {
|
||||||
gboolean auto_negotiate;
|
gboolean auto_negotiate;
|
||||||
char *device_mac_address;
|
char *device_mac_address;
|
||||||
char *cloned_mac_address;
|
char *cloned_mac_address;
|
||||||
|
char *generate_mac_address_mask;
|
||||||
GArray *mac_address_blacklist;
|
GArray *mac_address_blacklist;
|
||||||
guint32 mtu;
|
guint32 mtu;
|
||||||
char **s390_subchannels;
|
char **s390_subchannels;
|
||||||
|
@ -69,6 +71,7 @@ enum {
|
||||||
PROP_AUTO_NEGOTIATE,
|
PROP_AUTO_NEGOTIATE,
|
||||||
PROP_MAC_ADDRESS,
|
PROP_MAC_ADDRESS,
|
||||||
PROP_CLONED_MAC_ADDRESS,
|
PROP_CLONED_MAC_ADDRESS,
|
||||||
|
PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||||
PROP_MAC_ADDRESS_BLACKLIST,
|
PROP_MAC_ADDRESS_BLACKLIST,
|
||||||
PROP_MTU,
|
PROP_MTU,
|
||||||
PROP_S390_SUBCHANNELS,
|
PROP_S390_SUBCHANNELS,
|
||||||
|
@ -187,6 +190,22 @@ nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting)
|
||||||
return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address;
|
return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_setting_wired_get_generate_mac_address_mask:
|
||||||
|
* @setting: the #NMSettingWired
|
||||||
|
*
|
||||||
|
* Returns: the #NMSettingWired:generate-mac-address-mask property of the setting
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
**/
|
||||||
|
const char *
|
||||||
|
nm_setting_wired_get_generate_mac_address_mask (NMSettingWired *setting)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
|
||||||
|
|
||||||
|
return NM_SETTING_WIRED_GET_PRIVATE (setting)->generate_mac_address_mask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_setting_wired_get_mac_address_blacklist:
|
* nm_setting_wired_get_mac_address_blacklist:
|
||||||
* @setting: the #NMSettingWired
|
* @setting: the #NMSettingWired
|
||||||
|
@ -611,6 +630,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
const char *key, *value;
|
const char *key, *value;
|
||||||
int i;
|
int i;
|
||||||
|
GError *local = NULL;
|
||||||
|
|
||||||
if (priv->port && !g_strv_contains (valid_ports, priv->port)) {
|
if (priv->port && !g_strv_contains (valid_ports, priv->port)) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
|
@ -692,7 +712,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->cloned_mac_address && !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) {
|
if ( priv->cloned_mac_address
|
||||||
|
&& !NM_CLONED_MAC_IS_SPECIAL (priv->cloned_mac_address)
|
||||||
|
&& !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
NM_CONNECTION_ERROR,
|
NM_CONNECTION_ERROR,
|
||||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
@ -701,6 +723,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* generate-mac-address-mask only makes sense with cloned-mac-address "random" or
|
||||||
|
* "stable". Still, let's not be so strict about that and accept the value
|
||||||
|
* even if it is unused. */
|
||||||
|
if (!_nm_utils_generate_mac_address_mask_parse (priv->generate_mac_address_mask,
|
||||||
|
NULL, NULL, NULL, &local)) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
local->message);
|
||||||
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK);
|
||||||
|
g_error_free (local);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ( NM_FLAGS_ANY (priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS)
|
if ( NM_FLAGS_ANY (priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS)
|
||||||
&& !nm_utils_is_power_of_two (priv->wol)) {
|
&& !nm_utils_is_power_of_two (priv->wol)) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
|
@ -732,6 +768,25 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
compare_property (NMSetting *setting,
|
||||||
|
NMSetting *other,
|
||||||
|
const GParamSpec *prop_spec,
|
||||||
|
NMSettingCompareFlags flags)
|
||||||
|
{
|
||||||
|
NMSettingClass *parent_class;
|
||||||
|
|
||||||
|
if (nm_streq (prop_spec->name, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) {
|
||||||
|
return nm_streq0 (NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address,
|
||||||
|
NM_SETTING_WIRED_GET_PRIVATE (other)->cloned_mac_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class = NM_SETTING_CLASS (nm_setting_wired_parent_class);
|
||||||
|
return parent_class->compare_property (setting, other, prop_spec, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_blacklist_item (char **item_p)
|
clear_blacklist_item (char **item_p)
|
||||||
{
|
{
|
||||||
|
@ -763,6 +818,7 @@ finalize (GObject *object)
|
||||||
|
|
||||||
g_free (priv->device_mac_address);
|
g_free (priv->device_mac_address);
|
||||||
g_free (priv->cloned_mac_address);
|
g_free (priv->cloned_mac_address);
|
||||||
|
g_free (priv->generate_mac_address_mask);
|
||||||
g_array_unref (priv->mac_address_blacklist);
|
g_array_unref (priv->mac_address_blacklist);
|
||||||
|
|
||||||
if (priv->s390_subchannels)
|
if (priv->s390_subchannels)
|
||||||
|
@ -807,6 +863,10 @@ set_property (GObject *object, guint prop_id,
|
||||||
priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value),
|
priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value),
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
break;
|
break;
|
||||||
|
case PROP_GENERATE_MAC_ADDRESS_MASK:
|
||||||
|
g_free (priv->generate_mac_address_mask);
|
||||||
|
priv->generate_mac_address_mask = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
case PROP_MAC_ADDRESS_BLACKLIST:
|
case PROP_MAC_ADDRESS_BLACKLIST:
|
||||||
blacklist = g_value_get_boxed (value);
|
blacklist = g_value_get_boxed (value);
|
||||||
g_array_set_size (priv->mac_address_blacklist, 0);
|
g_array_set_size (priv->mac_address_blacklist, 0);
|
||||||
|
@ -872,6 +932,9 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_CLONED_MAC_ADDRESS:
|
case PROP_CLONED_MAC_ADDRESS:
|
||||||
g_value_set_string (value, nm_setting_wired_get_cloned_mac_address (setting));
|
g_value_set_string (value, nm_setting_wired_get_cloned_mac_address (setting));
|
||||||
break;
|
break;
|
||||||
|
case PROP_GENERATE_MAC_ADDRESS_MASK:
|
||||||
|
g_value_set_string (value, nm_setting_wired_get_generate_mac_address_mask (setting));
|
||||||
|
break;
|
||||||
case PROP_MAC_ADDRESS_BLACKLIST:
|
case PROP_MAC_ADDRESS_BLACKLIST:
|
||||||
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
||||||
break;
|
break;
|
||||||
|
@ -900,18 +963,19 @@ get_property (GObject *object, guint prop_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
nm_setting_wired_class_init (NMSettingWiredClass *setting_wired_class)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
|
GObjectClass *object_class = G_OBJECT_CLASS (setting_wired_class);
|
||||||
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
|
NMSettingClass *setting_class = NM_SETTING_CLASS (setting_wired_class);
|
||||||
|
|
||||||
g_type_class_add_private (setting_class, sizeof (NMSettingWiredPrivate));
|
g_type_class_add_private (setting_wired_class, sizeof (NMSettingWiredPrivate));
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
parent_class->verify = verify;
|
setting_class->verify = verify;
|
||||||
|
setting_class->compare_property = compare_property;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
/**
|
/**
|
||||||
|
@ -1023,7 +1087,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
NM_SETTING_PARAM_INFERRABLE |
|
NM_SETTING_PARAM_INFERRABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_MAC_ADDRESS,
|
_nm_setting_class_transform_property (setting_class, NM_SETTING_WIRED_MAC_ADDRESS,
|
||||||
G_VARIANT_TYPE_BYTESTRING,
|
G_VARIANT_TYPE_BYTESTRING,
|
||||||
_nm_utils_hwaddr_to_dbus,
|
_nm_utils_hwaddr_to_dbus,
|
||||||
_nm_utils_hwaddr_from_dbus);
|
_nm_utils_hwaddr_from_dbus);
|
||||||
|
@ -1033,6 +1097,20 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
||||||
*
|
*
|
||||||
* If specified, request that the device use this MAC address instead of its
|
* If specified, request that the device use this MAC address instead of its
|
||||||
* permanent MAC address. This is known as MAC cloning or spoofing.
|
* permanent MAC address. This is known as MAC cloning or spoofing.
|
||||||
|
*
|
||||||
|
* Beside explicitly specifing a MAC address, the special values "preserve", "permanent",
|
||||||
|
* "random" and "stable" are supported.
|
||||||
|
* "preserve" means not to touch the MAC address on activation.
|
||||||
|
* "permanent" means to use the permanent hardware address of the device.
|
||||||
|
* "random" creates a random MAC address on each connect.
|
||||||
|
* "stable" creates a hashed MAC address based on connection.stable-id (or
|
||||||
|
* the connection's UUID) and a machine dependent key.
|
||||||
|
*
|
||||||
|
* If unspecified, the value can be overwritten via global defaults, see manual
|
||||||
|
* of NetworkManager.conf. If still unspecified, it defaults to "permanent".
|
||||||
|
*
|
||||||
|
* On D-Bus, this field is expressed as "assigned-mac-address" or the deprecated
|
||||||
|
* "cloned-mac-address".
|
||||||
**/
|
**/
|
||||||
/* ---keyfile---
|
/* ---keyfile---
|
||||||
* property: cloned-mac-address
|
* property: cloned-mac-address
|
||||||
|
@ -1047,6 +1125,12 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
||||||
* description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons
|
* description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons
|
||||||
* notation (e.g. 00:22:68:14:5A:99).
|
* notation (e.g. 00:22:68:14:5A:99).
|
||||||
* ---end---
|
* ---end---
|
||||||
|
* ---dbus---
|
||||||
|
* property: cloned-mac-address
|
||||||
|
* format: byte array
|
||||||
|
* description: This D-Bus field is deprecated in favor of "assigned-mac-address"
|
||||||
|
* which is more flexible and allows specifying special variants like "random".
|
||||||
|
* ---end---
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_CLONED_MAC_ADDRESS,
|
(object_class, PROP_CLONED_MAC_ADDRESS,
|
||||||
|
@ -1055,10 +1139,75 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
NM_SETTING_PARAM_INFERRABLE |
|
NM_SETTING_PARAM_INFERRABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
_nm_setting_class_override_property (setting_class,
|
||||||
G_VARIANT_TYPE_BYTESTRING,
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||||
_nm_utils_hwaddr_to_dbus,
|
G_VARIANT_TYPE_BYTESTRING,
|
||||||
_nm_utils_hwaddr_from_dbus);
|
_nm_utils_hwaddr_cloned_get,
|
||||||
|
_nm_utils_hwaddr_cloned_set,
|
||||||
|
_nm_utils_hwaddr_cloned_not_set);
|
||||||
|
|
||||||
|
/* ---dbus---
|
||||||
|
* property: assigned-mac-address
|
||||||
|
* format: string
|
||||||
|
* description: The new field for the cloned MAC address. It can be either
|
||||||
|
* a hardware address in ASCII representation, or one of the special values
|
||||||
|
* "preserve", "permanent", "random", "random" or "stable".
|
||||||
|
* This field replaces the deprecated "cloned-mac-address" on D-Bus, which
|
||||||
|
* can only contain explict hardware addresses.
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
|
_nm_setting_class_add_dbus_only_property (setting_class,
|
||||||
|
"assigned-mac-address",
|
||||||
|
G_VARIANT_TYPE_STRING,
|
||||||
|
_nm_utils_hwaddr_cloned_data_synth,
|
||||||
|
_nm_utils_hwaddr_cloned_data_set);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMSettingWired:generate-mac-address-mask:
|
||||||
|
*
|
||||||
|
* With #NMSettingWired:cloned-mac-address setting "random" or "stable",
|
||||||
|
* by default all bits of the MAC address are scrambled and a locally-administered,
|
||||||
|
* unicast MAC address is created. This property allows to specify that certain bits
|
||||||
|
* are fixed. Note that the least significant bit of the first MAC address will
|
||||||
|
* always be unset to create a unicast MAC address.
|
||||||
|
*
|
||||||
|
* If the property is %NULL, it is eligible to be overwritten by a default
|
||||||
|
* connection setting. If the value is still %NULL or an empty string, the
|
||||||
|
* default is to create a locally-administered, unicast MAC address.
|
||||||
|
*
|
||||||
|
* If the value contains one MAC address, this address is used as mask. The set
|
||||||
|
* bits of the mask are to be filled with the current MAC address of the device,
|
||||||
|
* while the unset bits are subject to randomization.
|
||||||
|
* Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address
|
||||||
|
* and only randomize the lower 3 bytes using the "random" or "stable" algorithm.
|
||||||
|
*
|
||||||
|
* If the value contains one additional MAC address after the mask,
|
||||||
|
* this address is used instead of the current MAC address to fill the bits
|
||||||
|
* that shall not be randomized. For example, a value of
|
||||||
|
* "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address
|
||||||
|
* to 68:F7:28, while the lower bits are randomized. A value of
|
||||||
|
* "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled
|
||||||
|
* globally-administered, burned-in MAC address.
|
||||||
|
*
|
||||||
|
* If the value contains more then one additional MAC addresses, one of
|
||||||
|
* them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00"
|
||||||
|
* will create a fully scrambled MAC address, randomly locally or globally
|
||||||
|
* administered.
|
||||||
|
**/
|
||||||
|
/* ---ifcfg-rh---
|
||||||
|
* property: generate-mac-address-mask
|
||||||
|
* variable: GENERATE_MAC_ADDRESS_MASK
|
||||||
|
* description: the MAC address mask for generating randomized and stable
|
||||||
|
* cloned-mac-address.
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||||
|
g_param_spec_string (NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, "", "",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMSettingWired:mac-address-blacklist:
|
* NMSettingWired:mac-address-blacklist:
|
||||||
|
@ -1183,7 +1332,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
NM_SETTING_PARAM_INFERRABLE |
|
NM_SETTING_PARAM_INFERRABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_S390_OPTIONS,
|
_nm_setting_class_transform_property (setting_class, NM_SETTING_WIRED_S390_OPTIONS,
|
||||||
G_VARIANT_TYPE ("a{ss}"),
|
G_VARIANT_TYPE ("a{ss}"),
|
||||||
_nm_utils_strdict_to_dbus,
|
_nm_utils_strdict_to_dbus,
|
||||||
_nm_utils_strdict_from_dbus);
|
_nm_utils_strdict_from_dbus);
|
||||||
|
|
|
@ -85,6 +85,7 @@ typedef enum { /*< flags >*/
|
||||||
#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate"
|
#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate"
|
||||||
#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address"
|
#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address"
|
||||||
#define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address"
|
#define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address"
|
||||||
|
#define NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK "generate-mac-address-mask"
|
||||||
#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
|
#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
|
||||||
#define NM_SETTING_WIRED_MTU "mtu"
|
#define NM_SETTING_WIRED_MTU "mtu"
|
||||||
#define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels"
|
#define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels"
|
||||||
|
@ -117,6 +118,9 @@ gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting
|
||||||
const char * nm_setting_wired_get_mac_address (NMSettingWired *setting);
|
const char * nm_setting_wired_get_mac_address (NMSettingWired *setting);
|
||||||
const char * nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting);
|
const char * nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
const char * nm_setting_wired_get_generate_mac_address_mask (NMSettingWired *setting);
|
||||||
|
|
||||||
const char * const *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting);
|
const char * const *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting);
|
||||||
guint32 nm_setting_wired_get_num_mac_blacklist_items (NMSettingWired *setting);
|
guint32 nm_setting_wired_get_num_mac_blacklist_items (NMSettingWired *setting);
|
||||||
const char * nm_setting_wired_get_mac_blacklist_item (NMSettingWired *setting,
|
const char * nm_setting_wired_get_mac_blacklist_item (NMSettingWired *setting,
|
||||||
|
|
|
@ -22,11 +22,13 @@
|
||||||
|
|
||||||
#include "nm-default.h"
|
#include "nm-default.h"
|
||||||
|
|
||||||
|
#include "nm-setting-wireless.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
#include "nm-setting-wireless.h"
|
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
|
#include "nm-common-macros.h"
|
||||||
#include "nm-utils-private.h"
|
#include "nm-utils-private.h"
|
||||||
#include "nm-setting-private.h"
|
#include "nm-setting-private.h"
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ typedef struct {
|
||||||
guint32 tx_power;
|
guint32 tx_power;
|
||||||
char *device_mac_address;
|
char *device_mac_address;
|
||||||
char *cloned_mac_address;
|
char *cloned_mac_address;
|
||||||
|
char *generate_mac_address_mask;
|
||||||
GArray *mac_address_blacklist;
|
GArray *mac_address_blacklist;
|
||||||
guint32 mtu;
|
guint32 mtu;
|
||||||
GSList *seen_bssids;
|
GSList *seen_bssids;
|
||||||
|
@ -73,6 +76,7 @@ enum {
|
||||||
PROP_TX_POWER,
|
PROP_TX_POWER,
|
||||||
PROP_MAC_ADDRESS,
|
PROP_MAC_ADDRESS,
|
||||||
PROP_CLONED_MAC_ADDRESS,
|
PROP_CLONED_MAC_ADDRESS,
|
||||||
|
PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||||
PROP_MAC_ADDRESS_BLACKLIST,
|
PROP_MAC_ADDRESS_BLACKLIST,
|
||||||
PROP_MTU,
|
PROP_MTU,
|
||||||
PROP_SEEN_BSSIDS,
|
PROP_SEEN_BSSIDS,
|
||||||
|
@ -419,6 +423,22 @@ nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
|
||||||
return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
|
return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_setting_wireless_get_generate_mac_address_mask:
|
||||||
|
* @setting: the #NMSettingWireless
|
||||||
|
*
|
||||||
|
* Returns: the #NMSettingWireless:generate-mac-address-mask property of the setting
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
**/
|
||||||
|
const char *
|
||||||
|
nm_setting_wireless_get_generate_mac_address_mask (NMSettingWireless *setting)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
|
||||||
|
|
||||||
|
return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->generate_mac_address_mask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_setting_wireless_get_mac_address_blacklist:
|
* nm_setting_wireless_get_mac_address_blacklist:
|
||||||
* @setting: the #NMSettingWireless
|
* @setting: the #NMSettingWireless
|
||||||
|
@ -721,6 +741,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
int i;
|
int i;
|
||||||
gsize length;
|
gsize length;
|
||||||
|
GError *local = NULL;
|
||||||
|
|
||||||
if (!priv->ssid) {
|
if (!priv->ssid) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
|
@ -801,7 +822,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->cloned_mac_address && !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) {
|
if ( priv->cloned_mac_address
|
||||||
|
&& !NM_CLONED_MAC_IS_SPECIAL (priv->cloned_mac_address)
|
||||||
|
&& !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
NM_CONNECTION_ERROR,
|
NM_CONNECTION_ERROR,
|
||||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
@ -810,6 +833,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* generate-mac-address-mask only makes sense with cloned-mac-address "random" or
|
||||||
|
* "stable". Still, let's not be so strict about that and accept the value
|
||||||
|
* even if it is unused. */
|
||||||
|
if (!_nm_utils_generate_mac_address_mask_parse (priv->generate_mac_address_mask,
|
||||||
|
NULL, NULL, NULL, &local)) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
local->message);
|
||||||
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK);
|
||||||
|
g_error_free (local);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < priv->mac_address_blacklist->len; i++) {
|
for (i = 0; i < priv->mac_address_blacklist->len; i++) {
|
||||||
const char *mac = g_array_index (priv->mac_address_blacklist, const char *, i);
|
const char *mac = g_array_index (priv->mac_address_blacklist, const char *, i);
|
||||||
|
|
||||||
|
@ -836,9 +873,61 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!NM_IN_SET (priv->mac_address_randomization,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_NEVER,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) {
|
||||||
|
g_set_error (error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
_("invalid value"));
|
||||||
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */
|
||||||
|
|
||||||
|
if (priv->cloned_mac_address) {
|
||||||
|
if ( priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS
|
||||||
|
&& nm_streq (priv->cloned_mac_address, "random"))
|
||||||
|
goto mac_addr_rand_ok;
|
||||||
|
if ( priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER
|
||||||
|
&& nm_streq (priv->cloned_mac_address, "permanent"))
|
||||||
|
goto mac_addr_rand_ok;
|
||||||
|
if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
|
||||||
|
goto mac_addr_rand_ok;
|
||||||
|
} else if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT)
|
||||||
|
goto mac_addr_rand_ok;
|
||||||
|
g_set_error (error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
_("conflicting value of mac-address-randomization and cloned-mac-address"));
|
||||||
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS);
|
||||||
|
return NM_SETTING_VERIFY_NORMALIZABLE;
|
||||||
|
mac_addr_rand_ok:
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
compare_property (NMSetting *setting,
|
||||||
|
NMSetting *other,
|
||||||
|
const GParamSpec *prop_spec,
|
||||||
|
NMSettingCompareFlags flags)
|
||||||
|
{
|
||||||
|
NMSettingClass *parent_class;
|
||||||
|
|
||||||
|
if (nm_streq (prop_spec->name, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS)) {
|
||||||
|
return nm_streq0 (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address,
|
||||||
|
NM_SETTING_WIRELESS_GET_PRIVATE (other)->cloned_mac_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class = NM_SETTING_CLASS (nm_setting_wireless_parent_class);
|
||||||
|
return parent_class->compare_property (setting, other, prop_spec, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static GVariant *
|
static GVariant *
|
||||||
nm_setting_wireless_get_security (NMSetting *setting,
|
nm_setting_wireless_get_security (NMSetting *setting,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
|
@ -879,6 +968,7 @@ finalize (GObject *object)
|
||||||
g_free (priv->bssid);
|
g_free (priv->bssid);
|
||||||
g_free (priv->device_mac_address);
|
g_free (priv->device_mac_address);
|
||||||
g_free (priv->cloned_mac_address);
|
g_free (priv->cloned_mac_address);
|
||||||
|
g_free (priv->generate_mac_address_mask);
|
||||||
g_array_unref (priv->mac_address_blacklist);
|
g_array_unref (priv->mac_address_blacklist);
|
||||||
g_slist_free_full (priv->seen_bssids, g_free);
|
g_slist_free_full (priv->seen_bssids, g_free);
|
||||||
|
|
||||||
|
@ -931,6 +1021,10 @@ set_property (GObject *object, guint prop_id,
|
||||||
priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value),
|
priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value),
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
break;
|
break;
|
||||||
|
case PROP_GENERATE_MAC_ADDRESS_MASK:
|
||||||
|
g_free (priv->generate_mac_address_mask);
|
||||||
|
priv->generate_mac_address_mask = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
case PROP_MAC_ADDRESS_BLACKLIST:
|
case PROP_MAC_ADDRESS_BLACKLIST:
|
||||||
blacklist = g_value_get_boxed (value);
|
blacklist = g_value_get_boxed (value);
|
||||||
g_array_set_size (priv->mac_address_blacklist, 0);
|
g_array_set_size (priv->mac_address_blacklist, 0);
|
||||||
|
@ -998,6 +1092,9 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_CLONED_MAC_ADDRESS:
|
case PROP_CLONED_MAC_ADDRESS:
|
||||||
g_value_set_string (value, nm_setting_wireless_get_cloned_mac_address (setting));
|
g_value_set_string (value, nm_setting_wireless_get_cloned_mac_address (setting));
|
||||||
break;
|
break;
|
||||||
|
case PROP_GENERATE_MAC_ADDRESS_MASK:
|
||||||
|
g_value_set_string (value, nm_setting_wireless_get_generate_mac_address_mask (setting));
|
||||||
|
break;
|
||||||
case PROP_MAC_ADDRESS_BLACKLIST:
|
case PROP_MAC_ADDRESS_BLACKLIST:
|
||||||
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
||||||
break;
|
break;
|
||||||
|
@ -1023,18 +1120,19 @@ get_property (GObject *object, guint prop_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
nm_setting_wireless_class_init (NMSettingWirelessClass *setting_wireless_class)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
|
GObjectClass *object_class = G_OBJECT_CLASS (setting_wireless_class);
|
||||||
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
|
NMSettingClass *setting_class = NM_SETTING_CLASS (setting_wireless_class);
|
||||||
|
|
||||||
g_type_class_add_private (setting_class, sizeof (NMSettingWirelessPrivate));
|
g_type_class_add_private (setting_wireless_class, sizeof (NMSettingWirelessPrivate));
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
parent_class->verify = verify;
|
setting_class->verify = verify;
|
||||||
|
setting_class->compare_property = compare_property;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
/**
|
/**
|
||||||
|
@ -1154,7 +1252,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_BSSID,
|
_nm_setting_class_transform_property (setting_class, NM_SETTING_WIRELESS_BSSID,
|
||||||
G_VARIANT_TYPE_BYTESTRING,
|
G_VARIANT_TYPE_BYTESTRING,
|
||||||
_nm_utils_hwaddr_to_dbus,
|
_nm_utils_hwaddr_to_dbus,
|
||||||
_nm_utils_hwaddr_from_dbus);
|
_nm_utils_hwaddr_from_dbus);
|
||||||
|
@ -1231,7 +1329,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_MAC_ADDRESS,
|
_nm_setting_class_transform_property (setting_class, NM_SETTING_WIRELESS_MAC_ADDRESS,
|
||||||
G_VARIANT_TYPE_BYTESTRING,
|
G_VARIANT_TYPE_BYTESTRING,
|
||||||
_nm_utils_hwaddr_to_dbus,
|
_nm_utils_hwaddr_to_dbus,
|
||||||
_nm_utils_hwaddr_from_dbus);
|
_nm_utils_hwaddr_from_dbus);
|
||||||
|
@ -1239,8 +1337,22 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
/**
|
/**
|
||||||
* NMSettingWireless:cloned-mac-address:
|
* NMSettingWireless:cloned-mac-address:
|
||||||
*
|
*
|
||||||
* If specified, request that the Wi-Fi device use this MAC address instead
|
* If specified, request that the device use this MAC address instead of its
|
||||||
* of its permanent MAC address. This is known as MAC cloning or spoofing.
|
* permanent MAC address. This is known as MAC cloning or spoofing.
|
||||||
|
*
|
||||||
|
* Beside explicitly specifing a MAC address, the special values "preserve", "permanent",
|
||||||
|
* "random" and "stable" are supported.
|
||||||
|
* "preserve" means not to touch the MAC address on activation.
|
||||||
|
* "permanent" means to use the permanent hardware address of the device.
|
||||||
|
* "random" creates a random MAC address on each connect.
|
||||||
|
* "stable" creates a hashed MAC address based on connection.stable-id (or
|
||||||
|
* the connection's UUID) and a machine dependent key.
|
||||||
|
*
|
||||||
|
* If unspecified, the value can be overwritten via global defaults, see manual
|
||||||
|
* of NetworkManager.conf. If still unspecified, it defaults to "permanent".
|
||||||
|
*
|
||||||
|
* On D-Bus, this field is expressed as "assigned-mac-address" or the deprecated
|
||||||
|
* "cloned-mac-address".
|
||||||
**/
|
**/
|
||||||
/* ---keyfile---
|
/* ---keyfile---
|
||||||
* property: cloned-mac-address
|
* property: cloned-mac-address
|
||||||
|
@ -1255,6 +1367,12 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
* description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons
|
* description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons
|
||||||
* notation (e.g. 00:22:68:14:5A:99).
|
* notation (e.g. 00:22:68:14:5A:99).
|
||||||
* ---end---
|
* ---end---
|
||||||
|
* ---dbus---
|
||||||
|
* property: cloned-mac-address
|
||||||
|
* format: byte array
|
||||||
|
* description: This D-Bus field is deprecated in favor of "assigned-mac-address"
|
||||||
|
* which is more flexible and allows specifying special variants like "random".
|
||||||
|
* ---end---
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_CLONED_MAC_ADDRESS,
|
(object_class, PROP_CLONED_MAC_ADDRESS,
|
||||||
|
@ -1262,10 +1380,75 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
_nm_setting_class_override_property (setting_class,
|
||||||
G_VARIANT_TYPE_BYTESTRING,
|
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||||
_nm_utils_hwaddr_to_dbus,
|
G_VARIANT_TYPE_BYTESTRING,
|
||||||
_nm_utils_hwaddr_from_dbus);
|
_nm_utils_hwaddr_cloned_get,
|
||||||
|
_nm_utils_hwaddr_cloned_set,
|
||||||
|
_nm_utils_hwaddr_cloned_not_set);
|
||||||
|
|
||||||
|
/* ---dbus---
|
||||||
|
* property: assigned-mac-address
|
||||||
|
* format: string
|
||||||
|
* description: The new field for the cloned MAC address. It can be either
|
||||||
|
* a hardware address in ASCII representation, or one of the special values
|
||||||
|
* "preserve", "permanent", "random", "random" or "stable".
|
||||||
|
* This field replaces the deprecated "cloned-mac-address" on D-Bus, which
|
||||||
|
* can only contain explict hardware addresses.
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
|
_nm_setting_class_add_dbus_only_property (setting_class,
|
||||||
|
"assigned-mac-address",
|
||||||
|
G_VARIANT_TYPE_STRING,
|
||||||
|
_nm_utils_hwaddr_cloned_data_synth,
|
||||||
|
_nm_utils_hwaddr_cloned_data_set);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMSettingWireless:generate-mac-address-mask:
|
||||||
|
*
|
||||||
|
* With #NMSettingWireless:cloned-mac-address setting "random" or "stable",
|
||||||
|
* by default all bits of the MAC address are scrambled and a locally-administered,
|
||||||
|
* unicast MAC address is created. This property allows to specify that certain bits
|
||||||
|
* are fixed. Note that the least significant bit of the first MAC address will
|
||||||
|
* always be unset to create a unicast MAC address.
|
||||||
|
*
|
||||||
|
* If the property is %NULL, it is eligible to be overwritten by a default
|
||||||
|
* connection setting. If the value is still %NULL or an empty string, the
|
||||||
|
* default is to create a locally-administered, unicast MAC address.
|
||||||
|
*
|
||||||
|
* If the value contains one MAC address, this address is used as mask. The set
|
||||||
|
* bits of the mask are to be filled with the current MAC address of the device,
|
||||||
|
* while the unset bits are subject to randomization.
|
||||||
|
* Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address
|
||||||
|
* and only randomize the lower 3 bytes using the "random" or "stable" algorithm.
|
||||||
|
*
|
||||||
|
* If the value contains one additional MAC address after the mask,
|
||||||
|
* this address is used instead of the current MAC address to fill the bits
|
||||||
|
* that shall not be randomized. For example, a value of
|
||||||
|
* "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address
|
||||||
|
* to 68:F7:28, while the lower bits are randomized. A value of
|
||||||
|
* "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled
|
||||||
|
* globally-administered, burned-in MAC address.
|
||||||
|
*
|
||||||
|
* If the value contains more then one additional MAC addresses, one of
|
||||||
|
* them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00"
|
||||||
|
* will create a fully scrambled MAC address, randomly locally or globally
|
||||||
|
* administered.
|
||||||
|
**/
|
||||||
|
/* ---ifcfg-rh---
|
||||||
|
* property: generate-mac-address-mask
|
||||||
|
* variable: GENERATE_MAC_ADDRESS_MASK
|
||||||
|
* description: the MAC address mask for generating randomized and stable
|
||||||
|
* cloned-mac-address.
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||||
|
g_param_spec_string (NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, "", "",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMSettingWireless:mac-address-blacklist:
|
* NMSettingWireless:mac-address-blacklist:
|
||||||
|
@ -1398,6 +1581,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
* (always randomize the MAC address).
|
* (always randomize the MAC address).
|
||||||
*
|
*
|
||||||
* Since: 1.2
|
* Since: 1.2
|
||||||
|
* Deprecated: 1.4: Deprecated by NMSettingWireless:cloned-mac-address property
|
||||||
**/
|
**/
|
||||||
/* ---ifcfg-rh---
|
/* ---ifcfg-rh---
|
||||||
* property: mac-address-randomization
|
* property: mac-address-randomization
|
||||||
|
@ -1428,7 +1612,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
||||||
* NetworkManager daemons.
|
* NetworkManager daemons.
|
||||||
* ---end---
|
* ---end---
|
||||||
*/
|
*/
|
||||||
_nm_setting_class_add_dbus_only_property (parent_class, "security",
|
_nm_setting_class_add_dbus_only_property (setting_class, "security",
|
||||||
G_VARIANT_TYPE_STRING,
|
G_VARIANT_TYPE_STRING,
|
||||||
nm_setting_wireless_get_security, NULL);
|
nm_setting_wireless_get_security, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ G_BEGIN_DECLS
|
||||||
#define NM_SETTING_WIRELESS_TX_POWER "tx-power"
|
#define NM_SETTING_WIRELESS_TX_POWER "tx-power"
|
||||||
#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address"
|
#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address"
|
||||||
#define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address"
|
#define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address"
|
||||||
|
#define NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK "generate-mac-address-mask"
|
||||||
#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
|
#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
|
||||||
#define NM_SETTING_WIRELESS_MTU "mtu"
|
#define NM_SETTING_WIRELESS_MTU "mtu"
|
||||||
#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids"
|
#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids"
|
||||||
|
@ -126,6 +127,9 @@ guint32 nm_setting_wireless_get_tx_power (NMSettingWireless
|
||||||
const char *nm_setting_wireless_get_mac_address (NMSettingWireless *setting);
|
const char *nm_setting_wireless_get_mac_address (NMSettingWireless *setting);
|
||||||
const char *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting);
|
const char *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
const char *nm_setting_wireless_get_generate_mac_address_mask (NMSettingWireless *setting);
|
||||||
|
|
||||||
const char * const *nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting);
|
const char * const *nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting);
|
||||||
guint32 nm_setting_wireless_get_num_mac_blacklist_items (NMSettingWireless *setting);
|
guint32 nm_setting_wireless_get_num_mac_blacklist_items (NMSettingWireless *setting);
|
||||||
const char * nm_setting_wireless_get_mac_blacklist_item (NMSettingWireless *setting,
|
const char * nm_setting_wireless_get_mac_blacklist_item (NMSettingWireless *setting,
|
||||||
|
|
|
@ -36,6 +36,29 @@ gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, g
|
||||||
|
|
||||||
/* D-Bus transform funcs */
|
/* D-Bus transform funcs */
|
||||||
|
|
||||||
|
GVariant *_nm_utils_hwaddr_cloned_get (NMSetting *setting,
|
||||||
|
const char *property);
|
||||||
|
gboolean _nm_utils_hwaddr_cloned_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
GVariant *value,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error);
|
||||||
|
gboolean _nm_utils_hwaddr_cloned_not_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error);
|
||||||
|
GVariant * _nm_utils_hwaddr_cloned_data_synth (NMSetting *setting,
|
||||||
|
NMConnection *connection,
|
||||||
|
const char *property);
|
||||||
|
gboolean _nm_utils_hwaddr_cloned_data_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
GVariant *value,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
GVariant * _nm_utils_hwaddr_to_dbus (const GValue *prop_value);
|
GVariant * _nm_utils_hwaddr_to_dbus (const GValue *prop_value);
|
||||||
void _nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
void _nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
||||||
GValue *prop_value);
|
GValue *prop_value);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "nm-common-macros.h"
|
||||||
#include "nm-utils-private.h"
|
#include "nm-utils-private.h"
|
||||||
#include "nm-setting-private.h"
|
#include "nm-setting-private.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
@ -3114,6 +3115,33 @@ hwaddr_binary_len (const char *asc)
|
||||||
return octets;
|
return octets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _nm_utils_hwaddr_length:
|
||||||
|
* @asc: the ASCII representation of the hardware address
|
||||||
|
*
|
||||||
|
* Validates that @asc is a valid representation of a hardware
|
||||||
|
* address up to (including) %NM_UTILS_HWADDR_LEN_MAX bytes.
|
||||||
|
*
|
||||||
|
* Returns: binary length of the hardware address @asc or
|
||||||
|
* 0 on error.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
_nm_utils_hwaddr_length (const char *asc)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
if (!asc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
l = hwaddr_binary_len (asc);
|
||||||
|
if (l <= 0 || l > NM_UTILS_HWADDR_LEN_MAX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!nm_utils_hwaddr_valid (asc, l))
|
||||||
|
return 0;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_utils_hwaddr_valid:
|
* nm_utils_hwaddr_valid:
|
||||||
* @asc: the ASCII representation of a hardware address
|
* @asc: the ASCII representation of a hardware address
|
||||||
|
@ -3286,24 +3314,124 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1,
|
||||||
return !memcmp (hwaddr1, hwaddr2, hwaddr1_len);
|
return !memcmp (hwaddr1, hwaddr2, hwaddr1_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
GVariant *
|
/*****************************************************************************/
|
||||||
_nm_utils_hwaddr_to_dbus (const GValue *prop_value)
|
|
||||||
|
static GVariant *
|
||||||
|
_nm_utils_hwaddr_to_dbus_impl (const char *str)
|
||||||
{
|
{
|
||||||
const char *str = g_value_get_string (prop_value);
|
|
||||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (str) {
|
if (!str)
|
||||||
len = hwaddr_binary_len (str);
|
return NULL;
|
||||||
g_return_val_if_fail (len > 0 && len <= NM_UTILS_HWADDR_LEN_MAX, NULL);
|
|
||||||
if (!nm_utils_hwaddr_aton (str, buf, len))
|
len = _nm_utils_hwaddr_length (str);
|
||||||
len = 0;
|
if (len == 0)
|
||||||
} else
|
return NULL;
|
||||||
len = 0;
|
|
||||||
|
if (!nm_utils_hwaddr_aton (str, buf, len))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1);
|
return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
_nm_utils_hwaddr_cloned_get (NMSetting *setting,
|
||||||
|
const char *property)
|
||||||
|
{
|
||||||
|
gs_free char *addr = NULL;
|
||||||
|
|
||||||
|
nm_assert (nm_streq0 (property, "cloned-mac-address"));
|
||||||
|
|
||||||
|
g_object_get (setting, "cloned-mac-address", &addr, NULL);
|
||||||
|
return _nm_utils_hwaddr_to_dbus_impl (addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_nm_utils_hwaddr_cloned_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
GVariant *value,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gsize length;
|
||||||
|
const guint8 *array;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
nm_assert (nm_streq0 (property, "cloned-mac-address"));
|
||||||
|
|
||||||
|
if (!_nm_setting_use_legacy_property (setting, connection_dict, "cloned-mac-address", "assigned-mac-address"))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
length = 0;
|
||||||
|
array = g_variant_get_fixed_array (value, &length, 1);
|
||||||
|
|
||||||
|
if (!length)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
str = nm_utils_hwaddr_ntoa (array, length);
|
||||||
|
g_object_set (setting,
|
||||||
|
"cloned-mac-address",
|
||||||
|
str,
|
||||||
|
NULL);
|
||||||
|
g_free (str);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_nm_utils_hwaddr_cloned_not_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
nm_assert (nm_streq0 (property, "cloned-mac-address"));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
_nm_utils_hwaddr_cloned_data_synth (NMSetting *setting,
|
||||||
|
NMConnection *connection,
|
||||||
|
const char *property)
|
||||||
|
{
|
||||||
|
gs_free char *addr = NULL;
|
||||||
|
|
||||||
|
nm_assert (nm_streq0 (property, "assigned-mac-address"));
|
||||||
|
|
||||||
|
g_object_get (setting,
|
||||||
|
"cloned-mac-address",
|
||||||
|
&addr,
|
||||||
|
NULL);
|
||||||
|
return addr ? g_variant_new_string (addr) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_nm_utils_hwaddr_cloned_data_set (NMSetting *setting,
|
||||||
|
GVariant *connection_dict,
|
||||||
|
const char *property,
|
||||||
|
GVariant *value,
|
||||||
|
NMSettingParseFlags parse_flags,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
nm_assert (nm_streq0 (property, "assigned-mac-address"));
|
||||||
|
|
||||||
|
if (_nm_setting_use_legacy_property (setting, connection_dict, "cloned-mac-address", "assigned-mac-address"))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
g_object_set (setting,
|
||||||
|
"cloned-mac-address",
|
||||||
|
g_variant_get_string (value, NULL),
|
||||||
|
NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
_nm_utils_hwaddr_to_dbus (const GValue *prop_value)
|
||||||
|
{
|
||||||
|
return _nm_utils_hwaddr_to_dbus_impl (g_value_get_string (prop_value));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
_nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
||||||
GValue *prop_value)
|
GValue *prop_value)
|
||||||
|
@ -3316,6 +3444,93 @@ _nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
||||||
g_value_take_string (prop_value, str);
|
g_value_take_string (prop_value, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_split_word (char *s)
|
||||||
|
{
|
||||||
|
/* takes @s and truncates the string on the first white-space.
|
||||||
|
* then it returns the first word afterwards (again seeking
|
||||||
|
* over leading white-space). */
|
||||||
|
for (; s[0]; s++) {
|
||||||
|
if (g_ascii_isspace (s[0])) {
|
||||||
|
s[0] = '\0';
|
||||||
|
s++;
|
||||||
|
while (g_ascii_isspace (s[0]))
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_nm_utils_generate_mac_address_mask_parse (const char *value,
|
||||||
|
struct ether_addr *out_mask,
|
||||||
|
struct ether_addr **out_ouis,
|
||||||
|
gsize *out_ouis_len,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gs_free char *s_free = NULL;
|
||||||
|
char *s, *s_next;
|
||||||
|
struct ether_addr mask;
|
||||||
|
gs_unref_array GArray *ouis = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (!error || !*error, FALSE);
|
||||||
|
|
||||||
|
if (!value || !*value) {
|
||||||
|
/* NULL and "" are valid values and both mean the default
|
||||||
|
* "q */
|
||||||
|
if (out_mask) {
|
||||||
|
memset (out_mask, 0, sizeof (*out_mask));
|
||||||
|
out_mask->ether_addr_octet[0] |= 0x02;
|
||||||
|
}
|
||||||
|
NM_SET_OUT (out_ouis, NULL);
|
||||||
|
NM_SET_OUT (out_ouis_len, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_free = g_strdup (value);
|
||||||
|
s = s_free;
|
||||||
|
|
||||||
|
/* skip over leading whitespace */
|
||||||
|
while (g_ascii_isspace (s[0]))
|
||||||
|
s++;
|
||||||
|
|
||||||
|
/* parse the first mask */
|
||||||
|
s_next = _split_word (s);
|
||||||
|
if (!nm_utils_hwaddr_aton (s, &mask, ETH_ALEN)) {
|
||||||
|
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||||
|
_("not a valid ethernet MAC address for mask at position %lld"),
|
||||||
|
(long long) (s - s_free));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_next[0]) {
|
||||||
|
ouis = g_array_sized_new (FALSE, FALSE, sizeof (struct ether_addr), 4);
|
||||||
|
|
||||||
|
do {
|
||||||
|
s = s_next;
|
||||||
|
s_next = _split_word (s);
|
||||||
|
|
||||||
|
g_array_set_size (ouis, ouis->len + 1);
|
||||||
|
if (!nm_utils_hwaddr_aton (s, &g_array_index (ouis, struct ether_addr, ouis->len - 1), ETH_ALEN)) {
|
||||||
|
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||||
|
_("not a valid ethernet MAC address #%u at position %lld"),
|
||||||
|
ouis->len, (long long) (s - s_free));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} while (s_next[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NM_SET_OUT (out_mask, mask);
|
||||||
|
NM_SET_OUT (out_ouis_len, ouis ? ouis->len : 0);
|
||||||
|
NM_SET_OUT (out_ouis, ouis ? ((struct ether_addr *) g_array_free (g_steal_pointer (&ouis), FALSE)) : NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_utils_bin2hexstr:
|
* nm_utils_bin2hexstr:
|
||||||
* @src: (type guint8) (array length=len): an array of bytes
|
* @src: (type guint8) (array length=len): an array of bytes
|
||||||
|
|
|
@ -1916,6 +1916,7 @@ test_connection_diff_a_only (void)
|
||||||
{ NM_SETTING_CONNECTION_SETTING_NAME, {
|
{ NM_SETTING_CONNECTION_SETTING_NAME, {
|
||||||
{ NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
|
{ NM_SETTING_CONNECTION_STABLE_ID, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
|
@ -1940,6 +1941,7 @@ test_connection_diff_a_only (void)
|
||||||
{ NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
|
{ NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
{ NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A },
|
{ NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A },
|
||||||
|
@ -2384,6 +2386,154 @@ test_setting_compare_id (void)
|
||||||
g_assert (success);
|
g_assert (success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_setting_compare_addresses (void)
|
||||||
|
{
|
||||||
|
gs_unref_object NMSetting *s1 = NULL, *s2 = NULL;
|
||||||
|
gboolean success;
|
||||||
|
NMIPAddress *a;
|
||||||
|
GHashTable *result = NULL;
|
||||||
|
|
||||||
|
s1 = nm_setting_ip4_config_new ();
|
||||||
|
s2 = nm_setting_ip4_config_new ();
|
||||||
|
|
||||||
|
a = nm_ip_address_new (AF_INET, "192.168.7.5", 24, NULL);
|
||||||
|
|
||||||
|
nm_ip_address_set_attribute (a, "label", g_variant_new_string ("xoxoxo"));
|
||||||
|
nm_setting_ip_config_add_address ((NMSettingIPConfig *) s1, a);
|
||||||
|
|
||||||
|
nm_ip_address_set_attribute (a, "label", g_variant_new_string ("hello"));
|
||||||
|
nm_setting_ip_config_add_address ((NMSettingIPConfig *) s2, a);
|
||||||
|
|
||||||
|
nm_ip_address_unref (a);
|
||||||
|
|
||||||
|
if (nmtst_get_rand_int () % 2)
|
||||||
|
NMTST_SWAP (s1, s2);
|
||||||
|
|
||||||
|
success = nm_setting_compare (s1, s2, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
|
||||||
|
success = nm_setting_diff (s1, s2, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, &result);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_pointer (&result, g_hash_table_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_setting_compare_routes (void)
|
||||||
|
{
|
||||||
|
gs_unref_object NMSetting *s1 = NULL, *s2 = NULL;
|
||||||
|
gboolean success;
|
||||||
|
NMIPRoute *r;
|
||||||
|
GHashTable *result = NULL;
|
||||||
|
|
||||||
|
s1 = nm_setting_ip4_config_new ();
|
||||||
|
s2 = nm_setting_ip4_config_new ();
|
||||||
|
|
||||||
|
r = nm_ip_route_new (AF_INET, "192.168.12.0", 24, "192.168.11.1", 473, NULL);
|
||||||
|
|
||||||
|
nm_ip_route_set_attribute (r, "label", g_variant_new_string ("xoxoxo"));
|
||||||
|
nm_setting_ip_config_add_route ((NMSettingIPConfig *) s1, r);
|
||||||
|
|
||||||
|
nm_ip_route_set_attribute (r, "label", g_variant_new_string ("hello"));
|
||||||
|
nm_setting_ip_config_add_route ((NMSettingIPConfig *) s2, r);
|
||||||
|
|
||||||
|
nm_ip_route_unref (r);
|
||||||
|
|
||||||
|
if (nmtst_get_rand_int () % 2)
|
||||||
|
NMTST_SWAP (s1, s2);
|
||||||
|
|
||||||
|
success = nm_setting_compare (s1, s2, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
|
||||||
|
success = nm_setting_diff (s1, s2, NM_SETTING_COMPARE_FLAG_EXACT, FALSE, &result);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_pointer (&result, g_hash_table_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_setting_compare_wired_cloned_mac_address (void)
|
||||||
|
{
|
||||||
|
gs_unref_object NMSetting *old = NULL, *new = NULL;
|
||||||
|
gboolean success;
|
||||||
|
gs_free char *str1 = NULL;
|
||||||
|
|
||||||
|
old = nm_setting_wired_new ();
|
||||||
|
g_object_set (old,
|
||||||
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "stable",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("stable", ==, nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) old));
|
||||||
|
g_object_get (old, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("stable", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
new = nm_setting_duplicate (old);
|
||||||
|
g_object_set (new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "11:22:33:44:55:66", NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("11:22:33:44:55:66", ==, nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) new));
|
||||||
|
g_object_get (new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("11:22:33:44:55:66", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_object (&new);
|
||||||
|
|
||||||
|
new = nm_setting_duplicate (old);
|
||||||
|
g_object_set (new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "stable-bia", NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("stable-bia", ==, nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) new));
|
||||||
|
g_object_get (new, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("stable-bia", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_object (&new);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_setting_compare_wireless_cloned_mac_address (void)
|
||||||
|
{
|
||||||
|
gs_unref_object NMSetting *old = NULL, *new = NULL;
|
||||||
|
gboolean success;
|
||||||
|
gs_free char *str1 = NULL;
|
||||||
|
|
||||||
|
old = nm_setting_wireless_new ();
|
||||||
|
g_object_set (old,
|
||||||
|
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "stable",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("stable", ==, nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) old));
|
||||||
|
g_object_get (old, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("stable", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
new = nm_setting_duplicate (old);
|
||||||
|
g_object_set (new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "11:22:33:44:55:66", NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("11:22:33:44:55:66", ==, nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) new));
|
||||||
|
g_object_get (new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("11:22:33:44:55:66", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_object (&new);
|
||||||
|
|
||||||
|
new = nm_setting_duplicate (old);
|
||||||
|
g_object_set (new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "stable-bia", NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr ("stable-bia", ==, nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) new));
|
||||||
|
g_object_get (new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL);
|
||||||
|
g_assert_cmpstr ("stable-bia", ==, str1);
|
||||||
|
g_clear_pointer (&str1, g_free);
|
||||||
|
|
||||||
|
success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||||
|
g_assert (!success);
|
||||||
|
g_clear_object (&new);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_setting_compare_timestamp (void)
|
test_setting_compare_timestamp (void)
|
||||||
{
|
{
|
||||||
|
@ -5135,6 +5285,10 @@ int main (int argc, char **argv)
|
||||||
g_test_add_func ("/core/general/test_setting_to_dbus_transform", test_setting_to_dbus_transform);
|
g_test_add_func ("/core/general/test_setting_to_dbus_transform", test_setting_to_dbus_transform);
|
||||||
g_test_add_func ("/core/general/test_setting_to_dbus_enum", test_setting_to_dbus_enum);
|
g_test_add_func ("/core/general/test_setting_to_dbus_enum", test_setting_to_dbus_enum);
|
||||||
g_test_add_func ("/core/general/test_setting_compare_id", test_setting_compare_id);
|
g_test_add_func ("/core/general/test_setting_compare_id", test_setting_compare_id);
|
||||||
|
g_test_add_func ("/core/general/test_setting_compare_addresses", test_setting_compare_addresses);
|
||||||
|
g_test_add_func ("/core/general/test_setting_compare_routes", test_setting_compare_routes);
|
||||||
|
g_test_add_func ("/core/general/test_setting_compare_wired_cloned_mac_address", test_setting_compare_wired_cloned_mac_address);
|
||||||
|
g_test_add_func ("/core/general/test_setting_compare_wirless_cloned_mac_address", test_setting_compare_wireless_cloned_mac_address);
|
||||||
g_test_add_func ("/core/general/test_setting_compare_timestamp", test_setting_compare_timestamp);
|
g_test_add_func ("/core/general/test_setting_compare_timestamp", test_setting_compare_timestamp);
|
||||||
#define ADD_FUNC(name, func, secret_flags, comp_flags, remove_secret) \
|
#define ADD_FUNC(name, func, secret_flags, comp_flags, remove_secret) \
|
||||||
g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func) "_" name, \
|
g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func) "_" name, \
|
||||||
|
|
|
@ -1066,8 +1066,11 @@ libnm_1_2_4 {
|
||||||
libnm_1_4_0 {
|
libnm_1_4_0 {
|
||||||
global:
|
global:
|
||||||
nm_device_team_get_config;
|
nm_device_team_get_config;
|
||||||
|
nm_setting_connection_get_stable_id;
|
||||||
nm_setting_ip6_config_get_token;
|
nm_setting_ip6_config_get_token;
|
||||||
nm_setting_ip_config_get_dns_priority;
|
nm_setting_ip_config_get_dns_priority;
|
||||||
|
nm_setting_wired_get_generate_mac_address_mask;
|
||||||
|
nm_setting_wireless_get_generate_mac_address_mask;
|
||||||
nm_vpn_editor_plugin_get_plugin_info;
|
nm_vpn_editor_plugin_get_plugin_info;
|
||||||
nm_vpn_editor_plugin_get_vt;
|
nm_vpn_editor_plugin_get_vt;
|
||||||
nm_vpn_editor_plugin_load;
|
nm_vpn_editor_plugin_load;
|
||||||
|
|
|
@ -224,30 +224,12 @@ no-auto-default=*
|
||||||
<term><varname>ignore-carrier</varname></term>
|
<term><varname>ignore-carrier</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specify devices for which NetworkManager will (partially)
|
This setting is deprecated for the per-device setting
|
||||||
ignore the carrier state. Normally, for
|
<literal>ignore-carrier</literal> which overwrites this setting
|
||||||
device types that support carrier-detect, such as Ethernet
|
if specified (See <xref linked="ignore-carrier"/>).
|
||||||
and InfiniBand, NetworkManager will only allow a
|
Otherwise, it is a list of matches to specify for which device
|
||||||
connection to be activated on the device if carrier is
|
carrier should be ignored. See <xref linkend="device-spec"/> for the
|
||||||
present (ie, a cable is plugged in), and it will
|
syntax how to specify a device.
|
||||||
deactivate the device if carrier drops for more than a few
|
|
||||||
seconds.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Listing a device here will allow activating connections on
|
|
||||||
that device even when it does not have carrier, provided
|
|
||||||
that the connection uses only statically-configured IP
|
|
||||||
addresses. Additionally, it will allow any active
|
|
||||||
connection (whether static or dynamic) to remain active on
|
|
||||||
the device when carrier is lost.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Note that the "carrier" property of NMDevices and device D-Bus
|
|
||||||
interfaces will still reflect the actual device state; it's just
|
|
||||||
that NetworkManager will not make use of that information.
|
|
||||||
</para>
|
|
||||||
<para>See <xref linkend="device-spec"/> for the syntax how to
|
|
||||||
specify a device.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -583,6 +565,13 @@ ipv6.ip6-privacy=0
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>connection.lldp</varname></term>
|
<term><varname>connection.lldp</varname></term>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ethernet.cloned-mac-address</varname></term>
|
||||||
|
<listitem><para>If left unspecified, it defaults to "permanent".</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>ethernet.generate-mac-address-mask</varname></term>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>ethernet.wake-on-lan</varname></term>
|
<term><varname>ethernet.wake-on-lan</varname></term>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -610,9 +599,18 @@ ipv6.ip6-privacy=0
|
||||||
<term><varname>vpn.timeout</varname></term>
|
<term><varname>vpn.timeout</varname></term>
|
||||||
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
|
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>wifi.cloned-mac-address</varname></term>
|
||||||
|
<listitem><para>If left unspecified, it defaults to "permanent".</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>wifi.generate-mac-address-mask</varname></term>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>wifi.mac-address-randomization</varname></term>
|
<term><varname>wifi.mac-address-randomization</varname></term>
|
||||||
<listitem><para>If left unspecified, MAC address randomization is disabled.</para></listitem>
|
<listitem><para>If left unspecified, MAC address randomization is disabled.
|
||||||
|
This setting is deprecated for <literal>wifi.cloned-mac-address</literal>.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>wifi.powersave</varname></term>
|
<term><varname>wifi.powersave</varname></term>
|
||||||
|
@ -623,7 +621,7 @@ ipv6.ip6-privacy=0
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
<refsect2>
|
<refsect2 id="connection-sections">
|
||||||
<title>Sections</title>
|
<title>Sections</title>
|
||||||
<para>
|
<para>
|
||||||
You can configure multiple <literal>connection</literal>
|
You can configure multiple <literal>connection</literal>
|
||||||
|
@ -696,6 +694,97 @@ ipv6.ip6-privacy=1
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title><literal>device</literal> section</title>
|
||||||
|
<para>Contains per-device persistent configuration.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Example:
|
||||||
|
<programlisting>
|
||||||
|
[device]
|
||||||
|
match-device=interface-name:eth3
|
||||||
|
unmanaged=1
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<refsect2>
|
||||||
|
<title>Supported Properties</title>
|
||||||
|
<para>
|
||||||
|
The following properties can be configured per-device.
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry id="ignore-carrier">
|
||||||
|
<term><varname>ignore-carrier</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specify devices for which NetworkManager will (partially)
|
||||||
|
ignore the carrier state. Normally, for
|
||||||
|
device types that support carrier-detect, such as Ethernet
|
||||||
|
and InfiniBand, NetworkManager will only allow a
|
||||||
|
connection to be activated on the device if carrier is
|
||||||
|
present (ie, a cable is plugged in), and it will
|
||||||
|
deactivate the device if carrier drops for more than a few
|
||||||
|
seconds.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A device with carrier ignored will allow activating connections on
|
||||||
|
that device even when it does not have carrier, provided
|
||||||
|
that the connection uses only statically-configured IP
|
||||||
|
addresses. Additionally, it will allow any active
|
||||||
|
connection (whether static or dynamic) to remain active on
|
||||||
|
the device when carrier is lost.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Note that the "carrier" property of NMDevices and device D-Bus
|
||||||
|
interfaces will still reflect the actual device state; it's just
|
||||||
|
that NetworkManager will not make use of that information.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This setting overwrites the deprecated <literal>main.ignore-carrier</literal>
|
||||||
|
setting above.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>wifi.scan-rand-mac-address</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Configures the MAC address of a Wi-Fi device during scanning.
|
||||||
|
This defaults to <literal>yes</literal> in which case a random,
|
||||||
|
locally-administered MAC address will be confiugred.
|
||||||
|
Otherwise, the MAC address is left unchanged to whatever was
|
||||||
|
configured.
|
||||||
|
For the MAC address used while the device is connected, see instead
|
||||||
|
the per-connection setting <literal>wifi.cloned-mac-address</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>wifi.scan-generate-mac-address-mask</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Like the per-connection settings ethernet.generate-mac-address-mask
|
||||||
|
and wifi.generate-mac-address-mask, this allows to configure the
|
||||||
|
generated MAC addresses during scanning. See manual of nm-settings
|
||||||
|
for details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
</refsect2>
|
||||||
|
|
||||||
|
<refsect2>
|
||||||
|
<title>Sections</title>
|
||||||
|
<para>
|
||||||
|
The <literal>[device]</literal> section works the same as the <literal>[connection]</literal> section.
|
||||||
|
That is, multiple sections that all start with the prefix "device" can be specified.
|
||||||
|
The settings "match-device" and "stop-match" are available to match a device section
|
||||||
|
on a device. The order of multiple sections is also top-down within the file and
|
||||||
|
later files overwrite previous settings. See <xref linkend="connection-sections"/>
|
||||||
|
for details.
|
||||||
|
</para>
|
||||||
|
</refsect2>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title><literal>connectivity</literal> section</title>
|
<title><literal>connectivity</literal> section</title>
|
||||||
<para>This section controls NetworkManager's optional connectivity
|
<para>This section controls NetworkManager's optional connectivity
|
||||||
|
@ -978,7 +1067,8 @@ enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16
|
||||||
<title>Device List Format</title>
|
<title>Device List Format</title>
|
||||||
<para>
|
<para>
|
||||||
The configuration options <literal>main.no-auto-default</literal>, <literal>main.ignore-carrier</literal>,
|
The configuration options <literal>main.no-auto-default</literal>, <literal>main.ignore-carrier</literal>,
|
||||||
and <literal>keyfile.unmanaged-devices</literal> select devices based on a list of matchings.
|
<literal>keyfile.unmanaged-devices</literal>, <literal>connection*.match-device</literal> and
|
||||||
|
<literal>device*.match-device</literal> select devices based on a list of matchings.
|
||||||
Devices can be specified using the following format:
|
Devices can be specified using the following format:
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
@ -993,7 +1083,7 @@ enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>HWADDR</term>
|
<term>HWADDR</term>
|
||||||
<listitem><para>Match the MAC address of the device. Globbing is not supported</para></listitem>
|
<listitem><para>Match the permanent MAC address of the device. Globbing is not supported</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>interface-name:IFNAME</term>
|
<term>interface-name:IFNAME</term>
|
||||||
|
@ -1008,7 +1098,7 @@ enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>mac:HWADDR</term>
|
<term>mac:HWADDR</term>
|
||||||
<listitem><para>Match the MAC address of the device. Globbing is not supported</para></listitem>
|
<listitem><para>Match the permanent MAC address of the device. Globbing is not supported</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>s390-subchannels:HWADDR</term>
|
<term>s390-subchannels:HWADDR</term>
|
||||||
|
|
|
@ -257,6 +257,11 @@ DEVICETYPE=TeamPort
|
||||||
assigns the interface 10.42.0.1, or it uses the first static address,
|
assigns the interface 10.42.0.1, or it uses the first static address,
|
||||||
if configured.</para>
|
if configured.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>HWADDR</literal> -
|
||||||
|
initscripts compare the currently set hardware address of a device, while
|
||||||
|
NetworkManager considers the permanent one.</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -38,6 +38,21 @@
|
||||||
#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS "org.freedesktop.NetworkManager.settings.modify.global-dns"
|
#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS "org.freedesktop.NetworkManager.settings.modify.global-dns"
|
||||||
#define NM_AUTH_PERMISSION_RELOAD "org.freedesktop.NetworkManager.reload"
|
#define NM_AUTH_PERMISSION_RELOAD "org.freedesktop.NetworkManager.reload"
|
||||||
|
|
||||||
|
#define NM_CLONED_MAC_PRESERVE "preserve"
|
||||||
|
#define NM_CLONED_MAC_PERMANENT "permanent"
|
||||||
|
#define NM_CLONED_MAC_RANDOM "random"
|
||||||
|
#define NM_CLONED_MAC_STABLE "stable"
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
NM_CLONED_MAC_IS_SPECIAL (const char *str)
|
||||||
|
{
|
||||||
|
return NM_IN_STRSET (str,
|
||||||
|
NM_CLONED_MAC_PRESERVE,
|
||||||
|
NM_CLONED_MAC_PERMANENT,
|
||||||
|
NM_CLONED_MAC_RANDOM,
|
||||||
|
NM_CLONED_MAC_STABLE);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#endif /* __NM_COMMON_MACROS_H__ */
|
#endif /* __NM_COMMON_MACROS_H__ */
|
||||||
|
|
|
@ -529,8 +529,8 @@ check_connection_mac_address (NMConnection *orig,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
check_connection_cloned_mac_address (NMConnection *orig,
|
check_connection_cloned_mac_address (NMConnection *orig,
|
||||||
NMConnection *candidate,
|
NMConnection *candidate,
|
||||||
GHashTable *settings)
|
GHashTable *settings)
|
||||||
{
|
{
|
||||||
GHashTable *props;
|
GHashTable *props;
|
||||||
const char *orig_mac = NULL, *cand_mac = NULL;
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
||||||
|
@ -551,6 +551,12 @@ check_connection_cloned_mac_address (NMConnection *orig,
|
||||||
if (s_wired_cand)
|
if (s_wired_cand)
|
||||||
cand_mac = nm_setting_wired_get_cloned_mac_address (s_wired_cand);
|
cand_mac = nm_setting_wired_get_cloned_mac_address (s_wired_cand);
|
||||||
|
|
||||||
|
/* special cloned mac address entires are accepted. */
|
||||||
|
if (NM_CLONED_MAC_IS_SPECIAL (orig_mac))
|
||||||
|
orig_mac = NULL;
|
||||||
|
if (NM_CLONED_MAC_IS_SPECIAL (cand_mac))
|
||||||
|
cand_mac = NULL;
|
||||||
|
|
||||||
if (!orig_mac || !cand_mac) {
|
if (!orig_mac || !cand_mac) {
|
||||||
remove_from_hash (settings, props,
|
remove_from_hash (settings, props,
|
||||||
NM_SETTING_WIRED_SETTING_NAME,
|
NM_SETTING_WIRED_SETTING_NAME,
|
||||||
|
|
|
@ -1002,7 +1002,7 @@ nm_device_bt_new (NMBluezDevice *bt_device,
|
||||||
NM_DEVICE_UDI, udi,
|
NM_DEVICE_UDI, udi,
|
||||||
NM_DEVICE_IFACE, bdaddr,
|
NM_DEVICE_IFACE, bdaddr,
|
||||||
NM_DEVICE_DRIVER, "bluez",
|
NM_DEVICE_DRIVER, "bluez",
|
||||||
NM_DEVICE_HW_ADDRESS, bdaddr,
|
NM_DEVICE_PERM_HW_ADDRESS, bdaddr,
|
||||||
NM_DEVICE_BT_DEVICE, bt_device,
|
NM_DEVICE_BT_DEVICE, bt_device,
|
||||||
NM_DEVICE_BT_NAME, name,
|
NM_DEVICE_BT_NAME, name,
|
||||||
NM_DEVICE_BT_CAPABILITIES, capabilities,
|
NM_DEVICE_BT_CAPABILITIES, capabilities,
|
||||||
|
|
|
@ -120,7 +120,6 @@ typedef struct {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PERM_HW_ADDRESS,
|
|
||||||
PROP_SPEED,
|
PROP_SPEED,
|
||||||
PROP_S390_SUBCHANNELS,
|
PROP_S390_SUBCHANNELS,
|
||||||
|
|
||||||
|
@ -307,14 +306,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
|
|
||||||
realize_start_notify (NMDevice *device, const NMPlatformLink *plink)
|
|
||||||
{
|
|
||||||
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->realize_start_notify (device, plink);
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NMDeviceCapabilities
|
static NMDeviceCapabilities
|
||||||
get_generic_capabilities (NMDevice *device)
|
get_generic_capabilities (NMDevice *device)
|
||||||
{
|
{
|
||||||
|
@ -408,7 +399,7 @@ 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);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
mac = nm_setting_wired_get_mac_address (s_wired);
|
mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (perm_hw_addr) {
|
if (perm_hw_addr) {
|
||||||
if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||||
|
@ -813,21 +804,17 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *cloned_mac;
|
|
||||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
|
||||||
ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage1_prepare (dev, reason);
|
ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage1_prepare (dev, reason);
|
||||||
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
||||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||||
if (s_wired) {
|
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
/* Set device MAC address if the connection wants to change it */
|
}
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
|
||||||
nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_ETHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
||||||
/* If we're re-activating a PPPoE connection a short while after
|
/* If we're re-activating a PPPoE connection a short while after
|
||||||
* a previous PPPoE connection was torn down, wait a bit to allow the
|
* a previous PPPoE connection was torn down, wait a bit to allow the
|
||||||
* remote side to handle the disconnection. Otherwise the peer may
|
* remote side to handle the disconnection. Otherwise the peer may
|
||||||
|
@ -1365,10 +1352,6 @@ deactivate (NMDevice *device)
|
||||||
/* Set last PPPoE connection time */
|
/* Set last PPPoE connection time */
|
||||||
if (nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE))
|
if (nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE))
|
||||||
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 */
|
|
||||||
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
|
static gboolean
|
||||||
|
@ -1409,7 +1392,7 @@ complete_connection (NMDevice *device,
|
||||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
if (perm_hw_addr) {
|
if (perm_hw_addr) {
|
||||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (setting_mac) {
|
if (setting_mac) {
|
||||||
|
@ -1438,7 +1421,7 @@ new_default_connection (NMDevice *self)
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
NMSettingsConnection *const*connections;
|
NMSettingsConnection *const*connections;
|
||||||
NMSetting *setting;
|
NMSetting *setting;
|
||||||
const char *hw_address;
|
const char *perm_hw_addr;
|
||||||
gs_free char *defname = NULL;
|
gs_free char *defname = NULL;
|
||||||
gs_free char *uuid = NULL;
|
gs_free char *uuid = NULL;
|
||||||
gs_free char *machine_id = NULL;
|
gs_free char *machine_id = NULL;
|
||||||
|
@ -1446,8 +1429,8 @@ new_default_connection (NMDevice *self)
|
||||||
if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
|
if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hw_address = nm_device_get_hw_address (self);
|
perm_hw_addr = nm_device_get_permanent_hw_address (self, FALSE);
|
||||||
if (!hw_address)
|
if (!perm_hw_addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
connection = nm_simple_connection_new ();
|
connection = nm_simple_connection_new ();
|
||||||
|
@ -1466,7 +1449,7 @@ new_default_connection (NMDevice *self)
|
||||||
uuid = _nm_utils_uuid_generate_from_strings ("default-wired",
|
uuid = _nm_utils_uuid_generate_from_strings ("default-wired",
|
||||||
machine_id ?: "",
|
machine_id ?: "",
|
||||||
defname,
|
defname,
|
||||||
hw_address,
|
perm_hw_addr,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_object_set (setting,
|
g_object_set (setting,
|
||||||
|
@ -1480,7 +1463,7 @@ new_default_connection (NMDevice *self)
|
||||||
|
|
||||||
/* Lock the connection to the device */
|
/* Lock the connection to the device */
|
||||||
setting = nm_setting_wired_new ();
|
setting = nm_setting_wired_new ();
|
||||||
g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, hw_address, NULL);
|
g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL);
|
||||||
nm_connection_add_setting (connection, setting);
|
nm_connection_add_setting (connection, setting);
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
|
@ -1506,7 +1489,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 *perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
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;
|
||||||
|
@ -1582,34 +1565,10 @@ link_changed (NMDevice *device, NMPlatformLink *info)
|
||||||
{
|
{
|
||||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||||
const guint8 *hwaddr;
|
|
||||||
gsize hwaddrlen = 0;
|
|
||||||
|
|
||||||
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->link_changed (device, info);
|
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->link_changed (device, info);
|
||||||
if (!priv->subchan1 && info->initialized)
|
if (!priv->subchan1 && info->initialized)
|
||||||
_update_s390_subchannels (self);
|
_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, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth))) {
|
|
||||||
_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
|
static gboolean
|
||||||
|
@ -1663,9 +1622,6 @@ get_property (GObject *object, guint prop_id,
|
||||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PERM_HW_ADDRESS:
|
|
||||||
g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (object)));
|
|
||||||
break;
|
|
||||||
case PROP_SPEED:
|
case PROP_SPEED:
|
||||||
g_value_set_uint (value, priv->speed);
|
g_value_set_uint (value, priv->speed);
|
||||||
break;
|
break;
|
||||||
|
@ -1707,7 +1663,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->realize_start_notify = realize_start_notify;
|
|
||||||
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;
|
||||||
|
@ -1726,13 +1681,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
||||||
parent_class->state_changed = device_state_changed;
|
parent_class->state_changed = device_state_changed;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
g_object_class_install_property
|
|
||||||
(object_class, PROP_PERM_HW_ADDRESS,
|
|
||||||
g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READABLE |
|
|
||||||
G_PARAM_STATIC_STRINGS));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_SPEED,
|
(object_class, PROP_SPEED,
|
||||||
g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "",
|
g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "",
|
||||||
|
|
|
@ -33,7 +33,6 @@ G_BEGIN_DECLS
|
||||||
#define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET))
|
#define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET))
|
||||||
#define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass))
|
#define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass))
|
||||||
|
|
||||||
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
|
|
||||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||||
#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels"
|
#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels"
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ typedef struct {
|
||||||
* @connection: the #NMConnection to return the parent name for, if supported
|
* @connection: the #NMConnection to return the parent name for, if supported
|
||||||
*
|
*
|
||||||
* Given a connection, returns the a parent interface name, parent connection
|
* Given a connection, returns the a parent interface name, parent connection
|
||||||
* UUID, or parent device hardware address for @connection.
|
* UUID, or parent device permanent hardware address for @connection.
|
||||||
*
|
*
|
||||||
* Returns: the parent interface name, parent connection UUID, parent
|
* Returns: the parent interface name, parent connection UUID, parent
|
||||||
* device hardware address, or %NULL
|
* device permenent hardware address, or %NULL
|
||||||
*/
|
*/
|
||||||
const char * (*get_connection_parent) (NMDeviceFactory *factory,
|
const char * (*get_connection_parent) (NMDeviceFactory *factory,
|
||||||
NMConnection *connection);
|
NMConnection *connection);
|
||||||
|
|
|
@ -147,10 +147,15 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||||
|
|
||||||
if (nm_device_is_real (device)) {
|
if (nm_device_is_real (device)) {
|
||||||
const char *mac;
|
const char *mac;
|
||||||
|
const char *hw_addr;
|
||||||
|
|
||||||
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
||||||
if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1))
|
if (mac) {
|
||||||
return FALSE;
|
hw_addr = nm_device_get_permanent_hw_address (device, TRUE);
|
||||||
|
if ( !hw_addr
|
||||||
|
|| !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -183,7 +188,7 @@ complete_connection (NMDevice *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
||||||
hw_address = nm_device_get_hw_address (device);
|
hw_address = nm_device_get_permanent_hw_address (device, TRUE);
|
||||||
if (setting_mac) {
|
if (setting_mac) {
|
||||||
/* Make sure the setting MAC (if any) matches the device's MAC */
|
/* Make sure the setting MAC (if any) matches the device's MAC */
|
||||||
if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) {
|
if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) {
|
||||||
|
@ -209,7 +214,7 @@ static void
|
||||||
update_connection (NMDevice *device, NMConnection *connection)
|
update_connection (NMDevice *device, NMConnection *connection)
|
||||||
{
|
{
|
||||||
NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection);
|
NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection);
|
||||||
const char *mac = nm_device_get_hw_address (device);
|
const char *mac = nm_device_get_permanent_hw_address (device, TRUE);
|
||||||
const char *transport_mode = "datagram";
|
const char *transport_mode = "datagram";
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
|
|
|
@ -373,9 +373,8 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw
|
||||||
if (!priv->parent)
|
if (!priv->parent)
|
||||||
return !fail_if_no_hwaddr;
|
return !fail_if_no_hwaddr;
|
||||||
|
|
||||||
parent_mac = nm_device_get_hw_address (priv->parent);
|
parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE);
|
||||||
|
return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
||||||
return nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -503,8 +502,6 @@ update_connection (NMDevice *device, NMConnection *connection)
|
||||||
static NMActStageReturn
|
static NMActStageReturn
|
||||||
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *cloned_mac;
|
|
||||||
NMActStageReturn ret;
|
NMActStageReturn ret;
|
||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
@ -513,14 +510,9 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||||
if (s_wired) {
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
/* Set device MAC address if the connection wants to change it */
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
|
||||||
nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_HW);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -549,16 +541,6 @@ realize_start_notify (NMDevice *device, const NMPlatformLink *plink)
|
||||||
update_properties (device);
|
update_properties (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
deactivate (NMDevice *device)
|
|
||||||
{
|
|
||||||
/* Reset MAC address back to initial address */
|
|
||||||
if (nm_device_get_initial_hw_address (device)) {
|
|
||||||
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device),
|
|
||||||
"reset", LOGD_DEVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -639,7 +621,6 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
|
||||||
device_class->complete_connection = complete_connection;
|
device_class->complete_connection = complete_connection;
|
||||||
device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME;
|
device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME;
|
||||||
device_class->create_and_realize = create_and_realize;
|
device_class->create_and_realize = create_and_realize;
|
||||||
device_class->deactivate = deactivate;
|
|
||||||
device_class->get_generic_capabilities = get_generic_capabilities;
|
device_class->get_generic_capabilities = get_generic_capabilities;
|
||||||
device_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
device_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
||||||
device_class->is_available = is_available;
|
device_class->is_available = is_available;
|
||||||
|
|
|
@ -56,8 +56,9 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar
|
||||||
|
|
||||||
void nm_device_take_down (NMDevice *self, gboolean block);
|
void nm_device_take_down (NMDevice *self, gboolean block);
|
||||||
|
|
||||||
gboolean nm_device_set_hw_addr (NMDevice *device, const char *addr,
|
gboolean nm_device_hw_addr_set (NMDevice *device, const char *addr, const char *detail);
|
||||||
const char *detail, guint64 hw_log_domain);
|
gboolean nm_device_hw_addr_set_cloned (NMDevice *device, NMConnection *connection, gboolean is_wifi);
|
||||||
|
gboolean nm_device_hw_addr_reset (NMDevice *device, const char *detail);
|
||||||
|
|
||||||
void nm_device_set_firmware_missing (NMDevice *self, gboolean missing);
|
void nm_device_set_firmware_missing (NMDevice *self, gboolean missing);
|
||||||
|
|
||||||
|
@ -107,6 +108,8 @@ void nm_device_queue_recheck_available (NMDevice *device,
|
||||||
void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config);
|
void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config);
|
||||||
void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config);
|
void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config);
|
||||||
|
|
||||||
|
gboolean nm_device_hw_addr_is_explict (NMDevice *device);
|
||||||
|
|
||||||
void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason);
|
void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason);
|
||||||
|
|
||||||
gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value);
|
gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value);
|
||||||
|
|
|
@ -291,8 +291,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
NMDeviceTun *self = NM_DEVICE_TUN (device);
|
NMDeviceTun *self = NM_DEVICE_TUN (device);
|
||||||
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
|
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *cloned_mac;
|
|
||||||
NMActStageReturn ret;
|
NMActStageReturn ret;
|
||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
@ -305,12 +303,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
if (g_strcmp0 (priv->mode, "tap"))
|
if (g_strcmp0 (priv->mode, "tap"))
|
||||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
|
|
||||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED);
|
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
|
||||||
if (s_wired) {
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
/* Set device MAC address if the connection wants to change it */
|
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
|
||||||
nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
|
||||||
{
|
{
|
||||||
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
|
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *new_mac, *old_mac;
|
const char *new_mac, *old_mac;
|
||||||
NMSettingIPConfig *s_ip6;
|
NMSettingIPConfig *s_ip6;
|
||||||
|
|
||||||
|
@ -100,11 +99,8 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Update the VLAN MAC only if configuration does not specify one */
|
/* Update the VLAN MAC only if configuration does not specify one */
|
||||||
s_wired = nm_connection_get_setting_wired (connection);
|
if (nm_device_hw_addr_is_explict (self))
|
||||||
if (s_wired) {
|
return;
|
||||||
if (nm_setting_wired_get_cloned_mac_address (s_wired))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
old_mac = nm_device_get_hw_address (self);
|
old_mac = nm_device_get_hw_address (self);
|
||||||
new_mac = nm_device_get_hw_address (parent);
|
new_mac = nm_device_get_hw_address (parent);
|
||||||
|
@ -114,7 +110,7 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
|
||||||
_LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s",
|
_LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s",
|
||||||
NM_PRINT_FMT_QUOTE_STRING (new_mac));
|
NM_PRINT_FMT_QUOTE_STRING (new_mac));
|
||||||
if (new_mac) {
|
if (new_mac) {
|
||||||
nm_device_set_hw_addr (self, new_mac, "set", LOGD_VLAN);
|
nm_device_hw_addr_set (self, new_mac, "vlan-parent");
|
||||||
/* When changing the hw address the interface is taken down,
|
/* When changing the hw address the interface is taken down,
|
||||||
* removing the IPv6 configuration; reapply it.
|
* removing the IPv6 configuration; reapply it.
|
||||||
*/
|
*/
|
||||||
|
@ -378,21 +374,25 @@ match_parent (NMDeviceVlan *self, const char *parent)
|
||||||
static gboolean
|
static gboolean
|
||||||
match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr)
|
match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr)
|
||||||
{
|
{
|
||||||
NMSettingWired *s_wired;
|
NMDeviceVlanPrivate *priv;
|
||||||
const char *setting_mac;
|
NMSettingWired *s_wired;
|
||||||
const char *device_mac;
|
const char *setting_mac;
|
||||||
|
const char *parent_mac;
|
||||||
|
|
||||||
s_wired = nm_connection_get_setting_wired (connection);
|
s_wired = nm_connection_get_setting_wired (connection);
|
||||||
if (!s_wired)
|
if (!s_wired)
|
||||||
return !fail_if_no_hwaddr;
|
return !fail_if_no_hwaddr;
|
||||||
|
|
||||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (!setting_mac)
|
if (!setting_mac)
|
||||||
return !fail_if_no_hwaddr;
|
return !fail_if_no_hwaddr;
|
||||||
|
|
||||||
device_mac = nm_device_get_hw_address (device);
|
priv = NM_DEVICE_VLAN_GET_PRIVATE (device);
|
||||||
|
if (!priv->parent)
|
||||||
|
return !fail_if_no_hwaddr;
|
||||||
|
|
||||||
return nm_utils_hwaddr_matches (setting_mac, -1, device_mac, -1);
|
parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE);
|
||||||
|
return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -550,8 +550,6 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (dev);
|
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (dev);
|
||||||
NMSettingVlan *s_vlan;
|
NMSettingVlan *s_vlan;
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *cloned_mac;
|
|
||||||
NMActStageReturn ret;
|
NMActStageReturn ret;
|
||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
@ -560,12 +558,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||||
if (s_wired) {
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
/* Set device MAC address if the connection wants to change it */
|
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
|
||||||
nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change MAC address to parent's one if needed */
|
/* Change MAC address to parent's one if needed */
|
||||||
if (priv->parent)
|
if (priv->parent)
|
||||||
|
@ -619,14 +613,6 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
deactivate (NMDevice *device)
|
|
||||||
{
|
|
||||||
/* Reset MAC address back to initial address */
|
|
||||||
if (nm_device_get_initial_hw_address (device))
|
|
||||||
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_VLAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -690,7 +676,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
||||||
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;
|
||||||
parent_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
parent_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
||||||
parent_class->deactivate = deactivate;
|
|
||||||
parent_class->is_available = is_available;
|
parent_class->is_available = is_available;
|
||||||
parent_class->notify_new_device_added = notify_new_device_added;
|
parent_class->notify_new_device_added = notify_new_device_added;
|
||||||
|
|
||||||
|
|
|
@ -511,8 +511,6 @@ update_connection (NMDevice *device, NMConnection *connection)
|
||||||
static NMActStageReturn
|
static NMActStageReturn
|
||||||
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
{
|
{
|
||||||
NMSettingWired *s_wired;
|
|
||||||
const char *cloned_mac;
|
|
||||||
NMActStageReturn ret;
|
NMActStageReturn ret;
|
||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
@ -521,12 +519,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED);
|
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
|
||||||
if (s_wired) {
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
/* Set device MAC address if the connection wants to change it */
|
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
|
||||||
nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
|
||||||
PROP_IS_MASTER,
|
PROP_IS_MASTER,
|
||||||
PROP_MASTER,
|
PROP_MASTER,
|
||||||
PROP_HW_ADDRESS,
|
PROP_HW_ADDRESS,
|
||||||
|
PROP_PERM_HW_ADDRESS,
|
||||||
PROP_HAS_PENDING_ACTION,
|
PROP_HAS_PENDING_ACTION,
|
||||||
PROP_METERED,
|
PROP_METERED,
|
||||||
PROP_LLDP_NEIGHBORS,
|
PROP_LLDP_NEIGHBORS,
|
||||||
|
@ -208,6 +209,13 @@ typedef struct {
|
||||||
NMIP4Config **configs;
|
NMIP4Config **configs;
|
||||||
} ArpingData;
|
} ArpingData;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HW_ADDR_TYPE_UNSET = 0,
|
||||||
|
HW_ADDR_TYPE_PERMANENT,
|
||||||
|
HW_ADDR_TYPE_EXPLICIT,
|
||||||
|
HW_ADDR_TYPE_GENERATED,
|
||||||
|
} HwAddrType;
|
||||||
|
|
||||||
typedef struct _NMDevicePrivate {
|
typedef struct _NMDevicePrivate {
|
||||||
bool in_state_changed;
|
bool in_state_changed;
|
||||||
|
|
||||||
|
@ -225,7 +233,12 @@ typedef struct _NMDevicePrivate {
|
||||||
char * udi;
|
char * udi;
|
||||||
char * iface; /* may change, could be renamed by user */
|
char * iface; /* may change, could be renamed by user */
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
|
guint hw_addr_len;
|
||||||
|
guint8 /*HwAddrType*/ hw_addr_type;
|
||||||
|
|
||||||
bool real;
|
bool real;
|
||||||
|
|
||||||
char * ip_iface;
|
char * ip_iface;
|
||||||
int ip_ifindex;
|
int ip_ifindex;
|
||||||
NMDeviceType type;
|
NMDeviceType type;
|
||||||
|
@ -237,13 +250,13 @@ typedef struct _NMDevicePrivate {
|
||||||
char * driver_version;
|
char * driver_version;
|
||||||
char * firmware_version;
|
char * firmware_version;
|
||||||
RfKillType rfkill_type;
|
RfKillType rfkill_type;
|
||||||
bool firmware_missing;
|
bool firmware_missing:1;
|
||||||
bool nm_plugin_missing;
|
bool nm_plugin_missing:1;
|
||||||
|
bool hw_addr_perm_fake:1; /* whether the permanent HW address could not be read and is a fake */
|
||||||
GHashTable * available_connections;
|
GHashTable * available_connections;
|
||||||
char * hw_addr;
|
char * hw_addr;
|
||||||
guint hw_addr_len;
|
char * hw_addr_perm;
|
||||||
char * perm_hw_addr;
|
char * hw_addr_initial;
|
||||||
char * initial_hw_addr;
|
|
||||||
char * physical_port_id;
|
char * physical_port_id;
|
||||||
guint dev_id;
|
guint dev_id;
|
||||||
|
|
||||||
|
@ -616,6 +629,30 @@ _add_capabilities (NMDevice *self, NMDeviceCapabilities capabilities)
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_get_stable_id (NMConnection *connection, NMUtilsStableType *out_stable_type)
|
||||||
|
{
|
||||||
|
NMSettingConnection *s_con;
|
||||||
|
const char *stable_id;
|
||||||
|
|
||||||
|
nm_assert (NM_IS_CONNECTION (connection));
|
||||||
|
nm_assert (out_stable_type);
|
||||||
|
|
||||||
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
|
g_return_val_if_fail (s_con, NULL);
|
||||||
|
|
||||||
|
stable_id = nm_setting_connection_get_stable_id (s_con);
|
||||||
|
if (!stable_id) {
|
||||||
|
*out_stable_type = NM_UTILS_STABLE_TYPE_UUID;
|
||||||
|
return nm_connection_get_uuid (connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_stable_type = NM_UTILS_STABLE_TYPE_STABLE_ID;
|
||||||
|
return stable_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
nm_device_get_udi (NMDevice *self)
|
nm_device_get_udi (NMDevice *self)
|
||||||
{
|
{
|
||||||
|
@ -1106,7 +1143,11 @@ nm_device_get_settings_connection (NMDevice *self)
|
||||||
NMConnection *
|
NMConnection *
|
||||||
nm_device_get_applied_connection (NMDevice *self)
|
nm_device_get_applied_connection (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL;
|
return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL;
|
||||||
}
|
}
|
||||||
|
@ -1123,23 +1164,12 @@ nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFla
|
||||||
}
|
}
|
||||||
|
|
||||||
NMSetting *
|
NMSetting *
|
||||||
nm_device_get_applied_setting (NMDevice *device, GType setting_type)
|
nm_device_get_applied_setting (NMDevice *self, GType setting_type)
|
||||||
{
|
{
|
||||||
NMActRequest *req;
|
NMConnection *connection;
|
||||||
NMSetting *setting = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
|
connection = nm_device_get_applied_connection (self);
|
||||||
|
return connection ? nm_connection_get_setting (connection, setting_type) : NULL;
|
||||||
req = nm_device_get_act_request (device);
|
|
||||||
if (req) {
|
|
||||||
NMConnection *connection;
|
|
||||||
|
|
||||||
connection = nm_act_request_get_applied_connection (req);
|
|
||||||
if (connection)
|
|
||||||
setting = nm_connection_get_setting (connection, setting_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return setting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RfKillType
|
RfKillType
|
||||||
|
@ -1647,6 +1677,7 @@ device_link_changed (NMDevice *self)
|
||||||
int ifindex;
|
int ifindex;
|
||||||
gboolean was_up;
|
gboolean was_up;
|
||||||
gboolean update_unmanaged_specs = FALSE;
|
gboolean update_unmanaged_specs = FALSE;
|
||||||
|
gboolean got_hw_addr = FALSE, had_hw_addr;
|
||||||
|
|
||||||
priv->device_link_changed_id = 0;
|
priv->device_link_changed_id = 0;
|
||||||
|
|
||||||
|
@ -1684,6 +1715,11 @@ device_link_changed (NMDevice *self)
|
||||||
_notify (self, PROP_DRIVER);
|
_notify (self, PROP_DRIVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
had_hw_addr = (priv->hw_addr != NULL);
|
||||||
|
nm_device_update_hw_address (self);
|
||||||
|
got_hw_addr = (!had_hw_addr && priv->hw_addr);
|
||||||
|
nm_device_update_permanent_hw_address (self);
|
||||||
|
|
||||||
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
|
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
|
||||||
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
||||||
priv->ifindex, priv->iface, info.name);
|
priv->ifindex, priv->iface, info.name);
|
||||||
|
@ -1775,6 +1811,20 @@ device_link_changed (NMDevice *self)
|
||||||
if (update_unmanaged_specs)
|
if (update_unmanaged_specs)
|
||||||
nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
|
nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
|
||||||
|
|
||||||
|
if ( got_hw_addr
|
||||||
|
&& !priv->up
|
||||||
|
&& nm_device_get_state (self) == 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 (self,
|
||||||
|
NM_DEVICE_STATE_REASON_NONE,
|
||||||
|
NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2123,6 +2173,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
|
||||||
|
|
||||||
nm_device_update_hw_address (self);
|
nm_device_update_hw_address (self);
|
||||||
nm_device_update_initial_hw_address (self);
|
nm_device_update_initial_hw_address (self);
|
||||||
|
nm_device_update_permanent_hw_address (self);
|
||||||
|
|
||||||
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
|
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
|
||||||
config = nm_config_get ();
|
config = nm_config_get ();
|
||||||
|
@ -2308,6 +2359,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
||||||
_notify (self, PROP_UDI);
|
_notify (self, PROP_UDI);
|
||||||
}
|
}
|
||||||
if (priv->hw_addr) {
|
if (priv->hw_addr) {
|
||||||
|
priv->hw_addr_len = 0;
|
||||||
g_clear_pointer (&priv->hw_addr, g_free);
|
g_clear_pointer (&priv->hw_addr, g_free);
|
||||||
_notify (self, PROP_HW_ADDRESS);
|
_notify (self, PROP_HW_ADDRESS);
|
||||||
}
|
}
|
||||||
|
@ -2316,8 +2368,10 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
||||||
_notify (self, PROP_PHYSICAL_PORT_ID);
|
_notify (self, PROP_PHYSICAL_PORT_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_pointer (&priv->perm_hw_addr, g_free);
|
priv->hw_addr_type = HW_ADDR_TYPE_UNSET;
|
||||||
g_clear_pointer (&priv->initial_hw_addr, g_free);
|
g_clear_pointer (&priv->hw_addr_perm, g_free);
|
||||||
|
_notify (self, PROP_PERM_HW_ADDRESS);
|
||||||
|
g_clear_pointer (&priv->hw_addr_initial, g_free);
|
||||||
|
|
||||||
priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
|
priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
|
||||||
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
|
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
|
||||||
|
@ -3308,7 +3362,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave
|
||||||
static gboolean
|
static gboolean
|
||||||
nm_device_can_assume_connections (NMDevice *self)
|
nm_device_can_assume_connections (NMDevice *self)
|
||||||
{
|
{
|
||||||
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
|
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3324,7 +3378,7 @@ nm_device_can_assume_connections (NMDevice *self)
|
||||||
* if there is no active connection or the active connection cannot be
|
* if there is no active connection or the active connection cannot be
|
||||||
* assumed.
|
* assumed.
|
||||||
*/
|
*/
|
||||||
gboolean
|
static gboolean
|
||||||
nm_device_can_assume_active_connection (NMDevice *self)
|
nm_device_can_assume_active_connection (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
@ -3371,6 +3425,45 @@ nm_device_can_assume_active_connection (NMDevice *self)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
unmanaged_on_quit (NMDevice *self)
|
||||||
|
{
|
||||||
|
/* Leave certain devices alone when quitting so their configuration
|
||||||
|
* can be taken over when NM restarts. This ensures connectivity while
|
||||||
|
* NM is stopped.
|
||||||
|
*/
|
||||||
|
if (nm_device_uses_assumed_connection (self)) {
|
||||||
|
/* An assume connection must be left alone */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nm_device_get_act_request (self)) {
|
||||||
|
/* a device without any active connection is either UNAVAILABLE or DISCONNECTED
|
||||||
|
* state. Since we don't know whether the device was upped by NetworkManager,
|
||||||
|
* we must leave it up on exit.
|
||||||
|
*/
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (self))) {
|
||||||
|
/* The device has no layer 3 configuration. Leave it up. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nm_device_can_assume_active_connection (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_device_unmanage_on_quit (NMDevice *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||||
|
|
||||||
|
return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
nm_device_emit_recheck_assume (gpointer user_data)
|
nm_device_emit_recheck_assume (gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -5859,11 +5952,17 @@ check_and_add_ipv6ll_addr (NMDevice *self)
|
||||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
|
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
|
||||||
|
|
||||||
if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
|
if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
|
||||||
if (!nm_utils_ipv6_addr_set_stable_privacy (&lladdr,
|
NMUtilsStableType stable_type;
|
||||||
nm_device_get_iface (self),
|
const char *stable_id;
|
||||||
nm_connection_get_uuid (connection),
|
|
||||||
priv->linklocal6_dad_counter++,
|
stable_id = _get_stable_id (connection, &stable_type);
|
||||||
&error)) {
|
if ( !stable_id
|
||||||
|
|| !nm_utils_ipv6_addr_set_stable_privacy (stable_type,
|
||||||
|
&lladdr,
|
||||||
|
nm_device_get_iface (self),
|
||||||
|
stable_id,
|
||||||
|
priv->linklocal6_dad_counter++,
|
||||||
|
&error)) {
|
||||||
_LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
|
_LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
linklocal6_failed (self);
|
linklocal6_failed (self);
|
||||||
|
@ -6205,6 +6304,8 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
|
||||||
NMActStageReturn ret;
|
NMActStageReturn ret;
|
||||||
NMSettingIP6Config *s_ip6 = NULL;
|
NMSettingIP6Config *s_ip6 = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
NMUtilsStableType stable_type;
|
||||||
|
const char *stable_id;
|
||||||
|
|
||||||
connection = nm_device_get_applied_connection (self);
|
connection = nm_device_get_applied_connection (self);
|
||||||
g_assert (connection);
|
g_assert (connection);
|
||||||
|
@ -6218,12 +6319,16 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
|
||||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
|
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
|
||||||
g_assert (s_ip6);
|
g_assert (s_ip6);
|
||||||
|
|
||||||
priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
stable_id = _get_stable_id (connection, &stable_type);
|
||||||
nm_device_get_ip_ifindex (self),
|
if (stable_id) {
|
||||||
nm_device_get_ip_iface (self),
|
priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||||
nm_connection_get_uuid (connection),
|
nm_device_get_ip_ifindex (self),
|
||||||
nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
|
nm_device_get_ip_iface (self),
|
||||||
&error);
|
stable_type,
|
||||||
|
stable_id,
|
||||||
|
nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
|
||||||
|
&error);
|
||||||
|
}
|
||||||
if (!priv->rdisc) {
|
if (!priv->rdisc) {
|
||||||
_LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message);
|
_LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
@ -10548,6 +10653,8 @@ 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);
|
||||||
|
@ -10622,6 +10729,8 @@ nm_device_spawn_iface_helper (NMDevice *self)
|
||||||
GPtrArray *argv;
|
GPtrArray *argv;
|
||||||
gs_free char *dhcp4_address = NULL;
|
gs_free char *dhcp4_address = NULL;
|
||||||
char *logging_backend;
|
char *logging_backend;
|
||||||
|
NMUtilsStableType stable_type;
|
||||||
|
const char *stable_id;
|
||||||
|
|
||||||
if (priv->state != NM_DEVICE_STATE_ACTIVATED)
|
if (priv->state != NM_DEVICE_STATE_ACTIVATED)
|
||||||
return;
|
return;
|
||||||
|
@ -10640,6 +10749,12 @@ nm_device_spawn_iface_helper (NMDevice *self)
|
||||||
g_ptr_array_add (argv, g_strdup ("--uuid"));
|
g_ptr_array_add (argv, g_strdup ("--uuid"));
|
||||||
g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection)));
|
g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection)));
|
||||||
|
|
||||||
|
stable_id = _get_stable_id (connection, &stable_type);
|
||||||
|
if (stable_id && stable_type != NM_UTILS_STABLE_TYPE_UUID) {
|
||||||
|
g_ptr_array_add (argv, g_strdup ("--stable-id"));
|
||||||
|
g_ptr_array_add (argv, g_strdup_printf ("%d %s", (int) stable_type, stable_id));
|
||||||
|
}
|
||||||
|
|
||||||
logging_backend = nm_config_get_is_debug (nm_config_get ())
|
logging_backend = nm_config_get_is_debug (nm_config_get ())
|
||||||
? g_strdup ("debug")
|
? g_strdup ("debug")
|
||||||
: nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
|
: nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
|
||||||
|
@ -10935,6 +11050,7 @@ _set_state_full (NMDevice *self,
|
||||||
if (nm_device_get_act_request (self))
|
if (nm_device_get_act_request (self))
|
||||||
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
|
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
|
||||||
nm_device_take_down (self, TRUE);
|
nm_device_take_down (self, TRUE);
|
||||||
|
nm_device_hw_addr_reset (self, "unmanage");
|
||||||
set_nm_ipv6ll (self, FALSE);
|
set_nm_ipv6ll (self, FALSE);
|
||||||
restore_ip6_properties (self);
|
restore_ip6_properties (self);
|
||||||
}
|
}
|
||||||
|
@ -10982,6 +11098,9 @@ _set_state_full (NMDevice *self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NM_DEVICE_STATE_PREPARE:
|
||||||
|
nm_device_update_initial_hw_address (self);
|
||||||
|
break;
|
||||||
case NM_DEVICE_STATE_NEED_AUTH:
|
case NM_DEVICE_STATE_NEED_AUTH:
|
||||||
if (old_state > NM_DEVICE_STATE_NEED_AUTH) {
|
if (old_state > NM_DEVICE_STATE_NEED_AUTH) {
|
||||||
/* Clean up any half-done IP operations if the device's layer2
|
/* Clean up any half-done IP operations if the device's layer2
|
||||||
|
@ -11300,23 +11419,26 @@ nm_device_get_hw_address (NMDevice *self)
|
||||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
return priv->hw_addr_len ? priv->hw_addr : NULL;
|
nm_assert ((!priv->hw_addr) ^ (priv->hw_addr_len > 0));
|
||||||
|
|
||||||
|
return priv->hw_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_device_update_hw_address (NMDevice *self)
|
nm_device_update_hw_address (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv;
|
||||||
int ifindex = nm_device_get_ifindex (self);
|
|
||||||
const guint8 *hwaddr;
|
const guint8 *hwaddr;
|
||||||
gsize hwaddrlen = 0;
|
gsize hwaddrlen = 0;
|
||||||
|
|
||||||
if (ifindex <= 0)
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
if (priv->ifindex <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen);
|
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &hwaddrlen);
|
||||||
|
|
||||||
if ( priv->type == NM_DEVICE_TYPE_ETHERNET
|
if ( priv->type == NM_DEVICE_TYPE_ETHERNET
|
||||||
|
&& hwaddr
|
||||||
&& nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth)))
|
&& nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth)))
|
||||||
hwaddrlen = 0;
|
hwaddrlen = 0;
|
||||||
|
|
||||||
|
@ -11326,17 +11448,28 @@ nm_device_update_hw_address (NMDevice *self)
|
||||||
g_free (priv->hw_addr);
|
g_free (priv->hw_addr);
|
||||||
priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
|
priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
|
||||||
|
|
||||||
_LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr);
|
_LOGD (LOGD_HW | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr);
|
||||||
_notify (self, PROP_HW_ADDRESS);
|
_notify (self, PROP_HW_ADDRESS);
|
||||||
|
|
||||||
|
if ( !priv->hw_addr_initial
|
||||||
|
|| ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET
|
||||||
|
&& priv->state < NM_DEVICE_STATE_PREPARE
|
||||||
|
&& !nm_device_is_activating (self))) {
|
||||||
|
/* when we get a hw_addr the first time or while the device
|
||||||
|
* is not activated (with no explict hw address set), always
|
||||||
|
* update our inital hw-address as well. */
|
||||||
|
nm_device_update_initial_hw_address (self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Invalid or no hardware address */
|
/* Invalid or no hardware address */
|
||||||
if (priv->hw_addr_len != 0) {
|
if (priv->hw_addr_len != 0) {
|
||||||
g_clear_pointer (&priv->hw_addr, g_free);
|
|
||||||
priv->hw_addr_len = 0;
|
|
||||||
_LOGD (LOGD_HW | LOGD_DEVICE,
|
_LOGD (LOGD_HW | LOGD_DEVICE,
|
||||||
"previous hardware address is no longer valid");
|
"hw-addr: failed reading current MAC address (stay with %s)",
|
||||||
_notify (self, PROP_HW_ADDRESS);
|
priv->hw_addr);
|
||||||
|
} else {
|
||||||
|
_LOGD (LOGD_HW | LOGD_DEVICE,
|
||||||
|
"hw-addr: failed reading current MAC address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11346,84 +11479,361 @@ nm_device_update_initial_hw_address (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
if (priv->hw_addr_len) {
|
if ( priv->hw_addr
|
||||||
priv->initial_hw_addr = g_strdup (priv->hw_addr);
|
&& !nm_streq0 (priv->hw_addr_initial, priv->hw_addr)) {
|
||||||
_LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
|
if ( priv->hw_addr_initial
|
||||||
|
&& priv->hw_addr_type != HW_ADDR_TYPE_UNSET) {
|
||||||
if (priv->ifindex > 0) {
|
/* once we have the initial hw address set, we only allow
|
||||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
* update if the currenty type is "unset". */
|
||||||
size_t len = 0;
|
return;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
g_free (priv->hw_addr_initial);
|
||||||
|
priv->hw_addr_initial = g_strdup (priv->hw_addr);
|
||||||
|
_LOGD (LOGD_DEVICE, "hw-addr: update initial MAC address %s",
|
||||||
|
priv->hw_addr_initial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
void
|
||||||
nm_device_set_hw_addr (NMDevice *self, const char *addr,
|
nm_device_update_permanent_hw_address (NMDevice *self)
|
||||||
const char *detail, guint64 hw_log_domain)
|
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
gboolean success = FALSE;
|
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||||
const char *cur_addr = nm_device_get_hw_address (self);
|
size_t len = 0;
|
||||||
guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
|
gboolean success_read;
|
||||||
|
|
||||||
/* Fall back to the permanent address */
|
if (priv->hw_addr_perm) {
|
||||||
if (!addr)
|
/* the permanent hardware address is only read once and not
|
||||||
addr = priv->perm_hw_addr;
|
* re-read later.
|
||||||
if (!addr)
|
*
|
||||||
return FALSE;
|
* Except during unrealize/realize cycles, where we clear the permanent
|
||||||
|
* hardware address during unrealization. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->ifindex <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!priv->hw_addr_len) {
|
||||||
|
nm_device_update_hw_address (self);
|
||||||
|
if (!priv->hw_addr_len)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len);
|
||||||
|
if (!success_read || len != priv->hw_addr_len) {
|
||||||
|
/* Fall back to current address. We use the fake address and keep it
|
||||||
|
* until the device unrealizes.
|
||||||
|
*
|
||||||
|
* In some cases it might be necessary to know whether this is a "real" or
|
||||||
|
* a temporary address (fake). */
|
||||||
|
_LOGD (LOGD_HW | LOGD_ETHER, "hw-addr: %s (use current: %s)",
|
||||||
|
success_read
|
||||||
|
? "unable to read permanent MAC address"
|
||||||
|
: "read HW addr length of permanent MAC address differs",
|
||||||
|
priv->hw_addr);
|
||||||
|
priv->hw_addr_perm_fake = TRUE;
|
||||||
|
priv->hw_addr_perm = g_strdup (priv->hw_addr);
|
||||||
|
} else {
|
||||||
|
priv->hw_addr_perm_fake = FALSE;
|
||||||
|
priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len);
|
||||||
|
_LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'",
|
||||||
|
priv->hw_addr_perm);
|
||||||
|
}
|
||||||
|
_notify (self, PROP_PERM_HW_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_get_cloned_mac_address_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_addr)
|
||||||
|
{
|
||||||
|
NMSetting *setting;
|
||||||
|
const char *addr = NULL;
|
||||||
|
|
||||||
|
nm_assert (out_addr && !*out_addr);
|
||||||
|
|
||||||
|
setting = nm_connection_get_setting (connection,
|
||||||
|
is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED);
|
||||||
|
if (setting) {
|
||||||
|
addr = is_wifi
|
||||||
|
? nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) setting)
|
||||||
|
: nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!addr) {
|
||||||
|
gs_free char *a = NULL;
|
||||||
|
|
||||||
|
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
|
||||||
|
is_wifi ? "wifi.cloned-mac-address" : "ethernet.cloned-mac-address",
|
||||||
|
self);
|
||||||
|
/* default is permanent. */
|
||||||
|
addr = NM_CLONED_MAC_PERMANENT;
|
||||||
|
|
||||||
|
if (!a) {
|
||||||
|
if (is_wifi) {
|
||||||
|
NMSettingMacRandomization v;
|
||||||
|
|
||||||
|
/* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */
|
||||||
|
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
|
||||||
|
"wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
|
||||||
|
self);
|
||||||
|
v = _nm_utils_ascii_str_to_int64 (a, 10,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_ALWAYS,
|
||||||
|
NM_SETTING_MAC_RANDOMIZATION_DEFAULT);
|
||||||
|
if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS)
|
||||||
|
addr = NM_CLONED_MAC_RANDOM;
|
||||||
|
}
|
||||||
|
} else if ( NM_CLONED_MAC_IS_SPECIAL (a)
|
||||||
|
|| nm_utils_hwaddr_valid (a, ETH_ALEN))
|
||||||
|
addr = *out_addr = g_steal_pointer (&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_get_generate_mac_address_mask_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_value)
|
||||||
|
{
|
||||||
|
NMSetting *setting;
|
||||||
|
const char *value = NULL;
|
||||||
|
char *a;
|
||||||
|
|
||||||
|
nm_assert (out_value && !*out_value);
|
||||||
|
|
||||||
|
setting = nm_connection_get_setting (connection,
|
||||||
|
is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED);
|
||||||
|
if (setting) {
|
||||||
|
value = is_wifi
|
||||||
|
? nm_setting_wireless_get_generate_mac_address_mask ((NMSettingWireless *) setting)
|
||||||
|
: nm_setting_wired_get_generate_mac_address_mask ((NMSettingWired *) setting);
|
||||||
|
if (value)
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
|
||||||
|
is_wifi ? "wifi.generate-mac-address-mask" : "ethernet.generate-mac-mac-address-mask",
|
||||||
|
self);
|
||||||
|
if (!a)
|
||||||
|
return NULL;
|
||||||
|
*out_value = a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_device_hw_addr_is_explict (NMDevice *self)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
return !NM_IN_SET (priv->hw_addr_type, HW_ADDR_TYPE_PERMANENT, HW_ADDR_TYPE_UNSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_hw_addr_set (NMDevice *self,
|
||||||
|
const char *addr,
|
||||||
|
const char *operation,
|
||||||
|
const char *detail)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
const char *cur_addr;
|
||||||
|
guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
|
||||||
|
guint hw_addr_len;
|
||||||
|
gboolean was_up;
|
||||||
|
|
||||||
|
nm_assert (NM_IS_DEVICE (self));
|
||||||
|
nm_assert (addr);
|
||||||
|
nm_assert (operation);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
cur_addr = nm_device_get_hw_address (self);
|
||||||
|
|
||||||
/* Do nothing if current MAC is same */
|
/* Do nothing if current MAC is same */
|
||||||
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
||||||
_LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed");
|
_LOGD (LOGD_DEVICE, "set-hw-addr: no MAC address change needed");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) {
|
|
||||||
_LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr);
|
hw_addr_len = priv->hw_addr_len;
|
||||||
return FALSE;
|
if (!hw_addr_len)
|
||||||
|
hw_addr_len = _nm_utils_hwaddr_length (addr);
|
||||||
|
if ( !hw_addr_len
|
||||||
|
|| !nm_utils_hwaddr_aton (addr, addr_bytes, hw_addr_len))
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
|
||||||
|
_LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail);
|
||||||
|
|
||||||
|
was_up = nm_device_is_up (self);
|
||||||
|
if (was_up) {
|
||||||
|
/* Can't change MAC address while device is up */
|
||||||
|
nm_device_take_down (self, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can't change MAC address while device is up */
|
success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, hw_addr_len);
|
||||||
nm_device_take_down (self, FALSE);
|
|
||||||
|
|
||||||
success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len);
|
|
||||||
if (success) {
|
if (success) {
|
||||||
/* MAC address succesfully changed; update the current MAC to match */
|
/* MAC address succesfully changed; update the current MAC to match */
|
||||||
nm_device_update_hw_address (self);
|
nm_device_update_hw_address (self);
|
||||||
cur_addr = nm_device_get_hw_address (self);
|
cur_addr = nm_device_get_hw_address (self);
|
||||||
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
||||||
_LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s",
|
_LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
|
||||||
detail, addr);
|
operation, addr, detail);
|
||||||
} else {
|
} else {
|
||||||
_LOGW (LOGD_DEVICE | hw_log_domain,
|
_LOGW (LOGD_DEVICE,
|
||||||
"new MAC address %s not successfully set", addr);
|
"set-hw-addr: new MAC address %s not successfully set to %s (%s)",
|
||||||
|
addr, operation, detail);
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s",
|
_LOGW (LOGD_DEVICE, "set-hw-addr: failed to %s MAC address to %s (%s)",
|
||||||
detail, addr);
|
operation, addr, detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (was_up) {
|
||||||
|
if (!nm_device_bring_up (self, TRUE, NULL))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
nm_device_bring_up (self, TRUE, NULL);
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
gboolean
|
||||||
nm_device_get_permanent_hw_address (NMDevice *self)
|
nm_device_hw_addr_set (NMDevice *self, const char *addr, const char *detail)
|
||||||
{
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (!addr)
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
|
||||||
|
/* this is called by NMDeviceVlan to take the MAC address from the parent
|
||||||
|
* and by NMDeviceWifi to set a random MAC address during scanning.
|
||||||
|
* In this case, it's like setting it to PERMANENT. */
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT;
|
||||||
|
|
||||||
|
return _hw_addr_set (self, addr, "set", detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean is_wifi)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
gs_free char *hw_addr_tmp = NULL;
|
||||||
|
gs_free char *hw_addr_generated = NULL;
|
||||||
|
gs_free char *generate_mac_address_mask_tmp = NULL;
|
||||||
|
const char *addr, *addr_setting;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (!connection)
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
|
||||||
|
addr = addr_setting = _get_cloned_mac_address_setting (self, connection, is_wifi, &hw_addr_tmp);
|
||||||
|
|
||||||
|
if (nm_streq (addr, NM_CLONED_MAC_PRESERVE)) {
|
||||||
|
/* "preserve" means to reset the initial MAC address. */
|
||||||
|
return nm_device_hw_addr_reset (self, addr_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nm_streq (addr, NM_CLONED_MAC_PERMANENT)) {
|
||||||
|
addr = nm_device_get_permanent_hw_address (self, TRUE);
|
||||||
|
if (!addr)
|
||||||
|
return FALSE;
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT;
|
||||||
|
} else if (NM_IN_STRSET (addr, NM_CLONED_MAC_RANDOM)) {
|
||||||
|
if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) {
|
||||||
|
/* hm, we already use a generate MAC address. Most certainly, that is from the same
|
||||||
|
* activation request, so we should not create a new random address, instead keep
|
||||||
|
* the current. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
hw_addr_generated = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (self),
|
||||||
|
_get_generate_mac_address_mask_setting (self, connection, is_wifi, &generate_mac_address_mask_tmp));
|
||||||
|
if (!hw_addr_generated) {
|
||||||
|
_LOGW (LOGD_DEVICE, "set-hw-addr: failed to generate %s MAC address", "random");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_GENERATED;
|
||||||
|
addr = hw_addr_generated;
|
||||||
|
} else if (NM_IN_STRSET (addr, NM_CLONED_MAC_STABLE)) {
|
||||||
|
NMUtilsStableType stable_type;
|
||||||
|
const char *stable_id;
|
||||||
|
|
||||||
|
if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) {
|
||||||
|
/* hm, we already use a generate MAC address. Most certainly, that is from the same
|
||||||
|
* activation request, so let's skip creating the stable address anew. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
stable_id = _get_stable_id (connection, &stable_type);
|
||||||
|
if (stable_id) {
|
||||||
|
hw_addr_generated = nm_utils_hw_addr_gen_stable_eth (stable_type, stable_id,
|
||||||
|
nm_device_get_ip_iface (self),
|
||||||
|
nm_device_get_initial_hw_address (self),
|
||||||
|
_get_generate_mac_address_mask_setting (self, connection, is_wifi, &generate_mac_address_mask_tmp));
|
||||||
|
}
|
||||||
|
if (!hw_addr_generated) {
|
||||||
|
_LOGW (LOGD_DEVICE, "set-hw-addr: failed to generate %s MAC address", "stable");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_GENERATED;
|
||||||
|
addr = hw_addr_generated;
|
||||||
|
} else {
|
||||||
|
/* this must be a valid address. Otherwise, we shouldn't come here. */
|
||||||
|
if (_nm_utils_hwaddr_length (addr) <= 0) {
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_EXPLICIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _hw_addr_set (self, addr, "set-cloned", addr_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_device_hw_addr_reset (NMDevice *self, const char *detail)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
const char *addr;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||||
|
|
||||||
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (priv->hw_addr_type == HW_ADDR_TYPE_UNSET)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
priv->hw_addr_type = HW_ADDR_TYPE_UNSET;
|
||||||
|
addr = nm_device_get_initial_hw_address (self);
|
||||||
|
if (!addr) {
|
||||||
|
/* as hw_addr_type is not UNSET, we expect that we can get an
|
||||||
|
* initial address to which to reset. */
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _hw_addr_set (self, addr, "reset", detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_fake)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv;
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||||
|
|
||||||
return NM_DEVICE_GET_PRIVATE (self)->perm_hw_addr;
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
if (!priv->hw_addr_perm)
|
||||||
|
return NULL;
|
||||||
|
if ( priv->hw_addr_perm_fake
|
||||||
|
&& !fallback_fake)
|
||||||
|
return NULL;
|
||||||
|
return priv->hw_addr_perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -11431,7 +11841,7 @@ nm_device_get_initial_hw_address (NMDevice *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||||
|
|
||||||
return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr;
|
return NM_DEVICE_GET_PRIVATE (self)->hw_addr_initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11469,9 +11879,9 @@ nm_device_spec_match_list (NMDevice *self, const GSList *specs)
|
||||||
static NMMatchSpecMatchType
|
static NMMatchSpecMatchType
|
||||||
spec_match_list (NMDevice *self, const GSList *specs)
|
spec_match_list (NMDevice *self, const GSList *specs)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
||||||
NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m;
|
NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m;
|
||||||
const GSList *iter;
|
const GSList *iter;
|
||||||
|
const char *hw_addr_perm;
|
||||||
|
|
||||||
for (iter = specs; iter; iter = g_slist_next (iter)) {
|
for (iter = specs; iter; iter = g_slist_next (iter)) {
|
||||||
if (!strcmp ((const char *) iter->data, "*")) {
|
if (!strcmp ((const char *) iter->data, "*")) {
|
||||||
|
@ -11479,8 +11889,10 @@ spec_match_list (NMDevice *self, const GSList *specs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (priv->hw_addr_len && priv->hw_addr) {
|
|
||||||
m = nm_match_spec_hwaddr (specs, priv->hw_addr);
|
hw_addr_perm = nm_device_get_permanent_hw_address (self, FALSE);
|
||||||
|
if (hw_addr_perm) {
|
||||||
|
m = nm_match_spec_hwaddr (specs, hw_addr_perm);
|
||||||
matched = MAX (matched, m);
|
matched = MAX (matched, m);
|
||||||
}
|
}
|
||||||
if (matched != NM_MATCH_SPEC_NEG_MATCH) {
|
if (matched != NM_MATCH_SPEC_NEG_MATCH) {
|
||||||
|
@ -11563,7 +11975,8 @@ constructor (GType type,
|
||||||
self = NM_DEVICE (object);
|
self = NM_DEVICE (object);
|
||||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
||||||
if (priv->iface) {
|
if ( priv->iface
|
||||||
|
&& G_LIKELY (!nm_utils_get_testing ())) {
|
||||||
pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
|
pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
|
||||||
|
|
||||||
if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) {
|
if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) {
|
||||||
|
@ -11572,6 +11985,17 @@ constructor (GType type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->hw_addr_perm) {
|
||||||
|
priv->hw_addr_len = _nm_utils_hwaddr_length (priv->hw_addr_perm);
|
||||||
|
if (!priv->hw_addr_len) {
|
||||||
|
g_clear_pointer (&priv->hw_addr_perm, g_free);
|
||||||
|
g_return_val_if_reached (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->hw_addr = g_strdup (priv->hw_addr_perm);
|
||||||
|
_LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm);
|
||||||
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11697,8 +12121,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->hw_addr_perm);
|
||||||
g_free (priv->initial_hw_addr);
|
g_free (priv->hw_addr_initial);
|
||||||
g_slist_free_full (priv->pending_actions, g_free);
|
g_slist_free_full (priv->pending_actions, g_free);
|
||||||
g_slist_free_full (priv->dad6_failed_addrs, g_free);
|
g_slist_free_full (priv->dad6_failed_addrs, g_free);
|
||||||
g_clear_pointer (&priv->physical_port_id, g_free);
|
g_clear_pointer (&priv->physical_port_id, g_free);
|
||||||
|
@ -11727,10 +12151,8 @@ static void
|
||||||
set_property (GObject *object, guint prop_id,
|
set_property (GObject *object, guint prop_id,
|
||||||
const GValue *value, GParamSpec *pspec)
|
const GValue *value, GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
NMDevice *self = NM_DEVICE (object);
|
NMDevice *self = (NMDevice *) object;
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
const char *hw_addr, *p;
|
|
||||||
guint count;
|
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_UDI:
|
case PROP_UDI:
|
||||||
|
@ -11808,32 +12230,9 @@ set_property (GObject *object, guint prop_id,
|
||||||
case PROP_IS_MASTER:
|
case PROP_IS_MASTER:
|
||||||
priv->is_master = g_value_get_boolean (value);
|
priv->is_master = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
case PROP_HW_ADDRESS:
|
case PROP_PERM_HW_ADDRESS:
|
||||||
/* construct only */
|
/* construct only */
|
||||||
p = hw_addr = g_value_get_string (value);
|
priv->hw_addr_perm = g_value_dup_string (value);
|
||||||
|
|
||||||
/* Hardware address length is the number of ':' plus 1 */
|
|
||||||
count = 1;
|
|
||||||
while (p && *p) {
|
|
||||||
if (*p++ == ':')
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) {
|
|
||||||
if (hw_addr && *hw_addr) {
|
|
||||||
_LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d",
|
|
||||||
hw_addr, count);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->hw_addr_len = count;
|
|
||||||
g_free (priv->hw_addr);
|
|
||||||
if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len))
|
|
||||||
priv->hw_addr = g_strdup (hw_addr);
|
|
||||||
else {
|
|
||||||
_LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr);
|
|
||||||
priv->hw_addr = NULL;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
@ -11956,6 +12355,10 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_HW_ADDRESS:
|
case PROP_HW_ADDRESS:
|
||||||
g_value_set_string (value, priv->hw_addr);
|
g_value_set_string (value, priv->hw_addr);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PERM_HW_ADDRESS:
|
||||||
|
/* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */
|
||||||
|
g_value_set_string (value, nm_device_get_permanent_hw_address (self, FALSE));
|
||||||
|
break;
|
||||||
case PROP_HAS_PENDING_ACTION:
|
case PROP_HAS_PENDING_ACTION:
|
||||||
g_value_set_boolean (value, nm_device_has_pending_action (self));
|
g_value_set_boolean (value, nm_device_has_pending_action (self));
|
||||||
break;
|
break;
|
||||||
|
@ -12041,6 +12444,7 @@ nm_device_class_init (NMDeviceClass *klass)
|
||||||
klass->take_down = take_down;
|
klass->take_down = take_down;
|
||||||
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;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
obj_properties[PROP_UDI] =
|
obj_properties[PROP_UDI] =
|
||||||
|
@ -12198,6 +12602,11 @@ nm_device_class_init (NMDeviceClass *klass)
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
obj_properties[PROP_HW_ADDRESS] =
|
obj_properties[PROP_HW_ADDRESS] =
|
||||||
g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "",
|
g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
obj_properties[PROP_PERM_HW_ADDRESS] =
|
||||||
|
g_param_spec_string (NM_DEVICE_PERM_HW_ADDRESS, "", "",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
|
@ -57,6 +57,11 @@
|
||||||
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
|
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
|
||||||
#define NM_DEVICE_MTU "mtu"
|
#define NM_DEVICE_MTU "mtu"
|
||||||
#define NM_DEVICE_HW_ADDRESS "hw-address"
|
#define NM_DEVICE_HW_ADDRESS "hw-address"
|
||||||
|
|
||||||
|
/* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet
|
||||||
|
* and NMDeviceWifi. */
|
||||||
|
#define NM_DEVICE_PERM_HW_ADDRESS "perm-hw-address"
|
||||||
|
|
||||||
#define NM_DEVICE_METERED "metered"
|
#define NM_DEVICE_METERED "metered"
|
||||||
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
|
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
|
||||||
#define NM_DEVICE_REAL "real"
|
#define NM_DEVICE_REAL "real"
|
||||||
|
@ -323,6 +328,8 @@ typedef struct {
|
||||||
gboolean (* owns_iface) (NMDevice *self, const char *iface);
|
gboolean (* owns_iface) (NMDevice *self, const char *iface);
|
||||||
|
|
||||||
NMConnection * (* new_default_connection) (NMDevice *self);
|
NMConnection * (* new_default_connection) (NMDevice *self);
|
||||||
|
|
||||||
|
gboolean (* unmanaged_on_quit) (NMDevice *self);
|
||||||
} NMDeviceClass;
|
} NMDeviceClass;
|
||||||
|
|
||||||
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
|
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
|
||||||
|
@ -353,7 +360,8 @@ 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_permanent_hw_address (NMDevice *dev,
|
||||||
|
gboolean fallback_fake);
|
||||||
const char * nm_device_get_initial_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);
|
||||||
|
@ -411,7 +419,7 @@ gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnec
|
||||||
|
|
||||||
gboolean nm_device_uses_assumed_connection (NMDevice *device);
|
gboolean nm_device_uses_assumed_connection (NMDevice *device);
|
||||||
|
|
||||||
gboolean nm_device_can_assume_active_connection (NMDevice *device);
|
gboolean nm_device_unmanage_on_quit (NMDevice *self);
|
||||||
|
|
||||||
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);
|
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);
|
||||||
|
|
||||||
|
@ -578,6 +586,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device,
|
||||||
|
|
||||||
void nm_device_update_hw_address (NMDevice *self);
|
void nm_device_update_hw_address (NMDevice *self);
|
||||||
void nm_device_update_initial_hw_address (NMDevice *self);
|
void nm_device_update_initial_hw_address (NMDevice *self);
|
||||||
|
void nm_device_update_permanent_hw_address (NMDevice *self);
|
||||||
void nm_device_update_dynamic_ip_setup (NMDevice *self);
|
void nm_device_update_dynamic_ip_setup (NMDevice *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -62,6 +62,8 @@ _LOG_DECLARE_SELF(NMDeviceWifi);
|
||||||
#define SCAN_INTERVAL_STEP 20
|
#define SCAN_INTERVAL_STEP 20
|
||||||
#define SCAN_INTERVAL_MAX 120
|
#define SCAN_INTERVAL_MAX 120
|
||||||
|
|
||||||
|
#define SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN 5
|
||||||
|
|
||||||
#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries"
|
#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries"
|
||||||
|
|
||||||
G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
||||||
|
@ -71,7 +73,6 @@ G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PERM_HW_ADDRESS,
|
|
||||||
PROP_MODE,
|
PROP_MODE,
|
||||||
PROP_BITRATE,
|
PROP_BITRATE,
|
||||||
PROP_ACCESS_POINTS,
|
PROP_ACCESS_POINTS,
|
||||||
|
@ -120,6 +121,9 @@ struct _NMDeviceWifiPrivate {
|
||||||
guint reacquire_iface_id;
|
guint reacquire_iface_id;
|
||||||
|
|
||||||
NMDeviceWifiCapabilities capabilities;
|
NMDeviceWifiCapabilities capabilities;
|
||||||
|
|
||||||
|
gint32 hw_addr_scan_expire;
|
||||||
|
char *hw_addr_scan;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean check_scanning_allowed (NMDeviceWifi *self);
|
static gboolean check_scanning_allowed (NMDeviceWifi *self);
|
||||||
|
@ -170,6 +174,8 @@ static void ap_add_remove (NMDeviceWifi *self,
|
||||||
|
|
||||||
static void remove_supplicant_interface_error_handler (NMDeviceWifi *self);
|
static void remove_supplicant_interface_error_handler (NMDeviceWifi *self);
|
||||||
|
|
||||||
|
static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset);
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -187,6 +193,18 @@ constructed (GObject *object)
|
||||||
priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ());
|
priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
unmanaged_on_quit (NMDevice *self)
|
||||||
|
{
|
||||||
|
/* Wi-Fi devices cannot be assumed and are always taken down.
|
||||||
|
* However, also when being disconnected, we scan and thus
|
||||||
|
* set the MAC address to a random value.
|
||||||
|
*
|
||||||
|
* We must restore the original MAC address when quitting, thus
|
||||||
|
* signal to unmanage the device. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
supplicant_interface_acquire (NMDeviceWifi *self)
|
supplicant_interface_acquire (NMDeviceWifi *self)
|
||||||
{
|
{
|
||||||
|
@ -403,14 +421,6 @@ periodic_update_cb (gpointer user_data)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
realize_start_notify (NMDevice *device, const NMPlatformLink *plink)
|
|
||||||
{
|
|
||||||
NM_DEVICE_CLASS (nm_device_wifi_parent_class)->realize_start_notify (device, plink);
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
bring_up (NMDevice *device, gboolean *no_firmware)
|
bring_up (NMDevice *device, gboolean *no_firmware)
|
||||||
{
|
{
|
||||||
|
@ -491,9 +501,8 @@ 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);
|
||||||
|
|
||||||
/* Reset MAC address back to initial address */
|
g_clear_pointer (&priv->hw_addr_scan, g_free);
|
||||||
if (nm_device_get_initial_hw_address (device))
|
_hw_addr_set_scanning (self, TRUE);
|
||||||
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_WIFI);
|
|
||||||
|
|
||||||
/* 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.
|
||||||
|
@ -572,7 +581,7 @@ 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);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
||||||
if (perm_hw_addr) {
|
if (perm_hw_addr) {
|
||||||
if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||||
|
@ -685,35 +694,31 @@ check_connection_available (NMDevice *device,
|
||||||
return !!find_first_compatible_ap (NM_DEVICE_WIFI (device), connection, TRUE);
|
return !!find_first_compatible_ap (NM_DEVICE_WIFI (device), connection, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* List of manufacturer default SSIDs that are often unchanged by users.
|
|
||||||
*
|
|
||||||
* NOTE: this list should *not* contain networks that you would like to
|
|
||||||
* automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot".
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
manf_defaults[] = {
|
|
||||||
"linksys",
|
|
||||||
"linksys-a",
|
|
||||||
"linksys-g",
|
|
||||||
"default",
|
|
||||||
"belkin54g",
|
|
||||||
"NETGEAR",
|
|
||||||
"o2DSL",
|
|
||||||
"WLAN",
|
|
||||||
"ALICE-WLAN",
|
|
||||||
"Speedport W 501V",
|
|
||||||
"TURBONETT",
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_manf_default_ssid (const GByteArray *ssid)
|
is_manf_default_ssid (const GByteArray *ssid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
/*
|
||||||
|
* List of manufacturer default SSIDs that are often unchanged by users.
|
||||||
|
*
|
||||||
|
* NOTE: this list should *not* contain networks that you would like to
|
||||||
|
* automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot".
|
||||||
|
*/
|
||||||
|
static const char *manf_defaults[] = {
|
||||||
|
"linksys",
|
||||||
|
"linksys-a",
|
||||||
|
"linksys-g",
|
||||||
|
"default",
|
||||||
|
"belkin54g",
|
||||||
|
"NETGEAR",
|
||||||
|
"o2DSL",
|
||||||
|
"WLAN",
|
||||||
|
"ALICE-WLAN",
|
||||||
|
"Speedport W 501V",
|
||||||
|
"TURBONETT",
|
||||||
|
};
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (manf_defaults); i++) {
|
for (i = 0; i < G_N_ELEMENTS (manf_defaults); i++) {
|
||||||
if (ssid->len == strlen (manf_defaults[i])) {
|
if (ssid->len == strlen (manf_defaults[i])) {
|
||||||
if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0)
|
if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -868,7 +873,7 @@ 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);
|
||||||
|
|
||||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
if (perm_hw_addr) {
|
if (perm_hw_addr) {
|
||||||
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
||||||
if (setting_mac) {
|
if (setting_mac) {
|
||||||
|
@ -1027,6 +1032,60 @@ impl_device_wifi_get_all_access_points (NMDeviceWifi *self,
|
||||||
g_ptr_array_unref (paths);
|
g_ptr_array_unref (paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset)
|
||||||
|
{
|
||||||
|
NMDevice *device = (NMDevice *) self;
|
||||||
|
NMDeviceWifiPrivate *priv;
|
||||||
|
guint32 now;
|
||||||
|
gboolean randomize;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_DEVICE_WIFI (self));
|
||||||
|
|
||||||
|
if ( nm_device_is_activating (device)
|
||||||
|
|| nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
randomize = nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA,
|
||||||
|
"wifi.scan-rand-mac-address",
|
||||||
|
device,
|
||||||
|
TRUE, TRUE);
|
||||||
|
|
||||||
|
if (!randomize) {
|
||||||
|
g_clear_pointer (&priv->hw_addr_scan, g_free);
|
||||||
|
if (do_reset)
|
||||||
|
nm_device_hw_addr_reset (device, "scanning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
now = nm_utils_get_monotonic_timestamp_s ();
|
||||||
|
|
||||||
|
if ( !priv->hw_addr_scan
|
||||||
|
|| now >= priv->hw_addr_scan_expire) {
|
||||||
|
gs_free char *generate_mac_address_mask = NULL;
|
||||||
|
|
||||||
|
/* the random MAC address for scanning expires after a while.
|
||||||
|
*
|
||||||
|
* We don't bother with to update the MAC address exactly when
|
||||||
|
* it expires, instead on the next scan request, we will generate
|
||||||
|
* a new one.*/
|
||||||
|
priv->hw_addr_scan_expire = now + (SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN * 60);
|
||||||
|
|
||||||
|
generate_mac_address_mask = nm_config_data_get_device_config (NM_CONFIG_GET_DATA,
|
||||||
|
"wifi.scan-generate-mac-address-mask",
|
||||||
|
device,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_free (priv->hw_addr_scan);
|
||||||
|
priv->hw_addr_scan = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (device),
|
||||||
|
generate_mac_address_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_device_hw_addr_set (device, priv->hw_addr_scan, "scanning");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
request_scan_cb (NMDevice *device,
|
request_scan_cb (NMDevice *device,
|
||||||
GDBusMethodInvocation *context,
|
GDBusMethodInvocation *context,
|
||||||
|
@ -1336,6 +1395,8 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
|
||||||
_LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan");
|
_LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hw_addr_set_scanning (self, FALSE);
|
||||||
|
|
||||||
if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) {
|
if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) {
|
||||||
/* success */
|
/* success */
|
||||||
backoff = TRUE;
|
backoff = TRUE;
|
||||||
|
@ -2210,9 +2271,6 @@ build_supplicant_config (NMDeviceWifi *self,
|
||||||
NMSupplicantConfig *config = NULL;
|
NMSupplicantConfig *config = NULL;
|
||||||
NMSettingWireless *s_wireless;
|
NMSettingWireless *s_wireless;
|
||||||
NMSettingWirelessSecurity *s_wireless_sec;
|
NMSettingWirelessSecurity *s_wireless_sec;
|
||||||
NMSupplicantFeature mac_randomization_support;
|
|
||||||
NMSettingMacRandomization mac_randomization_fallback;
|
|
||||||
gs_free char *svalue = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (priv->sup_iface, NULL);
|
g_return_val_if_fail (priv->sup_iface, NULL);
|
||||||
|
|
||||||
|
@ -2227,20 +2285,9 @@ build_supplicant_config (NMDeviceWifi *self,
|
||||||
_LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out.");
|
_LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out.");
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_randomization_support = nm_supplicant_interface_get_mac_randomization_support (priv->sup_iface);
|
|
||||||
svalue = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
|
|
||||||
"wifi." NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
|
|
||||||
NM_DEVICE (self));
|
|
||||||
mac_randomization_fallback = _nm_utils_ascii_str_to_int64 (svalue, 10,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_ALWAYS,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT);
|
|
||||||
|
|
||||||
if (!nm_supplicant_config_add_setting_wireless (config,
|
if (!nm_supplicant_config_add_setting_wireless (config,
|
||||||
s_wireless,
|
s_wireless,
|
||||||
fixed_freq,
|
fixed_freq,
|
||||||
mac_randomization_support,
|
|
||||||
mac_randomization_fallback,
|
|
||||||
error)) {
|
error)) {
|
||||||
g_prefix_error (error, "802-11-wireless: ");
|
g_prefix_error (error, "802-11-wireless: ");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2290,7 +2337,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
NMActRequest *req;
|
NMActRequest *req;
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
NMSettingWireless *s_wireless;
|
NMSettingWireless *s_wireless;
|
||||||
const char *cloned_mac;
|
|
||||||
const char *mode;
|
const char *mode;
|
||||||
const char *ap_path;
|
const char *ap_path;
|
||||||
|
|
||||||
|
@ -2330,9 +2376,12 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* forget the temporary MAC address used during scanning */
|
||||||
|
g_clear_pointer (&priv->hw_addr_scan, g_free);
|
||||||
|
|
||||||
/* Set spoof MAC to the interface */
|
/* Set spoof MAC to the interface */
|
||||||
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
|
if (!nm_device_hw_addr_set_cloned (device, connection, TRUE))
|
||||||
nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_WIFI);
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
|
|
||||||
/* AP mode never uses a specific object or existing scanned AP */
|
/* AP mode never uses a specific object or existing scanned AP */
|
||||||
if (priv->mode != NM_802_11_MODE_AP) {
|
if (priv->mode != NM_802_11_MODE_AP) {
|
||||||
|
@ -2972,6 +3021,8 @@ finalize (GObject *object)
|
||||||
|
|
||||||
g_hash_table_unref (priv->aps);
|
g_hash_table_unref (priv->aps);
|
||||||
|
|
||||||
|
g_free (priv->hw_addr_scan);
|
||||||
|
|
||||||
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2986,9 +3037,6 @@ get_property (GObject *object, guint prop_id,
|
||||||
GPtrArray *array;
|
GPtrArray *array;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PERM_HW_ADDRESS:
|
|
||||||
g_value_set_string (value, nm_device_get_permanent_hw_address (NM_DEVICE (device)));
|
|
||||||
break;
|
|
||||||
case PROP_MODE:
|
case PROP_MODE:
|
||||||
g_value_set_uint (value, priv->mode);
|
g_value_set_uint (value, priv->mode);
|
||||||
break;
|
break;
|
||||||
|
@ -3053,7 +3101,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
object_class->finalize = finalize;
|
object_class->finalize = finalize;
|
||||||
|
|
||||||
parent_class->realize_start_notify = realize_start_notify;
|
|
||||||
parent_class->bring_up = bring_up;
|
parent_class->bring_up = bring_up;
|
||||||
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;
|
||||||
|
@ -3070,19 +3117,13 @@ 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->unmanaged_on_quit = unmanaged_on_quit;
|
||||||
|
|
||||||
parent_class->state_changed = device_state_changed;
|
parent_class->state_changed = device_state_changed;
|
||||||
|
|
||||||
klass->scanning_allowed = scanning_allowed;
|
klass->scanning_allowed = scanning_allowed;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
g_object_class_install_property
|
|
||||||
(object_class, PROP_PERM_HW_ADDRESS,
|
|
||||||
g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READABLE |
|
|
||||||
G_PARAM_STATIC_STRINGS));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(object_class, PROP_MODE,
|
(object_class, PROP_MODE,
|
||||||
g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "",
|
g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "",
|
||||||
|
|
|
@ -36,7 +36,6 @@ G_BEGIN_DECLS
|
||||||
#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI))
|
#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI))
|
||||||
#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass))
|
#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass))
|
||||||
|
|
||||||
#define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address"
|
|
||||||
#define NM_DEVICE_WIFI_MODE "mode"
|
#define NM_DEVICE_WIFI_MODE "mode"
|
||||||
#define NM_DEVICE_WIFI_BITRATE "bitrate"
|
#define NM_DEVICE_WIFI_BITRATE "bitrate"
|
||||||
#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points"
|
#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points"
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef struct {
|
||||||
gboolean has;
|
gboolean has;
|
||||||
GSList *spec;
|
GSList *spec;
|
||||||
} match_device;
|
} match_device;
|
||||||
} ConnectionInfo;
|
} MatchSectionInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *config_main_file;
|
char *config_main_file;
|
||||||
|
@ -52,7 +52,11 @@ typedef struct {
|
||||||
|
|
||||||
/* A zero-terminated list of pre-processed information from the
|
/* A zero-terminated list of pre-processed information from the
|
||||||
* [connection] sections. This is to speed up lookup. */
|
* [connection] sections. This is to speed up lookup. */
|
||||||
ConnectionInfo *connection_infos;
|
MatchSectionInfo *connection_infos;
|
||||||
|
|
||||||
|
/* A zero-terminated list of pre-processed information from the
|
||||||
|
* [device] sections. This is to speed up lookup. */
|
||||||
|
MatchSectionInfo *device_infos;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *uri;
|
char *uri;
|
||||||
|
@ -268,9 +272,16 @@ nm_config_data_get_rc_manager (const NMConfigData *self)
|
||||||
gboolean
|
gboolean
|
||||||
nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device)
|
nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device)
|
||||||
{
|
{
|
||||||
|
gs_free char *value = NULL;
|
||||||
|
gboolean has_match;
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE);
|
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE);
|
||||||
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
|
value = nm_config_data_get_device_config (self, NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER, device, &has_match);
|
||||||
|
if (has_match)
|
||||||
|
return nm_config_parse_boolean (value, FALSE);
|
||||||
|
|
||||||
return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier);
|
return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +462,7 @@ static int
|
||||||
_nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy)
|
_nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy)
|
||||||
{
|
{
|
||||||
gboolean a_is_connection, b_is_connection;
|
gboolean a_is_connection, b_is_connection;
|
||||||
|
gboolean a_is_device, b_is_device;
|
||||||
gboolean a_is_intern, b_is_intern;
|
gboolean a_is_intern, b_is_intern;
|
||||||
const char *a = *pa;
|
const char *a = *pa;
|
||||||
const char *b = *pb;
|
const char *b = *pb;
|
||||||
|
@ -488,6 +500,28 @@ _nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy)
|
||||||
if (b_is_connection && !a_is_connection)
|
if (b_is_connection && !a_is_connection)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* we sort device groups before connection groups (to the end). */
|
||||||
|
a_is_device = a && g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||||
|
b_is_device = b && g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||||
|
|
||||||
|
if (a_is_device && b_is_device) {
|
||||||
|
/* if both are device groups, we want the explicit [device] group first. */
|
||||||
|
a_is_device = a[NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE)] == '\0';
|
||||||
|
b_is_device = b[NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE)] == '\0';
|
||||||
|
|
||||||
|
if (a_is_device != b_is_device) {
|
||||||
|
if (a_is_device)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* the sections are ordered lowest-priority first. Reverse their order. */
|
||||||
|
return pa < pb ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (a_is_device && !b_is_device)
|
||||||
|
return 1;
|
||||||
|
if (b_is_device && !a_is_device)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* no reordering. */
|
/* no reordering. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1049,25 +1083,18 @@ global_dns_equal (NMGlobalDnsConfig *old, NMGlobalDnsConfig *new)
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
char *
|
static const MatchSectionInfo *
|
||||||
nm_config_data_get_connection_default (const NMConfigData *self,
|
_match_section_infos_lookup (const MatchSectionInfo *match_section_infos,
|
||||||
const char *property,
|
GKeyFile *keyfile,
|
||||||
NMDevice *device)
|
const char *property,
|
||||||
|
NMDevice *device,
|
||||||
|
char **out_value)
|
||||||
{
|
{
|
||||||
NMConfigDataPrivate *priv;
|
if (!match_section_infos)
|
||||||
const ConnectionInfo *connection_info;
|
|
||||||
|
|
||||||
g_return_val_if_fail (self, NULL);
|
|
||||||
g_return_val_if_fail (property && *property, NULL);
|
|
||||||
g_return_val_if_fail (strchr (property, '.'), NULL);
|
|
||||||
|
|
||||||
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
if (!priv->connection_infos)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (connection_info = &priv->connection_infos[0]; connection_info->group_name; connection_info++) {
|
for (; match_section_infos->group_name; match_section_infos++) {
|
||||||
char *value;
|
char *value = NULL;
|
||||||
gboolean match;
|
gboolean match;
|
||||||
|
|
||||||
/* FIXME: Here we use g_key_file_get_string(). This should be in sync with what keyfile-reader
|
/* FIXME: Here we use g_key_file_get_string(). This should be in sync with what keyfile-reader
|
||||||
|
@ -1077,23 +1104,87 @@ nm_config_data_get_connection_default (const NMConfigData *self,
|
||||||
* string_to_value(keyfile_to_string(keyfile)) in one. Optimally, keyfile library would
|
* string_to_value(keyfile_to_string(keyfile)) in one. Optimally, keyfile library would
|
||||||
* expose both functions, and we would return here keyfile_to_string(keyfile).
|
* expose both functions, and we would return here keyfile_to_string(keyfile).
|
||||||
* The caller then could convert the string to the proper value via string_to_value(value). */
|
* The caller then could convert the string to the proper value via string_to_value(value). */
|
||||||
value = g_key_file_get_string (priv->keyfile, connection_info->group_name, property, NULL);
|
value = g_key_file_get_string (keyfile, match_section_infos->group_name, property, NULL);
|
||||||
if (!value && !connection_info->stop_match)
|
if (!value && !match_section_infos->stop_match)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
if (connection_info->match_device.has)
|
if (match_section_infos->match_device.has)
|
||||||
match = device && nm_device_spec_match_list (device, connection_info->match_device.spec);
|
match = device && nm_device_spec_match_list (device, match_section_infos->match_device.spec);
|
||||||
|
|
||||||
if (match)
|
if (match) {
|
||||||
return value;
|
*out_value = value;
|
||||||
|
return match_section_infos;
|
||||||
|
}
|
||||||
g_free (value);
|
g_free (value);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nm_config_data_get_device_config (const NMConfigData *self,
|
||||||
|
const char *property,
|
||||||
|
NMDevice *device,
|
||||||
|
gboolean *has_match)
|
||||||
|
{
|
||||||
|
NMConfigDataPrivate *priv;
|
||||||
|
const MatchSectionInfo *connection_info;
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self, NULL);
|
||||||
|
g_return_val_if_fail (property && *property, NULL);
|
||||||
|
|
||||||
|
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
connection_info = _match_section_infos_lookup (&priv->device_infos[0],
|
||||||
|
priv->keyfile,
|
||||||
|
property,
|
||||||
|
device,
|
||||||
|
&value);
|
||||||
|
NM_SET_OUT (has_match, !!connection_info);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_config_data_get_device_config_boolean (const NMConfigData *self,
|
||||||
|
const char *property,
|
||||||
|
NMDevice *device,
|
||||||
|
gint val_no_match,
|
||||||
|
gint val_invalid)
|
||||||
|
{
|
||||||
|
gs_free char *value = NULL;
|
||||||
|
gboolean has_match;
|
||||||
|
|
||||||
|
value = nm_config_data_get_device_config (self, property, device, &has_match);
|
||||||
|
if (!has_match)
|
||||||
|
return val_no_match;
|
||||||
|
return nm_config_parse_boolean (value, val_invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nm_config_data_get_connection_default (const NMConfigData *self,
|
||||||
|
const char *property,
|
||||||
|
NMDevice *device)
|
||||||
|
{
|
||||||
|
NMConfigDataPrivate *priv;
|
||||||
|
char *value = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self, NULL);
|
||||||
|
g_return_val_if_fail (property && *property, NULL);
|
||||||
|
g_return_val_if_fail (strchr (property, '.'), NULL);
|
||||||
|
|
||||||
|
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
_match_section_infos_lookup (&priv->connection_infos[0],
|
||||||
|
priv->keyfile,
|
||||||
|
property,
|
||||||
|
device,
|
||||||
|
&value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_get_connection_info_init (ConnectionInfo *connection_info, GKeyFile *keyfile, char *group)
|
_get_connection_info_init (MatchSectionInfo *connection_info, GKeyFile *keyfile, char *group)
|
||||||
{
|
{
|
||||||
/* pass ownership of @group on... */
|
/* pass ownership of @group on... */
|
||||||
connection_info->group_name = group;
|
connection_info->group_name = group;
|
||||||
|
@ -1105,27 +1196,43 @@ _get_connection_info_init (ConnectionInfo *connection_info, GKeyFile *keyfile, c
|
||||||
connection_info->stop_match = nm_config_keyfile_get_boolean (keyfile, group, "stop-match", FALSE);
|
connection_info->stop_match = nm_config_keyfile_get_boolean (keyfile, group, "stop-match", FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *
|
static void
|
||||||
_get_connection_infos (GKeyFile *keyfile)
|
_match_section_infos_free (MatchSectionInfo *match_section_infos)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (!match_section_infos)
|
||||||
|
return;
|
||||||
|
for (i = 0; match_section_infos[i].group_name; i++) {
|
||||||
|
g_free (match_section_infos[i].group_name);
|
||||||
|
g_slist_free_full (match_section_infos[i].match_device.spec, g_free);
|
||||||
|
}
|
||||||
|
g_free (match_section_infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MatchSectionInfo *
|
||||||
|
_match_section_infos_construct (GKeyFile *keyfile, const char *prefix)
|
||||||
{
|
{
|
||||||
char **groups;
|
char **groups;
|
||||||
gsize i, j, ngroups;
|
gsize i, j, ngroups;
|
||||||
char *connection_tag = NULL;
|
char *connection_tag = NULL;
|
||||||
ConnectionInfo *connection_infos = NULL;
|
MatchSectionInfo *match_section_infos = NULL;
|
||||||
|
|
||||||
/* get the list of existing [connection.\+] sections that we consider
|
/* get the list of existing [connection.\+]/[device.\+] sections.
|
||||||
* for nm_config_data_get_connection_default().
|
|
||||||
*
|
*
|
||||||
* We expect the sections in their right order, with lowest priority
|
* We expect the sections in their right order, with lowest priority
|
||||||
* first. Only exception is the (literal) [connection] section, which
|
* first. Only exception is the (literal) [connection] section, which
|
||||||
* we will always reorder to the end. */
|
* we will always reorder to the end. */
|
||||||
groups = g_key_file_get_groups (keyfile, &ngroups);
|
groups = g_key_file_get_groups (keyfile, &ngroups);
|
||||||
if (!groups)
|
if (!groups)
|
||||||
ngroups = 0;
|
return NULL;
|
||||||
else if (ngroups > 0) {
|
|
||||||
|
if (ngroups > 0) {
|
||||||
|
gsize l = strlen (prefix);
|
||||||
|
|
||||||
for (i = 0, j = 0; i < ngroups; i++) {
|
for (i = 0, j = 0; i < ngroups; i++) {
|
||||||
if (g_str_has_prefix (groups[i], NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)) {
|
if (g_str_has_prefix (groups[i], prefix)) {
|
||||||
if (groups[i][NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)] == '\0')
|
if (groups[i][l] == '\0')
|
||||||
connection_tag = groups[i];
|
connection_tag = groups[i];
|
||||||
else
|
else
|
||||||
groups[j++] = groups[i];
|
groups[j++] = groups[i];
|
||||||
|
@ -1135,18 +1242,23 @@ _get_connection_infos (GKeyFile *keyfile)
|
||||||
ngroups = j;
|
ngroups = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection_infos = g_new0 (ConnectionInfo, ngroups + 1 + (connection_tag ? 1 : 0));
|
if (ngroups == 0 && !connection_tag) {
|
||||||
|
g_free (groups);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
match_section_infos = g_new0 (MatchSectionInfo, ngroups + 1 + (connection_tag ? 1 : 0));
|
||||||
for (i = 0; i < ngroups; i++) {
|
for (i = 0; i < ngroups; i++) {
|
||||||
/* pass ownership of @group on... */
|
/* pass ownership of @group on... */
|
||||||
_get_connection_info_init (&connection_infos[i], keyfile, groups[ngroups - i - 1]);
|
_get_connection_info_init (&match_section_infos[i], keyfile, groups[ngroups - i - 1]);
|
||||||
}
|
}
|
||||||
if (connection_tag) {
|
if (connection_tag) {
|
||||||
/* pass ownership of @connection_tag on... */
|
/* pass ownership of @connection_tag on... */
|
||||||
_get_connection_info_init (&connection_infos[i], keyfile, connection_tag);
|
_get_connection_info_init (&match_section_infos[i], keyfile, connection_tag);
|
||||||
}
|
}
|
||||||
g_free (groups);
|
g_free (groups);
|
||||||
|
|
||||||
return connection_infos;
|
return match_section_infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -1306,7 +1418,6 @@ static void
|
||||||
finalize (GObject *gobject)
|
finalize (GObject *gobject)
|
||||||
{
|
{
|
||||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (gobject);
|
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (gobject);
|
||||||
guint i;
|
|
||||||
|
|
||||||
g_free (priv->config_main_file);
|
g_free (priv->config_main_file);
|
||||||
g_free (priv->config_description);
|
g_free (priv->config_description);
|
||||||
|
@ -1326,13 +1437,8 @@ finalize (GObject *gobject)
|
||||||
|
|
||||||
nm_global_dns_config_free (priv->global_dns);
|
nm_global_dns_config_free (priv->global_dns);
|
||||||
|
|
||||||
if (priv->connection_infos) {
|
_match_section_infos_free (priv->connection_infos);
|
||||||
for (i = 0; priv->connection_infos[i].group_name; i++) {
|
_match_section_infos_free (priv->device_infos);
|
||||||
g_free (priv->connection_infos[i].group_name);
|
|
||||||
g_slist_free_full (priv->connection_infos[i].match_device.spec, g_free);
|
|
||||||
}
|
|
||||||
g_free (priv->connection_infos);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_key_file_unref (priv->keyfile);
|
g_key_file_unref (priv->keyfile);
|
||||||
if (priv->keyfile_user)
|
if (priv->keyfile_user)
|
||||||
|
@ -1359,7 +1465,8 @@ constructed (GObject *object)
|
||||||
|
|
||||||
priv->keyfile = _merge_keyfiles (priv->keyfile_user, priv->keyfile_intern);
|
priv->keyfile = _merge_keyfiles (priv->keyfile_user, priv->keyfile_intern);
|
||||||
|
|
||||||
priv->connection_infos = _get_connection_infos (priv->keyfile);
|
priv->connection_infos = _match_section_infos_construct (priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
|
||||||
|
priv->device_infos = _match_section_infos_construct (priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||||
|
|
||||||
priv->connectivity.uri = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", NULL));
|
priv->connectivity.uri = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "uri", NULL));
|
||||||
priv->connectivity.response = g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "response", NULL);
|
priv->connectivity.response = g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, "response", NULL);
|
||||||
|
|
|
@ -183,6 +183,17 @@ char *nm_config_data_get_connection_default (const NMConfigData *self,
|
||||||
const char *property,
|
const char *property,
|
||||||
NMDevice *device);
|
NMDevice *device);
|
||||||
|
|
||||||
|
char *nm_config_data_get_device_config (const NMConfigData *self,
|
||||||
|
const char *property,
|
||||||
|
NMDevice *device,
|
||||||
|
gboolean *has_match);
|
||||||
|
|
||||||
|
gboolean nm_config_data_get_device_config_boolean (const NMConfigData *self,
|
||||||
|
const char *property,
|
||||||
|
NMDevice *device,
|
||||||
|
gint val_no_match,
|
||||||
|
gint val_invalid);
|
||||||
|
|
||||||
char **nm_config_data_get_groups (const NMConfigData *self);
|
char **nm_config_data_get_groups (const NMConfigData *self);
|
||||||
char **nm_config_data_get_keys (const NMConfigData *self, const char *group);
|
char **nm_config_data_get_keys (const NMConfigData *self, const char *group);
|
||||||
gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const char *group);
|
gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const char *group);
|
||||||
|
|
|
@ -399,7 +399,9 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device)
|
||||||
|
|
||||||
priv = NM_CONFIG_GET_PRIVATE (self);
|
priv = NM_CONFIG_GET_PRIVATE (self);
|
||||||
|
|
||||||
hw_address = nm_device_get_hw_address (device);
|
hw_address = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
|
if (!hw_address)
|
||||||
|
return;
|
||||||
|
|
||||||
no_auto_default_current = nm_config_data_get_no_auto_default (priv->config_data);
|
no_auto_default_current = nm_config_data_get_no_auto_default (priv->config_data);
|
||||||
|
|
||||||
|
@ -576,14 +578,7 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
|
||||||
{
|
{
|
||||||
const char *a, *b;
|
const char *a, *b;
|
||||||
gboolean a_is_connection, b_is_connection;
|
gboolean a_is_connection, b_is_connection;
|
||||||
|
gboolean a_is_device, b_is_device;
|
||||||
/* basic NULL checking... */
|
|
||||||
if (pa == pb)
|
|
||||||
return 0;
|
|
||||||
if (!pa)
|
|
||||||
return -1;
|
|
||||||
if (!pb)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
a = *pa;
|
a = *pa;
|
||||||
b = *pb;
|
b = *pb;
|
||||||
|
@ -598,16 +593,34 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
|
||||||
return 1;
|
return 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!a_is_connection) {
|
if (a_is_connection) {
|
||||||
/* both are non-connection entries. Don't reorder. */
|
/* both are [connection.\+] entires. Reverse their order.
|
||||||
return 0;
|
* One of the sections might be literally [connection]. That section
|
||||||
|
* is special and it's order will be fixed later. It doesn't actually
|
||||||
|
* matter here how it compares with [connection.\+] sections. */
|
||||||
|
return pa > pb ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* both are [connection.\+] entires. Reverse their order.
|
a_is_device = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||||
* One of the sections might be literally [connection]. That section
|
b_is_device = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||||
* is special and it's order will be fixed later. It doesn't actually
|
|
||||||
* matter here how it compares with [connection.\+] sections. */
|
if (a_is_device != b_is_device) {
|
||||||
return pa > pb ? -1 : 1;
|
/* one is a [device*] entry, the other not. We sort [device*] entires
|
||||||
|
* after. */
|
||||||
|
if (a_is_device)
|
||||||
|
return 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a_is_device) {
|
||||||
|
/* both are [device.\+] entires. Reverse their order.
|
||||||
|
* One of the sections might be literally [device]. That section
|
||||||
|
* is special and it's order will be fixed later. It doesn't actually
|
||||||
|
* matter here how it compares with [device.\+] sections. */
|
||||||
|
return pa > pb ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't reorder the rest. */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -630,7 +643,8 @@ _setting_is_device_spec (const char *group, const char *key)
|
||||||
|| _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier")
|
|| _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier")
|
||||||
|| _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only")
|
|| _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only")
|
||||||
|| _IS (NM_CONFIG_KEYFILE_GROUP_KEYFILE, "unmanaged-devices")
|
|| _IS (NM_CONFIG_KEYFILE_GROUP_KEYFILE, "unmanaged-devices")
|
||||||
|| (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && !strcmp (key, "match-device"));
|
|| (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && !strcmp (key, "match-device"))
|
||||||
|
|| (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE ) && !strcmp (key, "match-device"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern."
|
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern."
|
||||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection"
|
#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection"
|
||||||
|
#define NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "device"
|
||||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-"
|
#define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-"
|
||||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist"
|
#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist"
|
||||||
|
|
||||||
|
@ -69,6 +70,8 @@
|
||||||
#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed"
|
#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed"
|
||||||
#define NM_CONFIG_KEYFILE_KEY_AUDIT "audit"
|
#define NM_CONFIG_KEYFILE_KEY_AUDIT "audit"
|
||||||
|
|
||||||
|
#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier"
|
||||||
|
|
||||||
#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was."
|
#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was."
|
||||||
#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set."
|
#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set."
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <resolv.h>
|
#include <resolv.h>
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int));
|
G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int));
|
||||||
int _nm_utils_testing = 0;
|
static int _nm_utils_testing = 0;
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_utils_get_testing_initialized ()
|
nm_utils_get_testing_initialized ()
|
||||||
|
@ -1271,8 +1272,10 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
||||||
{
|
{
|
||||||
const GSList *iter;
|
const GSList *iter;
|
||||||
NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH;
|
NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH;
|
||||||
|
guint hwaddr_len = 0;
|
||||||
|
guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX];
|
||||||
|
|
||||||
g_return_val_if_fail (hwaddr != NULL, NM_MATCH_SPEC_NO_MATCH);
|
nm_assert (nm_utils_hwaddr_valid (hwaddr, -1));
|
||||||
|
|
||||||
for (iter = specs; iter; iter = g_slist_next (iter)) {
|
for (iter = specs; iter; iter = g_slist_next (iter)) {
|
||||||
const char *spec_str = iter->data;
|
const char *spec_str = iter->data;
|
||||||
|
@ -1293,7 +1296,15 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
||||||
else if (except)
|
else if (except)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr, -1)) {
|
if (G_UNLIKELY (hwaddr_len == 0)) {
|
||||||
|
hwaddr_len = _nm_utils_hwaddr_length (hwaddr);
|
||||||
|
if (!hwaddr_len)
|
||||||
|
g_return_val_if_reached (NM_MATCH_SPEC_NO_MATCH);
|
||||||
|
if (!nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, hwaddr_len))
|
||||||
|
nm_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len)) {
|
||||||
if (except)
|
if (except)
|
||||||
return NM_MATCH_SPEC_NEG_MATCH;
|
return NM_MATCH_SPEC_NEG_MATCH;
|
||||||
match = NM_MATCH_SPEC_MATCH;
|
match = NM_MATCH_SPEC_MATCH;
|
||||||
|
@ -2701,6 +2712,123 @@ nm_utils_machine_id_read (void)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* taken from systemd's fd_wait_for_event(). Note that the timeout
|
||||||
|
* is here in nano-seconds, not micro-seconds. */
|
||||||
|
int
|
||||||
|
nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns)
|
||||||
|
{
|
||||||
|
struct pollfd pollfd = {
|
||||||
|
.fd = fd,
|
||||||
|
.events = event,
|
||||||
|
};
|
||||||
|
struct timespec ts, *pts;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (timeout_ns < 0)
|
||||||
|
pts = NULL;
|
||||||
|
else {
|
||||||
|
ts.tv_sec = (time_t) (timeout_ns / NM_UTILS_NS_PER_SECOND);
|
||||||
|
ts.tv_nsec = (long int) (timeout_ns % NM_UTILS_NS_PER_SECOND);
|
||||||
|
pts = &ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = ppoll (&pollfd, 1, pts, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
return pollfd.revents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* taken from systemd's loop_read() */
|
||||||
|
ssize_t
|
||||||
|
nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll)
|
||||||
|
{
|
||||||
|
uint8_t *p = buf;
|
||||||
|
ssize_t n = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (fd >= 0, -EINVAL);
|
||||||
|
g_return_val_if_fail (buf, -EINVAL);
|
||||||
|
|
||||||
|
/* If called with nbytes == 0, let's call read() at least
|
||||||
|
* once, to validate the operation */
|
||||||
|
|
||||||
|
if (nbytes > (size_t) SSIZE_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ssize_t k;
|
||||||
|
|
||||||
|
k = read (fd, p, nbytes);
|
||||||
|
if (k < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (errno == EAGAIN && do_poll) {
|
||||||
|
|
||||||
|
/* We knowingly ignore any return value here,
|
||||||
|
* and expect that any error/EOF is reported
|
||||||
|
* via read() */
|
||||||
|
|
||||||
|
(void) nm_utils_fd_wait_for_event (fd, POLLIN, -1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n > 0 ? n : -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k == 0)
|
||||||
|
return n;
|
||||||
|
|
||||||
|
g_assert ((size_t) k <= nbytes);
|
||||||
|
|
||||||
|
p += k;
|
||||||
|
nbytes -= k;
|
||||||
|
n += k;
|
||||||
|
} while (nbytes > 0);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* taken from systemd's loop_read_exact() */
|
||||||
|
int
|
||||||
|
nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
n = nm_utils_fd_read_loop (fd, buf, nbytes, do_poll);
|
||||||
|
if (n < 0)
|
||||||
|
return (int) n;
|
||||||
|
if ((size_t) n != nbytes)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* taken from systemd's dev_urandom(). */
|
||||||
|
int
|
||||||
|
nm_utils_read_urandom (void *p, size_t nbytes)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
again:
|
||||||
|
fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
|
if (fd < 0) {
|
||||||
|
r = errno;
|
||||||
|
if (r == EINTR)
|
||||||
|
goto again;
|
||||||
|
return r == ENOENT ? -ENOSYS : -r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = nm_utils_fd_read_loop_exact (fd, p, nbytes, TRUE);
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
guint8 *
|
guint8 *
|
||||||
nm_utils_secret_key_read (gsize *out_key_len, GError **error)
|
nm_utils_secret_key_read (gsize *out_key_len, GError **error)
|
||||||
{
|
{
|
||||||
|
@ -2719,34 +2847,28 @@ nm_utils_secret_key_read (gsize *out_key_len, GError **error)
|
||||||
key_len = 0;
|
key_len = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int urandom = open ("/dev/urandom", O_RDONLY);
|
int r;
|
||||||
mode_t key_mask;
|
mode_t key_mask;
|
||||||
|
|
||||||
if (urandom == -1) {
|
|
||||||
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
|
||||||
"Can't open /dev/urandom: %s", strerror (errno));
|
|
||||||
key_len = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RFC7217 mandates the key SHOULD be at least 128 bits.
|
/* RFC7217 mandates the key SHOULD be at least 128 bits.
|
||||||
* Let's use twice as much. */
|
* Let's use twice as much. */
|
||||||
key_len = 32;
|
key_len = 32;
|
||||||
secret_key = g_malloc (key_len);
|
secret_key = g_malloc (key_len);
|
||||||
|
|
||||||
|
r = nm_utils_read_urandom (secret_key, key_len);
|
||||||
|
if (r < 0) {
|
||||||
|
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||||
|
"Can't read /dev/urandom: %s", strerror (-r));
|
||||||
|
key_len = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
key_mask = umask (0077);
|
key_mask = umask (0077);
|
||||||
if (read (urandom, secret_key, key_len) == key_len) {
|
if (!g_file_set_contents (NMSTATEDIR "/secret_key", (char *) secret_key, key_len, error)) {
|
||||||
if (!g_file_set_contents (NMSTATEDIR "/secret_key", (char *) secret_key, key_len, error)) {
|
g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: ");
|
||||||
g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: ");
|
|
||||||
key_len = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
|
||||||
"Could not obtain a secret");
|
|
||||||
key_len = 0;
|
key_len = 0;
|
||||||
}
|
}
|
||||||
umask (key_mask);
|
umask (key_mask);
|
||||||
close (urandom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -2953,9 +3075,10 @@ nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_set_stable_privacy (struct in6_addr *addr,
|
_set_stable_privacy (guint8 stable_type,
|
||||||
|
struct in6_addr *addr,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *uuid,
|
const char *network_id,
|
||||||
guint dad_counter,
|
guint dad_counter,
|
||||||
guint8 *secret_key,
|
guint8 *secret_key,
|
||||||
gsize key_len,
|
gsize key_len,
|
||||||
|
@ -2979,11 +3102,24 @@ _set_stable_privacy (struct in6_addr *addr,
|
||||||
|
|
||||||
key_len = MIN (key_len, G_MAXUINT32);
|
key_len = MIN (key_len, G_MAXUINT32);
|
||||||
|
|
||||||
|
if (stable_type != NM_UTILS_STABLE_TYPE_UUID) {
|
||||||
|
/* Preferably, we would always like to include the stable-type,
|
||||||
|
* but for backward compatibility reasons, we cannot for UUID.
|
||||||
|
*
|
||||||
|
* That is no real problem and it is still impossible to
|
||||||
|
* force a collision here, because of how the remaining
|
||||||
|
* fields are hashed. That is, as we also hash @key_len
|
||||||
|
* and the terminating '\0' of @network_id, it is unambigiously
|
||||||
|
* possible to revert the process and deduce the @stable_type.
|
||||||
|
*/
|
||||||
|
g_checksum_update (sum, &stable_type, sizeof (stable_type));
|
||||||
|
}
|
||||||
|
|
||||||
g_checksum_update (sum, addr->s6_addr, 8);
|
g_checksum_update (sum, addr->s6_addr, 8);
|
||||||
g_checksum_update (sum, (const guchar *) ifname, strlen (ifname) + 1);
|
g_checksum_update (sum, (const guchar *) ifname, strlen (ifname) + 1);
|
||||||
if (!uuid)
|
if (!network_id)
|
||||||
uuid = "";
|
network_id = "";
|
||||||
g_checksum_update (sum, (const guchar *) uuid, strlen (uuid) + 1);
|
g_checksum_update (sum, (const guchar *) network_id, strlen (network_id) + 1);
|
||||||
tmp[0] = htonl (dad_counter);
|
tmp[0] = htonl (dad_counter);
|
||||||
tmp[1] = htonl (key_len);
|
tmp[1] = htonl (key_len);
|
||||||
g_checksum_update (sum, (const guchar *) tmp, sizeof (tmp));
|
g_checksum_update (sum, (const guchar *) tmp, sizeof (tmp));
|
||||||
|
@ -3009,15 +3145,20 @@ _set_stable_privacy (struct in6_addr *addr,
|
||||||
* Returns: %TRUE on success, %FALSE if the address could not be generated.
|
* Returns: %TRUE on success, %FALSE if the address could not be generated.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
|
nm_utils_ipv6_addr_set_stable_privacy (NMUtilsStableType stable_type,
|
||||||
|
struct in6_addr *addr,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *uuid,
|
const char *network_id,
|
||||||
guint dad_counter,
|
guint dad_counter,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gs_free guint8 *secret_key = NULL;
|
gs_free guint8 *secret_key = NULL;
|
||||||
gsize key_len = 0;
|
gsize key_len = 0;
|
||||||
|
|
||||||
|
nm_assert (NM_IN_SET (stable_type,
|
||||||
|
NM_UTILS_STABLE_TYPE_UUID,
|
||||||
|
NM_UTILS_STABLE_TYPE_STABLE_ID));
|
||||||
|
|
||||||
if (dad_counter >= RFC7217_IDGEN_RETRIES) {
|
if (dad_counter >= RFC7217_IDGEN_RETRIES) {
|
||||||
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||||
"Too many DAD collisions");
|
"Too many DAD collisions");
|
||||||
|
@ -3028,10 +3169,151 @@ nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
|
||||||
if (!secret_key)
|
if (!secret_key)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return _set_stable_privacy (addr, ifname, uuid, dad_counter,
|
return _set_stable_privacy (stable_type, addr, ifname, network_id, dad_counter,
|
||||||
secret_key, key_len, error);
|
secret_key, key_len, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
_hw_addr_eth_complete (struct ether_addr *addr,
|
||||||
|
const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask)
|
||||||
|
{
|
||||||
|
struct ether_addr mask;
|
||||||
|
struct ether_addr oui;
|
||||||
|
struct ether_addr *ouis;
|
||||||
|
gsize ouis_len;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
/* the second LSB of the first octet means
|
||||||
|
* "globally unique, OUI enforced, BIA (burned-in-address)"
|
||||||
|
* vs. "locally-administered". By default, set it to
|
||||||
|
* generate locally-administered addresses.
|
||||||
|
*
|
||||||
|
* Maybe be overwritten by a mask below. */
|
||||||
|
addr->ether_addr_octet[0] |= 2;
|
||||||
|
|
||||||
|
if (!generate_mac_address_mask || !*generate_mac_address_mask)
|
||||||
|
goto out;
|
||||||
|
if (!_nm_utils_generate_mac_address_mask_parse (generate_mac_address_mask,
|
||||||
|
&mask,
|
||||||
|
&ouis,
|
||||||
|
&ouis_len,
|
||||||
|
NULL))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
nm_assert ((ouis == NULL) ^ (ouis_len != 0));
|
||||||
|
if (ouis) {
|
||||||
|
/* g_random_int() is good enough here. It uses a static GRand instance
|
||||||
|
* that is seeded from /dev/urandom. */
|
||||||
|
oui = ouis[g_random_int () % ouis_len];
|
||||||
|
g_free (ouis);
|
||||||
|
} else {
|
||||||
|
if (!nm_utils_hwaddr_aton (current_mac_address, &oui, ETH_ALEN))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ETH_ALEN; i++) {
|
||||||
|
const guint8 a = addr->ether_addr_octet[i];
|
||||||
|
const guint8 o = oui.ether_addr_octet[i];
|
||||||
|
const guint8 m = mask.ether_addr_octet[i];
|
||||||
|
|
||||||
|
addr->ether_addr_octet[i] = (a & ~m) | (o & m);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* The LSB of the first octet must always be cleared,
|
||||||
|
* it means Unicast vs. Multicast */
|
||||||
|
addr->ether_addr_octet[0] &= ~1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nm_utils_hw_addr_gen_random_eth (const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask)
|
||||||
|
{
|
||||||
|
struct ether_addr bin_addr;
|
||||||
|
|
||||||
|
if (nm_utils_read_urandom (&bin_addr, ETH_ALEN) < 0)
|
||||||
|
return NULL;
|
||||||
|
_hw_addr_eth_complete (&bin_addr, current_mac_address, generate_mac_address_mask);
|
||||||
|
return nm_utils_hwaddr_ntoa (&bin_addr, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_hw_addr_gen_stable_eth (NMUtilsStableType stable_type,
|
||||||
|
const char *stable_id,
|
||||||
|
const guint8 *secret_key,
|
||||||
|
gsize key_len,
|
||||||
|
const char *ifname,
|
||||||
|
const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask)
|
||||||
|
{
|
||||||
|
GChecksum *sum;
|
||||||
|
guint32 tmp;
|
||||||
|
guint8 digest[32];
|
||||||
|
gsize len = sizeof (digest);
|
||||||
|
struct ether_addr bin_addr;
|
||||||
|
guint8 stable_type_uint8;
|
||||||
|
|
||||||
|
nm_assert (stable_id);
|
||||||
|
nm_assert (NM_IN_SET (stable_type,
|
||||||
|
NM_UTILS_STABLE_TYPE_UUID,
|
||||||
|
NM_UTILS_STABLE_TYPE_STABLE_ID));
|
||||||
|
nm_assert (secret_key);
|
||||||
|
|
||||||
|
sum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||||
|
if (!sum)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
key_len = MIN (key_len, G_MAXUINT32);
|
||||||
|
|
||||||
|
stable_type_uint8 = stable_type;
|
||||||
|
g_checksum_update (sum, (const guchar *) &stable_type_uint8, sizeof (stable_type_uint8));
|
||||||
|
|
||||||
|
tmp = htonl ((guint32) key_len);
|
||||||
|
g_checksum_update (sum, (const guchar *) &tmp, sizeof (tmp));
|
||||||
|
g_checksum_update (sum, (const guchar *) secret_key, key_len);
|
||||||
|
g_checksum_update (sum, (const guchar *) (ifname ?: ""), ifname ? (strlen (ifname) + 1) : 1);
|
||||||
|
g_checksum_update (sum, (const guchar *) stable_id, strlen (stable_id) + 1);
|
||||||
|
|
||||||
|
g_checksum_get_digest (sum, digest, &len);
|
||||||
|
g_checksum_free (sum);
|
||||||
|
|
||||||
|
g_return_val_if_fail (len == 32, NULL);
|
||||||
|
|
||||||
|
memcpy (&bin_addr, digest, ETH_ALEN);
|
||||||
|
_hw_addr_eth_complete (&bin_addr, current_mac_address, generate_mac_address_mask);
|
||||||
|
return nm_utils_hwaddr_ntoa (&bin_addr, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type,
|
||||||
|
const char *stable_id,
|
||||||
|
const char *ifname,
|
||||||
|
const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask)
|
||||||
|
{
|
||||||
|
gs_free guint8 *secret_key = NULL;
|
||||||
|
gsize key_len = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (stable_id, NULL);
|
||||||
|
|
||||||
|
secret_key = nm_utils_secret_key_read (&key_len, NULL);
|
||||||
|
if (!secret_key)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return _hw_addr_gen_stable_eth (stable_type,
|
||||||
|
stable_id,
|
||||||
|
secret_key,
|
||||||
|
key_len,
|
||||||
|
ifname,
|
||||||
|
current_mac_address,
|
||||||
|
generate_mac_address_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_utils_setpgid:
|
* nm_utils_setpgid:
|
||||||
* @unused: unused
|
* @unused: unused
|
||||||
|
|
|
@ -310,6 +310,12 @@ const char *nm_utils_ip4_property_path (const char *ifname, const char *property
|
||||||
|
|
||||||
gboolean nm_utils_is_specific_hostname (const char *name);
|
gboolean nm_utils_is_specific_hostname (const char *name);
|
||||||
|
|
||||||
|
int nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns);
|
||||||
|
ssize_t nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll);
|
||||||
|
int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll);
|
||||||
|
|
||||||
|
int nm_utils_read_urandom (void *p, size_t n);
|
||||||
|
|
||||||
char *nm_utils_machine_id_read (void);
|
char *nm_utils_machine_id_read (void);
|
||||||
gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_uuid);
|
gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_uuid);
|
||||||
|
|
||||||
|
@ -353,12 +359,26 @@ gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||||
guint dev_id,
|
guint dev_id,
|
||||||
NMUtilsIPv6IfaceId *out_iid);
|
NMUtilsIPv6IfaceId *out_iid);
|
||||||
|
|
||||||
gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
|
typedef enum {
|
||||||
|
NM_UTILS_STABLE_TYPE_UUID = 0,
|
||||||
|
NM_UTILS_STABLE_TYPE_STABLE_ID = 1,
|
||||||
|
} NMUtilsStableType;
|
||||||
|
|
||||||
|
gboolean nm_utils_ipv6_addr_set_stable_privacy (NMUtilsStableType id_type,
|
||||||
|
struct in6_addr *addr,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *uuid,
|
const char *network_id,
|
||||||
guint dad_counter,
|
guint dad_counter,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
char *nm_utils_hw_addr_gen_random_eth (const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask);
|
||||||
|
char *nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type,
|
||||||
|
const char *stable_id,
|
||||||
|
const char *ifname,
|
||||||
|
const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask);
|
||||||
|
|
||||||
void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len);
|
void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len);
|
||||||
|
|
||||||
void nm_utils_setpgid (gpointer unused);
|
void nm_utils_setpgid (gpointer unused);
|
||||||
|
|
|
@ -66,6 +66,7 @@ static struct {
|
||||||
int tempaddr;
|
int tempaddr;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
char *uuid;
|
char *uuid;
|
||||||
|
char *stable_id;
|
||||||
char *dhcp4_address;
|
char *dhcp4_address;
|
||||||
char *dhcp4_clientid;
|
char *dhcp4_clientid;
|
||||||
char *dhcp4_hostname;
|
char *dhcp4_hostname;
|
||||||
|
@ -278,8 +279,9 @@ do_early_setup (int *argc, char **argv[])
|
||||||
gint64 priority64_v6 = -1;
|
gint64 priority64_v6 = -1;
|
||||||
GOptionEntry options[] = {
|
GOptionEntry options[] = {
|
||||||
/* Interface/IP config */
|
/* Interface/IP config */
|
||||||
{ "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), N_("eth0") },
|
{ "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), "eth0" },
|
||||||
{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") },
|
{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), "661e8cd0-b618-46b8-9dc9-31a52baaa16b" },
|
||||||
|
{ "stable-id", '\0', 0, G_OPTION_ARG_STRING, &global_opt.stable_id, N_("Connection Token for Stable IDs"), "eth" },
|
||||||
{ "slaac", 's', 0, G_OPTION_ARG_NONE, &global_opt.slaac, N_("Whether to manage IPv6 SLAAC"), NULL },
|
{ "slaac", 's', 0, G_OPTION_ARG_NONE, &global_opt.slaac, N_("Whether to manage IPv6 SLAAC"), NULL },
|
||||||
{ "slaac-required", '6', 0, G_OPTION_ARG_NONE, &global_opt.slaac_required, N_("Whether SLAAC must be successful"), NULL },
|
{ "slaac-required", '6', 0, G_OPTION_ARG_NONE, &global_opt.slaac_required, N_("Whether SLAAC must be successful"), NULL },
|
||||||
{ "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &global_opt.tempaddr, N_("Use an IPv6 temporary privacy address"), NULL },
|
{ "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &global_opt.tempaddr, N_("Use an IPv6 temporary privacy address"), NULL },
|
||||||
|
@ -469,9 +471,23 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_opt.slaac) {
|
if (global_opt.slaac) {
|
||||||
|
NMUtilsStableType stable_type = NM_UTILS_STABLE_TYPE_UUID;
|
||||||
|
const char *stable_id = global_opt.uuid;
|
||||||
|
|
||||||
nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, TRUE);
|
nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, TRUE);
|
||||||
|
|
||||||
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname, global_opt.uuid, global_opt.addr_gen_mode, NULL);
|
if ( global_opt.stable_id
|
||||||
|
&& (global_opt.stable_id[0] >= '0' && global_opt.stable_id[0] <= '9')
|
||||||
|
&& global_opt.stable_id[1] == ' ') {
|
||||||
|
/* strict parsing of --stable-id, which is the numeric stable-type
|
||||||
|
* and the ID, joined with one space. For now, only support stable-types
|
||||||
|
* from 0 to 9. */
|
||||||
|
stable_type = (global_opt.stable_id[0] - '0');
|
||||||
|
stable_id = &global_opt.stable_id[2];
|
||||||
|
}
|
||||||
|
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname,
|
||||||
|
stable_type, stable_id,
|
||||||
|
global_opt.addr_gen_mode, NULL);
|
||||||
g_assert (rdisc);
|
g_assert (rdisc);
|
||||||
|
|
||||||
if (iid)
|
if (iid)
|
||||||
|
|
|
@ -595,7 +595,7 @@ nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMDevice *
|
static NMDevice *
|
||||||
find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
|
find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr)
|
||||||
{
|
{
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
const char *device_addr;
|
const char *device_addr;
|
||||||
|
@ -604,7 +604,7 @@ find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
|
||||||
|
|
||||||
if (nm_utils_hwaddr_valid (hwaddr, -1)) {
|
if (nm_utils_hwaddr_valid (hwaddr, -1)) {
|
||||||
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
||||||
device_addr = nm_device_get_hw_address (NM_DEVICE (iter->data));
|
device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data), FALSE);
|
||||||
if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
|
if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
|
||||||
return NM_DEVICE (iter->data);
|
return NM_DEVICE (iter->data);
|
||||||
}
|
}
|
||||||
|
@ -945,28 +945,12 @@ remove_device (NMManager *self,
|
||||||
nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
|
nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
|
||||||
|
|
||||||
if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
|
if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
|
||||||
unmanage = TRUE;
|
|
||||||
|
|
||||||
if (!quitting) {
|
if (quitting)
|
||||||
|
unmanage = nm_device_unmanage_on_quit (device);
|
||||||
|
else {
|
||||||
/* the device is already gone. Unmanage it. */
|
/* the device is already gone. Unmanage it. */
|
||||||
} else {
|
unmanage = TRUE;
|
||||||
/* Leave certain devices alone when quitting so their configuration
|
|
||||||
* can be taken over when NM restarts. This ensures connectivity while
|
|
||||||
* NM is stopped.
|
|
||||||
*/
|
|
||||||
if (nm_device_uses_assumed_connection (device)) {
|
|
||||||
/* An assume connection must be left alone */
|
|
||||||
unmanage = FALSE;
|
|
||||||
} else if (!nm_device_get_act_request (device)) {
|
|
||||||
/* a device without any active connection is either UNAVAILABLE or DISCONNECTED
|
|
||||||
* state. Since we don't know whether the device was upped by NetworkManager,
|
|
||||||
* we must leave it up on exit. */
|
|
||||||
unmanage = FALSE;
|
|
||||||
} else if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (device))) {
|
|
||||||
/* The device has no layer 3 configuration. Leave it up. */
|
|
||||||
unmanage = FALSE;
|
|
||||||
} else if (nm_device_can_assume_active_connection (device))
|
|
||||||
unmanage = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unmanage) {
|
if (unmanage) {
|
||||||
|
@ -1054,7 +1038,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM
|
||||||
return parent;
|
return parent;
|
||||||
|
|
||||||
/* Maybe a hardware address */
|
/* Maybe a hardware address */
|
||||||
parent = find_device_by_hw_addr (self, parent_name);
|
parent = find_device_by_permanent_hw_addr (self, parent_name);
|
||||||
if (parent)
|
if (parent)
|
||||||
return parent;
|
return parent;
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,8 @@ NMRDisc *
|
||||||
nm_lndp_rdisc_new (NMPlatform *platform,
|
nm_lndp_rdisc_new (NMPlatform *platform,
|
||||||
int ifindex,
|
int ifindex,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *uuid,
|
NMUtilsStableType stable_type,
|
||||||
|
const char *network_id,
|
||||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -342,7 +343,8 @@ nm_lndp_rdisc_new (NMPlatform *platform,
|
||||||
|
|
||||||
rdisc->ifindex = ifindex;
|
rdisc->ifindex = ifindex;
|
||||||
rdisc->ifname = g_strdup (ifname);
|
rdisc->ifname = g_strdup (ifname);
|
||||||
rdisc->uuid = g_strdup (uuid);
|
rdisc->stable_type = stable_type;
|
||||||
|
rdisc->network_id = g_strdup (network_id);
|
||||||
rdisc->addr_gen_mode = addr_gen_mode;
|
rdisc->addr_gen_mode = addr_gen_mode;
|
||||||
|
|
||||||
rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
|
rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define __NETWORKMANAGER_LNDP_RDISC_H__
|
#define __NETWORKMANAGER_LNDP_RDISC_H__
|
||||||
|
|
||||||
#include "nm-rdisc.h"
|
#include "nm-rdisc.h"
|
||||||
|
#include "nm-core-utils.h"
|
||||||
|
|
||||||
#define NM_TYPE_LNDP_RDISC (nm_lndp_rdisc_get_type ())
|
#define NM_TYPE_LNDP_RDISC (nm_lndp_rdisc_get_type ())
|
||||||
#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDisc))
|
#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDisc))
|
||||||
|
@ -47,7 +48,8 @@ GType nm_lndp_rdisc_get_type (void);
|
||||||
NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform,
|
NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform,
|
||||||
int ifindex,
|
int ifindex,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *uuid,
|
NMUtilsStableType stable_type,
|
||||||
|
const char *network_id,
|
||||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
|
@ -140,9 +140,10 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
|
if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
|
||||||
if (!nm_utils_ipv6_addr_set_stable_privacy (&addr->address,
|
if (!nm_utils_ipv6_addr_set_stable_privacy (rdisc->stable_type,
|
||||||
|
&addr->address,
|
||||||
rdisc->ifname,
|
rdisc->ifname,
|
||||||
rdisc->uuid,
|
rdisc->network_id,
|
||||||
addr->dad_counter++,
|
addr->dad_counter++,
|
||||||
&error)) {
|
&error)) {
|
||||||
_LOGW ("complete-address: failed to generate an stable-privacy address: %s",
|
_LOGW ("complete-address: failed to generate an stable-privacy address: %s",
|
||||||
|
@ -777,7 +778,7 @@ finalize (GObject *object)
|
||||||
NMRDisc *rdisc = NM_RDISC (object);
|
NMRDisc *rdisc = NM_RDISC (object);
|
||||||
|
|
||||||
g_free (rdisc->ifname);
|
g_free (rdisc->ifname);
|
||||||
g_free (rdisc->uuid);
|
g_free (rdisc->network_id);
|
||||||
g_array_unref (rdisc->gateways);
|
g_array_unref (rdisc->gateways);
|
||||||
g_array_unref (rdisc->addresses);
|
g_array_unref (rdisc->addresses);
|
||||||
g_array_unref (rdisc->routes);
|
g_array_unref (rdisc->routes);
|
||||||
|
|
|
@ -116,9 +116,11 @@ typedef struct {
|
||||||
NMPlatform *_platform;
|
NMPlatform *_platform;
|
||||||
NMPNetns *_netns;
|
NMPNetns *_netns;
|
||||||
|
|
||||||
|
NMUtilsStableType stable_type;
|
||||||
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
char *uuid;
|
char *network_id;
|
||||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
|
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
|
||||||
NMUtilsIPv6IfaceId iid;
|
NMUtilsIPv6IfaceId iid;
|
||||||
gint32 max_addresses;
|
gint32 max_addresses;
|
||||||
|
|
|
@ -64,6 +64,7 @@ main (int argc, char **argv)
|
||||||
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||||
ifindex,
|
ifindex,
|
||||||
ifname,
|
ifname,
|
||||||
|
NM_UTILS_STABLE_TYPE_UUID,
|
||||||
"8ce666e8-d34d-4fb1-b858-f15a7al28086",
|
"8ce666e8-d34d-4fb1-b858-f15a7al28086",
|
||||||
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
||||||
&error);
|
&error);
|
||||||
|
|
|
@ -1879,11 +1879,11 @@ have_connection_for_device (NMSettings *self, NMDevice *device)
|
||||||
NMSettingConnection *s_con;
|
NMSettingConnection *s_con;
|
||||||
NMSettingWired *s_wired;
|
NMSettingWired *s_wired;
|
||||||
const char *setting_hwaddr;
|
const char *setting_hwaddr;
|
||||||
const char *device_hwaddr;
|
const char *perm_hw_addr;
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
||||||
|
|
||||||
device_hwaddr = nm_device_get_hw_address (device);
|
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||||
|
|
||||||
/* Find a wired connection locked to the given MAC address, if any */
|
/* Find a wired connection locked to the given MAC address, if any */
|
||||||
g_hash_table_iter_init (&iter, priv->connections);
|
g_hash_table_iter_init (&iter, priv->connections);
|
||||||
|
@ -1917,8 +1917,8 @@ have_connection_for_device (NMSettings *self, NMDevice *device)
|
||||||
setting_hwaddr = nm_setting_wired_get_mac_address (s_wired);
|
setting_hwaddr = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (setting_hwaddr) {
|
if (setting_hwaddr) {
|
||||||
/* A connection mac-locked to this device */
|
/* A connection mac-locked to this device */
|
||||||
if ( device_hwaddr
|
if ( perm_hw_addr
|
||||||
&& nm_utils_hwaddr_matches (setting_hwaddr, -1, device_hwaddr, -1))
|
&& nm_utils_hwaddr_matches (setting_hwaddr, -1, perm_hw_addr, -1))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
/* A connection that applies to any wired device */
|
/* A connection that applies to any wired device */
|
||||||
|
|
|
@ -128,6 +128,7 @@ make_connection_setting (const char *file,
|
||||||
NMSettingConnectionLldp lldp;
|
NMSettingConnectionLldp lldp;
|
||||||
const char *ifcfg_name = NULL;
|
const char *ifcfg_name = NULL;
|
||||||
char *new_id, *uuid = NULL, *zone = NULL, *value;
|
char *new_id, *uuid = NULL, *zone = NULL, *value;
|
||||||
|
gs_free char *stable_id = NULL;
|
||||||
|
|
||||||
ifcfg_name = utils_get_ifcfg_name (file, TRUE);
|
ifcfg_name = utils_get_ifcfg_name (file, TRUE);
|
||||||
if (!ifcfg_name)
|
if (!ifcfg_name)
|
||||||
|
@ -146,9 +147,12 @@ make_connection_setting (const char *file,
|
||||||
uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL);
|
uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stable_id = svGetValue (ifcfg, "STABLE_ID", FALSE);
|
||||||
|
|
||||||
g_object_set (s_con,
|
g_object_set (s_con,
|
||||||
NM_SETTING_CONNECTION_TYPE, type,
|
NM_SETTING_CONNECTION_TYPE, type,
|
||||||
NM_SETTING_CONNECTION_UUID, uuid,
|
NM_SETTING_CONNECTION_UUID, uuid,
|
||||||
|
NM_SETTING_CONNECTION_STABLE_ID, stable_id,
|
||||||
NULL);
|
NULL);
|
||||||
g_free (uuid);
|
g_free (uuid);
|
||||||
|
|
||||||
|
@ -3364,6 +3368,10 @@ make_wireless_setting (shvarFile *ifcfg,
|
||||||
g_free (value);
|
g_free (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = svGetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", FALSE);
|
||||||
|
g_object_set (s_wireless, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, value, NULL);
|
||||||
|
g_free (value);
|
||||||
|
|
||||||
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
||||||
if (value) {
|
if (value) {
|
||||||
char **strv;
|
char **strv;
|
||||||
|
@ -3878,6 +3886,10 @@ make_wired_setting (shvarFile *ifcfg,
|
||||||
g_free (value);
|
g_free (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = svGetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK", FALSE);
|
||||||
|
g_object_set (s_wired, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, value, NULL);
|
||||||
|
g_free (value);
|
||||||
|
|
||||||
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE);
|
||||||
if (value) {
|
if (value) {
|
||||||
char **strv;
|
char **strv;
|
||||||
|
|
|
@ -853,6 +853,10 @@ write_wireless_setting (NMConnection *connection,
|
||||||
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
|
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
|
||||||
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
||||||
|
|
||||||
|
svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK",
|
||||||
|
nm_setting_wireless_get_generate_mac_address_mask (s_wireless),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE);
|
svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE);
|
||||||
macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
|
macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
|
||||||
if (macaddr_blacklist[0]) {
|
if (macaddr_blacklist[0]) {
|
||||||
|
@ -1111,6 +1115,10 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
||||||
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
||||||
|
|
||||||
|
svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK",
|
||||||
|
nm_setting_wired_get_generate_mac_address_mask (s_wired),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE);
|
svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE);
|
||||||
macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
|
macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
|
||||||
if (macaddr_blacklist[0]) {
|
if (macaddr_blacklist[0]) {
|
||||||
|
@ -1255,19 +1263,22 @@ write_wired_for_virtual (NMConnection *connection, shvarFile *ifcfg)
|
||||||
has_wired = TRUE;
|
has_wired = TRUE;
|
||||||
|
|
||||||
device_mac = nm_setting_wired_get_mac_address (s_wired);
|
device_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||||
if (device_mac)
|
svSetValue (ifcfg, "HWADDR", device_mac, FALSE);
|
||||||
svSetValue (ifcfg, "HWADDR", device_mac, FALSE);
|
|
||||||
|
|
||||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
||||||
if (cloned_mac)
|
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
||||||
svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE);
|
|
||||||
|
svSetValue (ifcfg, "GENERATE_MAC_ADDRESS_MASK",
|
||||||
|
nm_setting_wired_get_generate_mac_address_mask (s_wired),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
mtu = nm_setting_wired_get_mtu (s_wired);
|
mtu = nm_setting_wired_get_mtu (s_wired);
|
||||||
if (mtu) {
|
if (mtu) {
|
||||||
tmp = g_strdup_printf ("%u", mtu);
|
tmp = g_strdup_printf ("%u", mtu);
|
||||||
svSetValue (ifcfg, "MTU", tmp, FALSE);
|
svSetValue (ifcfg, "MTU", tmp, FALSE);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
}
|
} else
|
||||||
|
svSetValue (ifcfg, "MTU", NULL, FALSE);
|
||||||
}
|
}
|
||||||
return has_wired;
|
return has_wired;
|
||||||
}
|
}
|
||||||
|
@ -1800,6 +1811,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
|
||||||
|
|
||||||
svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE);
|
svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE);
|
||||||
svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE);
|
svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE);
|
||||||
|
svSetValue (ifcfg, "STABLE_ID", nm_setting_connection_get_stable_id (s_con), FALSE);
|
||||||
svSetValue (ifcfg, "DEVICE", nm_setting_connection_get_interface_name (s_con), FALSE);
|
svSetValue (ifcfg, "DEVICE", nm_setting_connection_get_interface_name (s_con), FALSE);
|
||||||
svSetValue (ifcfg, "ONBOOT",
|
svSetValue (ifcfg, "ONBOOT",
|
||||||
nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no",
|
nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no",
|
||||||
|
|
|
@ -47,7 +47,6 @@ typedef struct
|
||||||
GHashTable *config;
|
GHashTable *config;
|
||||||
GHashTable *blobs;
|
GHashTable *blobs;
|
||||||
guint32 ap_scan;
|
guint32 ap_scan;
|
||||||
NMSettingMacRandomization mac_randomization;
|
|
||||||
gboolean fast_required;
|
gboolean fast_required;
|
||||||
gboolean dispose_has_run;
|
gboolean dispose_has_run;
|
||||||
} NMSupplicantConfigPrivate;
|
} NMSupplicantConfigPrivate;
|
||||||
|
@ -85,7 +84,6 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
|
||||||
(GDestroyNotify) blob_free);
|
(GDestroyNotify) blob_free);
|
||||||
|
|
||||||
priv->ap_scan = 1;
|
priv->ap_scan = 1;
|
||||||
priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
|
|
||||||
priv->dispose_has_run = FALSE;
|
priv->dispose_has_run = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,32 +270,6 @@ nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self)
|
||||||
return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan;
|
return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
|
||||||
nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mac_addr - MAC address policy default
|
|
||||||
*
|
|
||||||
* 0 = use permanent MAC address
|
|
||||||
* 1 = use random MAC address for each ESS connection
|
|
||||||
* 2 = like 1, but maintain OUI (with local admin bit set)
|
|
||||||
*
|
|
||||||
* By default, permanent MAC address is used unless policy is changed by
|
|
||||||
* the per-network mac_addr parameter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->mac_randomization) {
|
|
||||||
case NM_SETTING_MAC_RANDOMIZATION_ALWAYS:
|
|
||||||
return "1";
|
|
||||||
case NM_SETTING_MAC_RANDOMIZATION_NEVER:
|
|
||||||
case NM_SETTING_MAC_RANDOMIZATION_DEFAULT:
|
|
||||||
default:
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_supplicant_config_fast_required (NMSupplicantConfig *self)
|
nm_supplicant_config_fast_required (NMSupplicantConfig *self)
|
||||||
{
|
{
|
||||||
|
@ -385,8 +357,6 @@ gboolean
|
||||||
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
|
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
|
||||||
NMSettingWireless * setting,
|
NMSettingWireless * setting,
|
||||||
guint32 fixed_freq,
|
guint32 fixed_freq,
|
||||||
NMSupplicantFeature mac_randomization_support,
|
|
||||||
NMSettingMacRandomization mac_randomization_fallback,
|
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
NMSupplicantConfigPrivate *priv;
|
NMSupplicantConfigPrivate *priv;
|
||||||
|
@ -477,23 +447,6 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->mac_randomization = nm_setting_wireless_get_mac_address_randomization (setting);
|
|
||||||
if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
|
|
||||||
priv->mac_randomization = mac_randomization_fallback;
|
|
||||||
if (priv->mac_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) {
|
|
||||||
/* Don't use randomization, unless explicitly enabled.
|
|
||||||
* Randomization can work badly with captive portals. */
|
|
||||||
priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( priv->mac_randomization != NM_SETTING_MAC_RANDOMIZATION_NEVER
|
|
||||||
&& mac_randomization_support != NM_SUPPLICANT_FEATURE_YES) {
|
|
||||||
g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
|
|
||||||
"cannot enable mac-randomization due to missing supplicant support");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,6 @@ NMSupplicantConfig *nm_supplicant_config_new (void);
|
||||||
|
|
||||||
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self);
|
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self);
|
||||||
|
|
||||||
const char *nm_supplicant_config_get_mac_randomization (NMSupplicantConfig *self);
|
|
||||||
|
|
||||||
gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self);
|
gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self);
|
||||||
|
|
||||||
GVariant *nm_supplicant_config_to_variant (NMSupplicantConfig *self);
|
GVariant *nm_supplicant_config_to_variant (NMSupplicantConfig *self);
|
||||||
|
@ -65,8 +63,6 @@ GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self);
|
||||||
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self,
|
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self,
|
||||||
NMSettingWireless *setting,
|
NMSettingWireless *setting,
|
||||||
guint32 fixed_freq,
|
guint32 fixed_freq,
|
||||||
NMSupplicantFeature mac_randomization_support,
|
|
||||||
NMSettingMacRandomization mac_randomization_fallback,
|
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
|
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
|
||||||
|
|
|
@ -503,12 +503,6 @@ nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self,
|
||||||
priv->ap_support = ap_support;
|
priv->ap_support = ap_support;
|
||||||
}
|
}
|
||||||
|
|
||||||
NMSupplicantFeature
|
|
||||||
nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self)
|
|
||||||
{
|
|
||||||
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->mac_randomization_support;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_preassoc_scan_mac_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
set_preassoc_scan_mac_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -563,7 +557,7 @@ iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data
|
||||||
g_variant_new ("(ssv)",
|
g_variant_new ("(ssv)",
|
||||||
WPAS_DBUS_IFACE_INTERFACE,
|
WPAS_DBUS_IFACE_INTERFACE,
|
||||||
"PreassocMacAddr",
|
"PreassocMacAddr",
|
||||||
g_variant_new_string ("1")),
|
g_variant_new_string ("0")),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
priv->init_cancellable,
|
priv->init_cancellable,
|
||||||
|
@ -1223,9 +1217,7 @@ set_mac_randomization_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LOGI ("config: set MAC randomization to %s",
|
_LOGT ("config: set MAC randomization to 0");
|
||||||
nm_supplicant_config_get_mac_randomization (priv->cfg));
|
|
||||||
|
|
||||||
add_network (self);
|
add_network (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,23 +1248,20 @@ set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||||
nm_supplicant_config_get_ap_scan (priv->cfg));
|
nm_supplicant_config_get_ap_scan (priv->cfg));
|
||||||
|
|
||||||
if (priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_YES) {
|
if (priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_YES) {
|
||||||
const char *mac_randomization = nm_supplicant_config_get_mac_randomization (priv->cfg);
|
|
||||||
|
|
||||||
/* Enable/disable association MAC address randomization */
|
/* Enable/disable association MAC address randomization */
|
||||||
g_dbus_proxy_call (priv->iface_proxy,
|
g_dbus_proxy_call (priv->iface_proxy,
|
||||||
DBUS_INTERFACE_PROPERTIES ".Set",
|
DBUS_INTERFACE_PROPERTIES ".Set",
|
||||||
g_variant_new ("(ssv)",
|
g_variant_new ("(ssv)",
|
||||||
WPAS_DBUS_IFACE_INTERFACE,
|
WPAS_DBUS_IFACE_INTERFACE,
|
||||||
"MacAddr",
|
"MacAddr",
|
||||||
g_variant_new_string (mac_randomization)),
|
g_variant_new_string ("0")),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
priv->assoc_cancellable,
|
priv->assoc_cancellable,
|
||||||
(GAsyncReadyCallback) set_mac_randomization_cb,
|
(GAsyncReadyCallback) set_mac_randomization_cb,
|
||||||
self);
|
self);
|
||||||
} else {
|
} else
|
||||||
add_network (self);
|
add_network (self);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -165,6 +165,4 @@ NMSupplicantFeature nm_supplicant_interface_get_ap_support (NMSupplicantInterfac
|
||||||
void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self,
|
void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self,
|
||||||
NMSupplicantFeature apmode);
|
NMSupplicantFeature apmode);
|
||||||
|
|
||||||
NMSupplicantFeature nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self);
|
|
||||||
|
|
||||||
#endif /* NM_SUPPLICANT_INTERFACE_H */
|
#endif /* NM_SUPPLICANT_INTERFACE_H */
|
||||||
|
|
|
@ -160,8 +160,6 @@ test_wifi_open (void)
|
||||||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||||
s_wifi,
|
s_wifi,
|
||||||
0,
|
0,
|
||||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
|
||||||
&error));
|
&error));
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
@ -265,8 +263,6 @@ test_wifi_wep_key (const char *detail,
|
||||||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||||
s_wifi,
|
s_wifi,
|
||||||
0,
|
0,
|
||||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
|
||||||
&error));
|
&error));
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
@ -410,8 +406,6 @@ test_wifi_wpa_psk (const char *detail,
|
||||||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||||
s_wifi,
|
s_wifi,
|
||||||
0,
|
0,
|
||||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
|
||||||
&error));
|
&error));
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
@ -557,8 +551,6 @@ test_wifi_eap (void)
|
||||||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||||
s_wifi,
|
s_wifi,
|
||||||
0,
|
0,
|
||||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
|
||||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
|
||||||
&error));
|
&error));
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
|
|
@ -38,17 +38,6 @@ nm_test_device_init (NMTestDevice *self)
|
||||||
/* We jump over NMDevice's construct/destruct methods, which require NMPlatform
|
/* We jump over NMDevice's construct/destruct methods, which require NMPlatform
|
||||||
* and NMConnectionProvider to be initialized.
|
* and NMConnectionProvider to be initialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static GObject*
|
|
||||||
constructor (GType type,
|
|
||||||
guint n_construct_params,
|
|
||||||
GObjectConstructParam *construct_params)
|
|
||||||
{
|
|
||||||
return PARENT_CLASS->constructor (type,
|
|
||||||
n_construct_params,
|
|
||||||
construct_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constructed (GObject *object)
|
constructed (GObject *object)
|
||||||
{
|
{
|
||||||
|
@ -73,7 +62,6 @@ nm_test_device_class_init (NMTestDeviceClass *klass)
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
|
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
object_class->constructor = constructor;
|
|
||||||
object_class->constructed = constructed;
|
object_class->constructed = constructed;
|
||||||
object_class->dispose = dispose;
|
object_class->dispose = dispose;
|
||||||
|
|
||||||
|
@ -85,6 +73,6 @@ nm_test_device_new (const char *hwaddr)
|
||||||
{
|
{
|
||||||
return g_object_new (NM_TYPE_TEST_DEVICE,
|
return g_object_new (NM_TYPE_TEST_DEVICE,
|
||||||
NM_DEVICE_IFACE, "dummy",
|
NM_DEVICE_IFACE, "dummy",
|
||||||
NM_DEVICE_HW_ADDRESS, hwaddr,
|
NM_DEVICE_PERM_HW_ADDRESS, hwaddr,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,21 +34,93 @@ test_stable_privacy (void)
|
||||||
struct in6_addr addr1;
|
struct in6_addr addr1;
|
||||||
|
|
||||||
inet_pton (AF_INET6, "1234::", &addr1);
|
inet_pton (AF_INET6, "1234::", &addr1);
|
||||||
_set_stable_privacy (&addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL);
|
_set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL);
|
||||||
nmtst_assert_ip6_address (&addr1, "1234::4ceb:14cd:3d54:793f");
|
nmtst_assert_ip6_address (&addr1, "1234::4ceb:14cd:3d54:793f");
|
||||||
|
|
||||||
/* We get an address without the UUID. */
|
/* We get an address without the UUID. */
|
||||||
inet_pton (AF_INET6, "1::", &addr1);
|
inet_pton (AF_INET6, "1::", &addr1);
|
||||||
_set_stable_privacy (&addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL);
|
_set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL);
|
||||||
nmtst_assert_ip6_address (&addr1, "1::11aa:2530:9144:dafa");
|
nmtst_assert_ip6_address (&addr1, "1::11aa:2530:9144:dafa");
|
||||||
|
|
||||||
/* We get a different address in a different network. */
|
/* We get a different address in a different network. */
|
||||||
inet_pton (AF_INET6, "2::", &addr1);
|
inet_pton (AF_INET6, "2::", &addr1);
|
||||||
_set_stable_privacy (&addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL);
|
_set_stable_privacy (NM_UTILS_STABLE_TYPE_UUID, &addr1, "eth666", NULL, 384, (guint8 *) "key", 3, NULL);
|
||||||
nmtst_assert_ip6_address (&addr1, "2::338e:8d:c11:8726");
|
nmtst_assert_ip6_address (&addr1, "2::338e:8d:c11:8726");
|
||||||
|
|
||||||
|
inet_pton (AF_INET6, "1234::", &addr1);
|
||||||
|
_set_stable_privacy (NM_UTILS_STABLE_TYPE_STABLE_ID, &addr1, "eth666", "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", 0, (guint8 *) "key", 3, NULL);
|
||||||
|
nmtst_assert_ip6_address (&addr1, "1234::ad4c:ae44:3d30:af1e");
|
||||||
|
|
||||||
|
inet_pton (AF_INET6, "1234::", &addr1);
|
||||||
|
_set_stable_privacy (NM_UTILS_STABLE_TYPE_STABLE_ID, &addr1, "eth666", "stable-id-1", 0, (guint8 *) "key", 3, NULL);
|
||||||
|
nmtst_assert_ip6_address (&addr1, "1234::4944:67b0:7a6c:1cf");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
_do_test_hw_addr (NMUtilsStableType stable_type,
|
||||||
|
const char *stable_id,
|
||||||
|
const guint8 *secret_key,
|
||||||
|
gsize key_len,
|
||||||
|
const char *ifname,
|
||||||
|
const char *current_mac_address,
|
||||||
|
const char *generate_mac_address_mask,
|
||||||
|
const char **expected)
|
||||||
|
{
|
||||||
|
gs_free char *generated = NULL;
|
||||||
|
const char **e;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
for (e = expected; *e; e++) {
|
||||||
|
g_assert (*e);
|
||||||
|
g_assert (nm_utils_hwaddr_valid (*e, ETH_ALEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
generated = _hw_addr_gen_stable_eth (stable_type,
|
||||||
|
stable_id,
|
||||||
|
secret_key,
|
||||||
|
key_len,
|
||||||
|
ifname,
|
||||||
|
current_mac_address,
|
||||||
|
generate_mac_address_mask);
|
||||||
|
|
||||||
|
g_assert (generated);
|
||||||
|
g_assert (nm_utils_hwaddr_valid (generated, ETH_ALEN));
|
||||||
|
for (e = expected; *e; e++) {
|
||||||
|
if (!nm_utils_hwaddr_matches (generated, -1, *e, -1))
|
||||||
|
continue;
|
||||||
|
g_assert (!found);
|
||||||
|
found = TRUE;
|
||||||
|
g_assert_cmpstr (generated, ==, *e);
|
||||||
|
}
|
||||||
|
g_assert (found);
|
||||||
|
}
|
||||||
|
#define do_test_hw_addr(stable_type, stable_id, secret_key, ifname, current_mac_address, generate_mac_address_mask, ...) \
|
||||||
|
_do_test_hw_addr ((stable_type), (stable_id), (const guint8 *) ""secret_key"", NM_STRLEN (secret_key), (ifname), ""current_mac_address"", generate_mac_address_mask, (const char *[]) { __VA_ARGS__, NULL })
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_hw_addr_gen_stable_eth (void)
|
||||||
|
{
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", NULL, "06:0D:CD:0C:9E:2C");
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_STABLE_ID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", NULL, "C6:AE:A9:9A:76:09");
|
||||||
|
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "FF:FF:FF:00:00:00", "00:23:45:0C:9E:2C");
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "03:23:45:67:89:ab", "FF:FF:FF:00:00:00", "02:23:45:0C:9E:2C");
|
||||||
|
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "00:00:00:00:00:00", "06:0D:CD:0C:9E:2C");
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00", "04:0D:CD:0C:9E:2C");
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00", "04:0D:CD:0C:9E:2C");
|
||||||
|
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 00:00:00:00:00:00", "04:0D:CD:0C:9E:2C");
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 02:00:00:00:00:00", "06:0D:CD:0C:9E:2C");
|
||||||
|
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "00:00:00:00:00:00 E9:60:CE:F5:ED:2F", "06:0D:CD:0C:9E:2C");
|
||||||
|
|
||||||
|
do_test_hw_addr (NM_UTILS_STABLE_TYPE_UUID, "stable-1", "key1", "eth0", "01:23:45:67:89:ab", "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00", "06:0D:CD:0C:9E:2C", "04:0D:CD:0C:9E:2C");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
NMTST_DEFINE ();
|
NMTST_DEFINE ();
|
||||||
|
|
||||||
|
@ -58,6 +130,7 @@ main (int argc, char **argv)
|
||||||
nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
|
nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
|
||||||
|
|
||||||
g_test_add_func ("/utils/stable_privacy", test_stable_privacy);
|
g_test_add_func ("/utils/stable_privacy", test_stable_privacy);
|
||||||
|
g_test_add_func ("/utils/hw_addr_gen_stable_eth", test_hw_addr_gen_stable_eth);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue