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 <arpa/inet.h>
|
||||
|
||||
#include "nm-common-macros.h"
|
||||
#include "utils.h"
|
||||
#include "common.h"
|
||||
#include "nm-vpn-helpers.h"
|
||||
|
@ -44,26 +45,28 @@ NmcOutputField nmc_fields_setting_connection[] = {
|
|||
SETTING_FIELD ("name"), /* 0 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_ID), /* 1 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_UUID), /* 2 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_INTERFACE_NAME), /* 3 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_TYPE), /* 4 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT), /* 5 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY), /* 6 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY), /* 8 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS), /* 9 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_ZONE), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_MASTER), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE), /* 12 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES), /* 13 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES), /* 14 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT), /* 15 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_METERED), /* 16 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_LLDP), /* 17 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_STABLE_ID), /* 3 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_INTERFACE_NAME), /* 4 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_TYPE), /* 5 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT), /* 6 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP), /* 8 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY), /* 9 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_ZONE), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_MASTER), /* 12 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE), /* 13 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES), /* 14 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES), /* 15 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT), /* 16 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_METERED), /* 17 */
|
||||
SETTING_FIELD (NM_SETTING_CONNECTION_LLDP), /* 18 */
|
||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||
};
|
||||
#define NMC_FIELDS_SETTING_CONNECTION_ALL "name"","\
|
||||
NM_SETTING_CONNECTION_ID","\
|
||||
NM_SETTING_CONNECTION_UUID","\
|
||||
NM_SETTING_CONNECTION_STABLE_ID","\
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME","\
|
||||
NM_SETTING_CONNECTION_TYPE","\
|
||||
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_MAC_ADDRESS), /* 5 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS), /* 6 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_MTU), /* 8 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS), /* 9 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN), /* 12 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD), /* 13 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST), /* 8 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_MTU), /* 9 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS), /* 12 */
|
||||
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}
|
||||
};
|
||||
#define NMC_FIELDS_SETTING_WIRED_ALL "name"","\
|
||||
|
@ -105,6 +109,7 @@ NmcOutputField nmc_fields_setting_wired[] = {
|
|||
NM_SETTING_WIRED_AUTO_NEGOTIATE","\
|
||||
NM_SETTING_WIRED_MAC_ADDRESS","\
|
||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
|
||||
NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK","\
|
||||
NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST","\
|
||||
NM_SETTING_WIRED_MTU","\
|
||||
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_MAC_ADDRESS), /* 8 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS), /* 9 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MTU), /* 12 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS), /* 13 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_HIDDEN), /* 14 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_POWERSAVE), /* 15 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK), /* 10 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST), /* 11 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION), /* 12 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_MTU), /* 13 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS), /* 14 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_HIDDEN), /* 15 */
|
||||
SETTING_FIELD (NM_SETTING_WIRELESS_POWERSAVE), /* 16 */
|
||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||
};
|
||||
#define NMC_FIELDS_SETTING_WIRELESS_ALL "name"","\
|
||||
|
@ -218,6 +224,7 @@ NmcOutputField nmc_fields_setting_wireless[] = {
|
|||
NM_SETTING_WIRELESS_TX_POWER","\
|
||||
NM_SETTING_WIRELESS_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_RANDOMIZATION","\
|
||||
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 --- */
|
||||
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_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_type, NM_SETTING_CONNECTION_TYPE)
|
||||
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_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_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_s390_subchannels, NM_SETTING_WIRED_S390_SUBCHANNELS)
|
||||
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_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_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_seen_bssids, NM_SETTING_WIRELESS_SEEN_BSSIDS)
|
||||
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
|
||||
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);
|
||||
|
||||
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);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2899,6 +2910,18 @@ nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GEr
|
|||
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
|
||||
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);
|
||||
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_property_connection_get_interface_name,
|
||||
nmc_property_set_ifname,
|
||||
|
@ -7188,7 +7218,14 @@ nmc_properties_init (void)
|
|||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (WIRED, 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,
|
||||
|
@ -7306,7 +7343,14 @@ nmc_properties_init (void)
|
|||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (WIRELESS, 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,
|
||||
|
@ -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, 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, 3, nmc_property_connection_get_interface_name (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 4, nmc_property_connection_get_type (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 5, nmc_property_connection_get_autoconnect (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, 7, nmc_property_connection_get_timestamp (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, 9, nmc_property_connection_get_permissions (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 10, nmc_property_connection_get_zone (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 11, nmc_property_connection_get_master (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, 13, nmc_property_connection_get_autoconnect_slaves (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 14, nmc_property_connection_get_secondaries (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, 16, nmc_property_connection_get_metered (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 17, nmc_property_connection_get_lldp (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_interface_name (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 (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_timestamp (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_permissions (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_master (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_autoconnect_slaves (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_gateway_ping_timeout (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);
|
||||
|
||||
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, 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, 7, nmc_property_wired_get_mac_address_blacklist (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 8, nmc_property_wired_get_mtu (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, 10, nmc_property_wired_get_s390_nettype (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, 12, nmc_property_wired_get_wake_on_lan (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, 7, nmc_property_wired_get_generate_mac_address_mask (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_mtu (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_nettype (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 (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);
|
||||
|
||||
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, 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, 10, nmc_property_wireless_get_mac_address_blacklist (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, 12, nmc_property_wireless_get_mtu (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, 14, nmc_property_wireless_get_hidden (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 15, nmc_property_wireless_get_powersave (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_blacklist (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_mtu (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_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);
|
||||
|
||||
print_data (nmc); /* Print all data */
|
||||
|
|
|
@ -28,11 +28,13 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nmt-mac-entry.h"
|
||||
|
||||
#include <string.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)
|
||||
|
||||
|
@ -41,6 +43,7 @@ G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
|
|||
typedef struct {
|
||||
int mac_length;
|
||||
int mac_str_length;
|
||||
NmtMacEntryType entry_type;
|
||||
|
||||
} NmtMacEntryPrivate;
|
||||
|
||||
|
@ -48,6 +51,7 @@ enum {
|
|||
PROP_0,
|
||||
PROP_MAC_LENGTH,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_ENTRY_TYPE,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
@ -57,6 +61,7 @@ enum {
|
|||
* @width: the width in characters of the entry
|
||||
* @mac_length: the length in bytes of the hardware address
|
||||
* (either %ETH_ALEN or %INFINIBAND_ALEN)
|
||||
* @entry_type: the type of the entry.
|
||||
*
|
||||
* Creates a new #NmtMacEntry.
|
||||
*
|
||||
|
@ -64,11 +69,13 @@ enum {
|
|||
*/
|
||||
NmtNewtWidget *
|
||||
nmt_mac_entry_new (int width,
|
||||
int mac_length)
|
||||
int mac_length,
|
||||
NmtMacEntryType entry_type)
|
||||
{
|
||||
return g_object_new (NMT_TYPE_MAC_ENTRY,
|
||||
"width", width,
|
||||
"mac-length", mac_length,
|
||||
"entry-type", (int) entry_type,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -81,6 +88,9 @@ mac_filter (NmtNewtEntry *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)
|
||||
return FALSE;
|
||||
|
||||
|
@ -98,6 +108,11 @@ mac_validator (NmtNewtEntry *entry,
|
|||
if (!*text)
|
||||
return TRUE;
|
||||
|
||||
if (priv->entry_type == NMT_MAC_ENTRY_TYPE_CLONED) {
|
||||
if (NM_CLONED_MAC_IS_SPECIAL (text))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
p = text;
|
||||
while ( g_ascii_isxdigit (p[0])
|
||||
&& g_ascii_isxdigit (p[1])
|
||||
|
@ -112,7 +127,9 @@ mac_validator (NmtNewtEntry *entry,
|
|||
if (!*p)
|
||||
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);
|
||||
|
||||
nmt_newt_entry_set_text (entry, fixed);
|
||||
|
@ -161,6 +178,10 @@ nmt_mac_entry_set_property (GObject *object,
|
|||
case PROP_MAC_ADDRESS:
|
||||
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ENTRY_TYPE:
|
||||
/* construct-only */
|
||||
priv->entry_type = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -182,6 +203,9 @@ nmt_mac_entry_get_property (GObject *object,
|
|||
case PROP_MAC_ADDRESS:
|
||||
g_value_set_string (value, nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)));
|
||||
break;
|
||||
case PROP_ENTRY_TYPE:
|
||||
g_value_set_int (value, priv->entry_type);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -224,4 +248,17 @@ nmt_mac_entry_class_init (NmtMacEntryClass *entry_class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
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
|
||||
|
||||
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_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))
|
||||
|
@ -45,7 +50,8 @@ typedef struct {
|
|||
GType nmt_mac_entry_get_type (void);
|
||||
|
||||
NmtNewtWidget *nmt_mac_entry_new (int width,
|
||||
int mac_length);
|
||||
int mac_length,
|
||||
NmtMacEntryType type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ nmt_page_ethernet_constructed (GObject *object)
|
|||
section = nmt_editor_section_new (_("ETHERNET"), NULL, FALSE);
|
||||
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,
|
||||
widget, "mac-address",
|
||||
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);
|
||||
|
||||
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,
|
||||
widget, "mac-address",
|
||||
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);
|
||||
|
||||
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,
|
||||
widget, "mac-address",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
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,
|
||||
widget, "mac-address",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
|
|
@ -847,6 +847,52 @@ _normalize_bond_mode (NMConnection *self, GHashTable *parameters)
|
|||
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:
|
||||
* @connection: the #NMConnection to verify
|
||||
|
@ -1089,6 +1135,7 @@ nm_connection_normalize (NMConnection *connection,
|
|||
was_modified |= _normalize_ip_config (connection, parameters);
|
||||
was_modified |= _normalize_infiniband_mtu (connection, parameters);
|
||||
was_modified |= _normalize_bond_mode (connection, parameters);
|
||||
was_modified |= _normalize_wireless_mac_address_randomization (connection, parameters);
|
||||
|
||||
/* Verify anew. */
|
||||
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);
|
||||
|
||||
guint _nm_utils_hwaddr_length (const char *asc);
|
||||
|
||||
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
||||
|
||||
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 {
|
||||
NM_BOND_OPTION_TYPE_INT,
|
||||
NM_BOND_OPTION_TYPE_STRING,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-common-macros.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-keyfile-utils.h"
|
||||
|
||||
|
@ -581,19 +582,28 @@ ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const cha
|
|||
}
|
||||
|
||||
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);
|
||||
char *tmp_string = NULL, *p, *mac_str;
|
||||
gint *tmp_list;
|
||||
GByteArray *array = NULL;
|
||||
gs_free char *tmp_string = NULL;
|
||||
const char *p, *mac_str;
|
||||
gs_free guint8 *buf_arr = NULL;
|
||||
guint buf_len;
|
||||
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]) {
|
||||
/* Look for enough ':' characters to signify a MAC address */
|
||||
guint i = 0;
|
||||
|
||||
p = tmp_string;
|
||||
while (*p) {
|
||||
if (*p == ':')
|
||||
i++;
|
||||
|
@ -602,23 +612,24 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
|
|||
|
||||
if (enforce_length == 0 || enforce_length == i+1) {
|
||||
/* If we found enough it's probably a string-format MAC address */
|
||||
array = g_byte_array_sized_new (i+1);
|
||||
g_byte_array_set_size (array, i+1);
|
||||
if (!nm_utils_hwaddr_aton (tmp_string, array->data, array->len)) {
|
||||
g_byte_array_unref (array);
|
||||
array = NULL;
|
||||
buf_len = i + 1;
|
||||
buf_arr = g_new (guint8, buf_len);
|
||||
if (!nm_utils_hwaddr_aton (tmp_string, buf_arr, buf_len))
|
||||
g_clear_pointer (&buf_arr, g_free);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 */
|
||||
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)) {
|
||||
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++) {
|
||||
int val = tmp_list[i];
|
||||
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,
|
||||
_("ignoring invalid byte element '%d' (not between 0 and 255 inclusive)"),
|
||||
val);
|
||||
g_byte_array_free (array, TRUE);
|
||||
g_free (tmp_list);
|
||||
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,
|
||||
_("ignoring invalid MAC address"));
|
||||
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_free (mac_str);
|
||||
g_byte_array_free (array, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
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
|
||||
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
|
||||
|
@ -1209,7 +1224,7 @@ static KeyParser key_parsers[] = {
|
|||
{ NM_SETTING_WIRED_SETTING_NAME,
|
||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||
TRUE,
|
||||
mac_address_parser_ETHER },
|
||||
mac_address_parser_ETHER_cloned },
|
||||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_MAC_ADDRESS,
|
||||
TRUE,
|
||||
|
@ -1217,7 +1232,7 @@ static KeyParser key_parsers[] = {
|
|||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||
TRUE,
|
||||
mac_address_parser_ETHER },
|
||||
mac_address_parser_ETHER_cloned },
|
||||
{ NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_BSSID,
|
||||
TRUE,
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
char *id;
|
||||
char *uuid;
|
||||
char *stable_id;
|
||||
char *interface_name;
|
||||
char *type;
|
||||
char *master;
|
||||
|
@ -99,6 +100,7 @@ enum {
|
|||
PROP_GATEWAY_PING_TIMEOUT,
|
||||
PROP_METERED,
|
||||
PROP_LLDP,
|
||||
PROP_STABLE_ID,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
@ -230,6 +232,24 @@ nm_setting_connection_get_uuid (NMSettingConnection *setting)
|
|||
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:
|
||||
* @setting: the #NMSettingConnection
|
||||
|
@ -1128,6 +1148,7 @@ finalize (GObject *object)
|
|||
|
||||
g_free (priv->id);
|
||||
g_free (priv->uuid);
|
||||
g_free (priv->stable_id);
|
||||
g_free (priv->interface_name);
|
||||
g_free (priv->type);
|
||||
g_free (priv->zone);
|
||||
|
@ -1174,6 +1195,10 @@ set_property (GObject *object, guint prop_id,
|
|||
g_free (priv->uuid);
|
||||
priv->uuid = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_STABLE_ID:
|
||||
g_free (priv->stable_id);
|
||||
priv->stable_id = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_INTERFACE_NAME:
|
||||
g_free (priv->interface_name);
|
||||
priv->interface_name = g_value_dup_string (value);
|
||||
|
@ -1260,6 +1285,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_UUID:
|
||||
g_value_set_string (value, nm_setting_connection_get_uuid (setting));
|
||||
break;
|
||||
case PROP_STABLE_ID:
|
||||
g_value_set_string (value, nm_setting_connection_get_stable_id (setting));
|
||||
break;
|
||||
case PROP_INTERFACE_NAME:
|
||||
g_value_set_string (value, nm_setting_connection_get_interface_name (setting));
|
||||
break;
|
||||
|
@ -1368,7 +1396,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
|
|||
* property: uuid
|
||||
* variable: UUID(+)
|
||||
* 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---
|
||||
*/
|
||||
g_object_class_install_property
|
||||
|
@ -1379,6 +1407,33 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
|
|||
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||
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:
|
||||
*
|
||||
|
|
|
@ -46,6 +46,7 @@ G_BEGIN_DECLS
|
|||
|
||||
#define NM_SETTING_CONNECTION_ID "id"
|
||||
#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_TYPE "type"
|
||||
#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect"
|
||||
|
@ -116,6 +117,8 @@ GType nm_setting_connection_get_type (void);
|
|||
NMSetting * nm_setting_connection_new (void);
|
||||
const char *nm_setting_connection_get_id (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_connection_type (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:
|
||||
* @address: the #NMIPAddress
|
||||
|
@ -312,17 +358,7 @@ nm_ip_address_unref (NMIPAddress *address)
|
|||
gboolean
|
||||
nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
|
||||
{
|
||||
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;
|
||||
return TRUE;
|
||||
return _nm_ip_address_equal (address, other, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -717,17 +753,18 @@ nm_ip_route_unref (NMIPRoute *route)
|
|||
}
|
||||
|
||||
/**
|
||||
* nm_ip_route_equal:
|
||||
* _nm_ip_route_equal:
|
||||
* @route: the #NMIPRoute
|
||||
* @other: the #NMIPRoute to compare @route to.
|
||||
* @consider_attributes: whether to compare attributes too
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
gboolean
|
||||
nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
|
||||
static gboolean
|
||||
_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->refcount > 0, FALSE);
|
||||
|
@ -740,9 +777,45 @@ nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
|
|||
|| strcmp (route->dest, other->dest) != 0
|
||||
|| g_strcmp0 (route->next_hop, other->next_hop) != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* @route: the #NMIPRoute
|
||||
|
@ -2306,6 +2379,48 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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
|
||||
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->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
parent_class->compare_property = compare_property;
|
||||
|
||||
/* Properties */
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <net/ethernet.h>
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-common-macros.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-setting-private.h"
|
||||
|
||||
|
@ -52,6 +53,7 @@ typedef struct {
|
|||
gboolean auto_negotiate;
|
||||
char *device_mac_address;
|
||||
char *cloned_mac_address;
|
||||
char *generate_mac_address_mask;
|
||||
GArray *mac_address_blacklist;
|
||||
guint32 mtu;
|
||||
char **s390_subchannels;
|
||||
|
@ -69,6 +71,7 @@ enum {
|
|||
PROP_AUTO_NEGOTIATE,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_CLONED_MAC_ADDRESS,
|
||||
PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||
PROP_MAC_ADDRESS_BLACKLIST,
|
||||
PROP_MTU,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* @setting: the #NMSettingWired
|
||||
|
@ -611,6 +630,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
GHashTableIter iter;
|
||||
const char *key, *value;
|
||||
int i;
|
||||
GError *local = NULL;
|
||||
|
||||
if (priv->port && !g_strv_contains (valid_ports, priv->port)) {
|
||||
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,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
@ -701,6 +723,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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)
|
||||
&& !nm_utils_is_power_of_two (priv->wol)) {
|
||||
g_set_error_literal (error,
|
||||
|
@ -732,6 +768,25 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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
|
||||
clear_blacklist_item (char **item_p)
|
||||
{
|
||||
|
@ -763,6 +818,7 @@ finalize (GObject *object)
|
|||
|
||||
g_free (priv->device_mac_address);
|
||||
g_free (priv->cloned_mac_address);
|
||||
g_free (priv->generate_mac_address_mask);
|
||||
g_array_unref (priv->mac_address_blacklist);
|
||||
|
||||
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),
|
||||
ETH_ALEN);
|
||||
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:
|
||||
blacklist = g_value_get_boxed (value);
|
||||
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:
|
||||
g_value_set_string (value, nm_setting_wired_get_cloned_mac_address (setting));
|
||||
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:
|
||||
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
||||
break;
|
||||
|
@ -900,18 +963,19 @@ get_property (GObject *object, guint prop_id,
|
|||
}
|
||||
|
||||
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);
|
||||
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (setting_wired_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 */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
setting_class->verify = verify;
|
||||
setting_class->compare_property = compare_property;
|
||||
|
||||
/* Properties */
|
||||
/**
|
||||
|
@ -1023,7 +1087,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
|||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
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,
|
||||
_nm_utils_hwaddr_to_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
|
||||
* 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---
|
||||
* 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
|
||||
* notation (e.g. 00:22:68:14:5A:99).
|
||||
* ---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
|
||||
(object_class, PROP_CLONED_MAC_ADDRESS,
|
||||
|
@ -1055,10 +1139,75 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
|||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||
_nm_setting_class_override_property (setting_class,
|
||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||
G_VARIANT_TYPE_BYTESTRING,
|
||||
_nm_utils_hwaddr_to_dbus,
|
||||
_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:
|
||||
|
@ -1183,7 +1332,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
|
|||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
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}"),
|
||||
_nm_utils_strdict_to_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_MAC_ADDRESS "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_MTU "mtu"
|
||||
#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_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);
|
||||
guint32 nm_setting_wired_get_num_mac_blacklist_items (NMSettingWired *setting);
|
||||
const char * nm_setting_wired_get_mac_blacklist_item (NMSettingWired *setting,
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-setting-wireless.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-common-macros.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-setting-private.h"
|
||||
|
||||
|
@ -54,6 +56,7 @@ typedef struct {
|
|||
guint32 tx_power;
|
||||
char *device_mac_address;
|
||||
char *cloned_mac_address;
|
||||
char *generate_mac_address_mask;
|
||||
GArray *mac_address_blacklist;
|
||||
guint32 mtu;
|
||||
GSList *seen_bssids;
|
||||
|
@ -73,6 +76,7 @@ enum {
|
|||
PROP_TX_POWER,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_CLONED_MAC_ADDRESS,
|
||||
PROP_GENERATE_MAC_ADDRESS_MASK,
|
||||
PROP_MAC_ADDRESS_BLACKLIST,
|
||||
PROP_MTU,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* @setting: the #NMSettingWireless
|
||||
|
@ -721,6 +741,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
GSList *iter;
|
||||
int i;
|
||||
gsize length;
|
||||
GError *local = NULL;
|
||||
|
||||
if (!priv->ssid) {
|
||||
g_set_error_literal (error,
|
||||
|
@ -801,7 +822,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
@ -810,6 +833,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 *
|
||||
nm_setting_wireless_get_security (NMSetting *setting,
|
||||
NMConnection *connection,
|
||||
|
@ -879,6 +968,7 @@ finalize (GObject *object)
|
|||
g_free (priv->bssid);
|
||||
g_free (priv->device_mac_address);
|
||||
g_free (priv->cloned_mac_address);
|
||||
g_free (priv->generate_mac_address_mask);
|
||||
g_array_unref (priv->mac_address_blacklist);
|
||||
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),
|
||||
ETH_ALEN);
|
||||
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:
|
||||
blacklist = g_value_get_boxed (value);
|
||||
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:
|
||||
g_value_set_string (value, nm_setting_wireless_get_cloned_mac_address (setting));
|
||||
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:
|
||||
g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data);
|
||||
break;
|
||||
|
@ -1023,18 +1120,19 @@ get_property (GObject *object, guint prop_id,
|
|||
}
|
||||
|
||||
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);
|
||||
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (setting_wireless_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 */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
setting_class->verify = verify;
|
||||
setting_class->compare_property = compare_property;
|
||||
|
||||
/* Properties */
|
||||
/**
|
||||
|
@ -1154,7 +1252,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
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,
|
||||
_nm_utils_hwaddr_to_dbus,
|
||||
_nm_utils_hwaddr_from_dbus);
|
||||
|
@ -1231,7 +1329,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
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,
|
||||
_nm_utils_hwaddr_to_dbus,
|
||||
_nm_utils_hwaddr_from_dbus);
|
||||
|
@ -1239,8 +1337,22 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
/**
|
||||
* NMSettingWireless:cloned-mac-address:
|
||||
*
|
||||
* If specified, request that the Wi-Fi device use this MAC address instead
|
||||
* of its permanent MAC address. This is known as MAC cloning or spoofing.
|
||||
* If specified, request that the device use this MAC address instead of its
|
||||
* 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---
|
||||
* 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
|
||||
* notation (e.g. 00:22:68:14:5A:99).
|
||||
* ---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
|
||||
(object_class, PROP_CLONED_MAC_ADDRESS,
|
||||
|
@ -1262,10 +1380,75 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
_nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||
_nm_setting_class_override_property (setting_class,
|
||||
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
|
||||
G_VARIANT_TYPE_BYTESTRING,
|
||||
_nm_utils_hwaddr_to_dbus,
|
||||
_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:
|
||||
|
@ -1398,6 +1581,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
* (always randomize the MAC address).
|
||||
*
|
||||
* Since: 1.2
|
||||
* Deprecated: 1.4: Deprecated by NMSettingWireless:cloned-mac-address property
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: mac-address-randomization
|
||||
|
@ -1428,7 +1612,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
|
|||
* NetworkManager daemons.
|
||||
* ---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,
|
||||
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_MAC_ADDRESS "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_MTU "mtu"
|
||||
#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_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);
|
||||
guint32 nm_setting_wireless_get_num_mac_blacklist_items (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 */
|
||||
|
||||
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);
|
||||
void _nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
||||
GValue *prop_value);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <jansson.h>
|
||||
#endif
|
||||
|
||||
#include "nm-common-macros.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-setting-private.h"
|
||||
#include "crypto.h"
|
||||
|
@ -3114,6 +3115,33 @@ hwaddr_binary_len (const char *asc)
|
|||
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:
|
||||
* @asc: the ASCII representation of a hardware address
|
||||
|
@ -3286,24 +3314,124 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1,
|
|||
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];
|
||||
int len;
|
||||
|
||||
if (str) {
|
||||
len = hwaddr_binary_len (str);
|
||||
g_return_val_if_fail (len > 0 && len <= NM_UTILS_HWADDR_LEN_MAX, NULL);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
len = _nm_utils_hwaddr_length (str);
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (!nm_utils_hwaddr_aton (str, buf, len))
|
||||
len = 0;
|
||||
} else
|
||||
len = 0;
|
||||
return NULL;
|
||||
|
||||
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
|
||||
_nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
||||
GValue *prop_value)
|
||||
|
@ -3316,6 +3444,93 @@ _nm_utils_hwaddr_from_dbus (GVariant *dbus_value,
|
|||
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:
|
||||
* @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_ID, 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_TYPE, 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_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_MTU, 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);
|
||||
}
|
||||
|
||||
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
|
||||
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_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_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);
|
||||
#define ADD_FUNC(name, func, secret_flags, comp_flags, remove_secret) \
|
||||
g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func) "_" name, \
|
||||
|
|
|
@ -1066,8 +1066,11 @@ libnm_1_2_4 {
|
|||
libnm_1_4_0 {
|
||||
global:
|
||||
nm_device_team_get_config;
|
||||
nm_setting_connection_get_stable_id;
|
||||
nm_setting_ip6_config_get_token;
|
||||
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_vt;
|
||||
nm_vpn_editor_plugin_load;
|
||||
|
|
|
@ -224,30 +224,12 @@ no-auto-default=*
|
|||
<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>
|
||||
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.
|
||||
This setting is deprecated for the per-device setting
|
||||
<literal>ignore-carrier</literal> which overwrites this setting
|
||||
if specified (See <xref linked="ignore-carrier"/>).
|
||||
Otherwise, it is a list of matches to specify for which device
|
||||
carrier should be ignored. See <xref linkend="device-spec"/> for the
|
||||
syntax how to specify a device.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -583,6 +565,13 @@ ipv6.ip6-privacy=0
|
|||
<varlistentry>
|
||||
<term><varname>connection.lldp</varname></term>
|
||||
</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>
|
||||
<term><varname>ethernet.wake-on-lan</varname></term>
|
||||
</varlistentry>
|
||||
|
@ -610,9 +599,18 @@ ipv6.ip6-privacy=0
|
|||
<term><varname>vpn.timeout</varname></term>
|
||||
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
|
||||
</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>
|
||||
<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>
|
||||
<term><varname>wifi.powersave</varname></term>
|
||||
|
@ -623,7 +621,7 @@ ipv6.ip6-privacy=0
|
|||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<refsect2 id="connection-sections">
|
||||
<title>Sections</title>
|
||||
<para>
|
||||
You can configure multiple <literal>connection</literal>
|
||||
|
@ -696,6 +694,97 @@ ipv6.ip6-privacy=1
|
|||
</refsect2>
|
||||
</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>
|
||||
<title><literal>connectivity</literal> section</title>
|
||||
<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>
|
||||
<para>
|
||||
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:
|
||||
</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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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,
|
||||
if configured.</para>
|
||||
</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>
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
|
|
@ -38,6 +38,21 @@
|
|||
#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_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__ */
|
||||
|
|
|
@ -551,6 +551,12 @@ check_connection_cloned_mac_address (NMConnection *orig,
|
|||
if (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) {
|
||||
remove_from_hash (settings, props,
|
||||
NM_SETTING_WIRED_SETTING_NAME,
|
||||
|
|
|
@ -1002,7 +1002,7 @@ nm_device_bt_new (NMBluezDevice *bt_device,
|
|||
NM_DEVICE_UDI, udi,
|
||||
NM_DEVICE_IFACE, bdaddr,
|
||||
NM_DEVICE_DRIVER, "bluez",
|
||||
NM_DEVICE_HW_ADDRESS, bdaddr,
|
||||
NM_DEVICE_PERM_HW_ADDRESS, bdaddr,
|
||||
NM_DEVICE_BT_DEVICE, bt_device,
|
||||
NM_DEVICE_BT_NAME, name,
|
||||
NM_DEVICE_BT_CAPABILITIES, capabilities,
|
||||
|
|
|
@ -120,7 +120,6 @@ typedef struct {
|
|||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PERM_HW_ADDRESS,
|
||||
PROP_SPEED,
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
get_generic_capabilities (NMDevice *device)
|
||||
{
|
||||
|
@ -408,7 +399,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
if (!match_subchans (self, s_wired, &try_mac))
|
||||
return FALSE;
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (perm_hw_addr) {
|
||||
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);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
|
||||
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);
|
||||
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
||||
if (s_wired) {
|
||||
/* 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 (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
||||
/* 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
|
||||
* remote side to handle the disconnection. Otherwise the peer may
|
||||
|
@ -1365,10 +1352,6 @@ deactivate (NMDevice *device)
|
|||
/* Set last PPPoE connection time */
|
||||
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 ();
|
||||
|
||||
/* 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
|
||||
|
@ -1409,7 +1392,7 @@ complete_connection (NMDevice *device,
|
|||
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) {
|
||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (setting_mac) {
|
||||
|
@ -1438,7 +1421,7 @@ new_default_connection (NMDevice *self)
|
|||
NMConnection *connection;
|
||||
NMSettingsConnection *const*connections;
|
||||
NMSetting *setting;
|
||||
const char *hw_address;
|
||||
const char *perm_hw_addr;
|
||||
gs_free char *defname = NULL;
|
||||
gs_free char *uuid = 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))
|
||||
return NULL;
|
||||
|
||||
hw_address = nm_device_get_hw_address (self);
|
||||
if (!hw_address)
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (self, FALSE);
|
||||
if (!perm_hw_addr)
|
||||
return NULL;
|
||||
|
||||
connection = nm_simple_connection_new ();
|
||||
|
@ -1466,7 +1449,7 @@ new_default_connection (NMDevice *self)
|
|||
uuid = _nm_utils_uuid_generate_from_strings ("default-wired",
|
||||
machine_id ?: "",
|
||||
defname,
|
||||
hw_address,
|
||||
perm_hw_addr,
|
||||
NULL);
|
||||
|
||||
g_object_set (setting,
|
||||
|
@ -1480,7 +1463,7 @@ new_default_connection (NMDevice *self)
|
|||
|
||||
/* Lock the connection to the device */
|
||||
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);
|
||||
|
||||
return connection;
|
||||
|
@ -1506,7 +1489,7 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||
NMSettingWired *s_wired = nm_connection_get_setting_wired (connection);
|
||||
const char *perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
const char *perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
const char *mac = nm_device_get_hw_address (device);
|
||||
const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
|
||||
GHashTableIter iter;
|
||||
|
@ -1582,34 +1565,10 @@ link_changed (NMDevice *device, NMPlatformLink *info)
|
|||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
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);
|
||||
if (!priv->subchan1 && info->initialized)
|
||||
_update_s390_subchannels (self);
|
||||
|
||||
if (!nm_device_get_initial_hw_address (device)) {
|
||||
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET,
|
||||
nm_device_get_ifindex (self),
|
||||
&hwaddrlen);
|
||||
if (!nm_utils_hwaddr_matches (hwaddr, hwaddrlen, 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
|
||||
|
@ -1663,9 +1622,6 @@ get_property (GObject *object, guint prop_id,
|
|||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
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:
|
||||
g_value_set_uint (value, priv->speed);
|
||||
break;
|
||||
|
@ -1707,7 +1663,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||
object_class->set_property = set_property;
|
||||
|
||||
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->complete_connection = complete_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;
|
||||
|
||||
/* 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
|
||||
(object_class, PROP_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_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_S390_SUBCHANNELS "s390-subchannels"
|
||||
|
||||
|
|
|
@ -92,10 +92,10 @@ typedef struct {
|
|||
* @connection: the #NMConnection to return the parent name for, if supported
|
||||
*
|
||||
* 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
|
||||
* device hardware address, or %NULL
|
||||
* device permenent hardware address, or %NULL
|
||||
*/
|
||||
const char * (*get_connection_parent) (NMDeviceFactory *factory,
|
||||
NMConnection *connection);
|
||||
|
|
|
@ -147,11 +147,16 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
|
||||
if (nm_device_is_real (device)) {
|
||||
const char *mac;
|
||||
const char *hw_addr;
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
@ -183,7 +188,7 @@ complete_connection (NMDevice *device,
|
|||
}
|
||||
|
||||
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) {
|
||||
/* Make sure the setting MAC (if any) matches the device's MAC */
|
||||
if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) {
|
||||
|
@ -209,7 +214,7 @@ static void
|
|||
update_connection (NMDevice *device, NMConnection *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";
|
||||
int ifindex;
|
||||
|
||||
|
|
|
@ -373,9 +373,8 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw
|
|||
if (!priv->parent)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
parent_mac = nm_device_get_hw_address (priv->parent);
|
||||
|
||||
return nm_utils_hwaddr_matches (setting_mac, -1, parent_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
|
||||
|
@ -503,8 +502,6 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret;
|
||||
|
||||
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)
|
||||
return ret;
|
||||
|
||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
||||
if (s_wired) {
|
||||
/* 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_HW);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -549,16 +541,6 @@ realize_start_notify (NMDevice *device, const NMPlatformLink *plink)
|
|||
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
|
||||
|
@ -639,7 +621,6 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
|
|||
device_class->complete_connection = complete_connection;
|
||||
device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME;
|
||||
device_class->create_and_realize = create_and_realize;
|
||||
device_class->deactivate = deactivate;
|
||||
device_class->get_generic_capabilities = get_generic_capabilities;
|
||||
device_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
||||
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);
|
||||
|
||||
gboolean nm_device_set_hw_addr (NMDevice *device, const char *addr,
|
||||
const char *detail, guint64 hw_log_domain);
|
||||
gboolean nm_device_hw_addr_set (NMDevice *device, const char *addr, const char *detail);
|
||||
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);
|
||||
|
||||
|
@ -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_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);
|
||||
|
||||
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);
|
||||
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret;
|
||||
|
||||
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"))
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
|
||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED);
|
||||
if (s_wired) {
|
||||
/* 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);
|
||||
}
|
||||
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
|
|||
{
|
||||
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
|
||||
NMConnection *connection;
|
||||
NMSettingWired *s_wired;
|
||||
const char *new_mac, *old_mac;
|
||||
NMSettingIPConfig *s_ip6;
|
||||
|
||||
|
@ -100,11 +99,8 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
|
|||
return;
|
||||
|
||||
/* Update the VLAN MAC only if configuration does not specify one */
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (s_wired) {
|
||||
if (nm_setting_wired_get_cloned_mac_address (s_wired))
|
||||
if (nm_device_hw_addr_is_explict (self))
|
||||
return;
|
||||
}
|
||||
|
||||
old_mac = nm_device_get_hw_address (self);
|
||||
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",
|
||||
NM_PRINT_FMT_QUOTE_STRING (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,
|
||||
* removing the IPv6 configuration; reapply it.
|
||||
*/
|
||||
|
@ -378,9 +374,10 @@ match_parent (NMDeviceVlan *self, const char *parent)
|
|||
static gboolean
|
||||
match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr)
|
||||
{
|
||||
NMDeviceVlanPrivate *priv;
|
||||
NMSettingWired *s_wired;
|
||||
const char *setting_mac;
|
||||
const char *device_mac;
|
||||
const char *parent_mac;
|
||||
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (!s_wired)
|
||||
|
@ -390,9 +387,12 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw
|
|||
if (!setting_mac)
|
||||
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
|
||||
|
@ -550,8 +550,6 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
{
|
||||
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (dev);
|
||||
NMSettingVlan *s_vlan;
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret;
|
||||
|
||||
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)
|
||||
return ret;
|
||||
|
||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_WIRED);
|
||||
if (s_wired) {
|
||||
/* 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);
|
||||
}
|
||||
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
/* Change MAC address to parent's one if needed */
|
||||
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
|
||||
|
@ -690,7 +676,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
|
|||
parent_class->bring_up = bring_up;
|
||||
parent_class->act_stage1_prepare = act_stage1_prepare;
|
||||
parent_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
||||
parent_class->deactivate = deactivate;
|
||||
parent_class->is_available = is_available;
|
||||
parent_class->notify_new_device_added = notify_new_device_added;
|
||||
|
||||
|
|
|
@ -511,8 +511,6 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret;
|
||||
|
||||
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)
|
||||
return ret;
|
||||
|
||||
s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED);
|
||||
if (s_wired) {
|
||||
/* 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);
|
||||
}
|
||||
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
|
|||
PROP_IS_MASTER,
|
||||
PROP_MASTER,
|
||||
PROP_HW_ADDRESS,
|
||||
PROP_PERM_HW_ADDRESS,
|
||||
PROP_HAS_PENDING_ACTION,
|
||||
PROP_METERED,
|
||||
PROP_LLDP_NEIGHBORS,
|
||||
|
@ -208,6 +209,13 @@ typedef struct {
|
|||
NMIP4Config **configs;
|
||||
} ArpingData;
|
||||
|
||||
typedef enum {
|
||||
HW_ADDR_TYPE_UNSET = 0,
|
||||
HW_ADDR_TYPE_PERMANENT,
|
||||
HW_ADDR_TYPE_EXPLICIT,
|
||||
HW_ADDR_TYPE_GENERATED,
|
||||
} HwAddrType;
|
||||
|
||||
typedef struct _NMDevicePrivate {
|
||||
bool in_state_changed;
|
||||
|
||||
|
@ -225,7 +233,12 @@ typedef struct _NMDevicePrivate {
|
|||
char * udi;
|
||||
char * iface; /* may change, could be renamed by user */
|
||||
int ifindex;
|
||||
|
||||
guint hw_addr_len;
|
||||
guint8 /*HwAddrType*/ hw_addr_type;
|
||||
|
||||
bool real;
|
||||
|
||||
char * ip_iface;
|
||||
int ip_ifindex;
|
||||
NMDeviceType type;
|
||||
|
@ -237,13 +250,13 @@ typedef struct _NMDevicePrivate {
|
|||
char * driver_version;
|
||||
char * firmware_version;
|
||||
RfKillType rfkill_type;
|
||||
bool firmware_missing;
|
||||
bool nm_plugin_missing;
|
||||
bool firmware_missing:1;
|
||||
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;
|
||||
char * hw_addr;
|
||||
guint hw_addr_len;
|
||||
char * perm_hw_addr;
|
||||
char * initial_hw_addr;
|
||||
char * hw_addr_perm;
|
||||
char * hw_addr_initial;
|
||||
char * physical_port_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 *
|
||||
nm_device_get_udi (NMDevice *self)
|
||||
{
|
||||
|
@ -1106,7 +1143,11 @@ nm_device_get_settings_connection (NMDevice *self)
|
|||
NMConnection *
|
||||
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;
|
||||
}
|
||||
|
@ -1123,23 +1164,12 @@ nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFla
|
|||
}
|
||||
|
||||
NMSetting *
|
||||
nm_device_get_applied_setting (NMDevice *device, GType setting_type)
|
||||
nm_device_get_applied_setting (NMDevice *self, GType setting_type)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMSetting *setting = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), 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;
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
return connection ? nm_connection_get_setting (connection, setting_type) : NULL;
|
||||
}
|
||||
|
||||
RfKillType
|
||||
|
@ -1647,6 +1677,7 @@ device_link_changed (NMDevice *self)
|
|||
int ifindex;
|
||||
gboolean was_up;
|
||||
gboolean update_unmanaged_specs = FALSE;
|
||||
gboolean got_hw_addr = FALSE, had_hw_addr;
|
||||
|
||||
priv->device_link_changed_id = 0;
|
||||
|
||||
|
@ -1684,6 +1715,11 @@ device_link_changed (NMDevice *self)
|
|||
_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) {
|
||||
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
||||
priv->ifindex, priv->iface, info.name);
|
||||
|
@ -1775,6 +1811,20 @@ device_link_changed (NMDevice *self)
|
|||
if (update_unmanaged_specs)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2123,6 +2173,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
|
|||
|
||||
nm_device_update_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() */
|
||||
config = nm_config_get ();
|
||||
|
@ -2308,6 +2359,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||
_notify (self, PROP_UDI);
|
||||
}
|
||||
if (priv->hw_addr) {
|
||||
priv->hw_addr_len = 0;
|
||||
g_clear_pointer (&priv->hw_addr, g_free);
|
||||
_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);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->perm_hw_addr, g_free);
|
||||
g_clear_pointer (&priv->initial_hw_addr, g_free);
|
||||
priv->hw_addr_type = HW_ADDR_TYPE_UNSET;
|
||||
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;
|
||||
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
|
||||
|
@ -3324,7 +3378,7 @@ nm_device_can_assume_connections (NMDevice *self)
|
|||
* if there is no active connection or the active connection cannot be
|
||||
* assumed.
|
||||
*/
|
||||
gboolean
|
||||
static gboolean
|
||||
nm_device_can_assume_active_connection (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
@ -3371,6 +3425,45 @@ nm_device_can_assume_active_connection (NMDevice *self)
|
|||
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
|
||||
nm_device_emit_recheck_assume (gpointer user_data)
|
||||
{
|
||||
|
@ -5859,9 +5952,15 @@ check_and_add_ipv6ll_addr (NMDevice *self)
|
|||
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 (!nm_utils_ipv6_addr_set_stable_privacy (&lladdr,
|
||||
NMUtilsStableType stable_type;
|
||||
const char *stable_id;
|
||||
|
||||
stable_id = _get_stable_id (connection, &stable_type);
|
||||
if ( !stable_id
|
||||
|| !nm_utils_ipv6_addr_set_stable_privacy (stable_type,
|
||||
&lladdr,
|
||||
nm_device_get_iface (self),
|
||||
nm_connection_get_uuid (connection),
|
||||
stable_id,
|
||||
priv->linklocal6_dad_counter++,
|
||||
&error)) {
|
||||
_LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
|
||||
|
@ -6205,6 +6304,8 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
|
|||
NMActStageReturn ret;
|
||||
NMSettingIP6Config *s_ip6 = NULL;
|
||||
GError *error = NULL;
|
||||
NMUtilsStableType stable_type;
|
||||
const char *stable_id;
|
||||
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
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));
|
||||
g_assert (s_ip6);
|
||||
|
||||
stable_id = _get_stable_id (connection, &stable_type);
|
||||
if (stable_id) {
|
||||
priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
nm_device_get_ip_iface (self),
|
||||
nm_connection_get_uuid (connection),
|
||||
stable_type,
|
||||
stable_id,
|
||||
nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
|
||||
&error);
|
||||
}
|
||||
if (!priv->rdisc) {
|
||||
_LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message);
|
||||
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_hw_addr_reset (self, "deactivate");
|
||||
|
||||
/* Call device type-specific deactivation */
|
||||
if (NM_DEVICE_GET_CLASS (self)->deactivate)
|
||||
NM_DEVICE_GET_CLASS (self)->deactivate (self);
|
||||
|
@ -10622,6 +10729,8 @@ nm_device_spawn_iface_helper (NMDevice *self)
|
|||
GPtrArray *argv;
|
||||
gs_free char *dhcp4_address = NULL;
|
||||
char *logging_backend;
|
||||
NMUtilsStableType stable_type;
|
||||
const char *stable_id;
|
||||
|
||||
if (priv->state != NM_DEVICE_STATE_ACTIVATED)
|
||||
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 (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 ())
|
||||
? g_strdup ("debug")
|
||||
: 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))
|
||||
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
|
||||
nm_device_take_down (self, TRUE);
|
||||
nm_device_hw_addr_reset (self, "unmanage");
|
||||
set_nm_ipv6ll (self, FALSE);
|
||||
restore_ip6_properties (self);
|
||||
}
|
||||
|
@ -10982,6 +11098,9 @@ _set_state_full (NMDevice *self,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_PREPARE:
|
||||
nm_device_update_initial_hw_address (self);
|
||||
break;
|
||||
case 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
|
||||
|
@ -11300,23 +11419,26 @@ nm_device_get_hw_address (NMDevice *self)
|
|||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
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
|
||||
nm_device_update_hw_address (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
int ifindex = nm_device_get_ifindex (self);
|
||||
NMDevicePrivate *priv;
|
||||
const guint8 *hwaddr;
|
||||
gsize hwaddrlen = 0;
|
||||
|
||||
if (ifindex <= 0)
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (priv->ifindex <= 0)
|
||||
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
|
||||
&& hwaddr
|
||||
&& nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth)))
|
||||
hwaddrlen = 0;
|
||||
|
||||
|
@ -11326,17 +11448,28 @@ nm_device_update_hw_address (NMDevice *self)
|
|||
g_free (priv->hw_addr);
|
||||
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);
|
||||
|
||||
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 {
|
||||
/* Invalid or no hardware address */
|
||||
if (priv->hw_addr_len != 0) {
|
||||
g_clear_pointer (&priv->hw_addr, g_free);
|
||||
priv->hw_addr_len = 0;
|
||||
_LOGD (LOGD_HW | LOGD_DEVICE,
|
||||
"previous hardware address is no longer valid");
|
||||
_notify (self, PROP_HW_ADDRESS);
|
||||
"hw-addr: failed reading current MAC address (stay with %s)",
|
||||
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);
|
||||
|
||||
if (priv->hw_addr_len) {
|
||||
priv->initial_hw_addr = g_strdup (priv->hw_addr);
|
||||
_LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
|
||||
|
||||
if (priv->ifindex > 0) {
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
size_t len = 0;
|
||||
|
||||
if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
|
||||
g_warn_if_fail (len == priv->hw_addr_len);
|
||||
priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
|
||||
_LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
|
||||
priv->perm_hw_addr);
|
||||
} else {
|
||||
/* Fall back to current address */
|
||||
_LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
|
||||
priv->perm_hw_addr = g_strdup (priv->hw_addr);
|
||||
}
|
||||
if ( priv->hw_addr
|
||||
&& !nm_streq0 (priv->hw_addr_initial, priv->hw_addr)) {
|
||||
if ( priv->hw_addr_initial
|
||||
&& priv->hw_addr_type != HW_ADDR_TYPE_UNSET) {
|
||||
/* once we have the initial hw address set, we only allow
|
||||
* update if the currenty type is "unset". */
|
||||
return;
|
||||
}
|
||||
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
|
||||
nm_device_set_hw_addr (NMDevice *self, const char *addr,
|
||||
const char *detail, guint64 hw_log_domain)
|
||||
void
|
||||
nm_device_update_permanent_hw_address (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
gboolean success = FALSE;
|
||||
const char *cur_addr = nm_device_get_hw_address (self);
|
||||
guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
size_t len = 0;
|
||||
gboolean success_read;
|
||||
|
||||
/* Fall back to the permanent address */
|
||||
if (!addr)
|
||||
addr = priv->perm_hw_addr;
|
||||
if (!addr)
|
||||
return FALSE;
|
||||
if (priv->hw_addr_perm) {
|
||||
/* the permanent hardware address is only read once and not
|
||||
* re-read later.
|
||||
*
|
||||
* 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 */
|
||||
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;
|
||||
}
|
||||
if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) {
|
||||
_LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hw_addr_len = priv->hw_addr_len;
|
||||
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);
|
||||
}
|
||||
|
||||
success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len);
|
||||
success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, hw_addr_len);
|
||||
if (success) {
|
||||
/* MAC address succesfully changed; update the current MAC to match */
|
||||
nm_device_update_hw_address (self);
|
||||
cur_addr = nm_device_get_hw_address (self);
|
||||
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
||||
_LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s",
|
||||
detail, addr);
|
||||
_LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
|
||||
operation, addr, detail);
|
||||
} else {
|
||||
_LOGW (LOGD_DEVICE | hw_log_domain,
|
||||
"new MAC address %s not successfully set", addr);
|
||||
_LOGW (LOGD_DEVICE,
|
||||
"set-hw-addr: new MAC address %s not successfully set to %s (%s)",
|
||||
addr, operation, detail);
|
||||
success = FALSE;
|
||||
}
|
||||
} else {
|
||||
_LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s",
|
||||
detail, addr);
|
||||
_LOGW (LOGD_DEVICE, "set-hw-addr: failed to %s MAC address to %s (%s)",
|
||||
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;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_permanent_hw_address (NMDevice *self)
|
||||
gboolean
|
||||
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);
|
||||
|
||||
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 *
|
||||
|
@ -11431,7 +11841,7 @@ nm_device_get_initial_hw_address (NMDevice *self)
|
|||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr;
|
||||
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
|
||||
spec_match_list (NMDevice *self, const GSList *specs)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m;
|
||||
const GSList *iter;
|
||||
const char *hw_addr_perm;
|
||||
|
||||
for (iter = specs; iter; iter = g_slist_next (iter)) {
|
||||
if (!strcmp ((const char *) iter->data, "*")) {
|
||||
|
@ -11479,8 +11889,10 @@ spec_match_list (NMDevice *self, const GSList *specs)
|
|||
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);
|
||||
}
|
||||
if (matched != NM_MATCH_SPEC_NEG_MATCH) {
|
||||
|
@ -11563,7 +11975,8 @@ constructor (GType type,
|
|||
self = NM_DEVICE (object);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -11697,8 +12121,8 @@ finalize (GObject *object)
|
|||
_LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
|
||||
|
||||
g_free (priv->hw_addr);
|
||||
g_free (priv->perm_hw_addr);
|
||||
g_free (priv->initial_hw_addr);
|
||||
g_free (priv->hw_addr_perm);
|
||||
g_free (priv->hw_addr_initial);
|
||||
g_slist_free_full (priv->pending_actions, g_free);
|
||||
g_slist_free_full (priv->dad6_failed_addrs, g_free);
|
||||
g_clear_pointer (&priv->physical_port_id, g_free);
|
||||
|
@ -11727,10 +12151,8 @@ static void
|
|||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE (object);
|
||||
NMDevice *self = (NMDevice *) object;
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const char *hw_addr, *p;
|
||||
guint count;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UDI:
|
||||
|
@ -11808,32 +12230,9 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_IS_MASTER:
|
||||
priv->is_master = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_HW_ADDRESS:
|
||||
case PROP_PERM_HW_ADDRESS:
|
||||
/* construct only */
|
||||
p = hw_addr = g_value_get_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;
|
||||
}
|
||||
priv->hw_addr_perm = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
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:
|
||||
g_value_set_string (value, priv->hw_addr);
|
||||
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:
|
||||
g_value_set_boolean (value, nm_device_has_pending_action (self));
|
||||
break;
|
||||
|
@ -12041,6 +12444,7 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
klass->take_down = take_down;
|
||||
klass->carrier_changed = carrier_changed;
|
||||
klass->get_ip_iface_identifier = get_ip_iface_identifier;
|
||||
klass->unmanaged_on_quit = unmanaged_on_quit;
|
||||
|
||||
/* Properties */
|
||||
obj_properties[PROP_UDI] =
|
||||
|
@ -12198,6 +12602,11 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
G_PARAM_STATIC_STRINGS);
|
||||
obj_properties[PROP_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,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
|
|
@ -57,6 +57,11 @@
|
|||
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
|
||||
#define NM_DEVICE_MTU "mtu"
|
||||
#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_LLDP_NEIGHBORS "lldp-neighbors"
|
||||
#define NM_DEVICE_REAL "real"
|
||||
|
@ -323,6 +328,8 @@ typedef struct {
|
|||
gboolean (* owns_iface) (NMDevice *self, const char *iface);
|
||||
|
||||
NMConnection * (* new_default_connection) (NMDevice *self);
|
||||
|
||||
gboolean (* unmanaged_on_quit) (NMDevice *self);
|
||||
} NMDeviceClass;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_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);
|
||||
|
||||
|
@ -578,6 +586,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device,
|
|||
|
||||
void nm_device_update_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);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -62,6 +62,8 @@ _LOG_DECLARE_SELF(NMDeviceWifi);
|
|||
#define SCAN_INTERVAL_STEP 20
|
||||
#define SCAN_INTERVAL_MAX 120
|
||||
|
||||
#define SCAN_RAND_MAC_ADDRESS_EXPIRE_MIN 5
|
||||
|
||||
#define WIRELESS_SECRETS_TRIES "wireless-secrets-tries"
|
||||
|
||||
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 {
|
||||
PROP_0,
|
||||
PROP_PERM_HW_ADDRESS,
|
||||
PROP_MODE,
|
||||
PROP_BITRATE,
|
||||
PROP_ACCESS_POINTS,
|
||||
|
@ -120,6 +121,9 @@ struct _NMDeviceWifiPrivate {
|
|||
guint reacquire_iface_id;
|
||||
|
||||
NMDeviceWifiCapabilities capabilities;
|
||||
|
||||
gint32 hw_addr_scan_expire;
|
||||
char *hw_addr_scan;
|
||||
};
|
||||
|
||||
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 _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset);
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
static void
|
||||
|
@ -187,6 +193,18 @@ constructed (GObject *object)
|
|||
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
|
||||
supplicant_interface_acquire (NMDeviceWifi *self)
|
||||
{
|
||||
|
@ -403,14 +421,6 @@ periodic_update_cb (gpointer user_data)
|
|||
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
|
||||
bring_up (NMDevice *device, gboolean *no_firmware)
|
||||
{
|
||||
|
@ -491,9 +501,8 @@ deactivate (NMDevice *device)
|
|||
/* Clear any critical protocol notification in the Wi-Fi stack */
|
||||
nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE);
|
||||
|
||||
/* 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_WIFI);
|
||||
g_clear_pointer (&priv->hw_addr_scan, g_free);
|
||||
_hw_addr_set_scanning (self, TRUE);
|
||||
|
||||
/* Ensure we're in infrastructure mode after deactivation; some devices
|
||||
* (usually older ones) don't scan well in adhoc mode.
|
||||
|
@ -572,7 +581,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
if (!s_wireless)
|
||||
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);
|
||||
if (perm_hw_addr) {
|
||||
if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||
|
@ -685,14 +694,17 @@ check_connection_available (NMDevice *device,
|
|||
return !!find_first_compatible_ap (NM_DEVICE_WIFI (device), connection, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
static gboolean
|
||||
is_manf_default_ssid (const GByteArray *ssid)
|
||||
{
|
||||
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[] = {
|
||||
static const char *manf_defaults[] = {
|
||||
"linksys",
|
||||
"linksys-a",
|
||||
"linksys-g",
|
||||
|
@ -704,16 +716,9 @@ manf_defaults[] = {
|
|||
"ALICE-WLAN",
|
||||
"Speedport W 501V",
|
||||
"TURBONETT",
|
||||
};
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
|
||||
|
||||
static gboolean
|
||||
is_manf_default_ssid (const GByteArray *ssid)
|
||||
{
|
||||
int i;
|
||||
|
||||
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 (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0)
|
||||
return TRUE;
|
||||
|
@ -868,7 +873,7 @@ complete_connection (NMDevice *device,
|
|||
if (hidden)
|
||||
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) {
|
||||
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
||||
if (setting_mac) {
|
||||
|
@ -1027,6 +1032,60 @@ impl_device_wifi_get_all_access_points (NMDeviceWifi *self,
|
|||
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
|
||||
request_scan_cb (NMDevice *device,
|
||||
GDBusMethodInvocation *context,
|
||||
|
@ -1336,6 +1395,8 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
|
|||
_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)) {
|
||||
/* success */
|
||||
backoff = TRUE;
|
||||
|
@ -2210,9 +2271,6 @@ build_supplicant_config (NMDeviceWifi *self,
|
|||
NMSupplicantConfig *config = NULL;
|
||||
NMSettingWireless *s_wireless;
|
||||
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);
|
||||
|
||||
|
@ -2227,20 +2285,9 @@ build_supplicant_config (NMDeviceWifi *self,
|
|||
_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,
|
||||
s_wireless,
|
||||
fixed_freq,
|
||||
mac_randomization_support,
|
||||
mac_randomization_fallback,
|
||||
error)) {
|
||||
g_prefix_error (error, "802-11-wireless: ");
|
||||
goto error;
|
||||
|
@ -2290,7 +2337,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
|||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingWireless *s_wireless;
|
||||
const char *cloned_mac;
|
||||
const char *mode;
|
||||
const char *ap_path;
|
||||
|
||||
|
@ -2330,9 +2376,12 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
|
|||
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 */
|
||||
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
|
||||
nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_WIFI);
|
||||
if (!nm_device_hw_addr_set_cloned (device, connection, TRUE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
/* AP mode never uses a specific object or existing scanned AP */
|
||||
if (priv->mode != NM_802_11_MODE_AP) {
|
||||
|
@ -2972,6 +3021,8 @@ finalize (GObject *object)
|
|||
|
||||
g_hash_table_unref (priv->aps);
|
||||
|
||||
g_free (priv->hw_addr_scan);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -2986,9 +3037,6 @@ get_property (GObject *object, guint prop_id,
|
|||
GPtrArray *array;
|
||||
|
||||
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:
|
||||
g_value_set_uint (value, priv->mode);
|
||||
break;
|
||||
|
@ -3053,7 +3101,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
parent_class->realize_start_notify = realize_start_notify;
|
||||
parent_class->bring_up = bring_up;
|
||||
parent_class->can_auto_connect = can_auto_connect;
|
||||
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_ip6_config_timeout = act_stage4_ip6_config_timeout;
|
||||
parent_class->deactivate = deactivate;
|
||||
parent_class->unmanaged_on_quit = unmanaged_on_quit;
|
||||
|
||||
parent_class->state_changed = device_state_changed;
|
||||
|
||||
klass->scanning_allowed = scanning_allowed;
|
||||
|
||||
/* 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
|
||||
(object_class, PROP_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_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_BITRATE "bitrate"
|
||||
#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points"
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct {
|
|||
gboolean has;
|
||||
GSList *spec;
|
||||
} match_device;
|
||||
} ConnectionInfo;
|
||||
} MatchSectionInfo;
|
||||
|
||||
typedef struct {
|
||||
char *config_main_file;
|
||||
|
@ -52,7 +52,11 @@ typedef struct {
|
|||
|
||||
/* A zero-terminated list of pre-processed information from the
|
||||
* [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 {
|
||||
char *uri;
|
||||
|
@ -268,9 +272,16 @@ nm_config_data_get_rc_manager (const NMConfigData *self)
|
|||
gboolean
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
@ -451,6 +462,7 @@ static int
|
|||
_nm_config_data_log_sort (const char **pa, const char **pb, gpointer dummy)
|
||||
{
|
||||
gboolean a_is_connection, b_is_connection;
|
||||
gboolean a_is_device, b_is_device;
|
||||
gboolean a_is_intern, b_is_intern;
|
||||
const char *a = *pa;
|
||||
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)
|
||||
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. */
|
||||
return 0;
|
||||
}
|
||||
|
@ -1049,25 +1083,18 @@ global_dns_equal (NMGlobalDnsConfig *old, NMGlobalDnsConfig *new)
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
char *
|
||||
nm_config_data_get_connection_default (const NMConfigData *self,
|
||||
static const MatchSectionInfo *
|
||||
_match_section_infos_lookup (const MatchSectionInfo *match_section_infos,
|
||||
GKeyFile *keyfile,
|
||||
const char *property,
|
||||
NMDevice *device)
|
||||
NMDevice *device,
|
||||
char **out_value)
|
||||
{
|
||||
NMConfigDataPrivate *priv;
|
||||
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)
|
||||
if (!match_section_infos)
|
||||
return NULL;
|
||||
|
||||
for (connection_info = &priv->connection_infos[0]; connection_info->group_name; connection_info++) {
|
||||
char *value;
|
||||
for (; match_section_infos->group_name; match_section_infos++) {
|
||||
char *value = NULL;
|
||||
gboolean match;
|
||||
|
||||
/* 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
|
||||
* 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). */
|
||||
value = g_key_file_get_string (priv->keyfile, connection_info->group_name, property, NULL);
|
||||
if (!value && !connection_info->stop_match)
|
||||
value = g_key_file_get_string (keyfile, match_section_infos->group_name, property, NULL);
|
||||
if (!value && !match_section_infos->stop_match)
|
||||
continue;
|
||||
|
||||
match = TRUE;
|
||||
if (connection_info->match_device.has)
|
||||
match = device && nm_device_spec_match_list (device, connection_info->match_device.spec);
|
||||
if (match_section_infos->match_device.has)
|
||||
match = device && nm_device_spec_match_list (device, match_section_infos->match_device.spec);
|
||||
|
||||
if (match)
|
||||
return value;
|
||||
if (match) {
|
||||
*out_value = value;
|
||||
return match_section_infos;
|
||||
}
|
||||
g_free (value);
|
||||
}
|
||||
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
|
||||
_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... */
|
||||
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);
|
||||
}
|
||||
|
||||
static ConnectionInfo *
|
||||
_get_connection_infos (GKeyFile *keyfile)
|
||||
static void
|
||||
_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;
|
||||
gsize i, j, ngroups;
|
||||
char *connection_tag = NULL;
|
||||
ConnectionInfo *connection_infos = NULL;
|
||||
MatchSectionInfo *match_section_infos = NULL;
|
||||
|
||||
/* get the list of existing [connection.\+] sections that we consider
|
||||
* for nm_config_data_get_connection_default().
|
||||
/* get the list of existing [connection.\+]/[device.\+] sections.
|
||||
*
|
||||
* We expect the sections in their right order, with lowest priority
|
||||
* first. Only exception is the (literal) [connection] section, which
|
||||
* we will always reorder to the end. */
|
||||
groups = g_key_file_get_groups (keyfile, &ngroups);
|
||||
if (!groups)
|
||||
ngroups = 0;
|
||||
else if (ngroups > 0) {
|
||||
return NULL;
|
||||
|
||||
if (ngroups > 0) {
|
||||
gsize l = strlen (prefix);
|
||||
|
||||
for (i = 0, j = 0; i < ngroups; i++) {
|
||||
if (g_str_has_prefix (groups[i], NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)) {
|
||||
if (groups[i][NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION)] == '\0')
|
||||
if (g_str_has_prefix (groups[i], prefix)) {
|
||||
if (groups[i][l] == '\0')
|
||||
connection_tag = groups[i];
|
||||
else
|
||||
groups[j++] = groups[i];
|
||||
|
@ -1135,18 +1242,23 @@ _get_connection_infos (GKeyFile *keyfile)
|
|||
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++) {
|
||||
/* 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) {
|
||||
/* 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);
|
||||
|
||||
return connection_infos;
|
||||
return match_section_infos;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -1306,7 +1418,6 @@ static void
|
|||
finalize (GObject *gobject)
|
||||
{
|
||||
NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (gobject);
|
||||
guint i;
|
||||
|
||||
g_free (priv->config_main_file);
|
||||
g_free (priv->config_description);
|
||||
|
@ -1326,13 +1437,8 @@ finalize (GObject *gobject)
|
|||
|
||||
nm_global_dns_config_free (priv->global_dns);
|
||||
|
||||
if (priv->connection_infos) {
|
||||
for (i = 0; priv->connection_infos[i].group_name; i++) {
|
||||
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);
|
||||
}
|
||||
_match_section_infos_free (priv->connection_infos);
|
||||
_match_section_infos_free (priv->device_infos);
|
||||
|
||||
g_key_file_unref (priv->keyfile);
|
||||
if (priv->keyfile_user)
|
||||
|
@ -1359,7 +1465,8 @@ constructed (GObject *object)
|
|||
|
||||
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.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,
|
||||
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_keys (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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -576,14 +578,7 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
|
|||
{
|
||||
const char *a, *b;
|
||||
gboolean a_is_connection, b_is_connection;
|
||||
|
||||
/* basic NULL checking... */
|
||||
if (pa == pb)
|
||||
return 0;
|
||||
if (!pa)
|
||||
return -1;
|
||||
if (!pb)
|
||||
return 1;
|
||||
gboolean a_is_device, b_is_device;
|
||||
|
||||
a = *pa;
|
||||
b = *pb;
|
||||
|
@ -598,16 +593,34 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
|
|||
return 1;
|
||||
return -1;
|
||||
}
|
||||
if (!a_is_connection) {
|
||||
/* both are non-connection entries. Don't reorder. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a_is_connection) {
|
||||
/* both are [connection.\+] entires. Reverse their order.
|
||||
* 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;
|
||||
}
|
||||
|
||||
a_is_device = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||
b_is_device = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
|
||||
|
||||
if (a_is_device != b_is_device) {
|
||||
/* 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
|
||||
|
@ -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, "assume-ipv6ll-only")
|
||||
|| _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
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern."
|
||||
#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_TEST_APPEND_STRINGLIST ".test-append-stringlist"
|
||||
|
||||
|
@ -69,6 +70,8 @@
|
|||
#define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed"
|
||||
#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_SET ".set."
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <resolv.h>
|
||||
|
@ -54,7 +55,7 @@
|
|||
#endif
|
||||
|
||||
G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int));
|
||||
int _nm_utils_testing = 0;
|
||||
static int _nm_utils_testing = 0;
|
||||
|
||||
gboolean
|
||||
nm_utils_get_testing_initialized ()
|
||||
|
@ -1271,8 +1272,10 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
|||
{
|
||||
const GSList *iter;
|
||||
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)) {
|
||||
const char *spec_str = iter->data;
|
||||
|
@ -1293,7 +1296,15 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
|||
else if (except)
|
||||
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)
|
||||
return NM_MATCH_SPEC_NEG_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 *
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
int urandom = open ("/dev/urandom", O_RDONLY);
|
||||
int r;
|
||||
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.
|
||||
* Let's use twice as much. */
|
||||
key_len = 32;
|
||||
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);
|
||||
if (read (urandom, secret_key, key_len) == key_len) {
|
||||
if (!g_file_set_contents (NMSTATEDIR "/secret_key", (char *) secret_key, key_len, error)) {
|
||||
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;
|
||||
}
|
||||
umask (key_mask);
|
||||
close (urandom);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -2953,9 +3075,10 @@ nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf)
|
|||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_set_stable_privacy (struct in6_addr *addr,
|
||||
_set_stable_privacy (guint8 stable_type,
|
||||
struct in6_addr *addr,
|
||||
const char *ifname,
|
||||
const char *uuid,
|
||||
const char *network_id,
|
||||
guint dad_counter,
|
||||
guint8 *secret_key,
|
||||
gsize key_len,
|
||||
|
@ -2979,11 +3102,24 @@ _set_stable_privacy (struct in6_addr *addr,
|
|||
|
||||
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, (const guchar *) ifname, strlen (ifname) + 1);
|
||||
if (!uuid)
|
||||
uuid = "";
|
||||
g_checksum_update (sum, (const guchar *) uuid, strlen (uuid) + 1);
|
||||
if (!network_id)
|
||||
network_id = "";
|
||||
g_checksum_update (sum, (const guchar *) network_id, strlen (network_id) + 1);
|
||||
tmp[0] = htonl (dad_counter);
|
||||
tmp[1] = htonl (key_len);
|
||||
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.
|
||||
*/
|
||||
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 *uuid,
|
||||
const char *network_id,
|
||||
guint dad_counter,
|
||||
GError **error)
|
||||
{
|
||||
gs_free guint8 *secret_key = NULL;
|
||||
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) {
|
||||
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||
"Too many DAD collisions");
|
||||
|
@ -3028,10 +3169,151 @@ nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
|
|||
if (!secret_key)
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
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:
|
||||
* @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);
|
||||
|
||||
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);
|
||||
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,
|
||||
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 *uuid,
|
||||
const char *network_id,
|
||||
guint dad_counter,
|
||||
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_setpgid (gpointer unused);
|
||||
|
|
|
@ -66,6 +66,7 @@ static struct {
|
|||
int tempaddr;
|
||||
char *ifname;
|
||||
char *uuid;
|
||||
char *stable_id;
|
||||
char *dhcp4_address;
|
||||
char *dhcp4_clientid;
|
||||
char *dhcp4_hostname;
|
||||
|
@ -278,8 +279,9 @@ do_early_setup (int *argc, char **argv[])
|
|||
gint64 priority64_v6 = -1;
|
||||
GOptionEntry options[] = {
|
||||
/* Interface/IP config */
|
||||
{ "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), N_("eth0") },
|
||||
{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") },
|
||||
{ "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"), "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-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 },
|
||||
|
@ -469,9 +471,23 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if (iid)
|
||||
|
|
|
@ -595,7 +595,7 @@ nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
|
|||
}
|
||||
|
||||
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;
|
||||
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)) {
|
||||
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))
|
||||
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));
|
||||
|
||||
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. */
|
||||
} else {
|
||||
/* 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;
|
||||
unmanage = TRUE;
|
||||
}
|
||||
|
||||
if (unmanage) {
|
||||
|
@ -1054,7 +1038,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM
|
|||
return parent;
|
||||
|
||||
/* 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)
|
||||
return parent;
|
||||
|
||||
|
|
|
@ -321,7 +321,8 @@ NMRDisc *
|
|||
nm_lndp_rdisc_new (NMPlatform *platform,
|
||||
int ifindex,
|
||||
const char *ifname,
|
||||
const char *uuid,
|
||||
NMUtilsStableType stable_type,
|
||||
const char *network_id,
|
||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||
GError **error)
|
||||
{
|
||||
|
@ -342,7 +343,8 @@ nm_lndp_rdisc_new (NMPlatform *platform,
|
|||
|
||||
rdisc->ifindex = ifindex;
|
||||
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->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define __NETWORKMANAGER_LNDP_RDISC_H__
|
||||
|
||||
#include "nm-rdisc.h"
|
||||
#include "nm-core-utils.h"
|
||||
|
||||
#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))
|
||||
|
@ -47,7 +48,8 @@ GType nm_lndp_rdisc_get_type (void);
|
|||
NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform,
|
||||
int ifindex,
|
||||
const char *ifname,
|
||||
const char *uuid,
|
||||
NMUtilsStableType stable_type,
|
||||
const char *network_id,
|
||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode,
|
||||
GError **error);
|
||||
|
||||
|
|
|
@ -140,9 +140,10 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
|
|||
GError *error = NULL;
|
||||
|
||||
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->uuid,
|
||||
rdisc->network_id,
|
||||
addr->dad_counter++,
|
||||
&error)) {
|
||||
_LOGW ("complete-address: failed to generate an stable-privacy address: %s",
|
||||
|
@ -777,7 +778,7 @@ finalize (GObject *object)
|
|||
NMRDisc *rdisc = NM_RDISC (object);
|
||||
|
||||
g_free (rdisc->ifname);
|
||||
g_free (rdisc->uuid);
|
||||
g_free (rdisc->network_id);
|
||||
g_array_unref (rdisc->gateways);
|
||||
g_array_unref (rdisc->addresses);
|
||||
g_array_unref (rdisc->routes);
|
||||
|
|
|
@ -116,9 +116,11 @@ typedef struct {
|
|||
NMPlatform *_platform;
|
||||
NMPNetns *_netns;
|
||||
|
||||
NMUtilsStableType stable_type;
|
||||
|
||||
int ifindex;
|
||||
char *ifname;
|
||||
char *uuid;
|
||||
char *network_id;
|
||||
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
|
||||
NMUtilsIPv6IfaceId iid;
|
||||
gint32 max_addresses;
|
||||
|
|
|
@ -64,6 +64,7 @@ main (int argc, char **argv)
|
|||
rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
|
||||
ifindex,
|
||||
ifname,
|
||||
NM_UTILS_STABLE_TYPE_UUID,
|
||||
"8ce666e8-d34d-4fb1-b858-f15a7al28086",
|
||||
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
||||
&error);
|
||||
|
|
|
@ -1879,11 +1879,11 @@ have_connection_for_device (NMSettings *self, NMDevice *device)
|
|||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
const char *setting_hwaddr;
|
||||
const char *device_hwaddr;
|
||||
const char *perm_hw_addr;
|
||||
|
||||
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 */
|
||||
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);
|
||||
if (setting_hwaddr) {
|
||||
/* A connection mac-locked to this device */
|
||||
if ( device_hwaddr
|
||||
&& nm_utils_hwaddr_matches (setting_hwaddr, -1, device_hwaddr, -1))
|
||||
if ( perm_hw_addr
|
||||
&& nm_utils_hwaddr_matches (setting_hwaddr, -1, perm_hw_addr, -1))
|
||||
return TRUE;
|
||||
} else {
|
||||
/* A connection that applies to any wired device */
|
||||
|
|
|
@ -128,6 +128,7 @@ make_connection_setting (const char *file,
|
|||
NMSettingConnectionLldp lldp;
|
||||
const char *ifcfg_name = NULL;
|
||||
char *new_id, *uuid = NULL, *zone = NULL, *value;
|
||||
gs_free char *stable_id = NULL;
|
||||
|
||||
ifcfg_name = utils_get_ifcfg_name (file, TRUE);
|
||||
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);
|
||||
}
|
||||
|
||||
stable_id = svGetValue (ifcfg, "STABLE_ID", FALSE);
|
||||
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_TYPE, type,
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_STABLE_ID, stable_id,
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
|
@ -3364,6 +3368,10 @@ make_wireless_setting (shvarFile *ifcfg,
|
|||
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);
|
||||
if (value) {
|
||||
char **strv;
|
||||
|
@ -3878,6 +3886,10 @@ make_wired_setting (shvarFile *ifcfg,
|
|||
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);
|
||||
if (value) {
|
||||
char **strv;
|
||||
|
|
|
@ -853,6 +853,10 @@ write_wireless_setting (NMConnection *connection,
|
|||
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
|
||||
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);
|
||||
macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
|
||||
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);
|
||||
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);
|
||||
macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
|
||||
if (macaddr_blacklist[0]) {
|
||||
|
@ -1255,19 +1263,22 @@ write_wired_for_virtual (NMConnection *connection, shvarFile *ifcfg)
|
|||
has_wired = TRUE;
|
||||
|
||||
device_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (device_mac)
|
||||
svSetValue (ifcfg, "HWADDR", device_mac, FALSE);
|
||||
|
||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
||||
if (cloned_mac)
|
||||
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);
|
||||
if (mtu) {
|
||||
tmp = g_strdup_printf ("%u", mtu);
|
||||
svSetValue (ifcfg, "MTU", tmp, FALSE);
|
||||
g_free (tmp);
|
||||
}
|
||||
} else
|
||||
svSetValue (ifcfg, "MTU", NULL, FALSE);
|
||||
}
|
||||
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, "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, "ONBOOT",
|
||||
nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no",
|
||||
|
|
|
@ -47,7 +47,6 @@ typedef struct
|
|||
GHashTable *config;
|
||||
GHashTable *blobs;
|
||||
guint32 ap_scan;
|
||||
NMSettingMacRandomization mac_randomization;
|
||||
gboolean fast_required;
|
||||
gboolean dispose_has_run;
|
||||
} NMSupplicantConfigPrivate;
|
||||
|
@ -85,7 +84,6 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
|
|||
(GDestroyNotify) blob_free);
|
||||
|
||||
priv->ap_scan = 1;
|
||||
priv->mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
nm_supplicant_config_fast_required (NMSupplicantConfig *self)
|
||||
{
|
||||
|
@ -385,8 +357,6 @@ gboolean
|
|||
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
|
||||
NMSettingWireless * setting,
|
||||
guint32 fixed_freq,
|
||||
NMSupplicantFeature mac_randomization_support,
|
||||
NMSettingMacRandomization mac_randomization_fallback,
|
||||
GError **error)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ NMSupplicantConfig *nm_supplicant_config_new (void);
|
|||
|
||||
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);
|
||||
|
||||
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,
|
||||
NMSettingWireless *setting,
|
||||
guint32 fixed_freq,
|
||||
NMSupplicantFeature mac_randomization_support,
|
||||
NMSettingMacRandomization mac_randomization_fallback,
|
||||
GError **error);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NMSupplicantFeature
|
||||
nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self)
|
||||
{
|
||||
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->mac_randomization_support;
|
||||
}
|
||||
|
||||
static void
|
||||
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)",
|
||||
WPAS_DBUS_IFACE_INTERFACE,
|
||||
"PreassocMacAddr",
|
||||
g_variant_new_string ("1")),
|
||||
g_variant_new_string ("0")),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
priv->init_cancellable,
|
||||
|
@ -1223,9 +1217,7 @@ set_mac_randomization_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user
|
|||
return;
|
||||
}
|
||||
|
||||
_LOGI ("config: set MAC randomization to %s",
|
||||
nm_supplicant_config_get_mac_randomization (priv->cfg));
|
||||
|
||||
_LOGT ("config: set MAC randomization to 0");
|
||||
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));
|
||||
|
||||
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 */
|
||||
g_dbus_proxy_call (priv->iface_proxy,
|
||||
DBUS_INTERFACE_PROPERTIES ".Set",
|
||||
g_variant_new ("(ssv)",
|
||||
WPAS_DBUS_IFACE_INTERFACE,
|
||||
"MacAddr",
|
||||
g_variant_new_string (mac_randomization)),
|
||||
g_variant_new_string ("0")),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
priv->assoc_cancellable,
|
||||
(GAsyncReadyCallback) set_mac_randomization_cb,
|
||||
self);
|
||||
} else {
|
||||
} else
|
||||
add_network (self);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -165,6 +165,4 @@ NMSupplicantFeature nm_supplicant_interface_get_ap_support (NMSupplicantInterfac
|
|||
void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self,
|
||||
NMSupplicantFeature apmode);
|
||||
|
||||
NMSupplicantFeature nm_supplicant_interface_get_mac_randomization_support (NMSupplicantInterface *self);
|
||||
|
||||
#endif /* NM_SUPPLICANT_INTERFACE_H */
|
||||
|
|
|
@ -160,8 +160,6 @@ test_wifi_open (void)
|
|||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||
s_wifi,
|
||||
0,
|
||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||
&error));
|
||||
g_assert_no_error (error);
|
||||
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,
|
||||
s_wifi,
|
||||
0,
|
||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||
&error));
|
||||
g_assert_no_error (error);
|
||||
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,
|
||||
s_wifi,
|
||||
0,
|
||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||
&error));
|
||||
g_assert_no_error (error);
|
||||
g_test_assert_expected_messages ();
|
||||
|
@ -557,8 +551,6 @@ test_wifi_eap (void)
|
|||
g_assert (nm_supplicant_config_add_setting_wireless (config,
|
||||
s_wifi,
|
||||
0,
|
||||
NM_SUPPLICANT_FEATURE_UNKNOWN,
|
||||
NM_SETTING_MAC_RANDOMIZATION_DEFAULT,
|
||||
&error));
|
||||
g_assert_no_error (error);
|
||||
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
|
||||
* 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
|
||||
constructed (GObject *object)
|
||||
{
|
||||
|
@ -73,7 +62,6 @@ nm_test_device_class_init (NMTestDeviceClass *klass)
|
|||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
|
||||
|
||||
object_class->constructor = constructor;
|
||||
object_class->constructed = constructed;
|
||||
object_class->dispose = dispose;
|
||||
|
||||
|
@ -85,6 +73,6 @@ nm_test_device_new (const char *hwaddr)
|
|||
{
|
||||
return g_object_new (NM_TYPE_TEST_DEVICE,
|
||||
NM_DEVICE_IFACE, "dummy",
|
||||
NM_DEVICE_HW_ADDRESS, hwaddr,
|
||||
NM_DEVICE_PERM_HW_ADDRESS, hwaddr,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -34,21 +34,93 @@ test_stable_privacy (void)
|
|||
struct in6_addr 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");
|
||||
|
||||
/* We get an address without the UUID. */
|
||||
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");
|
||||
|
||||
/* We get a different address in a different network. */
|
||||
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");
|
||||
|
||||
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 ();
|
||||
|
||||
|
@ -58,6 +130,7 @@ main (int argc, char **argv)
|
|||
nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue