libnm: add nm_sett_info_propert_type_direct_mac_address

A MAC address is a relatively common "type". The GObject property is of type string,
but the D-Bus type is a bytestring ("ay"). We will need a special NMSettInfoPropertType.

Note that like most implementations, the from-dbus implementation still is based
on GObject setters. This will change in the future.

Also note that the previous compare function was
_nm_setting_property_compare_fcn_default(). That is, it used to convert
the property to GVariant and compare those. The conversion to GVariant
in that case normalizes the string (e.g. it is case insensitive). Also,
only properties could be compared which were also convertible to D-Bus
(which is probably fine, because there is no guarantee the profiles that
don't verify can be compared).

The code now uses the direct comparison of the strings. That mostly
preserves the case-insensitivity of the previous comparison, because
the property setters for mac addresses all use
_nm_utils_hwaddr_canonical_or_invalid() to normalize the strings.
This is subtle, but still correct. Note that this will improve later,
by ensuring that the property setters for mac addresses automatically
perform the right normalization.
This commit is contained in:
Thomas Haller
2021-07-13 18:09:13 +02:00
parent dc2e4d04f1
commit 82e9f43289
13 changed files with 190 additions and 109 deletions

View File

@@ -316,15 +316,16 @@ nm_setting_bluetooth_class_init(NMSettingBluetoothClass *klass)
*
* The Bluetooth address of the device.
**/
obj_properties[PROP_BDADDR] = g_param_spec_string(
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_BLUETOOTH_BDADDR,
"",
"",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_BDADDR],
&nm_sett_info_propert_type_mac_address);
PROP_BDADDR,
NM_SETTING_PARAM_INFERRABLE,
NMSettingBluetoothPrivate,
bdaddr,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingBluetooth:type:

View File

@@ -1627,15 +1627,16 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass)
* BRIDGE_MACADDR for bridges is an NM extension.
* ---end---
*/
obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string(
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_BRIDGE_MAC_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_MAC_ADDRESS],
&nm_sett_info_propert_type_mac_address);
PROP_MAC_ADDRESS,
NM_SETTING_PARAM_INFERRABLE,
NMSettingBridgePrivate,
mac_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingBridge:stp:
@@ -1935,15 +1936,16 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass)
* example: BRIDGING_OPTS="group_address=01:80:C2:00:00:0A"
* ---end---
*/
obj_properties[PROP_GROUP_ADDRESS] = g_param_spec_string(
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_BRIDGE_GROUP_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_GROUP_ADDRESS],
&nm_sett_info_propert_type_mac_address);
PROP_GROUP_ADDRESS,
NM_SETTING_PARAM_INFERRABLE,
NMSettingBridgePrivate,
group_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingBridge:vlan-protocol:

View File

@@ -426,15 +426,16 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass)
* example: HWADDR=01:02:03:04:05:06:07:08:09:0A:01:02:03:04:05:06:07:08:09:11
* ---end---
*/
obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string(
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_INFINIBAND_MAC_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_MAC_ADDRESS],
&nm_sett_info_propert_type_mac_address);
PROP_MAC_ADDRESS,
NM_SETTING_PARAM_INFERRABLE,
NMSettingInfinibandPrivate,
mac_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingInfiniband:mtu:

View File

@@ -275,15 +275,16 @@ nm_setting_olpc_mesh_class_init(NMSettingOlpcMeshClass *klass)
*
* This is currently only implemented by dhclient DHCP plugin.
**/
obj_properties[PROP_DHCP_ANYCAST_ADDRESS] =
g_param_spec_string(NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_DHCP_ANYCAST_ADDRESS],
&nm_sett_info_propert_type_mac_address);
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS,
PROP_DHCP_ANYCAST_ADDRESS,
NM_SETTING_PARAM_NONE,
NMSettingOlpcMeshPrivate,
dhcp_anycast_addr,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);

View File

@@ -291,6 +291,7 @@ extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_u;
extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_boolean;
extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_uint32;
extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_string;
extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_mac_address;
NMSettingVerifyResult
_nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error);
@@ -364,6 +365,14 @@ GVariant *_nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting *
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options);
GVariant *_nm_setting_property_to_dbus_fcn_direct_mac_address(
const NMSettInfoSetting * sett_info,
const NMSettInfoProperty * property_info,
NMConnection * connection,
NMSetting * setting,
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options);
gboolean _nm_setting_property_from_dbus_fcn_ignore(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty *property_info,
NMSetting * setting,
@@ -645,6 +654,44 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
/*****************************************************************************/
#define _nm_setting_property_define_direct_mac_address(properties_override, \
obj_properties, \
prop_name, \
prop_id, \
param_flags, \
private_struct_type, \
private_struct_field, \
... /* extra NMSettInfoProperty fields */) \
G_STMT_START \
{ \
GParamSpec *_param_spec; \
\
G_STATIC_ASSERT(!NM_FLAGS_ANY((param_flags), \
~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_FUZZY_IGNORE \
| NM_SETTING_PARAM_INFERRABLE \
| NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \
\
_param_spec = \
g_param_spec_string("" prop_name "", \
"", \
"", \
NULL, \
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \
\
(obj_properties)[(prop_id)] = _param_spec; \
\
_nm_properties_override_gobj( \
(properties_override), \
_param_spec, \
&nm_sett_info_propert_type_direct_mac_address, \
.direct_offset = \
NM_STRUCT_OFFSET_ENSURE_TYPE(char *, private_struct_type, private_struct_field), \
__VA_ARGS__); \
} \
G_STMT_END
/*****************************************************************************/
gboolean _nm_setting_use_legacy_property(NMSetting * setting,
GVariant * connection_dict,
const char *legacy_property,

View File

@@ -252,15 +252,16 @@ nm_setting_wimax_class_init(NMSettingWimaxClass *klass)
*
* Deprecated: 1.2: WiMAX is no longer supported.
**/
obj_properties[PROP_MAC_ADDRESS] =
g_param_spec_string(NM_SETTING_WIMAX_MAC_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_MAC_ADDRESS],
&nm_sett_info_propert_type_mac_address);
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_WIMAX_MAC_ADDRESS,
PROP_MAC_ADDRESS,
NM_SETTING_PARAM_NONE,
NMSettingWimaxPrivate,
mac_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);

View File

@@ -1409,15 +1409,16 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass)
* permanent MAC address exists, the MAC address initially configured on the device.
* ---end---
*/
obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string(
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_WIRED_MAC_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_MAC_ADDRESS],
&nm_sett_info_propert_type_mac_address);
PROP_MAC_ADDRESS,
NM_SETTING_PARAM_INFERRABLE,
NMSettingWiredPrivate,
device_mac_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingWired:cloned-mac-address:

View File

@@ -1533,14 +1533,16 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass)
* example: BSSID=00:1E:BD:64:83:21
* ---end---
*/
obj_properties[PROP_BSSID] = g_param_spec_string(NM_SETTING_WIRELESS_BSSID,
"",
"",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_BSSID],
&nm_sett_info_propert_type_mac_address);
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_WIRELESS_BSSID,
PROP_BSSID,
NM_SETTING_PARAM_NONE,
NMSettingWirelessPrivate,
bssid,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingWireless:rate:
@@ -1611,15 +1613,16 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass)
* permanent MAC address exists, the MAC address initially configured on the device.
* ---end---
*/
obj_properties[PROP_MAC_ADDRESS] =
g_param_spec_string(NM_SETTING_WIRELESS_MAC_ADDRESS,
"",
"",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_MAC_ADDRESS],
&nm_sett_info_propert_type_mac_address);
_nm_setting_property_define_direct_mac_address(
properties_override,
obj_properties,
NM_SETTING_WIRELESS_MAC_ADDRESS,
PROP_MAC_ADDRESS,
NM_SETTING_PARAM_NONE,
NMSettingWirelessPrivate,
device_mac_address,
/* it's special, because it uses _nm_utils_hwaddr_canonical_or_invalid(). */
.direct_has_special_setter = TRUE);
/**
* NMSettingWireless:cloned-mac-address:

View File

@@ -954,6 +954,27 @@ _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting *
}
}
GVariant *
_nm_setting_property_to_dbus_fcn_direct_mac_address(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty * property_info,
NMConnection * connection,
NMSetting * setting,
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options)
{
const char *val;
nm_assert(property_info->property_type == &nm_sett_info_propert_type_direct_mac_address);
nm_assert(property_info->property_type->direct_type == NM_VALUE_TYPE_STRING);
nm_assert(!NM_G_PARAM_SPEC_GET_DEFAULT_STRING(property_info->param_spec));
nm_assert(!property_info->to_dbus_including_default);
val = *((const char *const *) _nm_setting_get_private(setting,
sett_info,
property_info->direct_offset));
return nm_utils_hwaddr_to_dbus(val);
}
GVariant *
_nm_setting_property_to_dbus_fcn_ignore(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty * property_info,
@@ -1008,8 +1029,6 @@ _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * s
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT:
nm_assert(G_VALUE_HOLDS(&prop_value, G_TYPE_HASH_TABLE));
return nm_utils_strdict_to_variant_ass(g_value_get_boxed(&prop_value));
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS:
return nm_utils_hwaddr_to_dbus(g_value_get_string(&prop_value));
}
return nm_assert_unreachable_val(NULL);
@@ -1847,7 +1866,9 @@ _nm_setting_property_compare_fcn_direct(const NMSettInfoSetting * sett_info,
gconstpointer p_a;
gconstpointer p_b;
nm_assert(property_info->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_direct);
nm_assert(NM_IN_SET(property_info->property_type->to_dbus_fcn,
_nm_setting_property_to_dbus_fcn_direct,
_nm_setting_property_to_dbus_fcn_direct_mac_address));
if (!property_info->param_spec)
return nm_assert_unreachable_val(NM_TERNARY_DEFAULT);
@@ -2867,6 +2888,17 @@ _nm_setting_get_deprecated_virtual_interface_name(const NMSettInfoSetting *
return NULL;
}
static void
_nm_utils_hwaddr_from_dbus(GVariant *dbus_value, GValue *prop_value)
{
gsize length = 0;
const guint8 *array = g_variant_get_fixed_array(dbus_value, &length, 1);
char * str;
str = length ? nm_utils_hwaddr_ntoa(array, length) : NULL;
g_value_take_string(prop_value, str);
}
const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_ignore,
@@ -2928,6 +2960,16 @@ const NMSettInfoPropertType nm_sett_info_propert_type_direct_string =
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_direct_mac_address =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_BYTESTRING,
.direct_type = NM_VALUE_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn =
_nm_setting_property_to_dbus_fcn_direct_mac_address,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE,
.typdata_from_dbus.gprop_fcn = _nm_utils_hwaddr_from_dbus);
/*****************************************************************************/
static GenData *

View File

@@ -34,8 +34,6 @@ gboolean _nm_utils_wps_method_validate(NMSettingWirelessSecurityWpsMethod wps_me
extern const NMSettInfoPropertType nm_sett_info_propert_type_strdict;
extern const NMSettInfoPropertType nm_sett_info_propert_type_mac_address;
extern const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address;
void _nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value);

View File

@@ -4149,26 +4149,6 @@ const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address =
.to_dbus_fcn = _nm_utils_hwaddr_cloned_data_synth,
.from_dbus_fcn = _nm_utils_hwaddr_cloned_data_set, );
static void
_nm_utils_hwaddr_from_dbus(GVariant *dbus_value, GValue *prop_value)
{
gsize length = 0;
const guint8 *array = g_variant_get_fixed_array(dbus_value, &length, 1);
char * str;
str = length ? nm_utils_hwaddr_ntoa(array, length) : NULL;
g_value_take_string(prop_value, str);
}
const NMSettInfoPropertType nm_sett_info_propert_type_mac_address =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_BYTESTRING,
.typdata_from_dbus.gprop_fcn = _nm_utils_hwaddr_from_dbus,
.typdata_to_dbus.gprop_type =
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
/*****************************************************************************/
/* Validate secret-flags. Most settings don't validate them, which is a bug.

View File

@@ -4470,9 +4470,16 @@ test_setting_metadata(void)
can_set_including_default = TRUE;
} else if (sip->property_type->direct_type == NM_VALUE_TYPE_STRING) {
if (sip->property_type == &nm_sett_info_propert_type_direct_mac_address) {
g_assert(g_variant_type_equal(sip->property_type->dbus_type, "ay"));
g_assert(sip->property_type->to_dbus_fcn
== _nm_setting_property_to_dbus_fcn_direct_mac_address);
g_assert(sip->direct_has_special_setter);
} else {
g_assert(g_variant_type_equal(sip->property_type->dbus_type, "s"));
g_assert(sip->property_type->to_dbus_fcn
== _nm_setting_property_to_dbus_fcn_direct);
}
g_assert(sip->param_spec);
g_assert(sip->param_spec->value_type == G_TYPE_STRING);
} else
@@ -4500,9 +4507,6 @@ test_setting_metadata(void)
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT:
g_assert(sip->param_spec->value_type == G_TYPE_HASH_TABLE);
goto check_done;
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS:
g_assert(sip->param_spec->value_type == G_TYPE_STRING);
goto check_done;
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT:
goto check_done;
}
@@ -4536,8 +4540,9 @@ check_done:;
} else if (sip->property_type->compare_fcn == _nm_setting_property_compare_fcn_direct) {
g_assert(sip->param_spec);
g_assert(sip->property_type->direct_type != NM_VALUE_TYPE_NONE);
g_assert(sip->property_type->to_dbus_fcn
== _nm_setting_property_to_dbus_fcn_direct);
g_assert(NM_IN_SET(sip->property_type->to_dbus_fcn,
_nm_setting_property_to_dbus_fcn_direct,
_nm_setting_property_to_dbus_fcn_direct_mac_address));
} else if (sip->property_type->compare_fcn == _nm_setting_property_compare_fcn_ignore) {
if (NM_IN_SET(sip->property_type,
&nm_sett_info_propert_type_deprecated_ignore_i,

View File

@@ -679,7 +679,6 @@ typedef enum _nm_packed {
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_GARRAY_UINT,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS,
} NMSettingPropertyToDBusFcnGPropType;
typedef struct {