libnm: always set from_dbus_fcn() property hook

When looking at a property, it should always be clear how it is handled.
Also the "default" action should be an explicit hook.

Add _nm_setting_property_from_dbus_fcn_gprop() and set that as
from_dbus_fcn() callback to handle the "default" case which us
build around g_object_set_property().

While this adds lines of code, I think it makes the code easier to
understand. Basically, to convert a GVariant to a property, now all
properties call their from_dbus_fcn() handler, there is no special casing.
And the gprop-hook is only called for properties that are using
_nm_setting_property_from_dbus_fcn_gprop(). So, you can reason about
these two functions at separate layers.
This commit is contained in:
Thomas Haller
2021-06-30 00:05:49 +02:00
parent a9ef71eb4a
commit 77d2c13e21
19 changed files with 274 additions and 118 deletions

View File

@@ -1211,10 +1211,12 @@ nm_setting_bond_class_init(NMSettingBondClass *klass)
properties_override,
obj_properties[PROP_OPTIONS],
NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"),
.gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus,
.typdata_from_dbus.gprop_fcn = _nm_utils_strdict_from_dbus,
.typdata_to_dbus.gprop_type =
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT,
.compare_fcn = compare_fcn_options));
.compare_fcn = compare_fcn_options,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/* ---dbus---
* property: interface-name

View File

@@ -1898,9 +1898,11 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
PROP_ID,
NM_SETTING_PARAM_FUZZY_IGNORE,
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING,
.direct_type = NM_VALUE_TYPE_STRING,
.compare_fcn = compare_fcn_id,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct),
.direct_type = NM_VALUE_TYPE_STRING,
.compare_fcn = compare_fcn_id,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE),
NMSettingConnectionPrivate,
id);
@@ -2025,7 +2027,9 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
.missing_from_dbus_fcn =
nm_setting_connection_no_interface_name),
nm_setting_connection_no_interface_name,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE),
NMSettingConnectionPrivate,
interface_name);
@@ -2223,8 +2227,10 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
properties_override,
obj_properties[PROP_TIMESTAMP],
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_UINT64,
.compare_fcn = compare_fcn_timestamp,
.to_dbus_fcn = _to_dbus_fcn_timestamp, ));
.compare_fcn = compare_fcn_timestamp,
.to_dbus_fcn = _to_dbus_fcn_timestamp,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingConnection:read-only:

View File

@@ -757,9 +757,11 @@ _nm_setting_dcb_uint_array_from_dbus(GVariant *dbus_value, GValue *prop_value)
static const NMSettInfoPropertType nm_sett_info_propert_type_dcb_au =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(
NM_G_VARIANT_TYPE("au"),
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_GARRAY_UINT,
.gprop_from_dbus_fcn = _nm_setting_dcb_uint_array_from_dbus,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_GARRAY_UINT,
.typdata_from_dbus.gprop_fcn = _nm_setting_dcb_uint_array_from_dbus,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
/*****************************************************************************/

View File

@@ -975,7 +975,9 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("au"),
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = ip4_dns_to_dbus,
.gprop_from_dbus_fcn = ip4_dns_from_dbus, ), );
.typdata_from_dbus.gprop_fcn = ip4_dns_from_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE), );
/* ---dbus---
* property: addresses

View File

@@ -1041,7 +1041,9 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aay"),
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = ip6_dns_to_dbus,
.gprop_from_dbus_fcn = ip6_dns_from_dbus, ));
.typdata_from_dbus.gprop_fcn = ip6_dns_from_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/* ---dbus---
* property: addresses

View File

@@ -536,10 +536,12 @@ nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass)
properties_override,
obj_properties[PROP_DATA],
NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"),
.gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus,
.typdata_from_dbus.gprop_fcn = _nm_utils_strdict_from_dbus,
.typdata_to_dbus.gprop_type =
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT,
.compare_fcn = compare_fcn_data));
.compare_fcn = compare_fcn_data,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);

View File

@@ -364,6 +364,22 @@ GVariant *_nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting *
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options);
gboolean _nm_setting_property_from_dbus_fcn_ignore(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty *property_info,
NMSetting * setting,
GVariant * connection_dict,
GVariant * value,
NMSettingParseFlags parse_flags,
GError ** error);
gboolean _nm_setting_property_from_dbus_fcn_gprop(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty *property_info,
NMSetting * setting,
GVariant * connection_dict,
GVariant * value,
NMSettingParseFlags parse_flags,
GError ** error);
GVariant *_nm_setting_to_dbus(NMSetting * setting,
NMConnection * connection,
NMConnectionSerializationFlags flags,

View File

@@ -321,7 +321,9 @@ nm_setting_serial_class_init(NMSettingSerialClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_BYTE,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = parity_to_dbus_fcn,
.gprop_from_dbus_fcn = parity_from_dbus, ));
.typdata_from_dbus.gprop_fcn = parity_from_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingSerial:stopbits:

View File

@@ -578,8 +578,10 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass)
properties_override,
obj_properties[NM_TEAM_ATTRIBUTE_CONFIG],
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING,
.compare_fcn = compare_fcn_config,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, ));
.compare_fcn = compare_fcn_config,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingTeamPort:queue-id:
@@ -701,8 +703,10 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"),
.compare_fcn = compare_fcn_link_watchers,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.gprop_from_dbus_fcn =
_nm_team_settings_property_from_dbus_link_watchers, ));
.typdata_from_dbus.gprop_fcn =
_nm_team_settings_property_from_dbus_link_watchers,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
g_object_class_install_properties(object_class, G_N_ELEMENTS(obj_properties), obj_properties);

View File

@@ -1540,8 +1540,10 @@ nm_setting_team_class_init(NMSettingTeamClass *klass)
properties_override,
obj_properties[NM_TEAM_ATTRIBUTE_CONFIG],
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING,
.compare_fcn = compare_fcn_config,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, ));
.compare_fcn = compare_fcn_config,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingTeam:notify-peers-count:
@@ -1824,8 +1826,10 @@ nm_setting_team_class_init(NMSettingTeamClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"),
.compare_fcn = compare_fcn_link_watchers,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.gprop_from_dbus_fcn =
_nm_team_settings_property_from_dbus_link_watchers, ));
.typdata_from_dbus.gprop_fcn =
_nm_team_settings_property_from_dbus_link_watchers,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/* ---dbus---
* property: interface-name

View File

@@ -577,10 +577,12 @@ nm_setting_user_class_init(NMSettingUserClass *klass)
properties_override,
obj_properties[PROP_DATA],
NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"),
.gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus,
.typdata_from_dbus.gprop_fcn = _nm_utils_strdict_from_dbus,
.typdata_to_dbus.gprop_type =
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT,
.compare_fcn = compare_fcn_data));
.compare_fcn = compare_fcn_data,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);

View File

@@ -929,7 +929,9 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass)
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_UINT32,
.to_dbus_fcn = _override_flags_get,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.missing_from_dbus_fcn = _override_flags_not_set, ));
.missing_from_dbus_fcn = _override_flags_not_set,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingVlan:ingress-priority-map:

View File

@@ -1939,8 +1939,10 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass)
properties_override,
obj_properties[PROP_WEP_KEY_TYPE],
NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_UINT32,
.to_dbus_fcn = wep_key_type_to_dbus,
.compare_fcn = _nm_setting_property_compare_fcn_default));
.to_dbus_fcn = wep_key_type_to_dbus,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE));
/**
* NMSettingWirelessSecurity:wps-method:

View File

@@ -54,6 +54,9 @@ G_DEFINE_ABSTRACT_TYPE(NMSetting, nm_setting, G_TYPE_OBJECT)
/*****************************************************************************/
static GenData *_gendata_hash(NMSetting *setting, gboolean create_if_necessary);
static gboolean set_property_from_dbus(const NMSettInfoProperty *property_info,
GVariant * src_value,
GValue * dst_value);
/*****************************************************************************/
@@ -171,12 +174,15 @@ _nm_properties_override_assert(const NMSettInfoProperty *prop_info)
/* we always require a dbus_type. */
nm_assert(property_type->dbus_type);
/* from_dbus_fcn and gprop_from_dbus_fcn cannot both be set. */
nm_assert(!property_type->from_dbus_fcn || !property_type->gprop_from_dbus_fcn);
if (property_type->typdata_from_dbus.gprop_fcn)
nm_assert(property_type->from_dbus_fcn == _nm_setting_property_from_dbus_fcn_gprop);
if (property_type->from_dbus_fcn == _nm_setting_property_from_dbus_fcn_gprop)
nm_assert(prop_info->param_spec);
if (!prop_info->param_spec) {
/* if we don't have a param_spec, we cannot have gprop_from_dbus_fcn. */
nm_assert(property_type->from_dbus_fcn || !property_type->gprop_from_dbus_fcn);
/* if we don't have a param_spec, we cannot have typdata_from_dbus.gprop_fcn. */
nm_assert(property_type->from_dbus_fcn || !property_type->typdata_from_dbus.gprop_fcn);
}
}
#endif
@@ -372,11 +378,15 @@ _nm_setting_class_commit(NMSettingClass * setting_class,
if (vtype == G_TYPE_BOOLEAN)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_BOOLEAN,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_UCHAR)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_BYTE,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_INT)
p->property_type = &nm_sett_info_propert_type_plain_i;
else if (vtype == G_TYPE_UINT)
@@ -384,11 +394,15 @@ _nm_setting_class_commit(NMSettingClass * setting_class,
else if (vtype == G_TYPE_INT64)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_INT64,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_UINT64)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_UINT64,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_STRING) {
nm_assert(nm_streq(p->name, NM_SETTING_NAME)
== (!NM_FLAGS_HAS(p->param_spec->flags, G_PARAM_WRITABLE)));
@@ -397,31 +411,43 @@ _nm_setting_class_commit(NMSettingClass * setting_class,
else {
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
}
} else if (vtype == G_TYPE_DOUBLE)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_DOUBLE,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_STRV)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_STRING_ARRAY,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
else if (vtype == G_TYPE_BYTES) {
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_BYTESTRING,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
} else if (g_type_is_a(vtype, G_TYPE_ENUM)) {
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_INT32,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
} else if (g_type_is_a(vtype, G_TYPE_FLAGS)) {
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_UINT32,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
} else
nm_assert_not_reached();
@@ -989,6 +1015,69 @@ _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * s
return nm_assert_unreachable_val(NULL);
}
gboolean
_nm_setting_property_from_dbus_fcn_ignore(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty *property_info,
NMSetting * setting,
GVariant * connection_dict,
GVariant * value,
NMSettingParseFlags parse_flags,
GError ** error)
{
return TRUE;
}
gboolean
_nm_setting_property_from_dbus_fcn_gprop(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty *property_info,
NMSetting * setting,
GVariant * connection_dict,
GVariant * value,
NMSettingParseFlags parse_flags,
GError ** error)
{
nm_auto_unset_gvalue GValue object_value = G_VALUE_INIT;
gs_free_error GError *local = NULL;
nm_assert(property_info->param_spec);
g_value_init(&object_value, property_info->param_spec->value_type);
if (!set_property_from_dbus(property_info, value, &object_value)) {
/* for backward behavior, fail unless best-effort is chosen. */
if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT))
return TRUE;
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can't set property of type '%s' from value of type '%s'"),
property_info->property_type->dbus_type
? g_variant_type_peek_string(property_info->property_type->dbus_type)
: (property_info->param_spec
? g_type_name(property_info->param_spec->value_type)
: "(unknown)"),
g_variant_get_type_string(value));
g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name);
return FALSE;
}
if (!nm_g_object_set_property(G_OBJECT(setting),
property_info->param_spec->name,
&object_value,
&local)) {
if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT))
return TRUE;
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can not set property: %s"),
local->message);
g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name);
return FALSE;
}
return TRUE;
}
static GVariant *
property_to_dbus(const NMSettInfoSetting * sett_info,
const NMSettInfoProperty * property_info,
@@ -1056,11 +1145,11 @@ set_property_from_dbus(const NMSettInfoProperty *property_info,
nm_assert(property_info->param_spec);
nm_assert(property_info->property_type->dbus_type);
if (property_info->property_type->gprop_from_dbus_fcn) {
if (property_info->property_type->typdata_from_dbus.gprop_fcn) {
if (!g_variant_type_equal(g_variant_get_type(src_value),
property_info->property_type->dbus_type))
return FALSE;
property_info->property_type->gprop_from_dbus_fcn(src_value, dst_value);
property_info->property_type->typdata_from_dbus.gprop_fcn(src_value, dst_value);
} else if (dst_value->g_type == G_TYPE_BYTES) {
if (!g_variant_is_of_type(src_value, G_VARIANT_TYPE_BYTESTRING))
return FALSE;
@@ -1328,8 +1417,11 @@ init_from_dbus(NMSetting * setting,
g_hash_table_remove(keys, property_info->name);
if (property_info->property_type->from_dbus_fcn) {
if (!g_variant_type_equal(g_variant_get_type(value),
property_info->property_type->dbus_type)) {
if (property_info->property_type->from_dbus_is_full) {
/* These hooks perform their own type checking, and can coerce/ignore
* a value regardless of the D-Bus type. */
} else if (!g_variant_type_equal(g_variant_get_type(value),
property_info->property_type->dbus_type)) {
/* for backward behavior, fail unless best-effort is chosen. */
if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT))
continue;
@@ -1354,7 +1446,10 @@ init_from_dbus(NMSetting * setting,
value,
parse_flags,
&local)) {
if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT))
if (property_info->property_type->from_dbus_is_full) {
/* the error we received from from_dbus_fcn() should be propagated, even
* in non-strict mode. */
} else if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT))
continue;
g_set_error(error,
NM_CONNECTION_ERROR,
@@ -1367,44 +1462,7 @@ init_from_dbus(NMSetting * setting,
continue;
}
if (property_info->param_spec) {
nm_auto_unset_gvalue GValue object_value = G_VALUE_INIT;
g_value_init(&object_value, property_info->param_spec->value_type);
if (!set_property_from_dbus(property_info, value, &object_value)) {
/* for backward behavior, fail unless best-effort is chosen. */
if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_BEST_EFFORT))
continue;
g_set_error(
error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can't set property of type '%s' from value of type '%s'"),
property_info->property_type->dbus_type
? g_variant_type_peek_string(property_info->property_type->dbus_type)
: (property_info->param_spec
? g_type_name(property_info->param_spec->value_type)
: "(unknown)"),
g_variant_get_type_string(value));
g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name);
return FALSE;
}
if (!nm_g_object_set_property(G_OBJECT(setting),
property_info->param_spec->name,
&object_value,
&local)) {
if (!NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT))
continue;
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can not set property: %s"),
local->message);
g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name);
return FALSE;
}
}
nm_assert(!property_info->param_spec);
}
return TRUE;
@@ -2817,7 +2875,9 @@ const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name
const NMSettInfoPropertType nm_sett_info_propert_type_setting_name =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_ignore,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_ignore,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_ignore,
.from_dbus_is_full = TRUE,
.compare_fcn = _nm_setting_property_compare_fcn_ignore);
const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_i =
@@ -2834,29 +2894,39 @@ const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u =
const NMSettInfoPropertType nm_sett_info_propert_type_plain_i =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_INT32,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_plain_u =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_UINT32,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_direct_boolean =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_BOOLEAN,
.direct_type = NM_VALUE_TYPE_BOOL,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct);
.direct_type = NM_VALUE_TYPE_BOOL,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_direct_uint32 =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_UINT32,
.direct_type = NM_VALUE_TYPE_UINT32,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct);
.direct_type = NM_VALUE_TYPE_UINT32,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_direct_string =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING,
.direct_type = NM_VALUE_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct);
.direct_type = NM_VALUE_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_direct,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
/*****************************************************************************/

View File

@@ -2787,23 +2787,31 @@ _nm_team_settings_property_from_dbus_link_watchers(GVariant *dbus_value, GValue
const NMSettInfoPropertType nm_sett_info_propert_type_team_b =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_BOOLEAN,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, );
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_team_i =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_INT32,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, );
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_team_s =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING,
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, );
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
const NMSettInfoPropertType nm_sett_info_propert_type_team_as =
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(NM_G_VARIANT_TYPE("as"),
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus, );
.compare_fcn = _nm_setting_property_compare_fcn_default,
.to_dbus_fcn = _nm_team_settings_property_to_dbus,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
/*****************************************************************************/

View File

@@ -775,10 +775,12 @@ _nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value)
const NMSettInfoPropertType nm_sett_info_propert_type_strdict =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(NM_G_VARIANT_TYPE("a{ss}"),
.gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus,
.typdata_from_dbus.gprop_fcn = _nm_utils_strdict_from_dbus,
.typdata_to_dbus.gprop_type =
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT,
.compare_fcn = _nm_setting_property_compare_fcn_default);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
GHashTable *
_nm_utils_copy_strdict(GHashTable *strdict)
@@ -4160,10 +4162,12 @@ _nm_utils_hwaddr_from_dbus(GVariant *dbus_value, GValue *prop_value)
const NMSettInfoPropertType nm_sett_info_propert_type_mac_address =
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_BYTESTRING,
.gprop_from_dbus_fcn = _nm_utils_hwaddr_from_dbus,
.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);
.compare_fcn = _nm_setting_property_compare_fcn_default,
.from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop,
.from_dbus_is_full = TRUE);
/*****************************************************************************/

View File

@@ -3094,8 +3094,7 @@ test_setting_new_from_dbus_bad(void)
"i",
10););
conn = _connection_new_from_dbus(dict, &error);
g_assert(conn);
g_assert_no_error(error);
nmtst_assert_success(conn, error);
setting = nm_connection_get_setting(conn, NM_TYPE_SETTING_WIRELESS);
g_assert(setting);
g_assert_cmpint(nm_setting_wireless_get_rate(NM_SETTING_WIRELESS(setting)), ==, 10);

View File

@@ -4514,8 +4514,18 @@ check_done:;
if (!can_set_including_default)
g_assert(!sip->to_dbus_including_default);
g_assert(!sip->property_type->from_dbus_fcn
|| !sip->property_type->gprop_from_dbus_fcn);
g_assert(sip->property_type->from_dbus_fcn || !sip->param_spec);
if (sip->property_type->typdata_from_dbus.gprop_fcn) {
g_assert(sip->property_type->from_dbus_fcn
== _nm_setting_property_from_dbus_fcn_gprop);
}
if (sip->property_type->from_dbus_fcn == _nm_setting_property_from_dbus_fcn_gprop)
g_assert(sip->param_spec);
g_assert(sip->property_type->from_dbus_is_full
== NM_IN_SET(sip->property_type->from_dbus_fcn,
_nm_setting_property_from_dbus_fcn_gprop,
_nm_setting_property_from_dbus_fcn_ignore));
if (!g_hash_table_insert(h_properties, (char *) sip->name, sip->param_spec))
g_assert_not_reached();
@@ -4708,7 +4718,10 @@ check_done:;
|| pt->from_dbus_fcn != pt_2->from_dbus_fcn
|| pt->compare_fcn != pt_2->compare_fcn
|| pt->missing_from_dbus_fcn != pt_2->missing_from_dbus_fcn
|| pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn
|| memcmp(&pt->typdata_from_dbus,
&pt_2->typdata_from_dbus,
sizeof(pt->typdata_from_dbus))
!= 0
|| memcmp(&pt->typdata_to_dbus,
&pt_2->typdata_to_dbus,
sizeof(pt->typdata_to_dbus))

View File

@@ -693,6 +693,15 @@ typedef struct {
* to the property value. */
NMValueType direct_type;
/* Whether from_dbus_fcn() has special capabilities
*
* - whether the from_dbus_fcn expects to handle differences between
* the D-Bus types and can convert between them. Otherwise, the caller
* will already pre-validate that the D-Bus types match.
* - by default, with NM_SETTING_PARSE_FLAGS_BEST_EFFORT all errors from
* from_dbus_fcn() are ignored. If true, then error are propagated. */
bool from_dbus_is_full : 1;
/* compare_fcn() returns a ternary, where DEFAULT means that the property should not
* be compared due to the compare @flags. A TRUE/FALSE result means that the property is
* equal/not-equal.
@@ -711,9 +720,14 @@ typedef struct {
NMSettInfoPropFromDBusFcn from_dbus_fcn;
NMSettInfoPropMissingFromDBusFcn missing_from_dbus_fcn;
/* Simpler variants of @from_dbus_fcn that operate solely
* on the GValue value of the GObject property. */
NMSettInfoPropGPropFromDBusFcn gprop_from_dbus_fcn;
struct {
union {
/* If from_dbus_fcn is set to _nm_setting_property_from_dbus_fcn_gprop,
* then this is an optional handler for converting between GVariant and
* GValue. */
NMSettInfoPropGPropFromDBusFcn gprop_fcn;
};
} typdata_from_dbus;
struct {
union {