diff options
author | Thomas Haller <thaller@redhat.com> | 2021-06-30 00:05:49 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-07-16 13:31:59 +0200 |
commit | 77d2c13e21c5153db71e033fe665b311f0a68e7a (patch) | |
tree | 2580c873bfc77cf2b2e675e8674a5763c3310aea | |
parent | a9ef71eb4aab3c3728400c47dfbc61241d1b20da (diff) | |
download | NetworkManager-77d2c13e21c5153db71e033fe665b311f0a68e7a.tar.gz |
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.
-rw-r--r-- | src/libnm-core-impl/nm-setting-bond.c | 6 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-connection.c | 18 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-dcb.c | 8 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-ip4-config.c | 4 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-ip6-config.c | 4 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-ovs-external-ids.c | 6 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-private.h | 16 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-serial.c | 4 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-team-port.c | 12 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-team.c | 12 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-user.c | 6 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-vlan.c | 4 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-wireless-security.c | 6 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting.c | 208 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-team-utils.c | 24 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-utils.c | 12 | ||||
-rw-r--r-- | src/libnm-core-impl/tests/test-general.c | 3 | ||||
-rw-r--r-- | src/libnm-core-impl/tests/test-setting.c | 19 | ||||
-rw-r--r-- | src/libnm-core-intern/nm-core-internal.h | 20 |
19 files changed, 274 insertions, 118 deletions
diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index bf5d88bacf..49e292a30f 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -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 diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index 89afbd6a92..a9a6fd9f1f 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -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: diff --git a/src/libnm-core-impl/nm-setting-dcb.c b/src/libnm-core-impl/nm-setting-dcb.c index 2fee3b9f0e..47528b5186 100644 --- a/src/libnm-core-impl/nm-setting-dcb.c +++ b/src/libnm-core-impl/nm-setting-dcb.c @@ -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); /*****************************************************************************/ diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index 46263fb332..5995a582b7 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -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 diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index 1d29141eea..3c2dfc8595 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -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 diff --git a/src/libnm-core-impl/nm-setting-ovs-external-ids.c b/src/libnm-core-impl/nm-setting-ovs-external-ids.c index 3f0fc48c3f..d044aaf202 100644 --- a/src/libnm-core-impl/nm-setting-ovs-external-ids.c +++ b/src/libnm-core-impl/nm-setting-ovs-external-ids.c @@ -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); diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index 6a19e0ec24..dc0654ce83 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -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, diff --git a/src/libnm-core-impl/nm-setting-serial.c b/src/libnm-core-impl/nm-setting-serial.c index 95edf500a1..fe59ac3da0 100644 --- a/src/libnm-core-impl/nm-setting-serial.c +++ b/src/libnm-core-impl/nm-setting-serial.c @@ -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: diff --git a/src/libnm-core-impl/nm-setting-team-port.c b/src/libnm-core-impl/nm-setting-team-port.c index d940200a2d..bed56656cf 100644 --- a/src/libnm-core-impl/nm-setting-team-port.c +++ b/src/libnm-core-impl/nm-setting-team-port.c @@ -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); diff --git a/src/libnm-core-impl/nm-setting-team.c b/src/libnm-core-impl/nm-setting-team.c index f78ce51801..881bb81974 100644 --- a/src/libnm-core-impl/nm-setting-team.c +++ b/src/libnm-core-impl/nm-setting-team.c @@ -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 diff --git a/src/libnm-core-impl/nm-setting-user.c b/src/libnm-core-impl/nm-setting-user.c index b315acdc10..f597a0201d 100644 --- a/src/libnm-core-impl/nm-setting-user.c +++ b/src/libnm-core-impl/nm-setting-user.c @@ -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); diff --git a/src/libnm-core-impl/nm-setting-vlan.c b/src/libnm-core-impl/nm-setting-vlan.c index 13315dbc14..783b539c1f 100644 --- a/src/libnm-core-impl/nm-setting-vlan.c +++ b/src/libnm-core-impl/nm-setting-vlan.c @@ -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: diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c index 0b806b7a0e..3c4993d79d 100644 --- a/src/libnm-core-impl/nm-setting-wireless-security.c +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -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: diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index 5ba37e0fce..342f9e0fa5 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -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); /*****************************************************************************/ diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c index fe546320c3..a632b08e43 100644 --- a/src/libnm-core-impl/nm-team-utils.c +++ b/src/libnm-core-impl/nm-team-utils.c @@ -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); /*****************************************************************************/ diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 499fab3430..5b1f85ccb5 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -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); /*****************************************************************************/ diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index a7e741ea24..503613160c 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -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); diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 4af74d0037..1c081b55db 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -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)) diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 89d86d0ee3..26f69d3e65 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -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 { |