summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-06-30 00:05:49 +0200
committerThomas Haller <thaller@redhat.com>2021-07-16 13:31:59 +0200
commit77d2c13e21c5153db71e033fe665b311f0a68e7a (patch)
tree2580c873bfc77cf2b2e675e8674a5763c3310aea
parenta9ef71eb4aab3c3728400c47dfbc61241d1b20da (diff)
downloadNetworkManager-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.c6
-rw-r--r--src/libnm-core-impl/nm-setting-connection.c18
-rw-r--r--src/libnm-core-impl/nm-setting-dcb.c8
-rw-r--r--src/libnm-core-impl/nm-setting-ip4-config.c4
-rw-r--r--src/libnm-core-impl/nm-setting-ip6-config.c4
-rw-r--r--src/libnm-core-impl/nm-setting-ovs-external-ids.c6
-rw-r--r--src/libnm-core-impl/nm-setting-private.h16
-rw-r--r--src/libnm-core-impl/nm-setting-serial.c4
-rw-r--r--src/libnm-core-impl/nm-setting-team-port.c12
-rw-r--r--src/libnm-core-impl/nm-setting-team.c12
-rw-r--r--src/libnm-core-impl/nm-setting-user.c6
-rw-r--r--src/libnm-core-impl/nm-setting-vlan.c4
-rw-r--r--src/libnm-core-impl/nm-setting-wireless-security.c6
-rw-r--r--src/libnm-core-impl/nm-setting.c208
-rw-r--r--src/libnm-core-impl/nm-team-utils.c24
-rw-r--r--src/libnm-core-impl/nm-utils.c12
-rw-r--r--src/libnm-core-impl/tests/test-general.c3
-rw-r--r--src/libnm-core-impl/tests/test-setting.c19
-rw-r--r--src/libnm-core-intern/nm-core-internal.h20
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 {