diff options
| author | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-08-26 02:18:32 +0200 |
| commit | 7514efc2f38c9ace4557d4e69d68e7d380389030 (patch) | |
| tree | 7fb00fda86cfcc2ca377f191633a7cfdbfea7ca3 /libnm-core/nm-setting-wired.c | |
| parent | d6201f5d8daada3d64a0a3e0038e14eebec683ce (diff) | |
Imported Upstream version 1.4.0 upstream/1.4.0
Diffstat (limited to 'libnm-core/nm-setting-wired.c')
| -rw-r--r-- | libnm-core/nm-setting-wired.c | 183 |
1 files changed, 166 insertions, 17 deletions
diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 132f8e05..fc5ab3e5 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -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, @@ -188,6 +191,22 @@ nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting) } /** + * 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 * @@ -504,7 +523,7 @@ nm_setting_wired_add_s390_option (NMSettingWired *setting, g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (strlen (key), FALSE); - g_return_val_if_fail (_nm_utils_string_in_list (key, valid_s390_opts), FALSE); + g_return_val_if_fail (g_strv_contains (valid_s390_opts, key), FALSE); g_return_val_if_fail (value != NULL, FALSE); value_len = strlen (value); @@ -611,8 +630,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) GHashTableIter iter; const char *key, *value; int i; + GError *local = NULL; - if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) { + if (priv->port && !g_strv_contains (valid_ports, priv->port)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -622,7 +642,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - if (priv->duplex && !_nm_utils_string_in_list (priv->duplex, valid_duplex)) { + if (priv->duplex && !g_strv_contains (valid_duplex, priv->duplex)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -668,7 +688,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - if (priv->s390_nettype && !_nm_utils_string_in_list (priv->s390_nettype, valid_nettype)) { + if (priv->s390_nettype && !g_strv_contains (valid_nettype, priv->s390_nettype)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -679,7 +699,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) g_hash_table_iter_init (&iter, priv->s390_options); while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { - if ( !_nm_utils_string_in_list (key, valid_s390_opts) + if ( !g_strv_contains (valid_s390_opts, key) || !strlen (value) || (strlen (value) > 200)) { 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, - G_VARIANT_TYPE_BYTESTRING, - _nm_utils_hwaddr_to_dbus, - _nm_utils_hwaddr_from_dbus); + _nm_setting_class_override_property (setting_class, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _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" 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); |