diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index 6ef85f633e..49e292a30f 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -1090,20 +1090,15 @@ options_equal(NMSettingBond *s_bond, NMSettingBond *s_bond2, NMSettingCompareFla } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_options(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BOND_OPTIONS)) { - return (!set_b || options_equal(NM_SETTING_BOND(set_a), NM_SETTING_BOND(set_b), flags)); - } - - return NM_SETTING_CLASS(nm_setting_bond_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return (!set_b || options_equal(NM_SETTING_BOND(set_a), NM_SETTING_BOND(set_b), flags)); } /*****************************************************************************/ @@ -1190,8 +1185,7 @@ nm_setting_bond_class_init(NMSettingBondClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->verify = verify; - setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingBond:options: (type GHashTable(utf8,utf8)): @@ -1213,9 +1207,16 @@ nm_setting_bond_class_init(NMSettingBondClass *klass) "", G_TYPE_HASH_TABLE, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_OPTIONS], - &nm_sett_info_propert_type_strdict); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_OPTIONS], + NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"), + .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, + .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-bridge-port.c b/src/libnm-core-impl/nm-setting-bridge-port.c index 50be8452d1..6a0b6f93f1 100644 --- a/src/libnm-core-impl/nm-setting-bridge-port.c +++ b/src/libnm-core-impl/nm-setting-bridge-port.c @@ -368,35 +368,19 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_vlans(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - NMSettingBridgePortPrivate *priv_a; - NMSettingBridgePortPrivate *priv_b; - guint i; - - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_PORT_VLANS)) { - if (set_b) { - priv_a = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_a); - priv_b = NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_b); - - if (priv_a->vlans->len != priv_b->vlans->len) - return FALSE; - for (i = 0; i < priv_a->vlans->len; i++) { - if (nm_bridge_vlan_cmp(priv_a->vlans->pdata[i], priv_b->vlans->pdata[i])) - return FALSE; - } - } - return TRUE; + if (set_b) { + return _nm_utils_bridge_compare_vlans(NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_a)->vlans, + NM_SETTING_BRIDGE_PORT_GET_PRIVATE(set_b)->vlans); } - - return NM_SETTING_CLASS(nm_setting_bridge_port_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } /*****************************************************************************/ @@ -504,8 +488,7 @@ nm_setting_bridge_port_class_init(NMSettingBridgePortClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingBridgePort:priority: @@ -604,9 +587,13 @@ nm_setting_bridge_port_class_init(NMSettingBridgePortClass *klass) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_VLANS], - &nm_sett_info_propert_type_bridge_vlans); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_VLANS], + NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), + .compare_fcn = compare_fcn_vlans, + .to_dbus_fcn = _nm_utils_bridge_vlans_to_dbus, + .from_dbus_fcn = _nm_utils_bridge_vlans_from_dbus, )); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c index 4567a28f0a..7ecd7fdbb8 100644 --- a/src/libnm-core-impl/nm-setting-bridge.c +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -1315,35 +1315,19 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_vlans(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - NMSettingBridgePrivate *priv_a; - NMSettingBridgePrivate *priv_b; - guint i; - - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_VLANS)) { - if (set_b) { - priv_a = NM_SETTING_BRIDGE_GET_PRIVATE(set_a); - priv_b = NM_SETTING_BRIDGE_GET_PRIVATE(set_b); - - if (priv_a->vlans->len != priv_b->vlans->len) - return FALSE; - for (i = 0; i < priv_a->vlans->len; i++) { - if (nm_bridge_vlan_cmp(priv_a->vlans->pdata[i], priv_b->vlans->pdata[i])) - return FALSE; - } - } - return TRUE; + if (set_b) { + return _nm_utils_bridge_compare_vlans(NM_SETTING_BRIDGE_GET_PRIVATE(set_a)->vlans, + NM_SETTING_BRIDGE_GET_PRIVATE(set_b)->vlans); } - - return NM_SETTING_CLASS(nm_setting_bridge_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } /*****************************************************************************/ @@ -1611,8 +1595,7 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingBridge:mac-address: @@ -1914,9 +1897,13 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass) G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_VLANS], - &nm_sett_info_propert_type_bridge_vlans); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_VLANS], + NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), + .to_dbus_fcn = _nm_utils_bridge_vlans_to_dbus, + .compare_fcn = compare_fcn_vlans, + .from_dbus_fcn = _nm_utils_bridge_vlans_from_dbus, )); /* ---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 869093f156..a9a6fd9f1f 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -622,7 +622,7 @@ nm_setting_connection_get_timestamp(NMSettingConnection *setting) static GVariant * _to_dbus_fcn_timestamp(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1558,24 +1558,45 @@ nm_setting_connection_no_interface_name(NMSetting * setting, } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_id(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_ID) - && nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_ID)) + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_ID)) return NM_TERNARY_DEFAULT; - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP) - && nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_CONNECTION_TIMESTAMP)) + return _nm_setting_property_compare_fcn_direct(sett_info, + property_info, + con_a, + set_a, + con_b, + set_b, + flags); +} + +static NMTernary +compare_fcn_timestamp(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)) return NM_TERNARY_DEFAULT; - return NM_SETTING_CLASS(nm_setting_connection_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return _nm_setting_property_compare_fcn_default(sett_info, + property_info, + con_a, + set_a, + con_b, + set_b, + flags); } /*****************************************************************************/ @@ -1856,8 +1877,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->verify = verify; - setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingConnection:id: @@ -1871,13 +1891,21 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * description: User friendly name for the connection profile. * ---end--- */ - _nm_setting_property_define_direct_string(properties_override, - obj_properties, - NM_SETTING_CONNECTION_ID, - PROP_ID, - NM_SETTING_PARAM_FUZZY_IGNORE, - NMSettingConnectionPrivate, - id); + _nm_setting_property_define_direct_string_full( + properties_override, + obj_properties, + NM_SETTING_CONNECTION_ID, + 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, + .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, + .from_dbus_is_full = TRUE), + + NMSettingConnectionPrivate, + id); /** * NMSettingConnection:uuid: @@ -1996,9 +2024,12 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NM_SETTING_PARAM_INFERRABLE, NM_SETT_INFO_PROPERT_TYPE_DBUS(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, .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); @@ -2196,7 +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, - .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 fa666654c5..47528b5186 100644 --- a/src/libnm-core-impl/nm-setting-dcb.c +++ b/src/libnm-core-impl/nm-setting-dcb.c @@ -757,8 +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, ); + .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-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index f1e0d7adce..7f524a24f7 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -4101,6 +4101,12 @@ nm_setting_ip_config_clear_dns(NMSettingIPConfig *setting) } } +GPtrArray * +_nm_setting_ip_config_get_dns_array(NMSettingIPConfig *setting) +{ + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns; +} + /** * nm_setting_ip_config_get_num_dns_searches: * @setting: the #NMSettingIPConfig @@ -4944,7 +4950,7 @@ nm_setting_ip_config_clear_routing_rules(NMSettingIPConfig *setting) static GVariant * _routing_rules_dbus_only_synth(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -4979,12 +4985,13 @@ _routing_rules_dbus_only_synth(const NMSettInfoSetting * sett_info } static gboolean -_routing_rules_dbus_only_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +_routing_rules_dbus_only_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GVariantIter iter_rules; GVariant * rule_var; @@ -5619,77 +5626,95 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return TRUE; } -static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +NMTernary +_nm_setting_ip_config_compare_fcn_addresses(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingIPConfigPrivate *a_priv; NMSettingIPConfigPrivate *b_priv; guint i; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ADDRESSES)) { - if (set_b) { - a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); - b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + if (set_b) { + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); - if (a_priv->addresses->len != b_priv->addresses->len) + if (a_priv->addresses->len != b_priv->addresses->len) + return FALSE; + for (i = 0; i < a_priv->addresses->len; i++) { + if (nm_ip_address_cmp_full(a_priv->addresses->pdata[i], + b_priv->addresses->pdata[i], + NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS) + != 0) return FALSE; - for (i = 0; i < a_priv->addresses->len; i++) { - if (nm_ip_address_cmp_full(a_priv->addresses->pdata[i], - b_priv->addresses->pdata[i], - NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS) - != 0) - return FALSE; - } } - return TRUE; } + return TRUE; +} - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ROUTES)) { - if (set_b) { - a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); - b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); +NMTernary +_nm_setting_ip_config_compare_fcn_routes(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingIPConfigPrivate *a_priv; + NMSettingIPConfigPrivate *b_priv; + guint i; - if (a_priv->routes->len != b_priv->routes->len) + if (set_b) { + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + + if (a_priv->routes->len != b_priv->routes->len) + return FALSE; + for (i = 0; i < a_priv->routes->len; i++) { + if (!nm_ip_route_equal_full(a_priv->routes->pdata[i], + b_priv->routes->pdata[i], + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) return FALSE; - for (i = 0; i < a_priv->routes->len; i++) { - if (!nm_ip_route_equal_full(a_priv->routes->pdata[i], - b_priv->routes->pdata[i], - NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) - return FALSE; - } } - return TRUE; } + return TRUE; +} - if (nm_streq(sett_info->property_infos[property_idx].name, - NM_SETTING_IP_CONFIG_ROUTING_RULES)) { - if (set_b) { - guint n; +static NMTernary +compare_fcn_routing_rules(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingIPConfigPrivate *a_priv; + NMSettingIPConfigPrivate *b_priv; + guint i; - a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); - b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + if (set_b) { + guint n; - n = (a_priv->routing_rules) ? a_priv->routing_rules->len : 0u; - if (n != (b_priv->routing_rules ? b_priv->routing_rules->len : 0u)) + a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_a); + b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(set_b); + + n = (a_priv->routing_rules) ? a_priv->routing_rules->len : 0u; + if (n != (b_priv->routing_rules ? b_priv->routing_rules->len : 0u)) + return FALSE; + for (i = 0; i < n; i++) { + if (nm_ip_routing_rule_cmp(a_priv->routing_rules->pdata[i], + b_priv->routing_rules->pdata[i]) + != 0) return FALSE; - for (i = 0; i < n; i++) { - if (nm_ip_routing_rule_cmp(a_priv->routing_rules->pdata[i], - b_priv->routing_rules->pdata[i]) - != 0) - return FALSE; - } } - return TRUE; } - - return NM_SETTING_CLASS(nm_setting_ip_config_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } static void @@ -5751,12 +5776,13 @@ enumerate_values(const NMSettInfoProperty *property_info, /*****************************************************************************/ static gboolean -ip_gateway_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip_gateway_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { /* FIXME: properly handle errors */ @@ -5764,7 +5790,7 @@ ip_gateway_set(NMSetting * setting, if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "gateway")) return TRUE; - g_object_set(setting, property, g_variant_get_string(value, NULL), NULL); + g_object_set(setting, property_info->name, g_variant_get_string(value, NULL), NULL); return TRUE; } @@ -5784,6 +5810,7 @@ _nm_sett_info_property_override_create_array_ip_config(void) obj_properties[PROP_GATEWAY], NM_SETT_INFO_PROPERT_TYPE_DBUS(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, .from_dbus_fcn = ip_gateway_set), .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, gateway), @@ -5814,6 +5841,7 @@ _nm_sett_info_property_override_create_array_ip_config(void) NM_SETTING_IP_CONFIG_ROUTING_RULES, NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = _routing_rules_dbus_only_synth, + .compare_fcn = compare_fcn_routing_rules, .from_dbus_fcn = _routing_rules_dbus_only_set, )); _nm_properties_override_gobj( @@ -6113,7 +6141,6 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) object_class->finalize = finalize; setting_class->verify = verify; - setting_class->compare_property = compare_property; setting_class->duplicate_copy_properties = duplicate_copy_properties; setting_class->enumerate_values = enumerate_values; diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index 4b6f92083d..5995a582b7 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -8,6 +8,7 @@ #include "nm-setting-ip4-config.h" #include "nm-setting-private.h" +#include "nm-utils-private.h" /** * SECTION:nm-setting-ip4-config @@ -321,9 +322,21 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static GVariant * -ip4_dns_to_dbus(const GValue *prop_value) +ip4_dns_to_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { - return nm_utils_ip4_dns_to_variant(g_value_get_boxed(prop_value)); + GPtrArray *dns; + + dns = _nm_setting_ip_config_get_dns_array(NM_SETTING_IP_CONFIG(setting)); + + if (nm_g_ptr_array_len(dns) == 0) + return NULL; + + return _nm_utils_ip4_dns_to_variant((const char *const *) dns->pdata, dns->len); } static void @@ -334,7 +347,7 @@ ip4_dns_from_dbus(GVariant *dbus_value, GValue *prop_value) static GVariant * ip4_addresses_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -349,12 +362,13 @@ ip4_addresses_get(const NMSettInfoSetting * sett_info, } static gboolean -ip4_addresses_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip4_addresses_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *addrs; GVariant * s_ip4; @@ -394,7 +408,7 @@ ip4_addresses_set(NMSetting * setting, static GVariant * ip4_address_labels_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -438,7 +452,7 @@ ip4_address_labels_get(const NMSettInfoSetting * sett_info, static GVariant * ip4_address_data_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -454,12 +468,13 @@ ip4_address_data_get(const NMSettInfoSetting * sett_info, } static gboolean -ip4_address_data_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip4_address_data_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *addrs; @@ -477,7 +492,7 @@ ip4_address_data_set(NMSetting * setting, static GVariant * ip4_routes_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -490,12 +505,13 @@ ip4_routes_get(const NMSettInfoSetting * sett_info, } static gboolean -ip4_routes_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip4_routes_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *routes; @@ -505,14 +521,14 @@ ip4_routes_set(NMSetting * setting, return TRUE; routes = nm_utils_ip4_routes_from_variant(value); - g_object_set(setting, property, routes, NULL); + g_object_set(setting, property_info->name, routes, NULL); g_ptr_array_unref(routes); return TRUE; } static GVariant * ip4_route_data_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -528,12 +544,13 @@ ip4_route_data_get(const NMSettInfoSetting * sett_info, } static gboolean -ip4_route_data_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip4_route_data_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *routes; @@ -955,9 +972,12 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) _nm_properties_override_gobj( properties_override, g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), - NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("au"), - .gprop_from_dbus_fcn = ip4_dns_from_dbus, ), - .to_dbus_data.gprop_to_dbus_fcn = ip4_dns_to_dbus); + 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, + .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 @@ -986,12 +1006,14 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ADDRESSES), NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aau"), .to_dbus_fcn = ip4_addresses_get, + .compare_fcn = _nm_setting_ip_config_compare_fcn_addresses, .from_dbus_fcn = ip4_addresses_set, )); _nm_properties_override_dbus( properties_override, "address-labels", NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING_ARRAY, - .to_dbus_fcn = ip4_address_labels_get, )); + .to_dbus_fcn = ip4_address_labels_get, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, )); /* ---dbus--- * property: address-data @@ -1007,6 +1029,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) "address-data", NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = ip4_address_data_get, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .from_dbus_fcn = ip4_address_data_set, )); /* ---dbus--- @@ -1040,6 +1063,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ROUTES), NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aau"), .to_dbus_fcn = ip4_routes_get, + .compare_fcn = _nm_setting_ip_config_compare_fcn_routes, .from_dbus_fcn = ip4_routes_set, )); /* ---dbus--- @@ -1060,6 +1084,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) "route-data", NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = ip4_route_data_get, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .from_dbus_fcn = ip4_route_data_set, )); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index 6e0e9897b7..3c2dfc8595 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -10,6 +10,7 @@ #include #include "nm-setting-private.h" +#include "nm-utils-private.h" #include "nm-core-enum-types.h" #include "libnm-core-intern/nm-core-internal.h" @@ -362,9 +363,21 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static GVariant * -ip6_dns_to_dbus(const GValue *prop_value) +ip6_dns_to_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { - return nm_utils_ip6_dns_to_variant(g_value_get_boxed(prop_value)); + GPtrArray *dns; + + dns = _nm_setting_ip_config_get_dns_array(NM_SETTING_IP_CONFIG(setting)); + + if (nm_g_ptr_array_len(dns) == 0) + return NULL; + + return _nm_utils_ip6_dns_to_variant((const char *const *) dns->pdata, dns->len); } static void @@ -375,7 +388,7 @@ ip6_dns_from_dbus(GVariant *dbus_value, GValue *prop_value) static GVariant * ip6_addresses_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -390,12 +403,13 @@ ip6_addresses_get(const NMSettInfoSetting * sett_info, } static gboolean -ip6_addresses_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip6_addresses_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *addrs; char * gateway = NULL; @@ -420,7 +434,7 @@ ip6_addresses_set(NMSetting * setting, static GVariant * ip6_address_data_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -436,12 +450,13 @@ ip6_address_data_get(const NMSettInfoSetting * sett_info, } static gboolean -ip6_address_data_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip6_address_data_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *addrs; @@ -459,7 +474,7 @@ ip6_address_data_set(NMSetting * setting, static GVariant * ip6_routes_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -472,12 +487,13 @@ ip6_routes_get(const NMSettInfoSetting * sett_info, } static gboolean -ip6_routes_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip6_routes_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *routes; @@ -487,14 +503,14 @@ ip6_routes_set(NMSetting * setting, return TRUE; routes = nm_utils_ip6_routes_from_variant(value); - g_object_set(setting, property, routes, NULL); + g_object_set(setting, property_info->name, routes, NULL); g_ptr_array_unref(routes); return TRUE; } static GVariant * ip6_route_data_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -510,12 +526,13 @@ ip6_route_data_get(const NMSettInfoSetting * sett_info, } static gboolean -ip6_route_data_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +ip6_route_data_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *routes; @@ -1021,9 +1038,12 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) _nm_properties_override_gobj( properties_override, g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), - NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("aay"), - .gprop_from_dbus_fcn = ip6_dns_from_dbus, ), - .to_dbus_data.gprop_to_dbus_fcn = ip6_dns_to_dbus); + 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, + .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 @@ -1044,6 +1064,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ADDRESSES), NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("a(ayuay)"), .to_dbus_fcn = ip6_addresses_get, + .compare_fcn = _nm_setting_ip_config_compare_fcn_addresses, .from_dbus_fcn = ip6_addresses_set, )); /* ---dbus--- @@ -1060,6 +1081,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) "address-data", NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = ip6_address_data_get, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .from_dbus_fcn = ip6_address_data_set, )); /* ---dbus--- @@ -1081,6 +1103,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ROUTES), NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("a(ayuayu)"), .to_dbus_fcn = ip6_routes_get, + .compare_fcn = _nm_setting_ip_config_compare_fcn_routes, .from_dbus_fcn = ip6_routes_set, )); /* ---dbus--- @@ -1101,6 +1124,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) "route-data", NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = ip6_route_data_get, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .from_dbus_fcn = ip6_route_data_set, )); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); 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 d8f41a5919..d044aaf202 100644 --- a/src/libnm-core-impl/nm-setting-ovs-external-ids.c +++ b/src/libnm-core-impl/nm-setting-ovs-external-ids.c @@ -387,31 +387,26 @@ connection_type_is_good: } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_data(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingOvsExternalIDsPrivate *priv; NMSettingOvsExternalIDsPrivate *pri2; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; - if (!set_b) - return TRUE; + if (!set_b) + return TRUE; - priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_a)); - pri2 = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_b)); - return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal); - } - - return NM_SETTING_CLASS(nm_setting_ovs_external_ids_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_a)); + pri2 = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_b)); + return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal); } /*****************************************************************************/ @@ -523,8 +518,7 @@ nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingOvsExternalIDs:data: (type GHashTable(utf8,utf8)) @@ -538,9 +532,16 @@ nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass) "", G_TYPE_HASH_TABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_DATA], - &nm_sett_info_propert_type_strdict); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_DATA], + NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"), + .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, + .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 48f225b6d4..dc0654ce83 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -70,24 +70,12 @@ struct _NMSettingClass { GError ** error); gboolean (*clear_secrets)(const struct _NMSettInfoSetting *sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMSetting * setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data); - /* compare_property() 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. - * - * @other may be %NULL, in which case the function only determines whether - * the setting should be compared (TRUE) or not (DEFAULT). */ - NMTernary (*compare_property)(const struct _NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags); + void (*padding_1)(void); void (*duplicate_copy_properties)(const struct _NMSettInfoSetting *sett_info, NMSetting * src, @@ -292,6 +280,7 @@ gboolean _nm_setting_clear_secrets(NMSetting * setting, */ #define NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS (1 << (7 + G_PARAM_USER_SHIFT)) +extern const NMSettInfoPropertType nm_sett_info_propert_type_setting_name; extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name; extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_i; extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u; @@ -315,6 +304,35 @@ gboolean _nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType typ gboolean _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type); +gboolean _nm_setting_compare_flags_check(const GParamSpec * param_spec, + NMSettingCompareFlags flags, + NMSetting * set_a, + NMSetting * set_b); + +NMTernary _nm_setting_property_compare_fcn_ignore(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + +NMTernary _nm_setting_property_compare_fcn_direct(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + +NMTernary _nm_setting_property_compare_fcn_default(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + void _nm_setting_property_get_property_direct(GObject * object, guint prop_id, GValue * value, @@ -325,20 +343,43 @@ void _nm_setting_property_set_property_direct(GObject * object, const GValue *value, GParamSpec * pspec); +GVariant *_nm_setting_property_to_dbus_fcn_ignore(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + GVariant *_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options); GVariant *_nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options); +gboolean _nm_setting_property_from_dbus_fcn_ignore(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + 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, @@ -397,11 +438,10 @@ void _nm_setting_class_commit(NMSettingClass * setting_class, .dbus_type = _dbus_type, __VA_ARGS__ \ } -#define NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(_dbus_type, ...) \ - { \ - .dbus_type = _dbus_type, .to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop, \ - __VA_ARGS__ \ - } +#define NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(_dbus_type, ...) \ + NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(_dbus_type, \ + .to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop, \ + __VA_ARGS__) #define NM_SETT_INFO_PROPERT_TYPE(init) \ ({ \ @@ -620,6 +660,58 @@ gboolean _nm_setting_should_compare_secret_property(NMSetting * settin NMBridgeVlan *_nm_bridge_vlan_dup(const NMBridgeVlan *vlan); NMBridgeVlan *_nm_bridge_vlan_dup_and_seal(const NMBridgeVlan *vlan); +gboolean _nm_utils_bridge_vlans_from_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error); + +GVariant *_nm_utils_bridge_vlans_to_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + +NMTernary _nm_setting_ip_config_compare_fcn_addresses(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + +NMTernary _nm_setting_ip_config_compare_fcn_routes(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + +gboolean _nm_utils_hwaddr_cloned_not_set(NMSetting * setting, + GVariant * connection_dict, + const char * property, + NMSettingParseFlags parse_flags, + GError ** error); + +GVariant *_nm_utils_hwaddr_cloned_get(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + +gboolean _nm_utils_hwaddr_cloned_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error); + /*****************************************************************************/ #endif /* NM_SETTING_PRIVATE_H */ diff --git a/src/libnm-core-impl/nm-setting-serial.c b/src/libnm-core-impl/nm-setting-serial.c index 0029551bc4..fe59ac3da0 100644 --- a/src/libnm-core-impl/nm-setting-serial.c +++ b/src/libnm-core-impl/nm-setting-serial.c @@ -130,16 +130,23 @@ nm_setting_serial_get_send_delay(NMSettingSerial *setting) } static GVariant * -parity_to_dbus(const GValue *from) +parity_to_dbus_fcn(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { - switch (g_value_get_enum(from)) { + switch (nm_setting_serial_get_parity(NM_SETTING_SERIAL(setting))) { case NM_SETTING_SERIAL_PARITY_EVEN: return g_variant_new_byte('E'); case NM_SETTING_SERIAL_PARITY_ODD: return g_variant_new_byte('o'); case NM_SETTING_SERIAL_PARITY_NONE: + /* the default, serializes to NULL. */ + return NULL; default: - return g_variant_new_byte('n'); + return NULL; } } @@ -311,9 +318,12 @@ nm_setting_serial_class_init(NMSettingSerialClass *klass) _nm_properties_override_gobj( properties_override, obj_properties[PROP_PARITY], - NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BYTE, - .gprop_from_dbus_fcn = parity_from_dbus, ), - .to_dbus_data.gprop_to_dbus_fcn = parity_to_dbus, ); + 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, + .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-sriov.c b/src/libnm-core-impl/nm-setting-sriov.c index e55bc4c53f..adf43ceccd 100644 --- a/src/libnm-core-impl/nm-setting-sriov.c +++ b/src/libnm-core-impl/nm-setting-sriov.c @@ -876,7 +876,7 @@ _nm_setting_sriov_sort_vfs(NMSettingSriov *setting) static GVariant * vfs_to_dbus(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -956,12 +956,13 @@ vfs_to_dbus(const NMSettInfoSetting * sett_info, } static gboolean -vfs_from_dbus(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +vfs_from_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray * vfs; GVariantIter vf_iter; @@ -1119,35 +1120,30 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_vfs(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingSriov *a; NMSettingSriov *b; guint i; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_SRIOV_VFS)) { - if (set_b) { - a = NM_SETTING_SRIOV(set_a); - b = NM_SETTING_SRIOV(set_b); + if (set_b) { + a = NM_SETTING_SRIOV(set_a); + b = NM_SETTING_SRIOV(set_b); - if (a->vfs->len != b->vfs->len) + if (a->vfs->len != b->vfs->len) + return FALSE; + for (i = 0; i < a->vfs->len; i++) { + if (!nm_sriov_vf_equal(a->vfs->pdata[i], b->vfs->pdata[i])) return FALSE; - for (i = 0; i < a->vfs->len; i++) { - if (!nm_sriov_vf_equal(a->vfs->pdata[i], b->vfs->pdata[i])) - return FALSE; - } } - return TRUE; } - - return NM_SETTING_CLASS(nm_setting_sriov_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } /*****************************************************************************/ @@ -1246,8 +1242,7 @@ nm_setting_sriov_class_init(NMSettingSriovClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingSriov:total-vfs @@ -1327,6 +1322,7 @@ nm_setting_sriov_class_init(NMSettingSriovClass *klass) obj_properties[PROP_VFS], NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = vfs_to_dbus, + .compare_fcn = compare_fcn_vfs, .from_dbus_fcn = vfs_from_dbus, )); /** diff --git a/src/libnm-core-impl/nm-setting-tc-config.c b/src/libnm-core-impl/nm-setting-tc-config.c index a82e65e61b..2260678d02 100644 --- a/src/libnm-core-impl/nm-setting-tc-config.c +++ b/src/libnm-core-impl/nm-setting-tc-config.c @@ -1314,46 +1314,52 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_qdiscs(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingTCConfig *a_tc_config = NM_SETTING_TC_CONFIG(set_a); NMSettingTCConfig *b_tc_config = NM_SETTING_TC_CONFIG(set_b); guint i; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_QDISCS)) { - if (set_b) { - if (a_tc_config->qdiscs->len != b_tc_config->qdiscs->len) + if (set_b) { + if (a_tc_config->qdiscs->len != b_tc_config->qdiscs->len) + return FALSE; + for (i = 0; i < a_tc_config->qdiscs->len; i++) { + if (!nm_tc_qdisc_equal(a_tc_config->qdiscs->pdata[i], b_tc_config->qdiscs->pdata[i])) return FALSE; - for (i = 0; i < a_tc_config->qdiscs->len; i++) { - if (!nm_tc_qdisc_equal(a_tc_config->qdiscs->pdata[i], - b_tc_config->qdiscs->pdata[i])) - return FALSE; - } } - return TRUE; } + return TRUE; +} - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TC_CONFIG_TFILTERS)) { - if (set_b) { - if (a_tc_config->tfilters->len != b_tc_config->tfilters->len) +static NMTernary +compare_fcn_tfilter(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTCConfig *a_tc_config = NM_SETTING_TC_CONFIG(set_a); + NMSettingTCConfig *b_tc_config = NM_SETTING_TC_CONFIG(set_b); + guint i; + + if (set_b) { + if (a_tc_config->tfilters->len != b_tc_config->tfilters->len) + return FALSE; + for (i = 0; i < a_tc_config->tfilters->len; i++) { + if (!nm_tc_tfilter_equal(a_tc_config->tfilters->pdata[i], + b_tc_config->tfilters->pdata[i])) return FALSE; - for (i = 0; i < a_tc_config->tfilters->len; i++) { - if (!nm_tc_tfilter_equal(a_tc_config->tfilters->pdata[i], - b_tc_config->tfilters->pdata[i])) - return FALSE; - } } - return TRUE; } - - return NM_SETTING_CLASS(nm_setting_tc_config_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } /** @@ -1482,7 +1488,7 @@ next: static GVariant * tc_qdiscs_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1495,12 +1501,13 @@ tc_qdiscs_get(const NMSettInfoSetting * sett_info, } static gboolean -tc_qdiscs_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +tc_qdiscs_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GPtrArray *qdiscs; @@ -1680,7 +1687,7 @@ next: static GVariant * tc_tfilters_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1693,12 +1700,13 @@ tc_tfilters_get(const NMSettInfoSetting * sett_info, } static gboolean -tc_tfilters_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +tc_tfilters_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { gs_unref_ptrarray GPtrArray *tfilters = NULL; @@ -1803,8 +1811,7 @@ nm_setting_tc_config_class_init(NMSettingTCConfigClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingTCConfig:qdiscs: (type GPtrArray(NMTCQdisc)) @@ -2116,6 +2123,7 @@ nm_setting_tc_config_class_init(NMSettingTCConfigClass *klass) obj_properties[PROP_QDISCS], NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = tc_qdiscs_get, + .compare_fcn = compare_fcn_qdiscs, .from_dbus_fcn = tc_qdiscs_set, )); /** @@ -2254,6 +2262,7 @@ nm_setting_tc_config_class_init(NMSettingTCConfigClass *klass) obj_properties[PROP_TFILTERS], NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = tc_tfilters_get, + .compare_fcn = compare_fcn_tfilter, .from_dbus_fcn = tc_tfilters_set, )); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-team-port.c b/src/libnm-core-impl/nm-setting-team-port.c index 11aae92638..bed56656cf 100644 --- a/src/libnm-core-impl/nm-setting-team-port.c +++ b/src/libnm-core-impl/nm-setting-team-port.c @@ -350,52 +350,57 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_link_watchers(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingTeamPortPrivate *a_priv; NMSettingTeamPortPrivate *b_priv; - if (nm_streq(sett_info->property_infos[property_idx].name, - NM_SETTING_TEAM_PORT_LINK_WATCHERS)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; - if (!set_b) - return TRUE; - a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); - b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); - return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, - b_priv->team_setting->d.link_watchers, - TRUE); - } + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + if (!set_b) + return TRUE; + a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); + return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, + b_priv->team_setting->d.link_watchers, + TRUE); +} - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_PORT_CONFIG)) { - if (set_b) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { - /* If we are trying to match a connection in order to assume it (and thus +static NMTernary +compare_fcn_config(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTeamPortPrivate *a_priv; + NMSettingTeamPortPrivate *b_priv; + + if (set_b) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { + /* If we are trying to match a connection in order to assume it (and thus * @flags contains INFERRABLE), use the "relaxed" matching for team * configuration. Otherwise, for all other purposes (including connection * comparison before an update), resort to the default string comparison. */ - return TRUE; - } - - a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); - b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); - - return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), - nm_team_setting_config_get(b_priv->team_setting)); + return TRUE; } - return TRUE; + a_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_PORT_GET_PRIVATE(set_b); + + return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), + nm_team_setting_config_get(b_priv->team_setting)); } - return NM_SETTING_CLASS(nm_setting_team_port_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } static void @@ -545,7 +550,6 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; setting_class->verify = verify; setting_class->duplicate_copy_properties = duplicate_copy_properties; setting_class->init_from_dbus = init_from_dbus; @@ -570,9 +574,14 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[NM_TEAM_ATTRIBUTE_CONFIG], - &nm_sett_info_propert_type_team_s); + _nm_properties_override_gobj( + 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, + .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, + .from_dbus_is_full = TRUE)); /** * NMSettingTeamPort:queue-id: @@ -688,9 +697,16 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) "", G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], - &nm_sett_info_propert_type_team_link_watchers); + _nm_properties_override_gobj( + properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], + 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, + .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 8669c58618..881bb81974 100644 --- a/src/libnm-core-impl/nm-setting-team.c +++ b/src/libnm-core-impl/nm-setting-team.c @@ -1275,50 +1275,57 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_link_watchers(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - NMSettingTeamPrivate *a_priv, *b_priv; + NMSettingTeamPrivate *a_priv; + NMSettingTeamPrivate *b_priv; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_LINK_WATCHERS)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; - if (!set_b) - return TRUE; - a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); - b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); - return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, - b_priv->team_setting->d.link_watchers, - TRUE); - } + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + if (!set_b) + return TRUE; + a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); + return nm_team_link_watchers_equal(a_priv->team_setting->d.link_watchers, + b_priv->team_setting->d.link_watchers, + TRUE); +} - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_TEAM_CONFIG)) { - if (set_b) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { - /* If we are trying to match a connection in order to assume it (and thus +static NMTernary +compare_fcn_config(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + NMSettingTeamPrivate *a_priv; + NMSettingTeamPrivate *b_priv; + + if (set_b) { + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) { + /* If we are trying to match a connection in order to assume it (and thus * @flags contains INFERRABLE), use the "relaxed" matching for team * configuration. Otherwise, for all other purposes (including connection * comparison before an update), resort to the default string comparison. */ - return TRUE; - } - - a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); - b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); - - return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), - nm_team_setting_config_get(b_priv->team_setting)); + return TRUE; } - return TRUE; + a_priv = NM_SETTING_TEAM_GET_PRIVATE(set_a); + b_priv = NM_SETTING_TEAM_GET_PRIVATE(set_b); + + return nm_streq0(nm_team_setting_config_get(a_priv->team_setting), + nm_team_setting_config_get(b_priv->team_setting)); } - return NM_SETTING_CLASS(nm_setting_team_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } static void @@ -1505,7 +1512,6 @@ nm_setting_team_class_init(NMSettingTeamClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; setting_class->verify = verify; setting_class->duplicate_copy_properties = duplicate_copy_properties; setting_class->init_from_dbus = init_from_dbus; @@ -1530,9 +1536,14 @@ nm_setting_team_class_init(NMSettingTeamClass *klass) "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[NM_TEAM_ATTRIBUTE_CONFIG], - &nm_sett_info_propert_type_team_s); + _nm_properties_override_gobj( + 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, + .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, + .from_dbus_is_full = TRUE)); /** * NMSettingTeam:notify-peers-count: @@ -1809,9 +1820,16 @@ nm_setting_team_class_init(NMSettingTeamClass *klass) "", G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], - &nm_sett_info_propert_type_team_link_watchers); + _nm_properties_override_gobj( + properties_override, + obj_properties[NM_TEAM_ATTRIBUTE_LINK_WATCHERS], + 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, + .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 d5e028ce53..f597a0201d 100644 --- a/src/libnm-core-impl/nm-setting-user.c +++ b/src/libnm-core-impl/nm-setting-user.c @@ -397,34 +397,27 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_data(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - NMSettingUserPrivate *priv, *pri2; + NMSettingUserPrivate *priv; + NMSettingUserPrivate *pri2; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_USER_DATA)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; - if (!set_b) - return TRUE; + if (!set_b) + return TRUE; - priv = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_a)); - pri2 = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_b)); - return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal) - && nm_utils_hashtable_equal(priv->data_invalid, - pri2->data_invalid, - TRUE, - g_str_equal); - } - - return NM_SETTING_CLASS(nm_setting_user_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + priv = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_a)); + pri2 = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_b)); + return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal) + && nm_utils_hashtable_equal(priv->data_invalid, pri2->data_invalid, TRUE, g_str_equal); } /*****************************************************************************/ @@ -552,8 +545,7 @@ nm_setting_user_class_init(NMSettingUserClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->compare_property = compare_property; - setting_class->verify = verify; + setting_class->verify = verify; /** * NMSettingUser:data: (type GHashTable(utf8,utf8)) @@ -581,9 +573,16 @@ nm_setting_user_class_init(NMSettingUserClass *klass) "", G_TYPE_HASH_TABLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_DATA], - &nm_sett_info_propert_type_strdict); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_DATA], + NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("a{ss}"), + .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, + .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 78eb9924bc..783b539c1f 100644 --- a/src/libnm-core-impl/nm-setting-vlan.c +++ b/src/libnm-core-impl/nm-setting-vlan.c @@ -677,7 +677,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) static GVariant * _override_flags_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -927,8 +927,11 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) properties_override, obj_properties[PROP_FLAGS], NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_UINT32, - .to_dbus_fcn = _override_flags_get, - .missing_from_dbus_fcn = _override_flags_not_set, )); + .to_dbus_fcn = _override_flags_get, + .compare_fcn = _nm_setting_property_compare_fcn_default, + .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-vpn.c b/src/libnm-core-impl/nm-setting-vpn.c index 1df4f66130..4faff54ad2 100644 --- a/src/libnm-core-impl/nm-setting-vpn.c +++ b/src/libnm-core-impl/nm-setting-vpn.c @@ -851,41 +851,36 @@ compare_property_secrets(NMSettingVpn *a, NMSettingVpn *b, NMSettingCompareFlags } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_secrets(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_VPN_SECRETS)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; - return compare_property_secrets(NM_SETTING_VPN(set_a), NM_SETTING_VPN(set_b), flags); - } - - return NM_SETTING_CLASS(nm_setting_vpn_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + return compare_property_secrets(NM_SETTING_VPN(set_a), NM_SETTING_VPN(set_b), flags); } static gboolean clear_secrets(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMSetting * setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data) { - NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); - GParamSpec * prop_spec = sett_info->property_infos[property_idx].param_spec; + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(setting); GHashTableIter iter; const char * secret; gboolean changed = TRUE; - if (!prop_spec || !NM_FLAGS_HAS(prop_spec->flags, NM_SETTING_PARAM_SECRET)) + if (!property_info->param_spec + || !NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET)) return FALSE; - nm_assert(nm_streq(prop_spec->name, NM_SETTING_VPN_SECRETS)); + nm_assert(nm_streq(property_info->param_spec->name, NM_SETTING_VPN_SECRETS)); if (!priv->secrets) return FALSE; @@ -914,12 +909,13 @@ clear_secrets(const NMSettInfoSetting * sett_info, } static gboolean -vpn_secrets_from_dbus(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +vpn_secrets_from_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { NMSettingVpn * self = NM_SETTING_VPN(setting); NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE(self); @@ -943,7 +939,7 @@ vpn_secrets_from_dbus(NMSetting * setting, static GVariant * vpn_secrets_to_dbus(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1131,7 +1127,6 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) setting_class->get_secret_flags = get_secret_flags; setting_class->set_secret_flags = set_secret_flags; setting_class->need_secrets = need_secrets; - setting_class->compare_property = compare_property; setting_class->clear_secrets = clear_secrets; setting_class->aggregate = aggregate; @@ -1231,6 +1226,7 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) obj_properties[PROP_SECRETS], NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("a{ss}"), .to_dbus_fcn = vpn_secrets_to_dbus, + .compare_fcn = compare_fcn_secrets, .from_dbus_fcn = vpn_secrets_from_dbus, )); /** diff --git a/src/libnm-core-impl/nm-setting-wired.c b/src/libnm-core-impl/nm-setting-wired.c index 3c0f0302f5..4c35545ce2 100644 --- a/src/libnm-core-impl/nm-setting-wired.c +++ b/src/libnm-core-impl/nm-setting-wired.c @@ -976,23 +976,17 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_cloned_mac_address(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - if (nm_streq(sett_info->property_infos[property_idx].name, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) { - return !set_b - || nm_streq0(NM_SETTING_WIRED_GET_PRIVATE(set_a)->cloned_mac_address, - NM_SETTING_WIRED_GET_PRIVATE(set_b)->cloned_mac_address); - } - - return NM_SETTING_CLASS(nm_setting_wired_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return !set_b + || nm_streq0(NM_SETTING_WIRED_GET_PRIVATE(set_a)->cloned_mac_address, + NM_SETTING_WIRED_GET_PRIVATE(set_b)->cloned_mac_address); } /*****************************************************************************/ @@ -1274,8 +1268,7 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) object_class->set_property = set_property; object_class->finalize = finalize; - setting_class->verify = verify; - setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingWired:port: @@ -1390,7 +1383,7 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) NM_SETTING_PARAM_NONE, NMSettingWiredPrivate, auto_negotiate, - .to_dbus_data.including_default = TRUE); + .to_dbus_including_default = TRUE); /** * NMSettingWired:mac-address: @@ -1475,9 +1468,14 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_CLONED_MAC_ADDRESS], - &nm_sett_info_propert_type_cloned_mac_address); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_CLONED_MAC_ADDRESS], + NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_BYTESTRING, + .compare_fcn = compare_fcn_cloned_mac_address, + .to_dbus_fcn = _nm_utils_hwaddr_cloned_get, + .from_dbus_fcn = _nm_utils_hwaddr_cloned_set, + .missing_from_dbus_fcn = _nm_utils_hwaddr_cloned_not_set, )); /* ---dbus--- * property: assigned-mac-address diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index a270881edf..e8eeabb317 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -1461,7 +1461,7 @@ nm_setting_wireguard_clear_peers(NMSettingWireGuard *self) static GVariant * _peers_dbus_only_synth(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1563,12 +1563,13 @@ _peers_dbus_only_synth(const NMSettInfoSetting * sett_info, } static gboolean -_peers_dbus_only_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +_peers_dbus_only_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { GVariantIter iter_peers; GVariant * peer_var; @@ -1842,12 +1843,12 @@ need_secrets(NMSetting *setting) static gboolean clear_secrets(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMSetting * setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data) { - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_WIREGUARD_PEERS)) { + if (nm_streq(property_info->name, NM_SETTING_WIREGUARD_PEERS)) { NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting); gboolean peers_changed = FALSE; guint i, j; @@ -1894,7 +1895,7 @@ clear_secrets(const NMSettInfoSetting * sett_info, } return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) - ->clear_secrets(sett_info, property_idx, setting, func, user_data); + ->clear_secrets(sett_info, property_info, setting, func, user_data); } static int @@ -1997,43 +1998,38 @@ update_one_secret(NMSetting *setting, const char *key, GVariant *value, GError * } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_peers(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMSettingWireGuardPrivate *a_priv; NMSettingWireGuardPrivate *b_priv; guint i; - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_WIREGUARD_PEERS)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; - - if (!set_b) - return TRUE; - - a_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_a); - b_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_b); - - if (a_priv->peers_arr->len != b_priv->peers_arr->len) - return FALSE; - for (i = 0; i < a_priv->peers_arr->len; i++) { - NMWireGuardPeer *a_peer = _peers_get(a_priv, i)->peer; - NMWireGuardPeer *b_peer = _peers_get(b_priv, i)->peer; - - if (nm_wireguard_peer_cmp(a_peer, b_peer, flags) != 0) - return FALSE; - } + if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) + return NM_TERNARY_DEFAULT; + if (!set_b) return TRUE; + + a_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_a); + b_priv = NM_SETTING_WIREGUARD_GET_PRIVATE(set_b); + + if (a_priv->peers_arr->len != b_priv->peers_arr->len) + return FALSE; + for (i = 0; i < a_priv->peers_arr->len; i++) { + NMWireGuardPeer *a_peer = _peers_get(a_priv, i)->peer; + NMWireGuardPeer *b_peer = _peers_get(b_priv, i)->peer; + + if (nm_wireguard_peer_cmp(a_peer, b_peer, flags) != 0) + return FALSE; } - return NM_SETTING_CLASS(nm_setting_wireguard_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + return TRUE; } static void @@ -2421,7 +2417,6 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) setting_class->need_secrets = need_secrets; setting_class->clear_secrets = clear_secrets; setting_class->update_one_secret = update_one_secret; - setting_class->compare_property = compare_property; setting_class->duplicate_copy_properties = duplicate_copy_properties; setting_class->enumerate_values = enumerate_values; setting_class->aggregate = aggregate; @@ -2597,6 +2592,7 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) NM_SETTING_WIREGUARD_PEERS, NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"), .to_dbus_fcn = _peers_dbus_only_synth, + .compare_fcn = compare_fcn_peers, .from_dbus_fcn = _peers_dbus_only_set, )); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c index ed77563295..3c4993d79d 100644 --- a/src/libnm-core-impl/nm-setting-wireless-security.c +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -1290,13 +1290,24 @@ set_secret_flags(NMSetting * setting, ->set_secret_flags(setting, secret_name, flags, error); } -/* NMSettingWirelessSecurity:wep-key-type is an enum, but needs to be marshalled - * as 'u', not 'i', for backward-compatibility. - */ static GVariant * -wep_key_type_to_dbus(const GValue *from) +wep_key_type_to_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { - return g_variant_new_uint32(g_value_get_enum(from)); + NMWepKeyType t; + + t = nm_setting_wireless_security_get_wep_key_type(NM_SETTING_WIRELESS_SECURITY(setting)); + if (t == NM_WEP_KEY_TYPE_UNKNOWN) + return NULL; + + /* NMSettingWirelessSecurity:wep-key-type is an enum, but needs to be marshalled + * as 'u', not 'i', for backward-compatibility. + */ + return g_variant_new_uint32(t); } /*****************************************************************************/ @@ -1924,10 +1935,14 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) NM_TYPE_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_UNKNOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_WEP_KEY_TYPE], - &nm_sett_info_propert_type_plain_u, - .to_dbus_data.gprop_to_dbus_fcn = wep_key_type_to_dbus, ); + _nm_properties_override_gobj( + 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, + .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-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c index 83f8afc158..4b7ec8fa1e 100644 --- a/src/libnm-core-impl/nm-setting-wireless.c +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -744,7 +744,7 @@ nm_setting_wireless_get_seen_bssid(NMSettingWireless *setting, guint32 i) static GVariant * _to_dbus_fcn_seen_bssids(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -769,12 +769,13 @@ _to_dbus_fcn_seen_bssids(const NMSettInfoSetting * sett_info, } static gboolean -_from_dbus_fcn_seen_bssids(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +_from_dbus_fcn_seen_bssids(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { NMSettingWirelessPrivate *priv; gs_free const char ** s = NULL; @@ -1102,36 +1103,39 @@ mac_addr_rand_ok: } static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +compare_fcn_cloned_mac_address(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { - if (sett_info->property_infos[property_idx].param_spec - == obj_properties[PROP_CLONED_MAC_ADDRESS]) { - return !set_b - || nm_streq0(NM_SETTING_WIRELESS_GET_PRIVATE(set_a)->cloned_mac_address, - NM_SETTING_WIRELESS_GET_PRIVATE(set_b)->cloned_mac_address); - } - if (sett_info->property_infos[property_idx].param_spec == obj_properties[PROP_SEEN_BSSIDS]) { - return !set_b - || (nm_strv_ptrarray_cmp(NM_SETTING_WIRELESS_GET_PRIVATE(set_a)->seen_bssids, - NM_SETTING_WIRELESS_GET_PRIVATE(set_b)->seen_bssids) - == 0); - } + return !set_b + || nm_streq0(NM_SETTING_WIRELESS_GET_PRIVATE(set_a)->cloned_mac_address, + NM_SETTING_WIRELESS_GET_PRIVATE(set_b)->cloned_mac_address); +} - return NM_SETTING_CLASS(nm_setting_wireless_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); +static NMTernary +compare_fcn_seen_bssids(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + return !set_b + || (nm_strv_ptrarray_cmp(NM_SETTING_WIRELESS_GET_PRIVATE(set_a)->seen_bssids, + NM_SETTING_WIRELESS_GET_PRIVATE(set_b)->seen_bssids) + == 0); } /*****************************************************************************/ static GVariant * nm_setting_wireless_get_security(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -1419,8 +1423,7 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - setting_class->verify = verify; - setting_class->compare_property = compare_property; + setting_class->verify = verify; /** * NMSettingWireless:ssid: @@ -1666,9 +1669,14 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_CLONED_MAC_ADDRESS], - &nm_sett_info_propert_type_cloned_mac_address); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_CLONED_MAC_ADDRESS], + NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_BYTESTRING, + .compare_fcn = compare_fcn_cloned_mac_address, + .to_dbus_fcn = _nm_utils_hwaddr_cloned_get, + .from_dbus_fcn = _nm_utils_hwaddr_cloned_set, + .missing_from_dbus_fcn = _nm_utils_hwaddr_cloned_not_set, )); /* ---dbus--- * property: assigned-mac-address @@ -1786,7 +1794,8 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) obj_properties[PROP_SEEN_BSSIDS], NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING_ARRAY, .to_dbus_fcn = _to_dbus_fcn_seen_bssids, - .from_dbus_fcn = _from_dbus_fcn_seen_bssids, )); + .from_dbus_fcn = _from_dbus_fcn_seen_bssids, + .compare_fcn = compare_fcn_seen_bssids, )); /** * NMSettingWireless:mtu: @@ -1917,7 +1926,8 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) properties_override, "security", NM_SETT_INFO_PROPERT_TYPE_DBUS(G_VARIANT_TYPE_STRING, - .to_dbus_fcn = nm_setting_wireless_get_security, )); + .to_dbus_fcn = nm_setting_wireless_get_security, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, )); /** * NMSettingWireless:wake-on-wlan: diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index f6ef8c74ba..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 @@ -370,35 +376,78 @@ _nm_setting_class_commit(NMSettingClass * setting_class, vtype = p->param_spec->value_type; if (vtype == G_TYPE_BOOLEAN) - p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BOOLEAN); + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_BOOLEAN, + .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); + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_BYTE, + .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) p->property_type = &nm_sett_info_propert_type_plain_u; else if (vtype == G_TYPE_INT64) - p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_INT64); + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_INT64, + .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); - else if (vtype == G_TYPE_STRING) - p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING); - else if (vtype == G_TYPE_DOUBLE) - p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_DOUBLE); + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_UINT64, + .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))); + if (!NM_FLAGS_HAS(p->param_spec->flags, G_PARAM_WRITABLE)) + p->property_type = &nm_sett_info_propert_type_setting_name; + else { + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_STRING, + .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, + .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); + p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( + G_VARIANT_TYPE_STRING_ARRAY, + .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); + .typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES, + .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); + .typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM, + .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); + .typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS, + .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(); @@ -471,7 +520,7 @@ const NMSettInfoProperty * _nm_sett_info_setting_get_property_info(const NMSettInfoSetting *sett_info, const char * property_name) { - const NMSettInfoProperty *property; + const NMSettInfoProperty *property_info; gssize idx; nm_assert(property_name); @@ -490,13 +539,13 @@ _nm_sett_info_setting_get_property_info(const NMSettInfoSetting *sett_info, if (idx < 0) return NULL; - property = &sett_info->property_infos[idx]; + property_info = &sett_info->property_infos[idx]; - nm_assert(idx == 0 || strcmp(property[-1].name, property[0].name) < 0); + nm_assert(idx == 0 || strcmp(property_info[-1].name, property_info[0].name) < 0); nm_assert(idx == sett_info->property_infos_len - 1 - || strcmp(property[0].name, property[1].name) < 0); + || strcmp(property_info[0].name, property_info[1].name) < 0); - return property; + return property_info; } const NMSettInfoSetting * @@ -851,21 +900,19 @@ _finalize_direct(NMSetting *setting) GVariant * _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options) { - const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx]; - switch (property_info->property_type->direct_type) { case NM_VALUE_TYPE_BOOL: { gboolean val; val = *((bool *) _nm_setting_get_private(setting, sett_info, property_info->direct_offset)); - if (!property_info->to_dbus_data.including_default + if (!property_info->to_dbus_including_default && val == NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN(property_info->param_spec)) return NULL; return g_variant_ref(nm_g_variant_singleton_b(val)); @@ -876,7 +923,7 @@ _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * val = *( (guint32 *) _nm_setting_get_private(setting, sett_info, property_info->direct_offset)); - if (!property_info->to_dbus_data.including_default + if (!property_info->to_dbus_including_default && val == NM_G_PARAM_SPEC_GET_DEFAULT_UINT(property_info->param_spec)) return NULL; return g_variant_new_uint32(val); @@ -891,7 +938,7 @@ _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * * Setting "including_default" for a string makes no sense because a * GVariant of type "s" cannot express NULL. */ nm_assert(!NM_G_PARAM_SPEC_GET_DEFAULT_STRING(property_info->param_spec)); - nm_assert(!property_info->to_dbus_data.including_default); + nm_assert(!property_info->to_dbus_including_default); val = *((const char *const *) _nm_setting_get_private(setting, sett_info, @@ -907,40 +954,44 @@ _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * } } +GVariant * +_nm_setting_property_to_dbus_fcn_ignore(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + return NULL; +} + GVariant * _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options) { - const NMSettInfoProperty *const property = &sett_info->property_infos[property_idx]; - nm_auto_unset_gvalue GValue prop_value = { + nm_auto_unset_gvalue GValue prop_value = { 0, }; GArray *tmp_array; - nm_assert(property->param_spec); - nm_assert(property->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_gprop); - nm_assert(property->property_type->typdata_to_dbus.gprop_type - == NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT - || !property->to_dbus_data.gprop_to_dbus_fcn); + nm_assert(property_info->param_spec); + nm_assert(property_info->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_gprop); - g_value_init(&prop_value, property->param_spec->value_type); + g_value_init(&prop_value, property_info->param_spec->value_type); - g_object_get_property(G_OBJECT(setting), property->param_spec->name, &prop_value); + g_object_get_property(G_OBJECT(setting), property_info->param_spec->name, &prop_value); - if (!property->to_dbus_data.including_default - && g_param_value_defaults(property->param_spec, &prop_value)) + if (!property_info->to_dbus_including_default + && g_param_value_defaults(property_info->param_spec, &prop_value)) return NULL; - switch (property->property_type->typdata_to_dbus.gprop_type) { + switch (property_info->property_type->typdata_to_dbus.gprop_type) { case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT: - if (property->to_dbus_data.gprop_to_dbus_fcn) - return property->to_dbus_data.gprop_to_dbus_fcn(&prop_value); - - return g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type); + return g_dbus_gvalue_to_gvariant(&prop_value, property_info->property_type->dbus_type); case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES: nm_assert(G_VALUE_HOLDS(&prop_value, G_TYPE_BYTES)); return nm_utils_gbytes_to_variant_ay(g_value_get_boxed(&prop_value)); @@ -964,44 +1015,108 @@ _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, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options, gboolean ignore_flags) { - const NMSettInfoProperty *property = &sett_info->property_infos[property_idx]; - GVariant * variant; + GVariant *variant; - nm_assert(property->property_type->dbus_type); + nm_assert(property_info->property_type->dbus_type); - if (!property->property_type->to_dbus_fcn) { - nm_assert(!property->param_spec); - nm_assert(!property->to_dbus_data.none); + if (!property_info->property_type->to_dbus_fcn) { + nm_assert(!property_info->param_spec); return NULL; } - if (property->param_spec - && (!ignore_flags - && !NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS))) { - if (!NM_FLAGS_HAS(property->param_spec->flags, G_PARAM_WRITABLE)) - return NULL; + nm_assert(!property_info->param_spec + || NM_FLAGS_HAS(property_info->param_spec->flags, G_PARAM_WRITABLE) + || property_info->property_type == &nm_sett_info_propert_type_setting_name); - if (NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_LEGACY) + if (property_info->param_spec && !ignore_flags + && !NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS)) { + if (NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_LEGACY) && !_nm_utils_is_manager_process) return NULL; - if (NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_SECRET)) { + if (NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET)) { NMSettingSecretFlags f = NM_SETTING_SECRET_FLAG_NONE; if (NM_FLAGS_ANY(flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED | NM_CONNECTION_SERIALIZE_WITH_SECRETS_SYSTEM_OWNED | NM_CONNECTION_SERIALIZE_WITH_SECRETS_NOT_SAVED)) { - if (!nm_setting_get_secret_flags(setting, property->param_spec->name, &f, NULL)) + if (!nm_setting_get_secret_flags(setting, + property_info->param_spec->name, + &f, + NULL)) return NULL; } @@ -1013,26 +1128,28 @@ property_to_dbus(const NMSettInfoSetting * sett_info, } } - variant = property->property_type - ->to_dbus_fcn(sett_info, property_idx, connection, setting, flags, options); + variant = property_info->property_type + ->to_dbus_fcn(sett_info, property_info, connection, setting, flags, options); nm_g_variant_take_ref(variant); - nm_assert(!variant || g_variant_is_of_type(variant, property->property_type->dbus_type)); + nm_assert(!variant || g_variant_is_of_type(variant, property_info->property_type->dbus_type)); return variant; } static gboolean -set_property_from_dbus(const NMSettInfoProperty *property, GVariant *src_value, GValue *dst_value) +set_property_from_dbus(const NMSettInfoProperty *property_info, + GVariant * src_value, + GValue * dst_value) { - nm_assert(property->param_spec); - nm_assert(property->property_type->dbus_type); + nm_assert(property_info->param_spec); + nm_assert(property_info->property_type->dbus_type); - if (property->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->property_type->dbus_type)) + property_info->property_type->dbus_type)) return FALSE; - property->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; @@ -1102,11 +1219,13 @@ _nm_setting_to_dbus(NMSetting * setting, sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); for (j = 0; j < sett_info->property_infos_len; j++) { - gs_unref_variant GVariant *dbus_value = NULL; + const NMSettInfoProperty *property_info = &sett_info->property_infos[j]; + gs_unref_variant GVariant *dbus_value = NULL; - dbus_value = property_to_dbus(sett_info, j, connection, setting, flags, options, FALSE); + dbus_value = + property_to_dbus(sett_info, property_info, connection, setting, flags, options, FALSE); if (dbus_value) { - g_variant_builder_add(&builder, "{sv}", sett_info->property_infos[j].name, dbus_value); + g_variant_builder_add(&builder, "{sv}", property_info->name, dbus_value); } } @@ -1266,17 +1385,43 @@ init_from_dbus(NMSetting * setting, gs_unref_variant GVariant *value = NULL; gs_free_error GError *local = NULL; - if (property_info->param_spec && !(property_info->param_spec->flags & G_PARAM_WRITABLE)) + if (property_info->property_type == &nm_sett_info_propert_type_setting_name) continue; + nm_assert(!property_info->param_spec + || NM_FLAGS_HAS(property_info->param_spec->flags, G_PARAM_WRITABLE)); + value = g_variant_lookup_value(setting_dict, property_info->name, NULL); - if (value && keys) + if (!value) { + if (property_info->property_type->missing_from_dbus_fcn + && !property_info->property_type->missing_from_dbus_fcn(setting, + connection_dict, + property_info->name, + parse_flags, + &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, + _("failed to set property: %s"), + local->message); + g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); + return FALSE; + } + continue; + } + + if (keys) g_hash_table_remove(keys, property_info->name); - if (value && 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_fcn) { + 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; @@ -1294,13 +1439,17 @@ init_from_dbus(NMSetting * setting, return FALSE; } - if (!property_info->property_type->from_dbus_fcn(setting, + if (!property_info->property_type->from_dbus_fcn(sett_info, + property_info, + setting, connection_dict, - property_info->name, 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, @@ -1310,60 +1459,10 @@ init_from_dbus(NMSetting * setting, g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); return FALSE; } - } else if (!value && property_info->property_type->missing_from_dbus_fcn) { - if (!property_info->property_type->missing_from_dbus_fcn(setting, - connection_dict, - property_info->name, - parse_flags, - &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, - _("failed to set property: %s"), - local->message); - g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), property_info->name); - return FALSE; - } - } else if (value && 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; - } + continue; } + + nm_assert(!property_info->param_spec); } return TRUE; @@ -1382,19 +1481,21 @@ init_from_dbus(NMSetting * setting, const GVariantType * nm_setting_get_dbus_property_type(NMSetting *setting, const char *property_name) { - const NMSettInfoProperty *property; + const NMSettInfoProperty *property_info; g_return_val_if_fail(NM_IS_SETTING(setting), NULL); g_return_val_if_fail(property_name != NULL, NULL); - property = _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), property_name); + property_info = + _nm_setting_class_get_property_info(NM_SETTING_GET_CLASS(setting), property_name); - g_return_val_if_fail(property != NULL, NULL); + g_return_val_if_fail(property_info != NULL, NULL); - nm_assert(property->property_type); - nm_assert(g_variant_type_string_is_valid((const char *) property->property_type->dbus_type)); + nm_assert(property_info->property_type); + nm_assert( + g_variant_type_string_is_valid((const char *) property_info->property_type->dbus_type)); - return property->property_type->dbus_type; + return property_info->property_type->dbus_type; } gboolean @@ -1476,21 +1577,23 @@ duplicate_copy_properties(const NMSettInfoSetting *sett_info, NMSetting *src, NM for (i = 0; i < sett_info->property_infos_len; i++) { const NMSettInfoProperty *property_info = &sett_info->property_infos[i]; - if (property_info->param_spec) { - if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) - != G_PARAM_WRITABLE) - continue; - - if (!frozen) { - g_object_freeze_notify(G_OBJECT(dst)); - frozen = TRUE; - } - _gobject_copy_property(G_OBJECT(src), - G_OBJECT(dst), - property_info->param_spec->name, - G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); + if (!property_info->param_spec) continue; + + nm_assert(!NM_FLAGS_HAS(property_info->param_spec->flags, G_PARAM_CONSTRUCT_ONLY)); + if (property_info->property_type == &nm_sett_info_propert_type_setting_name) + continue; + + nm_assert(NM_FLAGS_HAS(property_info->param_spec->flags, G_PARAM_WRITABLE)); + + if (!frozen) { + g_object_freeze_notify(G_OBJECT(dst)); + frozen = TRUE; } + _gobject_copy_property(G_OBJECT(src), + G_OBJECT(dst), + property_info->param_spec->name, + G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); } if (frozen) @@ -1689,110 +1792,163 @@ _nm_setting_should_compare_secret_property(NMSetting * setting, return TRUE; } -static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +/*****************************************************************************/ + +gboolean +_nm_setting_compare_flags_check(const GParamSpec * param_spec, + NMSettingCompareFlags flags, + NMSetting * set_a, + NMSetting * set_b) { - const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx]; - const GParamSpec * param_spec = property_info->param_spec; - - if (!param_spec) - return NM_TERNARY_DEFAULT; - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_FUZZY) && NM_FLAGS_ANY(param_spec->flags, NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)) - return NM_TERNARY_DEFAULT; + return FALSE; if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) && !NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_INFERRABLE)) - return NM_TERNARY_DEFAULT; + return FALSE; if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY) && NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_REAPPLY_IMMEDIATELY)) - return NM_TERNARY_DEFAULT; + return FALSE; if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) && NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_SECRET)) - return NM_TERNARY_DEFAULT; - - if (nm_streq(param_spec->name, NM_SETTING_NAME)) - return NM_TERNARY_DEFAULT; + return FALSE; if (NM_FLAGS_HAS(param_spec->flags, NM_SETTING_PARAM_SECRET) && !_nm_setting_should_compare_secret_property(set_a, set_b, param_spec->name, flags)) + return FALSE; + + return TRUE; +} + +NMTernary +_nm_setting_property_compare_fcn_ignore(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + return NM_TERNARY_DEFAULT; +} + +NMTernary +_nm_setting_property_compare_fcn_direct(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + gconstpointer p_a; + gconstpointer p_b; + + nm_assert(property_info->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_direct); + + if (!property_info->param_spec) + return nm_assert_unreachable_val(NM_TERNARY_DEFAULT); + + if (!_nm_setting_compare_flags_check(property_info->param_spec, flags, set_a, set_b)) return NM_TERNARY_DEFAULT; - if (set_b) { + if (!set_b) + return TRUE; + + p_a = _nm_setting_get_private(set_a, sett_info, property_info->direct_offset); + p_b = _nm_setting_get_private(set_b, sett_info, property_info->direct_offset); + + switch (property_info->property_type->direct_type) { + case NM_VALUE_TYPE_BOOL: + return *((const bool *) p_a) == *((const bool *) p_b); + case NM_VALUE_TYPE_UINT32: + return *((const guint32 *) p_a) == *((const guint32 *) p_b); + case NM_VALUE_TYPE_STRING: + return nm_streq0(*((const char *const *) p_a), *((const char *const *) p_b)); + default: + return nm_assert_unreachable_val(TRUE); + } +} + +NMTernary +_nm_setting_property_compare_fcn_default(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) +{ + nm_assert(property_info->property_type->direct_type == NM_VALUE_TYPE_NONE); + + if (!property_info->param_spec) + return nm_assert_unreachable_val(NM_TERNARY_DEFAULT); + + if (!_nm_setting_compare_flags_check(property_info->param_spec, flags, set_a, set_b)) + return NM_TERNARY_DEFAULT; + + if (!set_b) + return TRUE; + + { gs_unref_variant GVariant *value1 = NULL; gs_unref_variant GVariant *value2 = NULL; value1 = property_to_dbus(sett_info, - property_idx, + property_info, con_a, set_a, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE); value2 = property_to_dbus(sett_info, - property_idx, + property_info, con_b, set_b, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE); - if (nm_property_compare(value1, value2) != 0) - return NM_TERNARY_FALSE; + return nm_property_compare(value1, value2) == 0; } - - return NM_TERNARY_TRUE; } static NMTernary -_compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) +_compare_property(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags) { NMTernary compare_result; nm_assert(sett_info); nm_assert(NM_IS_SETTING_CLASS(sett_info->setting_class)); - nm_assert(property_idx < sett_info->property_infos_len); + nm_assert(property_info); nm_assert(NM_SETTING_GET_CLASS(set_a) == sett_info->setting_class); nm_assert(!set_b || NM_SETTING_GET_CLASS(set_b) == sett_info->setting_class); - compare_result = - NM_SETTING_GET_CLASS(set_a) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); + compare_result = property_info->property_type + ->compare_fcn(sett_info, property_info, con_a, set_a, con_b, set_b, flags); - nm_assert(NM_IN_SET(compare_result, NM_TERNARY_DEFAULT, NM_TERNARY_FALSE, NM_TERNARY_TRUE)); + nm_assert_is_ternary(compare_result); /* check that the inferable flag and the GObject property flag corresponds. */ - nm_assert(!NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) - || !sett_info->property_infos[property_idx].param_spec - || NM_FLAGS_HAS(sett_info->property_infos[property_idx].param_spec->flags, - NM_SETTING_PARAM_INFERRABLE) + nm_assert(!NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE) || !property_info->param_spec + || NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_INFERRABLE) || compare_result == NM_TERNARY_DEFAULT); #if NM_MORE_ASSERTS > 10 - /* assert that compare_property() is symeric. */ - nm_assert(!set_b - || compare_result - == NM_SETTING_GET_CLASS(set_a)->compare_property(sett_info, - property_idx, - con_b, - set_b, - con_a, - set_a, - flags)); + /* assert that compare_fcn() is symeric. */ + nm_assert( + !set_b + || compare_result + == property_info->property_type + ->compare_fcn(sett_info, property_info, con_b, set_b, con_a, set_a, flags)); #endif return compare_result; @@ -1849,7 +2005,8 @@ _nm_setting_compare(NMConnection * con_a, } for (i = 0; i < sett_info->property_infos_len; i++) { - if (_compare_property(sett_info, i, con_a, a, con_b, b, flags) == NM_TERNARY_FALSE) + if (_compare_property(sett_info, &sett_info->property_infos[i], con_a, a, con_b, b, flags) + == NM_TERNARY_FALSE) return FALSE; } @@ -2005,12 +2162,12 @@ _nm_setting_diff(NMConnection * con_a, } } else { for (i = 0; i < sett_info->property_infos_len; i++) { - NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; - const NMSettInfoProperty *property_info; + NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; + const NMSettInfoProperty *property_info = &sett_info->property_infos[i]; NMTernary compare_result; GParamSpec * prop_spec; - compare_result = _compare_property(sett_info, i, con_a, a, con_b, b, flags); + compare_result = _compare_property(sett_info, property_info, con_a, a, con_b, b, flags); if (compare_result == NM_TERNARY_DEFAULT) continue; @@ -2031,15 +2188,14 @@ _nm_setting_diff(NMConnection * con_a, * * We need to double-check whether the property should be ignored by * looking at @a alone. */ - if (_compare_property(sett_info, i, con_a, a, NULL, NULL, flags) + if (_compare_property(sett_info, property_info, con_a, a, NULL, NULL, flags) == NM_TERNARY_DEFAULT) continue; } compared_any = TRUE; - property_info = &sett_info->property_infos[i]; - prop_spec = property_info->param_spec; + prop_spec = property_info->param_spec; if (b) { if (compare_result == NM_TERNARY_FALSE) { @@ -2287,13 +2443,13 @@ _nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType type, gpoint static gboolean clear_secrets(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMSetting * setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data) { NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - GParamSpec * param_spec = sett_info->property_infos[property_idx].param_spec; + GParamSpec * param_spec = property_info->param_spec; if (!param_spec) return FALSE; @@ -2344,7 +2500,7 @@ _nm_setting_clear_secrets(NMSetting * setting, gboolean changed = FALSE; guint16 i; gboolean (*my_clear_secrets)(const struct _NMSettInfoSetting *sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMSetting * setting, NMSettingClearSecretsWithFlagsFn func, gpointer user_data); @@ -2355,7 +2511,8 @@ _nm_setting_clear_secrets(NMSetting * setting, sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); for (i = 0; i < sett_info->property_infos_len; i++) { - changed |= my_clear_secrets(sett_info, i, setting, func, user_data); + changed |= + my_clear_secrets(sett_info, &sett_info->property_infos[i], setting, func, user_data); } return changed; } @@ -2689,7 +2846,7 @@ nm_setting_to_string(NMSetting *setting) static GVariant * _nm_setting_get_deprecated_virtual_interface_name(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -2712,41 +2869,64 @@ _nm_setting_get_deprecated_virtual_interface_name(const NMSettInfoSetting * const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .to_dbus_fcn = _nm_setting_get_deprecated_virtual_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, + .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 = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT( G_VARIANT_TYPE_INT32, /* No functions set. This property type is to silently ignore the value on D-Bus. */ - ); + .compare_fcn = _nm_setting_property_compare_fcn_ignore); const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT( G_VARIANT_TYPE_UINT32, /* No functions set. This property type is to silently ignore the value on D-Bus. */ - ); + .compare_fcn = _nm_setting_property_compare_fcn_ignore); const NMSettInfoPropertType nm_sett_info_propert_type_plain_i = - NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_INT32); + NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_INT32, + .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); + NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_UINT32, + .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, - .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, - .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, - .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); /*****************************************************************************/ @@ -3244,7 +3424,6 @@ nm_setting_class_init(NMSettingClass *setting_class) setting_class->update_one_secret = update_one_secret; setting_class->get_secret_flags = get_secret_flags; setting_class->set_secret_flags = set_secret_flags; - setting_class->compare_property = compare_property; setting_class->clear_secrets = clear_secrets; setting_class->for_each_secret = for_each_secret; setting_class->duplicate_copy_properties = duplicate_copy_properties; diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c index bd9ef510cb..a632b08e43 100644 --- a/src/libnm-core-impl/nm-team-utils.c +++ b/src/libnm-core-impl/nm-team-utils.c @@ -2729,9 +2729,9 @@ _nm_setting_get_team_setting(struct _NMSetting *setting) return _nm_setting_team_port_get_team_setting(NM_SETTING_TEAM_PORT(setting)); } -static GVariant * +GVariant * _nm_team_settings_property_to_dbus(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -2739,8 +2739,7 @@ _nm_team_settings_property_to_dbus(const NMSettInfoSetting * sett_ { NMTeamSetting * self = _nm_setting_get_team_setting(setting); const TeamAttrData *attr_data = - _team_attr_data_get(self->d.is_port, - sett_info->property_infos[property_idx].param_spec->param_id); + _team_attr_data_get(self->d.is_port, property_info->param_spec->param_id); if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG) { const char *config; @@ -2779,7 +2778,7 @@ _nm_team_settings_property_to_dbus(const NMSettInfoSetting * sett_ return NULL; } -static void +void _nm_team_settings_property_from_dbus_link_watchers(GVariant *dbus_value, GValue *prop_value) { g_value_take_boxed(prop_value, @@ -2788,25 +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, - .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, - .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, - .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"), - .to_dbus_fcn = _nm_team_settings_property_to_dbus, ); - -const NMSettInfoPropertType nm_sett_info_propert_type_team_link_watchers = - NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(NM_G_VARIANT_TYPE("aa{sv}"), - .to_dbus_fcn = _nm_team_settings_property_to_dbus, - .gprop_from_dbus_fcn = - _nm_team_settings_property_from_dbus_link_watchers, ); + .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-team-utils.h b/src/libnm-core-impl/nm-team-utils.h index 41943eee8d..d888e191f8 100644 --- a/src/libnm-core-impl/nm-team-utils.h +++ b/src/libnm-core-impl/nm-team-utils.h @@ -266,6 +266,5 @@ extern const NMSettInfoPropertType nm_sett_info_propert_type_team_b; extern const NMSettInfoPropertType nm_sett_info_propert_type_team_i; extern const NMSettInfoPropertType nm_sett_info_propert_type_team_s; extern const NMSettInfoPropertType nm_sett_info_propert_type_team_as; -extern const NMSettInfoPropertType nm_sett_info_propert_type_team_link_watchers; #endif /* __NM_TEAM_UITLS_H__ */ diff --git a/src/libnm-core-impl/nm-utils-private.h b/src/libnm-core-impl/nm-utils-private.h index 5001aeb394..eec84dc637 100644 --- a/src/libnm-core-impl/nm-utils-private.h +++ b/src/libnm-core-impl/nm-utils-private.h @@ -36,12 +36,8 @@ extern const NMSettInfoPropertType nm_sett_info_propert_type_strdict; extern const NMSettInfoPropertType nm_sett_info_propert_type_mac_address; -extern const NMSettInfoPropertType nm_sett_info_propert_type_cloned_mac_address; - extern const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address; -extern const NMSettInfoPropertType nm_sett_info_propert_type_bridge_vlans; - void _nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value); void _nm_utils_bytes_from_dbus(GVariant *dbus_value, GValue *prop_value); @@ -58,4 +54,18 @@ gboolean _nm_utils_bridge_vlan_verify_list(GPtrArray * vlans, const char *setting, const char *property); +NMTernary _nm_utils_bridge_compare_vlans(GPtrArray *vlans_a, GPtrArray *vlans_b); + +GVariant *_nm_team_settings_property_to_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty * property_info, + NMConnection * connection, + NMSetting * setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + +void _nm_team_settings_property_from_dbus_link_watchers(GVariant *dbus_value, GValue *prop_value); + +GVariant *_nm_utils_ip4_dns_to_variant(const char *const *dns, gssize len); +GVariant *_nm_utils_ip6_dns_to_variant(const char *const *dns, gssize len); + #endif diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 12e3bd40f4..5b1f85ccb5 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -775,9 +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); + NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_STRDICT, + .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) @@ -1282,19 +1285,29 @@ nm_utils_wpa_psk_valid(const char *psk) **/ GVariant * nm_utils_ip4_dns_to_variant(char **dns) +{ + return _nm_utils_ip4_dns_to_variant(NM_CAST_STRV_CC(dns), -1); +} + +GVariant * +_nm_utils_ip4_dns_to_variant(const char *const *dns, gssize len) { GVariantBuilder builder; + gsize l; gsize i; + if (len < 0) + l = NM_PTRARRAY_LEN(dns); + else + l = len; + g_variant_builder_init(&builder, G_VARIANT_TYPE("au")); - if (dns) { - for (i = 0; dns[i]; i++) { - guint32 ip = 0; + for (i = 0; i < l; i++) { + in_addr_t ip; - inet_pton(AF_INET, dns[i], &ip); + if (inet_pton(AF_INET, dns[i], &ip) == 1) g_variant_builder_add(&builder, "u", ip); - } } return g_variant_builder_end(&builder); @@ -1591,19 +1604,29 @@ nm_utils_ip4_get_default_prefix(guint32 ip) **/ GVariant * nm_utils_ip6_dns_to_variant(char **dns) +{ + return _nm_utils_ip6_dns_to_variant(NM_CAST_STRV_CC(dns), -1); +} + +GVariant * +_nm_utils_ip6_dns_to_variant(const char *const *dns, gssize len) { GVariantBuilder builder; gsize i; + gsize l; + + if (len < 0) + l = NM_PTRARRAY_LEN(dns); + else + l = len; g_variant_builder_init(&builder, G_VARIANT_TYPE("aay")); - if (dns) { - for (i = 0; dns[i]; i++) { - struct in6_addr ip; + for (i = 0; i < l; i++) { + struct in6_addr ip; - if (inet_pton(AF_INET6, dns[i], &ip) != 1) - continue; - g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&ip)); - } + if (inet_pton(AF_INET6, dns[i], &ip) != 1) + continue; + g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&ip)); } return g_variant_builder_end(&builder); } @@ -4002,9 +4025,9 @@ nm_utils_hwaddr_to_dbus(const char *str) return nm_g_variant_new_ay(buf, len); } -static GVariant * +GVariant * _nm_utils_hwaddr_cloned_get(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -4012,25 +4035,26 @@ _nm_utils_hwaddr_cloned_get(const NMSettInfoSetting * sett_info, { gs_free char *addr = NULL; - nm_assert(nm_streq(sett_info->property_infos[property_idx].name, "cloned-mac-address")); + nm_assert(nm_streq(property_info->name, "cloned-mac-address")); g_object_get(setting, "cloned-mac-address", &addr, NULL); return nm_utils_hwaddr_to_dbus(addr); } -static gboolean -_nm_utils_hwaddr_cloned_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +gboolean +_nm_utils_hwaddr_cloned_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { gsize length; const guint8 *array; char * str; - nm_assert(nm_streq0(property, "cloned-mac-address")); + nm_assert(nm_streq0(property_info->name, "cloned-mac-address")); if (!_nm_setting_use_legacy_property(setting, connection_dict, @@ -4050,7 +4074,7 @@ _nm_utils_hwaddr_cloned_set(NMSetting * setting, return TRUE; } -static gboolean +gboolean _nm_utils_hwaddr_cloned_not_set(NMSetting * setting, GVariant * connection_dict, const char * property, @@ -4061,15 +4085,9 @@ _nm_utils_hwaddr_cloned_not_set(NMSetting * setting, return TRUE; } -const NMSettInfoPropertType nm_sett_info_propert_type_cloned_mac_address = - NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_BYTESTRING, - .to_dbus_fcn = _nm_utils_hwaddr_cloned_get, - .from_dbus_fcn = _nm_utils_hwaddr_cloned_set, - .missing_from_dbus_fcn = _nm_utils_hwaddr_cloned_not_set, ); - static GVariant * _nm_utils_hwaddr_cloned_data_synth(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -4080,7 +4098,7 @@ _nm_utils_hwaddr_cloned_data_synth(const NMSettInfoSetting * sett_ if (!_nm_connection_serialize_non_secret(flags)) return NULL; - nm_assert(nm_streq0(sett_info->property_infos[property_idx].name, "assigned-mac-address")); + nm_assert(nm_streq0(property_info->name, "assigned-mac-address")); g_object_get(setting, "cloned-mac-address", &addr, NULL); @@ -4102,14 +4120,15 @@ _nm_utils_hwaddr_cloned_data_synth(const NMSettInfoSetting * sett_ } static gboolean -_nm_utils_hwaddr_cloned_data_set(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +_nm_utils_hwaddr_cloned_data_set(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { - nm_assert(nm_streq0(property, "assigned-mac-address")); + nm_assert(nm_streq0(property_info->name, "assigned-mac-address")); if (_nm_setting_use_legacy_property(setting, connection_dict, @@ -4126,6 +4145,7 @@ _nm_utils_hwaddr_cloned_data_set(NMSetting * setting, const NMSettInfoPropertType nm_sett_info_propert_type_assigned_mac_address = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_STRING, + .compare_fcn = _nm_setting_property_compare_fcn_ignore, .to_dbus_fcn = _nm_utils_hwaddr_cloned_data_synth, .from_dbus_fcn = _nm_utils_hwaddr_cloned_data_set, ); @@ -4141,10 +4161,13 @@ _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_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS); + NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_BYTESTRING, + .typdata_from_dbus.gprop_fcn = _nm_utils_hwaddr_from_dbus, + .typdata_to_dbus.gprop_type = + NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_MAC_ADDRESS, + .compare_fcn = _nm_setting_property_compare_fcn_default, + .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, + .from_dbus_is_full = TRUE); /*****************************************************************************/ @@ -5445,9 +5468,9 @@ nm_utils_base64secret_normalize(const char *base64_key, return TRUE; } -static GVariant * +GVariant * _nm_utils_bridge_vlans_to_dbus(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, @@ -5456,7 +5479,7 @@ _nm_utils_bridge_vlans_to_dbus(const NMSettInfoSetting * sett_info gs_unref_ptrarray GPtrArray *vlans = NULL; GVariantBuilder builder; guint i; - const char * property_name = sett_info->property_infos[property_idx].name; + const char * property_name = property_info->name; nm_assert(property_name); @@ -5492,13 +5515,14 @@ _nm_utils_bridge_vlans_to_dbus(const NMSettInfoSetting * sett_info return g_variant_builder_end(&builder); } -static gboolean -_nm_utils_bridge_vlans_from_dbus(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error) +gboolean +_nm_utils_bridge_vlans_from_dbus(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error) { gs_unref_ptrarray GPtrArray *vlans = NULL; GVariantIter vlan_iter; @@ -5539,15 +5563,25 @@ _nm_utils_bridge_vlans_from_dbus(NMSetting * setting, g_ptr_array_add(vlans, vlan); } - g_object_set(setting, property, vlans, NULL); + g_object_set(setting, property_info->name, vlans, NULL); return TRUE; } -const NMSettInfoPropertType nm_sett_info_propert_type_bridge_vlans = - NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(NM_G_VARIANT_TYPE("aa{sv}"), - .to_dbus_fcn = _nm_utils_bridge_vlans_to_dbus, - .from_dbus_fcn = _nm_utils_bridge_vlans_from_dbus, ); +NMTernary +_nm_utils_bridge_compare_vlans(GPtrArray *vlans_a, GPtrArray *vlans_b) +{ + guint l = nm_g_ptr_array_len(vlans_a); + guint i; + + if (l != nm_g_ptr_array_len(vlans_b)) + return FALSE; + for (i = 0; i < l; i++) { + if (nm_bridge_vlan_cmp(vlans_a->pdata[i], vlans_b->pdata[i])) + return FALSE; + } + return TRUE; +} gboolean _nm_utils_bridge_vlan_verify_list(GPtrArray * vlans, 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 51077e2360..1c081b55db 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4480,9 +4480,8 @@ test_setting_metadata(void) if (!sip->property_type->to_dbus_fcn) { /* it's allowed to have no to_dbus_fcn(), to ignore a property. But such - * properties must not have a param_spec and no gprop_to_dbus_fcn. */ + * properties must not have a param_spec. */ g_assert(!sip->param_spec); - g_assert(!sip->to_dbus_data.none); } else if (sip->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_gprop) { g_assert(sip->param_spec); switch (sip->property_type->typdata_to_dbus.gprop_type) { @@ -4509,21 +4508,58 @@ test_setting_metadata(void) } g_assert_not_reached(); check_done:; - if (sip->property_type->typdata_to_dbus.gprop_type - != NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT) - g_assert(!sip->to_dbus_data.gprop_to_dbus_fcn); can_set_including_default = TRUE; } if (!can_set_including_default) - g_assert(!sip->to_dbus_data.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(); + if (sip->property_type->compare_fcn == _nm_setting_property_compare_fcn_default) { + g_assert(sip->param_spec); + g_assert_cmpstr(sip->name, !=, NM_SETTING_NAME); + } else if (sip->property_type->compare_fcn == _nm_setting_property_compare_fcn_direct) { + g_assert(sip->param_spec); + g_assert(sip->property_type->direct_type != NM_VALUE_TYPE_NONE); + g_assert(sip->property_type->to_dbus_fcn + == _nm_setting_property_to_dbus_fcn_direct); + } else if (sip->property_type->compare_fcn == _nm_setting_property_compare_fcn_ignore) { + if (NM_IN_SET(sip->property_type, + &nm_sett_info_propert_type_deprecated_ignore_i, + &nm_sett_info_propert_type_deprecated_ignore_u, + &nm_sett_info_propert_type_assigned_mac_address)) { + /* pass */ + } else if (!sip->param_spec) { + /* pass */ + } else if (nm_streq(sip->name, NM_SETTING_NAME)) { + /* pass */ + } else { + /* ignoring a property for comparison make only sense in very specific cases. */ + g_assert_not_reached(); + } + } else if (sip->property_type->compare_fcn) { + /* pass */ + } else { + g_assert_not_reached(); + } + g_assert((sip->property_type->compare_fcn != _nm_setting_property_compare_fcn_direct) + || (sip->property_type->direct_type != NM_VALUE_TYPE_NONE)); + property_types_data = g_hash_table_lookup(h_property_types, sip->property_type); if (!property_types_data) { property_types_data = g_array_new(FALSE, FALSE, sizeof(guint)); @@ -4540,6 +4576,11 @@ check_done:; g_assert_cmpstr(sip->name, ==, sip->param_spec->name); + g_assert(NM_FLAGS_HAS(sip->param_spec->flags, G_PARAM_WRITABLE) + != nm_streq(sip->name, NM_SETTING_NAME)); + g_assert((sip->property_type == &nm_sett_info_propert_type_setting_name) + == nm_streq(sip->name, NM_SETTING_NAME)); + g_value_init(&val, sip->param_spec->value_type); g_object_get_property(G_OBJECT(setting), sip->name, &val); @@ -4675,8 +4716,12 @@ check_done:; if (!g_variant_type_equal(pt->dbus_type, pt_2->dbus_type) || pt->direct_type != pt_2->direct_type || pt->to_dbus_fcn != pt_2->to_dbus_fcn || 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 98fc0509ae..26f69d3e65 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -651,23 +651,23 @@ typedef struct _NMSettInfoSetting NMSettInfoSetting; typedef struct _NMSettInfoProperty NMSettInfoProperty; typedef GVariant *(*NMSettInfoPropToDBusFcn)(const NMSettInfoSetting * sett_info, - guint property_idx, + const NMSettInfoProperty * property_info, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options); -typedef gboolean (*NMSettInfoPropFromDBusFcn)(NMSetting * setting, - GVariant * connection_dict, - const char * property, - GVariant * value, - NMSettingParseFlags parse_flags, - GError ** error); +typedef gboolean (*NMSettInfoPropFromDBusFcn)(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMSetting * setting, + GVariant * connection_dict, + GVariant * value, + NMSettingParseFlags parse_flags, + GError ** error); typedef gboolean (*NMSettInfoPropMissingFromDBusFcn)(NMSetting * setting, GVariant * connection_dict, const char * property, NMSettingParseFlags parse_flags, GError ** error); -typedef GVariant *(*NMSettInfoPropGPropToDBusFcn)(const GValue *from); typedef void (*NMSettInfoPropGPropFromDBusFcn)(GVariant *from, GValue *to); const NMSettInfoSetting *nmtst_sett_info_settings(void); @@ -693,13 +693,41 @@ 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. + * + * The "b" setting may be %NULL, in which case the function only determines whether + * the setting should be compared (TRUE) or not (DEFAULT). */ + NMTernary (*compare_fcn)(const NMSettInfoSetting * sett_info, + const NMSettInfoProperty *property_info, + NMConnection * con_a, + NMSetting * set_a, + NMConnection * con_b, + NMSetting * set_b, + NMSettingCompareFlags flags); + NMSettInfoPropToDBusFcn to_dbus_fcn; 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 { @@ -731,18 +759,11 @@ struct _NMSettInfoProperty { * except of marking those properties and serve as a reminder that special care needs to be taken. */ bool direct_has_special_setter : 1; - struct { - union { - gpointer none; - NMSettInfoPropGPropToDBusFcn gprop_to_dbus_fcn; - }; - - /* Usually, properties that are set to the default value for the GParamSpec - * are not serialized to GVariant (and NULL is returned by to_dbus_data(). - * Set this flag to force always converting the property even if the value - * is the default. */ - bool including_default : 1; - } to_dbus_data; + /* Usually, properties that are set to the default value for the GParamSpec + * are not serialized to GVariant (and NULL is returned by to_dbus_data(). + * Set this flag to force always converting the property even if the value + * is the default. */ + bool to_dbus_including_default : 1; }; typedef struct { @@ -952,4 +973,6 @@ _nm_variant_attribute_spec_find_binary_search(const NMVariantAttributeSpec *cons gboolean _nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode); +GPtrArray *_nm_setting_ip_config_get_dns_array(NMSettingIPConfig *setting); + #endif