diff options
| author | Michael Biebl <biebl@debian.org> | 2024-01-25 09:46:18 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2024-01-25 09:46:18 +0100 |
| commit | 70e18d99b8e3e77bb37e218d7ac582130156f8ef (patch) | |
| tree | d40c587e6d3f0e094ff558e415f1bb9803643214 /src/libnm-core-impl | |
| parent | d4d8b2b91f7ba000d97a8b2aab48c85000c11314 (diff) | |
New upstream version 1.45.90 upstream/1.45.90
Diffstat (limited to 'src/libnm-core-impl')
70 files changed, 3180 insertions, 2070 deletions
diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 4e17a45b..e008b135 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -779,6 +779,10 @@ dbus-type="i" gprop-type="NMSettingConnectionAutoconnectSlaves" /> + <property name="controller" + dbus-type="s" + gprop-type="gchararray" + /> <property name="dns-over-tls" dbus-type="i" gprop-type="gint" @@ -804,6 +808,7 @@ gprop-type="gint" /> <property name="master" + is-deprecated="1" dbus-type="s" gprop-type="gchararray" /> @@ -831,6 +836,10 @@ dbus-type="as" gprop-type="GStrv" /> + <property name="port-type" + dbus-type="s" + gprop-type="gchararray" + /> <property name="read-only" is-deprecated="1" dbus-type="b" @@ -841,6 +850,7 @@ gprop-type="GStrv" /> <property name="slave-type" + is-deprecated="1" dbus-type="s" gprop-type="gchararray" /> @@ -1276,6 +1286,10 @@ dbus-type="b" is-setting-option="1" /> + <property name="eee-enabled" + dbus-type="b" + is-setting-option="1" + /> <property name="ring-rx" dbus-type="u" is-setting-option="1" @@ -1292,6 +1306,22 @@ dbus-type="u" is-setting-option="1" /> + <property name="channels-rx" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-tx" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-other" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-combined" + dbus-type="u" + is-setting-option="1" + /> </setting> <setting name="generic" gtype="NMSettingGeneric" @@ -1398,6 +1428,26 @@ gprop-type="gint" /> </setting> + <setting name="hsr" + gtype="NMSettingHsr" + > + <property name="multicast-spec" + dbus-type="u" + gprop-type="guint" + /> + <property name="port1" + dbus-type="s" + gprop-type="gchararray" + /> + <property name="port2" + dbus-type="s" + gprop-type="gchararray" + /> + <property name="prp" + dbus-type="b" + gprop-type="gboolean" + /> + </setting> <setting name="infiniband" gtype="NMSettingInfiniband" > diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build index 635b417b..e1f11f32 100644 --- a/src/libnm-core-impl/meson.build +++ b/src/libnm-core-impl/meson.build @@ -19,6 +19,7 @@ libnm_core_settings_sources = files( 'nm-setting-generic.c', 'nm-setting-gsm.c', 'nm-setting-hostname.c', + 'nm-setting-hsr.c', 'nm-setting-infiniband.c', 'nm-setting-ip-config.c', 'nm-setting-ip-tunnel.c', @@ -67,7 +68,6 @@ libnm_core_impl_sources = files( 'nm-keyfile-utils.c', 'nm-keyfile.c', 'nm-meta-setting-base-impl.c', - 'nm-property-compare.c', 'nm-setting.c', 'nm-simple-connection.c', 'nm-team-utils.c', diff --git a/src/libnm-core-impl/nm-connection-private.h b/src/libnm-core-impl/nm-connection-private.h index 08abb9a4..3b2c36fd 100644 --- a/src/libnm-core-impl/nm-connection-private.h +++ b/src/libnm-core-impl/nm-connection-private.h @@ -6,7 +6,7 @@ #ifndef __NM_CONNECTION_PRIVATE_H__ #define __NM_CONNECTION_PRIVATE_H__ -#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) +#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) #error Cannot use this header. #endif diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 6ffc750a..a23dc113 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -908,7 +908,7 @@ _nm_setting_connection_verify_secondaries(GArray *secondaries, GError **error) * Now, when we find any invalid/non-normalized values, we reject/normalize * them. We also filter out duplicates. */ - strv = nm_strvarray_get_strv_non_empty(secondaries, NULL); + strv = nm_strvarray_get_strv_notempty(secondaries, NULL); for (i = 0; i < len; i++) { const char *uuid = strv[i]; @@ -977,7 +977,7 @@ _normalize_connection_secondaries(NMConnection *self) if (_nm_setting_connection_verify_secondaries(secondaries, NULL)) return FALSE; - strv = nm_strvarray_get_strv_non_empty_dup(secondaries, NULL); + strv = nm_strvarray_get_strv_notempty_dup(secondaries, NULL); for (i = 0, j = 0; strv[i]; i++) { gs_free char *s = g_steal_pointer(&strv[i]); char uuid_normalized[37]; @@ -986,7 +986,7 @@ _normalize_connection_secondaries(NMConnection *self) if (!nm_uuid_is_valid_nm(s, &uuid_is_normalized, uuid_normalized)) continue; - if (nm_strv_find_first(strv, j, uuid_is_normalized ? uuid_normalized : s) >= 0) + if (nm_strv_contains(strv, j, uuid_is_normalized ? uuid_normalized : s)) continue; strv[j++] = uuid_is_normalized ? g_strdup(uuid_normalized) : g_steal_pointer(&s); @@ -1096,7 +1096,7 @@ _normalize_connection_slave_type(NMConnection *self) if (!nm_setting_connection_get_master(s_con)) return FALSE; - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type) { if (_nm_setting_slave_type_is_valid(slave_type, &port_type) && port_type) { NMSetting *s_port; @@ -1112,7 +1112,7 @@ _normalize_connection_slave_type(NMConnection *self) } } else { if ((slave_type = _nm_connection_detect_slave_type(self, NULL))) { - g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_PORT_TYPE, slave_type, NULL); return TRUE; } } @@ -1172,7 +1172,7 @@ _supports_addr_family(NMConnection *self, int family) if (strcmp(connection_type, NM_SETTING_6LOWPAN_SETTING_NAME) == 0) return family == AF_INET6 || family == AF_UNSPEC; if ((s_con = nm_connection_get_setting_connection(self)) - && (nm_streq0(nm_setting_connection_get_slave_type(s_con), NM_SETTING_VRF_SETTING_NAME))) + && (nm_streq0(nm_setting_connection_get_port_type(s_con), NM_SETTING_VRF_SETTING_NAME))) return TRUE; return !nm_setting_connection_get_master(nm_connection_get_setting_connection(self)); @@ -1430,52 +1430,42 @@ again: } static gboolean -_normalize_wireless_mac_address_randomization(NMConnection *self) +_normalize_wireless_mac_address_randomization(NMSettingWireless *s_wifi) { - NMSettingWireless *s_wifi = nm_connection_get_setting_wireless(self); + const char *desired_cloned_mac_address; const char *cloned_mac_address; + NMSettingMacRandomization desired_mac_address_randomization; NMSettingMacRandomization mac_address_randomization; + gboolean changed = FALSE; - if (!s_wifi) - return FALSE; + _nm_setting_wireless_normalize_mac_address_randomization(s_wifi, + &desired_cloned_mac_address, + &desired_mac_address_randomization); mac_address_randomization = nm_setting_wireless_get_mac_address_randomization(s_wifi); - if (!NM_IN_SET(mac_address_randomization, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, - NM_SETTING_MAC_RANDOMIZATION_NEVER, - NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) - return FALSE; + cloned_mac_address = nm_setting_wireless_get_cloned_mac_address(s_wifi); - cloned_mac_address = nm_setting_wireless_get_cloned_mac_address(s_wifi); - if (cloned_mac_address) { - if (nm_streq(cloned_mac_address, "random")) { - if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) - return FALSE; - mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; - } else if (nm_streq(cloned_mac_address, "permanent")) { - if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER) - return FALSE; - mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; - } else { - if (mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) - return FALSE; - mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; - } + /* Note that "mac_address_randomization" is possibly the string owned by + * "s_wifi". We must be careful that modifying "s_wifi" might invalidate + * the string. */ + + if (!nm_streq0(cloned_mac_address, desired_cloned_mac_address)) { g_object_set(s_wifi, - NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, - mac_address_randomization, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + desired_cloned_mac_address, NULL); - return TRUE; + changed = TRUE; } - if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { + + if (mac_address_randomization != desired_mac_address_randomization) { g_object_set(s_wifi, - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS ? "random" - : "permanent", + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + (guint) desired_mac_address_randomization, NULL); - return TRUE; + changed = TRUE; } - return FALSE; + + return changed; } static gboolean @@ -1497,6 +1487,9 @@ _normalize_wireless(NMConnection *self) changed = TRUE; } + if (_normalize_wireless_mac_address_randomization(s_wifi)) + changed = TRUE; + return changed; } @@ -1775,7 +1768,7 @@ _normalize_invalid_slave_port_settings(NMConnection *self) const char *slave_type; gboolean changed = FALSE; - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (!nm_streq0(slave_type, NM_SETTING_BRIDGE_SETTING_NAME) && _nm_connection_remove_setting(self, NM_TYPE_SETTING_BRIDGE_PORT)) @@ -2043,7 +2036,6 @@ _connection_normalize(NMConnection *connection, was_modified |= _normalize_infiniband(connection); was_modified |= _normalize_bond_mode(connection); was_modified |= _normalize_bond_options(connection); - was_modified |= _normalize_wireless_mac_address_randomization(connection); was_modified |= _normalize_wireless(connection); was_modified |= _normalize_macsec(connection); was_modified |= _normalize_team_config(connection); @@ -3182,6 +3174,7 @@ nm_connection_is_virtual(NMConnection *connection) NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_DUMMY_SETTING_NAME, + NM_SETTING_HSR_SETTING_NAME, NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACVLAN_SETTING_NAME, diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c index 82581d9f..078ea5d7 100644 --- a/src/libnm-core-impl/nm-keyfile.c +++ b/src/libnm-core-impl/nm-keyfile.c @@ -1219,9 +1219,14 @@ mac_address_parser(KeyfileReaderInfo *info, tmp_string = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); - if (cloned_mac_addr && NM_CLONED_MAC_IS_SPECIAL(tmp_string)) { - mac_str = tmp_string; - goto out; + if (cloned_mac_addr) { + gboolean is_wifi; + + is_wifi = NM_IS_SETTING_WIRELESS(setting); + if (NM_CLONED_MAC_IS_SPECIAL(tmp_string, is_wifi)) { + mac_str = tmp_string; + goto out; + } } if (tmp_string && nm_utils_hwaddr_aton(tmp_string, addr_bin, addr_len)) diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c index b531ae85..34a7d22e 100644 --- a/src/libnm-core-impl/nm-meta-setting-base-impl.c +++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c @@ -29,6 +29,7 @@ #include "nm-setting-generic.h" #include "nm-setting-gsm.h" #include "nm-setting-hostname.h" +#include "nm-setting-hsr.h" #include "nm-setting-infiniband.h" #include "nm-setting-ip-config.h" #include "nm-setting-ip-tunnel.h" @@ -335,6 +336,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_HOSTNAME_SETTING_NAME, .get_setting_gtype = nm_setting_hostname_get_type, }, + [NM_META_SETTING_TYPE_HSR] = + { + .meta_type = NM_META_SETTING_TYPE_HSR, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_HSR_SETTING_NAME, + .get_setting_gtype = nm_setting_hsr_get_type, + }, [NM_META_SETTING_TYPE_INFINIBAND] = { .meta_type = NM_META_SETTING_TYPE_INFINIBAND, @@ -632,6 +640,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = { NM_META_SETTING_TYPE_DUMMY, NM_META_SETTING_TYPE_GENERIC, NM_META_SETTING_TYPE_GSM, + NM_META_SETTING_TYPE_HSR, NM_META_SETTING_TYPE_INFINIBAND, NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_LOOPBACK, diff --git a/src/libnm-core-impl/nm-property-compare.c b/src/libnm-core-impl/nm-property-compare.c deleted file mode 100644 index 6273e90b..00000000 --- a/src/libnm-core-impl/nm-property-compare.c +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2007 - 2014 Red Hat, Inc. - * Copyright (C) 2007 - 2008 Novell, Inc. - */ - -#include "libnm-core-impl/nm-default-libnm-core.h" - -#include "nm-property-compare.h" - -#include <netinet/in.h> - -static int -_nm_property_compare_collection(GVariant *value1, GVariant *value2) -{ - GVariant *child1, *child2; - int i, len1, len2; - int ret; - - len1 = g_variant_n_children(value1); - len2 = g_variant_n_children(value2); - - if (len1 != len2) - return len1 < len2 ? -1 : len1 > len2; - - for (i = 0; i < len1; i++) { - child1 = g_variant_get_child_value(value1, i); - child2 = g_variant_get_child_value(value2, i); - - ret = nm_property_compare(child1, child2); - g_variant_unref(child1); - g_variant_unref(child2); - - if (ret) - return ret; - } - - return 0; -} - -static int -_nm_property_compare_vardict(GVariant *value1, GVariant *value2) -{ - GVariantIter iter; - int len1, len2; - const char *key; - GVariant *val1, *val2; - - len1 = g_variant_n_children(value1); - len2 = g_variant_n_children(value2); - - if (len1 != len2) - return len1 < len2 ? -1 : 1; - - g_variant_iter_init(&iter, value1); - while (g_variant_iter_next(&iter, "{&sv}", &key, &val1)) { - if (!g_variant_lookup(value2, key, "v", &val2)) { - g_variant_unref(val1); - return -1; - } - if (!g_variant_equal(val1, val2)) { - g_variant_unref(val1); - g_variant_unref(val2); - return -1; - } - g_variant_unref(val1); - g_variant_unref(val2); - } - - return 0; -} - -static int -_nm_property_compare_strdict(GVariant *value1, GVariant *value2) -{ - GVariantIter iter; - int len1, len2; - const char *key, *val1, *val2; - int ret; - - len1 = g_variant_n_children(value1); - len2 = g_variant_n_children(value2); - - if (len1 != len2) - return len1 < len2 ? -1 : len1 > len2; - - g_variant_iter_init(&iter, value1); - while (g_variant_iter_next(&iter, "{&s&s}", &key, &val1)) { - if (!g_variant_lookup(value2, key, "&s", &val2)) - return -1; - - ret = strcmp(val1, val2); - if (ret) - return ret; - } - - return 0; -} - -int -nm_property_compare(GVariant *value1, GVariant *value2) -{ - const GVariantType *type1; - const GVariantType *type2; - int ret; - - if (value1 == value2) - return 0; - if (!value1) - return 1; - if (!value2) - return -1; - - type1 = g_variant_get_type(value1); - type2 = g_variant_get_type(value2); - - if (!g_variant_type_equal(type1, type2)) - return type1 < type2 ? -1 : type1 > type2; - - if (g_variant_type_is_basic(type1)) - ret = g_variant_compare(value1, value2); - else if (g_variant_is_of_type(value1, G_VARIANT_TYPE("a{ss}"))) - ret = _nm_property_compare_strdict(value1, value2); - else if (g_variant_is_of_type(value1, G_VARIANT_TYPE("a{sv}"))) - ret = _nm_property_compare_vardict(value1, value2); - else if (g_variant_type_is_array(type1)) - ret = _nm_property_compare_collection(value1, value2); - else if (g_variant_type_is_tuple(type1)) - ret = _nm_property_compare_collection(value1, value2); - else { - g_warning("Don't know how to compare variant type '%s'", (const char *) type1); - ret = value1 == value2; - } - - return ret; -} diff --git a/src/libnm-core-impl/nm-property-compare.h b/src/libnm-core-impl/nm-property-compare.h deleted file mode 100644 index 2400bc42..00000000 --- a/src/libnm-core-impl/nm-property-compare.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2007 - 2014 Red Hat, Inc. - * Copyright (C) 2007 - 2008 Novell, Inc. - */ - -#ifndef __NM_PROPERTY_COMPARE_H__ -#define __NM_PROPERTY_COMPARE_H__ - -#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) -#error Cannot use this header. -#endif - -int nm_property_compare(GVariant *value1, GVariant *value2); - -#endif /* __NM_PROPERTY_COMPARE_H__ */ diff --git a/src/libnm-core-impl/nm-setting-6lowpan.c b/src/libnm-core-impl/nm-setting-6lowpan.c index e0b5d650..7066c3e6 100644 --- a/src/libnm-core-impl/nm-setting-6lowpan.c +++ b/src/libnm-core-impl/nm-setting-6lowpan.c @@ -33,7 +33,8 @@ typedef struct { * Since: 1.14 */ struct _NMSetting6Lowpan { - NMSetting parent; + NMSetting parent; + NMSetting6LowpanPrivate _priv; }; struct _NMSetting6LowpanClass { @@ -43,7 +44,7 @@ struct _NMSetting6LowpanClass { G_DEFINE_TYPE(NMSetting6Lowpan, nm_setting_6lowpan, NM_TYPE_SETTING) #define NM_SETTING_6LOWPAN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_6LOWPAN, NMSetting6LowpanPrivate)) + _NM_GET_PRIVATE(o, NMSetting6Lowpan, NM_IS_SETTING_6LOWPAN, NMSetting) /*****************************************************************************/ @@ -92,7 +93,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) if (s_con) { const char *master = NULL, *slave_type = NULL; - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (!g_strcmp0(slave_type, NM_SETTING_6LOWPAN_SETTING_NAME)) master = nm_setting_connection_get_master(s_con); @@ -102,7 +103,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' value doesn't match '%s=%s'"), priv->parent, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, master); g_prefix_error(error, "%s.%s: ", @@ -156,8 +157,6 @@ nm_setting_6lowpan_class_init(NMSetting6LowpanClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSetting6LowpanPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -177,7 +176,8 @@ nm_setting_6lowpan_class_init(NMSetting6LowpanClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSetting6LowpanPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); @@ -185,5 +185,5 @@ nm_setting_6lowpan_class_init(NMSetting6LowpanClass *klass) NM_META_SETTING_TYPE_6LOWPAN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSetting6Lowpan, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-8021x.c b/src/libnm-core-impl/nm-setting-8021x.c index 626673e8..945fd6d3 100644 --- a/src/libnm-core-impl/nm-setting-8021x.c +++ b/src/libnm-core-impl/nm-setting-8021x.c @@ -189,20 +189,18 @@ typedef struct { * IEEE 802.1x Authentication Settings */ struct _NMSetting8021x { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSetting8021xPrivate _priv; }; struct _NMSetting8021xClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING) #define NM_SETTING_802_1X_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) + _NM_GET_PRIVATE(o, NMSetting8021x, NM_IS_SETTING_802_1X, NMSetting) /*****************************************************************************/ @@ -3199,9 +3197,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray *properties_override = _nm_sett_info_property_override_create_array(); - - g_type_class_add_private(klass, sizeof(NMSetting8021xPrivate)); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(55); object_class->get_property = get_property; object_class->set_property = set_property; @@ -3227,11 +3223,11 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) * example: IEEE_8021X_EAP_METHODS=PEAP * ---end--- */ - obj_properties[PROP_EAP] = g_param_spec_boxed(NM_SETTING_802_1X_EAP, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_802_1X_EAP, + PROP_EAP, + NM_SETTING_PARAM_NONE); /** * NMSetting8021x:identity: @@ -3252,7 +3248,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_IDENTITY, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - identity); + identity, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:anonymous-identity: @@ -3273,7 +3270,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_ANONYMOUS_IDENTITY, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - anonymous_identity); + anonymous_identity, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:pac-file: @@ -3293,7 +3291,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PAC_FILE, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - pac_file); + pac_file, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:ca-cert: @@ -3346,7 +3345,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_CA_CERT_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - ca_cert_password); + ca_cert_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:ca-cert-password-flags: @@ -3384,7 +3384,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_CA_PATH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - ca_path); + ca_path, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:subject-match: @@ -3410,7 +3411,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, subject_match, - .is_deprecated = TRUE, ); + .is_deprecated = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:altsubject-matches: @@ -3426,12 +3428,11 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) * example: IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc" * ---end--- */ - obj_properties[PROP_ALTSUBJECT_MATCHES] = - g_param_spec_boxed(NM_SETTING_802_1X_ALTSUBJECT_MATCHES, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_802_1X_ALTSUBJECT_MATCHES, + PROP_ALTSUBJECT_MATCHES, + NM_SETTING_PARAM_NONE); /** * NMSetting8021x:domain-suffix-match: @@ -3458,7 +3459,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_DOMAIN_SUFFIX_MATCH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - domain_suffix_match); + domain_suffix_match, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:domain-match: @@ -3484,7 +3486,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_DOMAIN_MATCH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - domain_match); + domain_match, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:client-cert: @@ -3532,7 +3535,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_CLIENT_CERT_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - client_cert_password); + client_cert_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:client-cert-password-flags: @@ -3571,7 +3575,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE1_PEAPVER, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase1_peapver); + phase1_peapver, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase1-peaplabel: @@ -3595,7 +3600,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE1_PEAPLABEL, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase1_peaplabel); + phase1_peaplabel, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase1-fast-provisioning: @@ -3621,7 +3627,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE1_FAST_PROVISIONING, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase1_fast_provisioning); + phase1_fast_provisioning, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase1-auth-flags: @@ -3685,7 +3692,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_AUTH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase2_auth); + phase2_auth, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-autheap: @@ -3712,7 +3720,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_AUTHEAP, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase2_autheap); + phase2_autheap, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-ca-cert: @@ -3759,7 +3768,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_CA_CERT_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - phase2_ca_cert_password); + phase2_ca_cert_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-ca-cert-password-flags: @@ -3797,7 +3807,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_CA_PATH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase2_ca_path); + phase2_ca_path, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-subject-match: @@ -3824,7 +3835,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, phase2_subject_match, - .is_deprecated = TRUE, ); + .is_deprecated = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-altsubject-matches: @@ -3839,12 +3851,11 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) * variable: IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES(+) * ---end--- */ - obj_properties[PROP_PHASE2_ALTSUBJECT_MATCHES] = - g_param_spec_boxed(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, + PROP_PHASE2_ALTSUBJECT_MATCHES, + NM_SETTING_PARAM_NONE); /** * NMSetting8021x:phase2-domain-suffix-match: @@ -3872,7 +3883,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_DOMAIN_SUFFIX_MATCH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase2_domain_suffix_match); + phase2_domain_suffix_match, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-domain-match: @@ -3899,7 +3911,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_DOMAIN_MATCH, NM_SETTING_PARAM_NONE, NMSetting8021xPrivate, - phase2_domain_match); + phase2_domain_match, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-client-cert: @@ -3950,7 +3963,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_CLIENT_CERT_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - phase2_client_cert_password); + phase2_client_cert_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-client-cert-password-flags: @@ -3987,7 +4001,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - password); + password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:password-flags: @@ -4119,7 +4134,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PRIVATE_KEY_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - private_key_password); + private_key_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:private-key-password-flags: @@ -4205,7 +4221,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PHASE2_PRIVATE_KEY_PASSWORD, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - phase2_private_key_password); + phase2_private_key_password, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:phase2-private-key-password-flags: @@ -4245,7 +4262,8 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) PROP_PIN, NM_SETTING_PARAM_SECRET, NMSetting8021xPrivate, - pin); + pin, + .direct_string_allow_empty = TRUE); /** * NMSetting8021x:pin-flags: @@ -4352,5 +4370,5 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) NM_META_SETTING_TYPE_802_1X, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSetting8021x, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-adsl.c b/src/libnm-core-impl/nm-setting-adsl.c index ca291389..f9aacb83 100644 --- a/src/libnm-core-impl/nm-setting-adsl.c +++ b/src/libnm-core-impl/nm-setting-adsl.c @@ -46,20 +46,18 @@ typedef struct { * ADSL Settings */ struct _NMSettingAdsl { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingAdslPrivate _priv; }; struct _NMSettingAdslClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingAdsl, nm_setting_adsl, NM_TYPE_SETTING) #define NM_SETTING_ADSL_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_ADSL, NMSettingAdslPrivate)) + _NM_GET_PRIVATE(o, NMSettingAdsl, NM_IS_SETTING_ADSL, NMSetting) /*****************************************************************************/ @@ -267,8 +265,6 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingAdslPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -287,7 +283,8 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) PROP_USERNAME, NM_SETTING_PARAM_NONE, NMSettingAdslPrivate, - username); + username, + .direct_string_allow_empty = TRUE); /** * NMSettingAdsl:password: @@ -300,7 +297,8 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) PROP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSettingAdslPrivate, - password); + password, + .direct_string_allow_empty = TRUE); /** * NMSettingAdsl:password-flags: @@ -326,7 +324,8 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) NM_SETTING_PARAM_NONE, NMSettingAdslPrivate, protocol, - .direct_set_string_ascii_strdown = TRUE); + .direct_set_string_ascii_strdown = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingAdsl:encapsulation: @@ -340,7 +339,8 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) NM_SETTING_PARAM_NONE, NMSettingAdslPrivate, encapsulation, - .direct_set_string_ascii_strdown = TRUE); + .direct_set_string_ascii_strdown = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingAdsl:vpi: @@ -380,5 +380,5 @@ nm_setting_adsl_class_init(NMSettingAdslClass *klass) NM_META_SETTING_TYPE_ADSL, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingAdsl, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-bluetooth.c b/src/libnm-core-impl/nm-setting-bluetooth.c index f657ff13..3c2605a1 100644 --- a/src/libnm-core-impl/nm-setting-bluetooth.c +++ b/src/libnm-core-impl/nm-setting-bluetooth.c @@ -42,20 +42,18 @@ typedef struct { * Bluetooth Settings */ struct _NMSettingBluetooth { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingBluetoothPrivate _priv; }; struct _NMSettingBluetoothClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING) #define NM_SETTING_BLUETOOTH_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothPrivate)) + _NM_GET_PRIVATE(o, NMSettingBluetooth, NM_IS_SETTING_BLUETOOTH, NMSetting) /*****************************************************************************/ @@ -254,8 +252,6 @@ nm_setting_bluetooth_class_init(NMSettingBluetoothClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingBluetoothPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -287,7 +283,8 @@ nm_setting_bluetooth_class_init(NMSettingBluetoothClass *klass) PROP_TYPE, NM_SETTING_PARAM_INFERRABLE, NMSettingBluetoothPrivate, - type); + type, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); @@ -295,5 +292,5 @@ nm_setting_bluetooth_class_init(NMSettingBluetoothClass *klass) NM_META_SETTING_TYPE_BLUETOOTH, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingBluetooth, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c index e8917902..342d6dd0 100644 --- a/src/libnm-core-impl/nm-setting-bond-port.c +++ b/src/libnm-core-impl/nm-setting-bond-port.c @@ -101,7 +101,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type && !nm_streq(slave_type, NM_SETTING_BOND_SETTING_NAME)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -114,7 +114,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index 81c67d51..60ae0294 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -44,20 +44,18 @@ typedef struct { * Bonding Settings */ struct _NMSettingBond { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingBondPrivate _priv; }; struct _NMSettingBondClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingBond, nm_setting_bond, NM_TYPE_SETTING) #define NM_SETTING_BOND_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BOND, NMSettingBondPrivate)) + _NM_GET_PRIVATE(o, NMSettingBond, NM_IS_SETTING_BOND, NMSetting) /*****************************************************************************/ @@ -1322,8 +1320,6 @@ nm_setting_bond_class_init(NMSettingBondClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingBondPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -1380,5 +1376,5 @@ nm_setting_bond_class_init(NMSettingBondClass *klass) NM_META_SETTING_TYPE_BOND, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingBond, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-bridge-port.c b/src/libnm-core-impl/nm-setting-bridge-port.c index b94a348e..dcb17896 100644 --- a/src/libnm-core-impl/nm-setting-bridge-port.c +++ b/src/libnm-core-impl/nm-setting-bridge-port.c @@ -45,20 +45,18 @@ typedef struct { * Bridge Port Settings */ struct _NMSettingBridgePort { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingBridgePortPrivate _priv; }; struct _NMSettingBridgePortClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING) #define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate)) + _NM_GET_PRIVATE(o, NMSettingBridgePort, NM_IS_SETTING_BRIDGE_PORT, NMSetting) /*****************************************************************************/ @@ -330,7 +328,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type && strcmp(slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -343,7 +341,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } @@ -455,8 +453,6 @@ nm_setting_bridge_port_class_init(NMSettingBridgePortClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingBridgePortPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -579,5 +575,5 @@ nm_setting_bridge_port_class_init(NMSettingBridgePortClass *klass) NM_META_SETTING_TYPE_BRIDGE_PORT, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingBridgePort, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c index c1a2621d..7e9a0964 100644 --- a/src/libnm-core-impl/nm-setting-bridge.c +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -1416,7 +1416,7 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray *properties_override = _nm_sett_info_property_override_create_array(); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(35); object_class->get_property = get_property; object_class->set_property = set_property; @@ -1811,7 +1811,8 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass) PROP_VLAN_PROTOCOL, NM_SETTING_PARAM_INFERRABLE, NMSettingBridge, - _priv.vlan_protocol); + _priv.vlan_protocol, + .direct_string_allow_empty = TRUE); /** * NMSettingBridge:vlan-stats-enabled: @@ -1862,7 +1863,8 @@ nm_setting_bridge_class_init(NMSettingBridgeClass *klass) PROP_MULTICAST_ROUTER, NM_SETTING_PARAM_INFERRABLE, NMSettingBridge, - _priv.multicast_router); + _priv.multicast_router, + .direct_string_allow_empty = TRUE); /** * NMSettingBridge:multicast-query-use-ifaddr: diff --git a/src/libnm-core-impl/nm-setting-cdma.c b/src/libnm-core-impl/nm-setting-cdma.c index c32af6b7..b497cf14 100644 --- a/src/libnm-core-impl/nm-setting-cdma.c +++ b/src/libnm-core-impl/nm-setting-cdma.c @@ -42,20 +42,18 @@ typedef struct { * CDMA-based Mobile Broadband Settings */ struct _NMSettingCdma { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingCdmaPrivate _priv; }; struct _NMSettingCdmaClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING) #define NM_SETTING_CDMA_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_CDMA, NMSettingCdmaPrivate)) + _NM_GET_PRIVATE(o, NMSettingCdma, NM_IS_SETTING_CDMA, NMSetting) /*****************************************************************************/ @@ -218,8 +216,6 @@ nm_setting_cdma_class_init(NMSettingCdmaClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingCdmaPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -240,7 +236,8 @@ nm_setting_cdma_class_init(NMSettingCdmaClass *klass) PROP_NUMBER, NM_SETTING_PARAM_NONE, NMSettingCdmaPrivate, - number); + number, + .direct_string_allow_empty = TRUE); /** * NMSettingCdma:username: @@ -255,7 +252,8 @@ nm_setting_cdma_class_init(NMSettingCdmaClass *klass) PROP_USERNAME, NM_SETTING_PARAM_NONE, NMSettingCdmaPrivate, - username); + username, + .direct_string_allow_empty = TRUE); /** * NMSettingCdma:password: @@ -270,7 +268,8 @@ nm_setting_cdma_class_init(NMSettingCdmaClass *klass) PROP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSettingCdmaPrivate, - password); + password, + .direct_string_allow_empty = TRUE); /** * NMSettingCdma:password-flags: @@ -309,5 +308,5 @@ nm_setting_cdma_class_init(NMSettingCdmaClass *klass) NM_META_SETTING_TYPE_CDMA, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingCdma, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index 3c26ab5d..892e7d31 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -56,7 +56,9 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection, PROP_READ_ONLY, PROP_ZONE, PROP_MASTER, + PROP_CONTROLLER, PROP_SLAVE_TYPE, + PROP_PORT_TYPE, PROP_AUTOCONNECT_SLAVES, PROP_SECONDARIES, PROP_GATEWAY_PING_TIMEOUT, @@ -80,8 +82,8 @@ typedef struct { char *stable_id; char *interface_name; char *type; - char *master; - char *slave_type; + char *controller; + char *port_type; char *zone; char *mud_url; guint64 timestamp; @@ -109,20 +111,18 @@ typedef struct { * General Connection Profile Settings */ struct _NMSettingConnection { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingConnectionPrivate _priv; }; struct _NMSettingConnectionClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) #define NM_SETTING_CONNECTION_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) + _NM_GET_PRIVATE(o, NMSettingConnection, NM_IS_SETTING_CONNECTION, NMSetting) /*****************************************************************************/ @@ -357,24 +357,14 @@ invalid: return TRUE; } -/** - * nm_setting_connection_permissions_user_allowed: - * @setting: the #NMSettingConnection - * @uname: the user name to check permissions for - * - * Checks whether the given username is allowed to view/access this connection. - * - * Returns: %TRUE if the requested user is allowed to view this connection, - * %FALSE if the given user is not allowed to view this connection - */ -gboolean -nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, const char *uname) +static gboolean +_permissions_user_allowed(NMSettingConnection *setting, const char *uname, gulong uid) { + gs_free struct passwd *pw = NULL; NMSettingConnectionPrivate *priv; guint i; - g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); - g_return_val_if_fail(uname != NULL, FALSE); + nm_assert(NM_IS_SETTING_CONNECTION(setting)); priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); @@ -386,7 +376,19 @@ nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, con for (i = 0; i < priv->permissions->len; i++) { const Permission *permission = &nm_g_array_index(priv->permissions, Permission, i); - if (permission->ptype == PERM_TYPE_USER && nm_streq(permission->item, uname)) + if (permission->ptype != PERM_TYPE_USER) + continue; + + if (!uname) { + if (uid != G_MAXULONG) { + pw = nm_getpwuid(uid); + uname = nm_passwd_name(pw); + } + if (!uname) + return FALSE; + } + + if (nm_streq(permission->item, uname)) return TRUE; } @@ -394,6 +396,33 @@ nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, con } /** + * nm_setting_connection_permissions_user_allowed: + * @setting: the #NMSettingConnection + * @uname: the user name to check permissions for + * + * Checks whether the given username is allowed to view/access this connection. + * + * Returns: %TRUE if the requested user is allowed to view this connection, + * %FALSE if the given user is not allowed to view this connection + */ +gboolean +nm_setting_connection_permissions_user_allowed(NMSettingConnection *setting, const char *uname) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(uname != NULL, FALSE); + + return _permissions_user_allowed(setting, uname, G_MAXULONG); +} + +gboolean +nm_setting_connection_permissions_user_allowed_by_uid(NMSettingConnection *setting, gulong uid) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + + return _permissions_user_allowed(setting, NULL, uid); +} + +/** * nm_setting_connection_add_permission: * @setting: the #NMSettingConnection * @ptype: the permission type; at this time only "user" is supported @@ -682,13 +711,51 @@ nm_setting_connection_get_zone(NMSettingConnection *setting) * * Returns: interface name of the master device or UUID of the master * connection. + * + * Deprecated: 1.46. Use nm_setting_connection_get_controller() instead which + * is just an alias. */ const char * nm_setting_connection_get_master(NMSettingConnection *setting) { + return nm_setting_connection_get_controller(setting); +} + +/** + * nm_setting_connection_get_controller: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:controller property of the connection. + * + * Returns: interface name of the controller device or UUID of the controller + * connection. + * + * Since: 1.46 + */ +const char * +nm_setting_connection_get_controller(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->controller; +} + +/** + * nm_setting_connection_get_port_type: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:port-type property of the connection. + * + * Returns: the type of port this connection is, if any. + * + * Since: 1.46 + */ +const char * +nm_setting_connection_get_port_type(NMSettingConnection *setting) +{ g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); - return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->master; + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->port_type; } /** @@ -698,13 +765,14 @@ nm_setting_connection_get_master(NMSettingConnection *setting) * Returns the #NMSettingConnection:slave-type property of the connection. * * Returns: the type of slave this connection is, if any + * + * Deprecated: 1.46. Use nm_setting_connection_get_port_type() instead which + * is just an alias. */ const char * nm_setting_connection_get_slave_type(NMSettingConnection *setting) { - g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); - - return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->slave_type; + return nm_setting_connection_get_port_type(setting); } /** @@ -714,13 +782,15 @@ nm_setting_connection_get_slave_type(NMSettingConnection *setting) * against @setting's slave type * * Returns: %TRUE if connection is of the given slave @type + * + * Deprecated: 1.46. */ gboolean nm_setting_connection_is_slave_type(NMSettingConnection *setting, const char *type) { g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); - return !g_strcmp0(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->slave_type, type); + return nm_streq0(NM_SETTING_CONNECTION_GET_PRIVATE(setting)->port_type, type); } /** @@ -810,21 +880,11 @@ nm_setting_connection_get_num_secondaries(NMSettingConnection *setting) const char * nm_setting_connection_get_secondary(NMSettingConnection *setting, guint32 idx) { - NMSettingConnectionPrivate *priv; - guint secondaries_len; - g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); - priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); - - secondaries_len = nm_g_array_len(priv->secondaries.arr); - if (idx >= secondaries_len) { - /* access one past the length is OK. */ - g_return_val_if_fail(idx == secondaries_len, NULL); - return NULL; - } - - return nm_strvarray_get_idx(priv->secondaries.arr, idx); + return nm_strvarray_get_idxnull_or_greturn( + NM_SETTING_CONNECTION_GET_PRIVATE(setting)->secondaries.arr, + idx); } /** @@ -864,10 +924,9 @@ nm_setting_connection_add_secondary(NMSettingConnection *setting, const char *se priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); - if (nm_strvarray_find_first(priv->secondaries.arr, sec_uuid) >= 0) + if (!nm_strvarray_ensure_and_add_unique(&priv->secondaries.arr, sec_uuid)) return FALSE; - nm_strvarray_add(nm_strvarray_ensure(&priv->secondaries.arr), sec_uuid); _notify(setting, PROP_SECONDARIES); return TRUE; } @@ -890,7 +949,7 @@ nm_setting_connection_remove_secondary(NMSettingConnection *setting, guint32 idx g_return_if_fail(idx < nm_g_array_len(priv->secondaries.arr)); - g_array_remove_index(priv->secondaries.arr, idx); + nm_strvarray_remove_index(priv->secondaries.arr, idx); _notify(setting, PROP_SECONDARIES); } @@ -913,11 +972,11 @@ nm_setting_connection_remove_secondary_by_value(NMSettingConnection *setting, co priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); - if (nm_strvarray_remove_first(priv->secondaries.arr, sec_uuid)) { - _notify(setting, PROP_SECONDARIES); - return TRUE; - } - return FALSE; + if (!nm_strvarray_remove_first(priv->secondaries.arr, sec_uuid)) + return FALSE; + + _notify(setting, PROP_SECONDARIES); + return TRUE; } /** @@ -1065,7 +1124,7 @@ _nm_connection_detect_slave_type_full(NMSettingConnection *s_con, is_slave = FALSE; slave_setting_type = NULL; - slave_type = priv->slave_type; + slave_type = priv->port_type; if (slave_type) { is_slave = _nm_setting_slave_type_is_valid(slave_type, &slave_setting_type); if (!is_slave) { @@ -1077,22 +1136,22 @@ _nm_connection_detect_slave_type_full(NMSettingConnection *s_con, g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } if (is_slave) { - if (!priv->master) { + if (!priv->controller) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, _("Slave connections need a valid '%s' property"), - NM_SETTING_CONNECTION_MASTER); + NM_SETTING_CONNECTION_CONTROLLER); g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER); + NM_SETTING_CONNECTION_CONTROLLER); return FALSE; } if (slave_setting_type && connection @@ -1100,7 +1159,7 @@ _nm_connection_detect_slave_type_full(NMSettingConnection *s_con, normerr_slave_setting_type = slave_setting_type; } else { nm_assert(!slave_type); - if (priv->master) { + if (priv->controller) { NMSetting *s_port; if (connection @@ -1112,12 +1171,12 @@ _nm_connection_detect_slave_type_full(NMSettingConnection *s_con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, _("Cannot set '%s' without '%s'"), - NM_SETTING_CONNECTION_MASTER, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_CONTROLLER, + NM_SETTING_CONNECTION_PORT_TYPE); g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } @@ -1328,7 +1387,7 @@ after_interface_name: g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } @@ -1545,8 +1604,8 @@ after_interface_name: g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, - _("slave-type '%s' requires a '%s' setting in the connection"), - priv->slave_type, + _("port-type '%s' requires a '%s' setting in the connection"), + priv->port_type, normerr_slave_setting_type); g_prefix_error(error, "%s: ", normerr_slave_setting_type); return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; @@ -1558,39 +1617,39 @@ after_interface_name: NM_CONNECTION_ERROR_MISSING_PROPERTY, _("Detect a slave connection with '%s' set and a port type '%s'. '%s' should " "be set to '%s'"), - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, normerr_missing_slave_type_port, - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, normerr_missing_slave_type); g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } if (connection) { gboolean has_bridge_port = FALSE; - if ((!nm_streq0(priv->slave_type, NM_SETTING_BRIDGE_SETTING_NAME) + if ((!nm_streq0(priv->port_type, NM_SETTING_BRIDGE_SETTING_NAME) && (has_bridge_port = !!nm_connection_get_setting_by_name(connection, NM_SETTING_BRIDGE_PORT_SETTING_NAME))) - || (!nm_streq0(priv->slave_type, NM_SETTING_TEAM_SETTING_NAME) + || (!nm_streq0(priv->port_type, NM_SETTING_TEAM_SETTING_NAME) && nm_connection_get_setting_by_name(connection, NM_SETTING_TEAM_PORT_SETTING_NAME))) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, _("A slave connection with '%s' set to '%s' cannot have a '%s' setting"), - NM_SETTING_CONNECTION_SLAVE_TYPE, - priv->slave_type ?: "", + NM_SETTING_CONNECTION_PORT_TYPE, + priv->port_type ?: "", has_bridge_port ? NM_SETTING_BRIDGE_PORT_SETTING_NAME : NM_SETTING_TEAM_PORT_SETTING_NAME); g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } } @@ -1775,6 +1834,126 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /*****************************************************************************/ +gboolean +_nm_setting_connection_master_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) +{ + const char *str; + + if (!_nm_setting_use_legacy_property(setting, + connection_dict, + NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER)) { + *out_is_modified = FALSE; + return TRUE; + } + str = g_variant_get_string(value, NULL); + + g_object_set(setting, NM_SETTING_CONNECTION_MASTER, str, NULL); + return TRUE; +} + +GVariant * +_nm_setting_connection_controller_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil) +{ + const char *controller; + + /* FIXME: `controller` is an alias of `master` property. Serializing the + * property to the clients would break them as they won't be able to drop + * it if they are not aware of the existance of `controller`. In order to + * give them time to adapt their code, NetworkManager is not serializing + * `controller` on DBus. + */ + if (_nm_utils_is_manager_process) { + return NULL; + } + + controller = nm_setting_connection_get_controller(NM_SETTING_CONNECTION(setting)); + if (!controller) + return NULL; + + return g_variant_new_string(controller); +} + +gboolean +_nm_setting_connection_controller_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) +{ + const char *str; + + /* Ignore 'controller' if we're going to process 'master' */ + if (_nm_setting_use_legacy_property(setting, + connection_dict, + NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER)) { + *out_is_modified = FALSE; + return TRUE; + } + str = g_variant_get_string(value, NULL); + + g_object_set(setting, NM_SETTING_CONNECTION_CONTROLLER, str, NULL); + return TRUE; +} + +gboolean +_nm_setting_connection_slave_type_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) +{ + const char *str; + + if (!_nm_setting_use_legacy_property(setting, + connection_dict, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE)) { + *out_is_modified = FALSE; + return TRUE; + } + str = g_variant_get_string(value, NULL); + + g_object_set(setting, NM_SETTING_CONNECTION_SLAVE_TYPE, str, NULL); + return TRUE; +} + +GVariant * +_nm_setting_connection_port_type_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil) +{ + const char *port_type; + + /* FIXME: `port-type` is an alias of `slave-type` property. Serializing the + * property to the clients would break them as they won't be able to drop + * it if they are not aware of the existance of `port-type`. In order to + * give them time to adapt their code, NetworkManager is not serializing + * `port-type` on DBus. + */ + if (_nm_utils_is_manager_process) { + return NULL; + } + + port_type = nm_setting_connection_get_port_type(NM_SETTING_CONNECTION(setting)); + if (!port_type) + return NULL; + + return g_variant_new_string(port_type); +} + +gboolean +_nm_setting_connection_port_type_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) +{ + const char *str; + + /* Ignore 'port-type' if we're going to process 'slave-type' */ + if (_nm_setting_use_legacy_property(setting, + connection_dict, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE)) { + *out_is_modified = FALSE; + return TRUE; + } + str = g_variant_get_string(value, NULL); + + g_object_set(setting, NM_SETTING_CONNECTION_PORT_TYPE, str, NULL); + return TRUE; +} + +/*****************************************************************************/ + static void nm_setting_connection_init(NMSettingConnection *setting) {} @@ -1798,7 +1977,6 @@ finalize(GObject *object) NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE(object); nm_clear_pointer(&priv->permissions, g_array_unref); - nm_clear_pointer(&priv->secondaries.arr, g_array_unref); G_OBJECT_CLASS(nm_setting_connection_parent_class)->finalize(object); } @@ -1808,9 +1986,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray *properties_override = _nm_sett_info_property_override_create_array(); - - g_type_class_add_private(klass, sizeof(NMSettingConnectionPrivate)); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(35); + guint prop_idx; object_class->get_property = get_property; object_class->set_property = set_property; @@ -1915,13 +2092,15 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * * The '$' character is treated special to perform dynamic substitutions at * activation time. Currently, supported are "${CONNECTION}", "${DEVICE}", - * "${MAC}", "${BOOT}", "${RANDOM}". These effectively create unique IDs - * per-connection, per-device, per-boot, or every time. The "${CONNECTION}" - * uses the profile's connection.uuid, the "${DEVICE}" uses the interface - * name of the device and "${MAC}" the permanent MAC address of the device. - * Any unrecognized patterns following '$' are treated verbatim, however - * are reserved for future use. You are thus advised to avoid '$' or escape - * it as "$$". For example, set it to "${CONNECTION}-${BOOT}-${DEVICE}" to + * "${MAC}", "${NETWORK_SSID}", "${BOOT}", "${RANDOM}". These effectively + * create unique IDs per-connection, per-device, per-SSID, per-boot, or + * every time. The "${CONNECTION}" uses the profile's connection.uuid, the + * "${DEVICE}" uses the interface name of the device and "${MAC}" the + * permanent MAC address of the device. "${NETWORK_SSID}" uses the SSID for + * Wi-Fi networks and falls back to "${CONNECTION}" on other networks. Any + * unrecognized patterns following '$' are treated verbatim, however are + * reserved for future use. You are thus advised to avoid '$' or escape it + * as "$$". For example, set it to "${CONNECTION}-${BOOT}-${DEVICE}" to * create a unique id for this connection that changes with every reboot * and differs depending on the interface where the profile activates. * @@ -1943,7 +2122,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) PROP_STABLE_ID, NM_SETTING_PARAM_FUZZY_IGNORE, NMSettingConnectionPrivate, - stable_id); + stable_id, + .direct_string_allow_empty = TRUE); /** * NMSettingConnection:interface-name: @@ -1984,7 +2164,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) .from_dbus_is_full = TRUE, .from_dbus_direct_allow_transform = TRUE), NMSettingConnectionPrivate, - interface_name); + interface_name, + .direct_string_allow_empty = TRUE); /** * NMSettingConnection:type: @@ -2011,7 +2192,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NM_SETTING_PARAM_INFERRABLE, NMSettingConnectionPrivate, type, - .direct_string_is_refstr = TRUE); + .direct_string_is_refstr = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingConnection:permissions: @@ -2038,12 +2220,11 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * example: USERS="joe bob" * ---end--- */ - obj_properties[PROP_PERMISSIONS] = - g_param_spec_boxed(NM_SETTING_CONNECTION_PERMISSIONS, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_CONNECTION_PERMISSIONS, + PROP_PERMISSIONS, + NM_SETTING_PARAM_NONE); /** * NMSettingConnection:autoconnect: @@ -2244,12 +2425,15 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY, NMSettingConnectionPrivate, - zone); + zone, + .direct_string_allow_empty = TRUE); /** * NMSettingConnection:master: * * Interface name of the master device or UUID of the master connection. + * + * Deprecated 1.46. Use #NMSettingConnection:controller instead, this is just an alias. **/ /* ---ifcfg-rh--- * property: master @@ -2260,14 +2444,46 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * for compatibility with legacy tooling. * ---end--- */ - _nm_setting_property_define_direct_string(properties_override, - obj_properties, - NM_SETTING_CONNECTION_MASTER, - PROP_MASTER, - NM_SETTING_PARAM_FUZZY_IGNORE - | NM_SETTING_PARAM_INFERRABLE, - NMSettingConnectionPrivate, - master); + prop_idx = _nm_setting_property_define_direct_string_full( + properties_override, + obj_properties, + NM_SETTING_CONNECTION_MASTER, + PROP_MASTER, + NM_SETTING_PARAM_INFERRABLE | NM_SETTING_PARAM_FUZZY_IGNORE, + 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 = _nm_setting_connection_master_from_dbus, ), + NMSettingConnectionPrivate, + controller, + .direct_string_allow_empty = TRUE, + .is_deprecated = TRUE); + + /** + * NMSettingConnection:controller: + * + * Interface name of the controller device or UUID of the controller connection. + **/ + _nm_setting_property_define_direct_string_full( + properties_override, + obj_properties, + NM_SETTING_CONNECTION_CONTROLLER, + PROP_CONTROLLER, + NM_SETTING_PARAM_INFERRABLE | NM_SETTING_PARAM_FUZZY_IGNORE, + 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_connection_controller_to_dbus, + .from_dbus_fcn = + _nm_setting_connection_controller_from_dbus), + NMSettingConnectionPrivate, + controller, + .direct_string_allow_empty = TRUE, + .direct_also_notify = obj_properties[PROP_MASTER]); + + nm_g_array_index(properties_override, NMSettInfoProperty, prop_idx).direct_also_notify = + obj_properties[PROP_CONTROLLER]; /** * NMSettingConnection:slave-type: @@ -2275,6 +2491,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * Setting name of the device type of this slave's master connection (eg, * %NM_SETTING_BOND_SETTING_NAME), or %NULL if this connection is not a * slave. + * + * Deprecated 1.46. Use #NMSettingConnection:port-type instead, this is just an alias. **/ /* ---ifcfg-rh--- * property: slave-type @@ -2286,14 +2504,51 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * and BRIDGE_UUID for bridging. * ---end--- */ - _nm_setting_property_define_direct_string(properties_override, - obj_properties, - NM_SETTING_CONNECTION_SLAVE_TYPE, - PROP_SLAVE_TYPE, - NM_SETTING_PARAM_FUZZY_IGNORE - | NM_SETTING_PARAM_INFERRABLE, - NMSettingConnectionPrivate, - slave_type); + prop_idx = _nm_setting_property_define_direct_string_full( + properties_override, + obj_properties, + NM_SETTING_CONNECTION_SLAVE_TYPE, + PROP_SLAVE_TYPE, + NM_SETTING_PARAM_FUZZY_IGNORE | 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, + .from_dbus_fcn = + _nm_setting_connection_slave_type_from_dbus, ), + NMSettingConnectionPrivate, + port_type, + .is_deprecated = 1, + .direct_string_allow_empty = TRUE); + + /** + * NMSettingConnection:port-type: + * + * Setting name of the device type of this port's controller connection (eg, + * %NM_SETTING_BOND_SETTING_NAME), or %NULL if this connection is not a + * port. + * + * Since: 1.46 + **/ + _nm_setting_property_define_direct_string_full( + properties_override, + obj_properties, + NM_SETTING_CONNECTION_PORT_TYPE, + PROP_PORT_TYPE, + NM_SETTING_PARAM_FUZZY_IGNORE | 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_connection_port_type_to_dbus, + .from_dbus_fcn = + _nm_setting_connection_port_type_from_dbus, ), + NMSettingConnectionPrivate, + port_type, + .direct_string_allow_empty = TRUE, + .direct_also_notify = obj_properties[PROP_SLAVE_TYPE]); + + nm_g_array_index(properties_override, NMSettInfoProperty, prop_idx).direct_also_notify = + obj_properties[PROP_PORT_TYPE]; /** * NMSettingConnection:autoconnect-slaves: @@ -2740,7 +2995,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) PROP_MUD_URL, NM_SETTING_PARAM_NONE, NMSettingConnectionPrivate, - mud_url); + mud_url, + .direct_string_allow_empty = TRUE); /** * NMSettingConnection:wait-activation-delay: @@ -2779,5 +3035,5 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NM_META_SETTING_TYPE_CONNECTION, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingConnection, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-dcb.c b/src/libnm-core-impl/nm-setting-dcb.c index d6890891..c59ee8b4 100644 --- a/src/libnm-core-impl/nm-setting-dcb.c +++ b/src/libnm-core-impl/nm-setting-dcb.c @@ -71,20 +71,17 @@ typedef struct { * Data Center Bridging Settings */ struct _NMSettingDcb { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingDcbPrivate _priv; }; struct _NMSettingDcbClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING) -#define NM_SETTING_DCB_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate)) +#define NM_SETTING_DCB_GET_PRIVATE(o) _NM_GET_PRIVATE(o, NMSettingDcb, NM_IS_SETTING_DCB, NMSetting) /*****************************************************************************/ @@ -845,8 +842,6 @@ nm_setting_dcb_class_init(NMSettingDcbClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingDcbPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; @@ -925,7 +920,8 @@ nm_setting_dcb_class_init(NMSettingDcbClass *klass) PROP_APP_FCOE_MODE, NM_SETTING_PARAM_NONE, NMSettingDcbPrivate, - app_fcoe_mode); + app_fcoe_mode, + .direct_string_allow_empty = TRUE); /** * NMSettingDcb:app-iscsi-flags: @@ -1230,5 +1226,5 @@ nm_setting_dcb_class_init(NMSettingDcbClass *klass) NM_META_SETTING_TYPE_DCB, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingDcb, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-dummy.c b/src/libnm-core-impl/nm-setting-dummy.c index bfc82aea..c37b8c08 100644 --- a/src/libnm-core-impl/nm-setting-dummy.c +++ b/src/libnm-core-impl/nm-setting-dummy.c @@ -28,13 +28,10 @@ */ struct _NMSettingDummy { NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ }; struct _NMSettingDummyClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingDummy, nm_setting_dummy, NM_TYPE_SETTING) diff --git a/src/libnm-core-impl/nm-setting-ethtool.c b/src/libnm-core-impl/nm-setting-ethtool.c index ab1ed0e2..06c9c12b 100644 --- a/src/libnm-core-impl/nm-setting-ethtool.c +++ b/src/libnm-core-impl/nm-setting-ethtool.c @@ -76,6 +76,37 @@ nm_ethtool_optname_is_ring(const char *optname) } /** + * nm_ethtool_optname_is_channels: + * @optname: (nullable): the option name to check + * + * Checks whether @optname is a valid option name for a channels setting. + * + * Returns: %TRUE, if @optname is valid + * + * Since: 1.46 + */ +gboolean +nm_ethtool_optname_is_channels(const char *optname) +{ + return optname && nm_ethtool_id_is_channels(nm_ethtool_id_get_by_name(optname)); +} + +/** + * nm_ethtool_optname_is_eee: + * @optname: (nullable): the option name to check + * + * Checks whether @optname is a valid option name for an eee setting. + * + * Returns: %TRUE, if @optname is valid + * + * Since: 1.46 + */ +gboolean +nm_ethtool_optname_is_eee(const char *optname) +{ + return optname && nm_ethtool_id_is_eee(nm_ethtool_id_get_by_name(optname)); +} +/** * nm_ethtool_optname_is_pause: * @optname: (nullable): the option name to check * diff --git a/src/libnm-core-impl/nm-setting-generic.c b/src/libnm-core-impl/nm-setting-generic.c index ce212554..6623e71f 100644 --- a/src/libnm-core-impl/nm-setting-generic.c +++ b/src/libnm-core-impl/nm-setting-generic.c @@ -23,10 +23,6 @@ /*****************************************************************************/ -typedef struct { - int dummy; -} NMSettingGenericPrivate; - /** * NMSettingGeneric: * @@ -34,20 +30,14 @@ typedef struct { */ struct _NMSettingGeneric { NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ }; struct _NMSettingGenericClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING) -#define NM_SETTING_GENERIC_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_GENERIC, NMSettingGenericPrivate)) - /*****************************************************************************/ static void @@ -72,7 +62,5 @@ nm_setting_generic_class_init(NMSettingGenericClass *klass) { NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - g_type_class_add_private(klass, sizeof(NMSettingGenericPrivate)); - _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_GENERIC, NULL, NULL, 0); } diff --git a/src/libnm-core-impl/nm-setting-gsm.c b/src/libnm-core-impl/nm-setting-gsm.c index 4dde515a..632b0ccc 100644 --- a/src/libnm-core-impl/nm-setting-gsm.c +++ b/src/libnm-core-impl/nm-setting-gsm.c @@ -65,20 +65,17 @@ typedef struct { * GSM-based Mobile Broadband Settings */ struct _NMSettingGsm { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingGsmPrivate _priv; }; struct _NMSettingGsmClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING) -#define NM_SETTING_GSM_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_GSM, NMSettingGsmPrivate)) +#define NM_SETTING_GSM_GET_PRIVATE(o) _NM_GET_PRIVATE(o, NMSettingGsm, NM_IS_SETTING_GSM, NMSetting) /*****************************************************************************/ @@ -565,8 +562,6 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingGsmPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -607,7 +602,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, number, - .is_deprecated = TRUE, ); + .is_deprecated = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:username: @@ -622,7 +618,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_USERNAME, NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, - username); + username, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:password: @@ -637,7 +634,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSettingGsmPrivate, - password); + password, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:password-flags: @@ -660,6 +658,10 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) * is important to use the correct APN for the user's mobile broadband plan. * The APN may only be composed of the characters a-z, 0-9, ., and - per GSM * 03.60 Section 14.9. + * + * If the APN is unset (the default) then it may be detected based on + * "auto-config" setting. The property can be explicitly set to the + * empty string to prevent that and use no APN. **/ _nm_setting_property_define_direct_string(properties_override, obj_properties, @@ -668,7 +670,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, apn, - .direct_set_string_strip = TRUE); + .direct_set_string_strip = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:network-id: @@ -686,7 +689,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, network_id, - .direct_set_string_strip = TRUE); + .direct_set_string_strip = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:pin: @@ -701,7 +705,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_PIN, NM_SETTING_PARAM_SECRET, NMSettingGsmPrivate, - pin); + pin, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:pin-flags: @@ -745,7 +750,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_DEVICE_ID, NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, - device_id); + device_id, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:sim-id: @@ -763,7 +769,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_SIM_ID, NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, - sim_id); + sim_id, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:sim-operator-id: @@ -782,7 +789,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_SIM_OPERATOR_ID, NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, - sim_operator_id); + sim_operator_id, + .direct_string_allow_empty = TRUE); /** * NMSettingGsm:mtu: @@ -836,7 +844,8 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) PROP_INITIAL_EPS_APN, NM_SETTING_PARAM_NONE, NMSettingGsmPrivate, - initial_eps_apn); + initial_eps_apn, + .direct_string_allow_empty = TRUE); /* Ignore incoming deprecated properties */ _nm_properties_override_dbus(properties_override, @@ -854,5 +863,5 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) NM_META_SETTING_TYPE_GSM, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingGsm, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-hsr.c b/src/libnm-core-impl/nm-setting-hsr.c new file mode 100644 index 00000000..d9a662b1 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-hsr.c @@ -0,0 +1,266 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-hsr.h" + +#include <linux/if_ether.h> + +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-hsr + * @short_description: Describes connection properties for HSR/PRP interfaces + * + * The #NMSettingHsr object is a #NMSetting subclass that describes properties + * necessary for HSR/PRP connections. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr, PROP_PORT1, PROP_PORT2, PROP_MULTICAST_SPEC, PROP_PRP, ); + +typedef struct { + char *port1; + char *port2; + guint32 multicast_spec; + bool prp; +} NMSettingHsrPrivate; + +/** + * NMSettingHsr: + * + * HSR/PRP Settings + */ +struct _NMSettingHsr { + NMSetting parent; + NMSettingHsrPrivate _priv; +}; + +struct _NMSettingHsrClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingHsr, nm_setting_hsr, NM_TYPE_SETTING) + +#define NM_SETTING_HSR_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingHsr, NM_IS_SETTING_HSR, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_hsr_get_port1: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:port1 property of the setting + * + * Since: 1.46 + **/ +const char * +nm_setting_hsr_get_port1(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->port1; +} + +/** + * nm_setting_hsr_get_port2: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:port2 property of the setting + * + * Since: 1.46 + **/ +const char * +nm_setting_hsr_get_port2(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->port2; +} + +/** + * nm_setting_hsr_get_multicast_spec: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:multicast_spec property of the setting + * + * Since: 1.46 + **/ +guint32 +nm_setting_hsr_get_multicast_spec(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), 0); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->multicast_spec; +} + +/** + * nm_setting_hsr_get_prp: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:prp property of the setting + * + * Since: 1.46 + **/ +gboolean +nm_setting_hsr_get_prp(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), FALSE); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->prp; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingHsrPrivate *priv = NM_SETTING_HSR_GET_PRIVATE(setting); + + if (!priv->port1) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT1); + return FALSE; + } + if (!nm_utils_ifname_valid(priv->port1, NMU_IFACE_KERNEL, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + priv->port1); + g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT1); + return FALSE; + } + + if (!priv->port2) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT2); + return FALSE; + } + if (!nm_utils_ifname_valid(priv->port2, NMU_IFACE_KERNEL, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + priv->port2); + g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT2); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +nm_setting_hsr_init(NMSettingHsr *setting) +{} + +/** + * nm_setting_hsr_new: + * + * Creates a new #NMSettingHsr object with default values. + * + * Returns: (transfer full): the new empty #NMSettingHsr object + * + * Since: 1.46 + **/ +NMSetting * +nm_setting_hsr_new(void) +{ + return g_object_new(NM_TYPE_SETTING_HSR, NULL); +} + +static void +nm_setting_hsr_class_init(NMSettingHsrClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray *properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = _nm_setting_property_get_property_direct; + object_class->set_property = _nm_setting_property_set_property_direct; + + setting_class->verify = verify; + + /** + * NMSettingHsr:port1: + * + * The port1 interface name of the HSR. This property is mandatory. + * + * Since: 1.46 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_HSR_PORT1, + PROP_PORT1, + NM_SETTING_PARAM_INFERRABLE, + NMSettingHsr, + _priv.port1); + + /** + * NMSettingHsr:port2: + * + * The port2 interface name of the HSR. This property is mandatory. + * + * Since: 1.46 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_HSR_PORT2, + PROP_PORT2, + NM_SETTING_PARAM_INFERRABLE, + NMSettingHsr, + _priv.port2); + + /** + * NMSettingHsr:multicast-spec: + * + * The last byte of supervision address. + * + * Since: 1.46 + **/ + _nm_setting_property_define_direct_uint32(properties_override, + obj_properties, + NM_SETTING_HSR_MULTICAST_SPEC, + PROP_MULTICAST_SPEC, + 0, + G_MAXUINT8, + 0, + NM_SETTING_PARAM_INFERRABLE, + NMSettingHsr, + _priv.multicast_spec); + + /** + * NMSettingHsr:prp: + * + * The protocol used by the interface, whether it is PRP or HSR. + * + * Since: 1.46 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_HSR_PRP, + PROP_PRP, + FALSE, + NM_SETTING_PARAM_INFERRABLE, + NMSettingHsr, + _priv.prp); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HSR, NULL, properties_override, 0); +} diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c index a0d5578c..203e4b2b 100644 --- a/src/libnm-core-impl/nm-setting-infiniband.c +++ b/src/libnm-core-impl/nm-setting-infiniband.c @@ -47,20 +47,18 @@ typedef struct { * Infiniband Settings */ struct _NMSettingInfiniband { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingInfinibandPrivate _priv; }; struct _NMSettingInfinibandClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingInfiniband, nm_setting_infiniband, NM_TYPE_SETTING) #define NM_SETTING_INFINIBAND_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandPrivate)) + _NM_GET_PRIVATE(o, NMSettingInfiniband, NM_IS_SETTING_INFINIBAND, NMSetting) /*****************************************************************************/ @@ -332,8 +330,6 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingInfinibandPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -418,7 +414,8 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) PROP_TRANSPORT_MODE, NM_SETTING_PARAM_INFERRABLE, NMSettingInfinibandPrivate, - transport_mode); + transport_mode, + .direct_string_allow_empty = TRUE); /** * NMSettingInfiniband:p-key: @@ -484,7 +481,8 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingInfinibandPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); @@ -492,5 +490,5 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) NM_META_SETTING_TYPE_INFINIBAND, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingInfiniband, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index 727a4bae..bfebe7d1 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -52,6 +52,8 @@ const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[] = { {NM_SETTING_DNS_OPTION_NO_RELOAD, FALSE, FALSE}, {NM_SETTING_DNS_OPTION_TRUST_AD, FALSE, FALSE}, {NM_SETTING_DNS_OPTION_NO_AAAA, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_INTERNAL_NO_ADD_EDNS0, FALSE, FALSE}, + {NM_SETTING_DNS_OPTION_INTERNAL_NO_ADD_TRUST_AD, FALSE, FALSE}, {NULL, FALSE, FALSE}}; static char * @@ -4014,7 +4016,7 @@ _NM_SETTING_IP_CONFIG_GET_PRIVATE(NMSettingIPConfig *self) klass = NM_SETTING_IP_CONFIG_GET_CLASS(self); - nm_assert(klass->private_offset < 0); + nm_assert(klass->private_offset > 0); return (gpointer) (((char *) ((gpointer) self)) + klass->private_offset); } @@ -4229,7 +4231,7 @@ nm_setting_ip_config_get_num_dns_searches(NMSettingIPConfig *setting) { g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); - return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_search->len; + return nm_g_array_len(NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_search.arr); } /** @@ -4237,19 +4239,18 @@ nm_setting_ip_config_get_num_dns_searches(NMSettingIPConfig *setting) * @setting: the #NMSettingIPConfig * @idx: index number of the DNS search domain to return * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the DNS search domain at index @idx **/ const char * nm_setting_ip_config_get_dns_search(NMSettingIPConfig *setting, int idx) { - NMSettingIPConfigPrivate *priv; - g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_val_if_fail(idx >= 0 && idx < priv->dns_search->len, NULL); - - return priv->dns_search->pdata[idx]; + return nm_strvarray_get_idxnull_or_greturn( + NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_search.arr, + idx); } /** @@ -4266,19 +4267,16 @@ gboolean nm_setting_ip_config_add_dns_search(NMSettingIPConfig *setting, const char *dns_search) { NMSettingIPConfigPrivate *priv; - guint i; g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); g_return_val_if_fail(dns_search != NULL, FALSE); g_return_val_if_fail(dns_search[0] != '\0', FALSE); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - for (i = 0; i < priv->dns_search->len; i++) { - if (!strcmp(dns_search, priv->dns_search->pdata[i])) - return FALSE; - } - g_ptr_array_add(priv->dns_search, g_strdup(dns_search)); + if (!nm_strvarray_ensure_and_add_unique(&priv->dns_search.arr, dns_search)) + return FALSE; + _notify(setting, PROP_DNS_SEARCH); return TRUE; } @@ -4298,9 +4296,10 @@ nm_setting_ip_config_remove_dns_search(NMSettingIPConfig *setting, int idx) g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_if_fail(idx >= 0 && idx < priv->dns_search->len); - g_ptr_array_remove_index(priv->dns_search, idx); + g_return_if_fail(idx >= 0 && idx < nm_g_array_len(priv->dns_search.arr)); + + nm_strvarray_remove_index(priv->dns_search.arr, idx); _notify(setting, PROP_DNS_SEARCH); } @@ -4317,21 +4316,18 @@ gboolean nm_setting_ip_config_remove_dns_search_by_value(NMSettingIPConfig *setting, const char *dns_search) { NMSettingIPConfigPrivate *priv; - guint i; g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), FALSE); g_return_val_if_fail(dns_search != NULL, FALSE); g_return_val_if_fail(dns_search[0] != '\0', FALSE); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - for (i = 0; i < priv->dns_search->len; i++) { - if (!strcmp(dns_search, priv->dns_search->pdata[i])) { - g_ptr_array_remove_index(priv->dns_search, i); - _notify(setting, PROP_DNS_SEARCH); - return TRUE; - } - } - return FALSE; + + if (!nm_strvarray_remove_first(priv->dns_search.arr, dns_search)) + return FALSE; + + _notify(setting, PROP_DNS_SEARCH); + return TRUE; } /** @@ -4343,16 +4339,16 @@ nm_setting_ip_config_remove_dns_search_by_value(NMSettingIPConfig *setting, cons void nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting) { - NMSettingIPConfigPrivate *priv; - g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - - if (priv->dns_search->len != 0) { - g_ptr_array_set_size(priv->dns_search, 0); + if (nm_strvarray_clear(&NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_search.arr)) _notify(setting, PROP_DNS_SEARCH); - } +} + +static gssize +_dns_option_find_idx_garray(const GArray *arr, const char *option) +{ + return _nm_utils_dns_option_find_idx(nm_g_array_data(arr), nm_g_array_len(arr), option); } /** @@ -4366,13 +4362,9 @@ nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting) guint nm_setting_ip_config_get_num_dns_options(NMSettingIPConfig *setting) { - NMSettingIPConfigPrivate *priv; - g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - - return priv->dns_options ? priv->dns_options->len : 0; + return nm_g_array_len(NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr); } /** @@ -4394,7 +4386,7 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) { g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); - return !!NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options; + return !!NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr; } /** @@ -4402,6 +4394,8 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) * @setting: the #NMSettingIPConfig * @idx: index number of the DNS option * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the DNS option at index @idx * * Since: 1.2 @@ -4409,15 +4403,11 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) const char * nm_setting_ip_config_get_dns_option(NMSettingIPConfig *setting, guint idx) { - NMSettingIPConfigPrivate *priv; - g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_val_if_fail(priv->dns_options, NULL); - g_return_val_if_fail(idx < priv->dns_options->len, NULL); - - return priv->dns_options->pdata[idx]; + return nm_strvarray_get_idxnull_or_greturn( + NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr, + idx); } /** @@ -4437,14 +4427,14 @@ nm_setting_ip_config_next_valid_dns_option(NMSettingIPConfig *setting, guint idx priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) + if (!priv->dns_options.arr) return -1; - for (; idx < priv->dns_options->len; idx++) { - if (_nm_utils_dns_option_validate(priv->dns_options->pdata[idx], + for (; idx < priv->dns_options.arr->len; idx++) { + if (_nm_utils_dns_option_validate(nm_strvarray_get_idx(priv->dns_options.arr, idx), NULL, NULL, - NM_IS_SETTING_IP6_CONFIG(setting), + NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), _nm_utils_dns_option_descs)) return idx; } @@ -4472,18 +4462,15 @@ nm_setting_ip_config_add_dns_option(NMSettingIPConfig *setting, const char *dns_ g_return_val_if_fail(dns_option != NULL, FALSE); g_return_val_if_fail(dns_option[0] != '\0', FALSE); - if (!_nm_utils_dns_option_validate(dns_option, NULL, NULL, FALSE, NULL)) + if (!_nm_utils_dns_option_validate(dns_option, NULL, NULL, AF_UNSPEC, NULL)) return FALSE; priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) - priv->dns_options = g_ptr_array_new_with_free_func(g_free); - else { - if (_nm_utils_dns_option_find_idx(priv->dns_options, dns_option) >= 0) - return FALSE; - } - g_ptr_array_add(priv->dns_options, g_strdup(dns_option)); + if (_dns_option_find_idx_garray(priv->dns_options.arr, dns_option) >= 0) + return FALSE; + + nm_strvarray_ensure_and_add(&priv->dns_options.arr, dns_option); _notify(setting, PROP_DNS_OPTIONS); return TRUE; } @@ -4505,10 +4492,10 @@ nm_setting_ip_config_remove_dns_option(NMSettingIPConfig *setting, int idx) g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_if_fail(priv->dns_options); - g_return_if_fail(idx >= 0 && idx < priv->dns_options->len); - g_ptr_array_remove_index(priv->dns_options, idx); + g_return_if_fail(idx >= 0 && idx < nm_g_array_len(priv->dns_options.arr)); + + nm_strvarray_remove_index(priv->dns_options.arr, idx); _notify(setting, PROP_DNS_OPTIONS); } @@ -4534,17 +4521,14 @@ nm_setting_ip_config_remove_dns_option_by_value(NMSettingIPConfig *setting, cons g_return_val_if_fail(dns_option[0] != '\0', FALSE); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) - return FALSE; - i = _nm_utils_dns_option_find_idx(priv->dns_options, dns_option); - if (i >= 0) { - g_ptr_array_remove_index(priv->dns_options, i); - _notify(setting, PROP_DNS_OPTIONS); - return TRUE; - } + i = _dns_option_find_idx_garray(priv->dns_options.arr, dns_option); + if (i < 0) + return FALSE; - return FALSE; + nm_strvarray_remove_index(priv->dns_options.arr, i); + _notify(setting, PROP_DNS_OPTIONS); + return TRUE; } /** @@ -4565,18 +4549,17 @@ nm_setting_ip_config_clear_dns_options(NMSettingIPConfig *setting, gboolean is_s g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) { + if (!priv->dns_options.arr) { if (!is_set) return; - priv->dns_options = g_ptr_array_new_with_free_func(g_free); + nm_strvarray_ensure(&priv->dns_options.arr); } else { - if (!is_set) { - g_ptr_array_unref(priv->dns_options); - priv->dns_options = NULL; - } else { - if (priv->dns_options->len == 0) + if (!is_set) + nm_strvarray_clear(&priv->dns_options.arr); + else { + if (priv->dns_options.arr->len == 0) return; - g_ptr_array_set_size(priv->dns_options, 0); + g_array_set_size(priv->dns_options.arr, 0); } } _notify(setting, PROP_DNS_OPTIONS); @@ -5361,8 +5344,10 @@ const char *const * nm_setting_ip_config_get_dhcp_reject_servers(NMSettingIPConfig *setting, guint *out_len) { g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); - return nm_strvarray_get_strv(&NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_reject_servers, - out_len); + + return nm_strvarray_get_strv_notnull( + NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_reject_servers.arr, + out_len); } /** @@ -5377,13 +5362,11 @@ nm_setting_ip_config_get_dhcp_reject_servers(NMSettingIPConfig *setting, guint * void nm_setting_ip_config_add_dhcp_reject_server(NMSettingIPConfig *setting, const char *server) { - NMSettingIPConfigPrivate *priv; - g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); - g_return_if_fail(server != NULL); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + g_return_if_fail(server); - nm_strvarray_add(nm_strvarray_ensure(&priv->dhcp_reject_servers), server); + nm_strvarray_ensure_and_add(&NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_reject_servers.arr, + server); _notify(setting, PROP_DHCP_REJECT_SERVERS); } @@ -5402,10 +5385,12 @@ nm_setting_ip_config_remove_dhcp_reject_server(NMSettingIPConfig *setting, guint NMSettingIPConfigPrivate *priv; g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_if_fail(priv->dhcp_reject_servers && idx < priv->dhcp_reject_servers->len); - g_array_remove_index(priv->dhcp_reject_servers, idx); + g_return_if_fail(idx < nm_g_array_len(priv->dhcp_reject_servers.arr)); + + nm_strvarray_remove_index(priv->dhcp_reject_servers.arr, idx); _notify(setting, PROP_DHCP_REJECT_SERVERS); } @@ -5420,15 +5405,10 @@ nm_setting_ip_config_remove_dhcp_reject_server(NMSettingIPConfig *setting, guint void nm_setting_ip_config_clear_dhcp_reject_servers(NMSettingIPConfig *setting) { - NMSettingIPConfigPrivate *priv; - g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (nm_g_array_len(priv->dhcp_reject_servers) != 0) { - nm_clear_pointer(&priv->dhcp_reject_servers, g_array_unref); + if (nm_strvarray_clear(&NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_reject_servers.arr)) _notify(setting, PROP_DHCP_REJECT_SERVERS); - } } /** @@ -5718,7 +5698,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } /* Validate reject servers */ - if (priv->dhcp_reject_servers && priv->dhcp_reject_servers->len != 0) { + if (priv->dhcp_reject_servers.arr && priv->dhcp_reject_servers.arr->len > 0) { if (NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting) != AF_INET) { g_set_error_literal(error, NM_CONNECTION_ERROR, @@ -5731,17 +5711,17 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - for (i = 0; i < priv->dhcp_reject_servers->len; i++) { + for (i = 0; i < priv->dhcp_reject_servers.arr->len; i++) { if (!nm_inet_parse_with_prefix_str( NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), - nm_g_array_index(priv->dhcp_reject_servers, const char *, i), + nm_g_array_index(priv->dhcp_reject_servers.arr, const char *, i), NULL, NULL)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid IP or subnet"), - nm_g_array_index(priv->dhcp_reject_servers, const char *, i)); + nm_g_array_index(priv->dhcp_reject_servers.arr, const char *, i)); g_prefix_error(error, "%s.%s: ", nm_setting_get_name(setting), @@ -5963,7 +5943,7 @@ dns_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) GArray * _nm_sett_info_property_override_create_array_ip_config(int addr_family) { - GArray *properties_override = _nm_sett_info_property_override_create_array(); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(45); nm_assert_addr_family(addr_family); @@ -5971,7 +5951,8 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) properties_override, obj_properties[PROP_METHOD], &nm_sett_info_propert_type_direct_string, - .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, method)); + .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, method), + .direct_string_allow_empty = TRUE); _nm_properties_override_gobj( properties_override, @@ -5984,20 +5965,23 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_direct_ip_config_gateway), .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, gateway), .direct_set_string_ip_address_addr_family = addr_family + 1, - .direct_set_string_ip_address_addr_family_map_zero_to_null = TRUE); + .direct_set_string_ip_address_addr_family_map_zero_to_null = TRUE, + .direct_string_allow_empty = TRUE); _nm_properties_override_gobj( properties_override, obj_properties[PROP_DHCP_HOSTNAME], &nm_sett_info_propert_type_direct_string, .direct_offset = - NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, dhcp_hostname)); + NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, dhcp_hostname), + .direct_string_allow_empty = TRUE); _nm_properties_override_gobj( properties_override, obj_properties[PROP_DHCP_IAID], &nm_sett_info_propert_type_direct_string, - .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, dhcp_iaid)); + .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, dhcp_iaid), + .direct_string_allow_empty = TRUE); /* ---dbus--- * property: routing-rules @@ -6130,6 +6114,29 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, replace_local_rule)); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_DNS_SEARCH], + &nm_sett_info_propert_type_direct_strv, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(NMValueStrv, NMSettingIPConfigPrivate, dns_search)); + + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_DNS_OPTIONS], + &nm_sett_info_propert_type_direct_strv, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(NMValueStrv, NMSettingIPConfigPrivate, dns_options), + .direct_strv_preserve_empty = TRUE, ); + + _nm_properties_override_gobj(properties_override, + obj_properties[PROP_DHCP_REJECT_SERVERS], + &nm_sett_info_propert_type_direct_strv, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(NMValueStrv, + NMSettingIPConfigPrivate, + dhcp_reject_servers)); + return properties_override; } @@ -6143,15 +6150,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_DNS: - g_value_take_boxed(value, _nm_utils_ptrarray_to_strv(priv->dns)); - break; - case PROP_DNS_SEARCH: - g_value_take_boxed(value, _nm_utils_ptrarray_to_strv(priv->dns_search)); - break; - case PROP_DNS_OPTIONS: - g_value_take_boxed(value, - priv->dns_options ? _nm_utils_ptrarray_to_strv(priv->dns_options) - : NULL); + g_value_take_boxed(value, nm_strv_ptrarray_to_strv(priv->dns)); break; case PROP_ADDRESSES: g_value_take_boxed(value, @@ -6165,9 +6164,6 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) (NMUtilsCopyFunc) nm_ip_route_dup, (GDestroyNotify) nm_ip_route_unref)); break; - case PROP_DHCP_REJECT_SERVERS: - g_value_set_boxed(value, nm_strvarray_get_strv_non_empty(priv->dhcp_reject_servers, NULL)); - break; default: _nm_setting_property_get_property_direct(object, prop_id, value, pspec); break; @@ -6179,7 +6175,8 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps { NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG(object); NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - char **strv; + gs_unref_array GArray *array = NULL; + const char *const *strv; guint i; switch (prop_id) { @@ -6195,28 +6192,22 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps } break; } - case PROP_DNS_SEARCH: - g_ptr_array_unref(priv->dns_search); - priv->dns_search = nm_strv_to_ptrarray(g_value_get_boxed(value)); - break; case PROP_DNS_OPTIONS: strv = g_value_get_boxed(value); - if (!strv) { - if (priv->dns_options) { - g_ptr_array_unref(priv->dns_options); - priv->dns_options = NULL; - } - } else { - if (priv->dns_options) - g_ptr_array_set_size(priv->dns_options, 0); - else - priv->dns_options = g_ptr_array_new_with_free_func(g_free); + if (strv) { + nm_strvarray_ensure(&array); for (i = 0; strv[i]; i++) { - if (_nm_utils_dns_option_validate(strv[i], NULL, NULL, FALSE, NULL) - && _nm_utils_dns_option_find_idx(priv->dns_options, strv[i]) < 0) - g_ptr_array_add(priv->dns_options, g_strdup(strv[i])); + const char *str = strv[i]; + + if (_nm_utils_dns_option_validate(str, NULL, NULL, AF_UNSPEC, NULL) + && _dns_option_find_idx_garray(array, str) < 0) + nm_strvarray_add(array, str); } } + if (!nm_strvarray_equal(priv->dns_options.arr, array)) { + NM_SWAP(&priv->dns_options.arr, &array); + _notify(setting, PROP_DNS_OPTIONS); + } break; case PROP_ADDRESSES: g_ptr_array_unref(priv->addresses); @@ -6230,9 +6221,6 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps (NMUtilsCopyFunc) nm_ip_route_dup, (GDestroyNotify) nm_ip_route_unref); break; - case PROP_DHCP_REJECT_SERVERS: - nm_strvarray_set_strv(&priv->dhcp_reject_servers, g_value_get_boxed(value)); - break; default: _nm_setting_property_set_property_direct(object, prop_id, value, pspec); break; @@ -6246,9 +6234,8 @@ _nm_setting_ip_config_private_init(gpointer self, NMSettingIPConfigPrivate *priv { nm_assert(NM_IS_SETTING_IP_CONFIG(self)); - priv->dns_search = g_ptr_array_new_with_free_func(g_free); - priv->addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); - priv->routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + priv->addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + priv->routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); } static void @@ -6264,12 +6251,9 @@ finalize(GObject *object) NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(self); nm_g_ptr_array_unref(priv->dns); - g_ptr_array_unref(priv->dns_search); - nm_g_ptr_array_unref(priv->dns_options); g_ptr_array_unref(priv->addresses); g_ptr_array_unref(priv->routes); nm_g_ptr_array_unref(priv->routing_rules); - nm_g_array_unref(priv->dhcp_reject_servers); G_OBJECT_CLASS(nm_setting_ip_config_parent_class)->finalize(object); } @@ -6311,12 +6295,13 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * shared method must be configured on the interface which shares the internet * to a subnet, not on the uplink which is shared. **/ - obj_properties[PROP_METHOD] = g_param_spec_string( - NM_SETTING_IP_CONFIG_METHOD, - "", - "", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_METHOD] = + g_param_spec_string(NM_SETTING_IP_CONFIG_METHOD, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY + | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dns: @@ -6359,22 +6344,29 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dns-options: * - * Array of DNS options as described in man 5 resolv.conf. + * Array of DNS options to be added to resolv.conf. * * %NULL means that the options are unset and left at the default. * In this case NetworkManager will use default options. This is * distinct from an empty list of properties. * - * The currently supported options are "attempts", "debug", "edns0", + * The following options are directly added to resolv.conf: "attempts", + * "debug", "edns0", * "inet6", "ip6-bytestring", "ip6-dotint", "ndots", "no-aaaa", * "no-check-names", "no-ip6-dotint", "no-reload", "no-tld-query", * "rotate", "single-request", "single-request-reopen", "timeout", - * "trust-ad", "use-vc". + * "trust-ad", "use-vc". See the resolv.conf(5) man page for a + * detailed description of these options. + * + * In addition, NetworkManager supports the special options "_no-add-edns0" + * and "_no-add-trust-ad". They are not added to resolv.conf, and can be + * used to prevent the automatic addition of options "edns0" and "trust-ad" + * when using caching DNS plugins (see below). * * The "trust-ad" setting is only honored if the profile contributes * name servers to resolv.conf, and if all contributing profiles have @@ -6382,7 +6374,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * When using a caching DNS plugin (dnsmasq or systemd-resolved in * NetworkManager.conf) then "edns0" and "trust-ad" are automatically - * added. + * added, unless "_no-add-edns0" and "_no-add-trust-ad" are present. * * Since: 1.2 **/ @@ -6391,7 +6383,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dns-priority: @@ -6453,7 +6445,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) G_MININT32, G_MAXINT32, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:addresses: (type GPtrArray(NMIPAddress)) @@ -6484,14 +6476,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * for WireGuard interfaces, so usually it should not be set in that case. See * #NMSettingWireGuard:ip4-auto-default-route. **/ - obj_properties[PROP_GATEWAY] = g_param_spec_string( - NM_SETTING_IP_CONFIG_GATEWAY, - "", - "", - NULL, - /* On D-Bus, the legacy property "addresses" contains the gateway. - * This was replaced by "address-data" and "gateway". */ - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_GATEWAY] = + g_param_spec_string(NM_SETTING_IP_CONFIG_GATEWAY, + "", + "", + NULL, + /* On D-Bus, the legacy property "addresses" contains the gateway. + * This was replaced by "address-data" and "gateway". */ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY + | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:routes: (type GPtrArray(NMIPRoute)) @@ -6528,7 +6521,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) -1, G_MAXUINT32, -1, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:route-table: @@ -6551,14 +6544,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Since: 1.10 **/ - obj_properties[PROP_ROUTE_TABLE] = g_param_spec_uint( - NM_SETTING_IP_CONFIG_ROUTE_TABLE, - "", - "", - 0, - G_MAXUINT32, - 0, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_TABLE] = + g_param_spec_uint(NM_SETTING_IP_CONFIG_ROUTE_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY + | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:ignore-auto-routes: * @@ -6571,7 +6565,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:ignore-auto-dns: @@ -6587,7 +6581,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-hostname: @@ -6602,7 +6596,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-send-hostname: @@ -6618,7 +6612,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:never-default: @@ -6632,7 +6626,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:may-fail: @@ -6650,30 +6644,33 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dad-timeout: * - * Timeout in milliseconds used to check for the presence of duplicate IP - * addresses on the network. If an address conflict is detected, the - * activation will fail. A zero value means that no duplicate address - * detection is performed, -1 means the default value (either configuration - * ipvx.dad-timeout override or zero). A value greater than zero is a - * timeout in milliseconds. + * Maximum timeout in milliseconds used to check for the presence of duplicate + * IP addresses on the network. If an address conflict is detected, the + * activation will fail. The property is currently implemented only for IPv4. * - * The property is currently implemented only for IPv4. + * A zero value means that no duplicate address detection is performed, -1 means + * the default value (either the value configured globally in NetworkManger.conf + * or 200ms). A value greater than zero is a timeout in milliseconds. Note that + * the time intervals are subject to randomization as per RFC 5227 and so the + * actual duration can be between half and the full time specified in this + * property. * * Since: 1.2 **/ - obj_properties[PROP_DAD_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_DAD_TIMEOUT, - "", - "", - -1, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, - -1, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DAD_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DAD_TIMEOUT, + "", + "", + -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, + -1, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-timeout: @@ -6684,14 +6681,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Set to 2147483647 (MAXINT32) for infinity. **/ - obj_properties[PROP_DHCP_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, - "", - "", - 0, - G_MAXINT32, - 0, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DHCP_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:required-timeout: @@ -6716,14 +6714,15 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * * Since: 1.34 **/ - obj_properties[PROP_REQUIRED_TIMEOUT] = g_param_spec_int( - NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, - "", - "", - -1, - G_MAXINT32, - -1, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_REQUIRED_TIMEOUT] = + g_param_spec_int(NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + "", + "", + -1, + G_MAXINT32, + -1, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-iaid: @@ -6758,7 +6757,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-hostname-flags: @@ -6792,7 +6791,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) 0, G_MAXUINT32, NM_DHCP_HOSTNAME_FLAG_NONE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:dhcp-reject-servers: @@ -6812,7 +6811,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", "", G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:auto-route-ext-gw: @@ -6831,7 +6830,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", NM_TYPE_TERNARY, NM_TERNARY_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * NMSettingIPConfig:replace-local-rule: @@ -6847,7 +6846,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) "", NM_TYPE_TERNARY, NM_TERNARY_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/libnm-core-impl/nm-setting-ip-tunnel.c b/src/libnm-core-impl/nm-setting-ip-tunnel.c index 2deebf42..3512ff2e 100644 --- a/src/libnm-core-impl/nm-setting-ip-tunnel.c +++ b/src/libnm-core-impl/nm-setting-ip-tunnel.c @@ -55,20 +55,18 @@ typedef struct { * IP Tunneling Settings */ struct _NMSettingIPTunnel { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingIPTunnelPrivate _priv; }; struct _NMSettingIPTunnelClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING) #define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate)) + _NM_GET_PRIVATE(o, NMSettingIPTunnel, NM_IS_SETTING_IP_TUNNEL, NMSetting) /*****************************************************************************/ @@ -566,8 +564,6 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingIPTunnelPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -588,7 +584,8 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingIPTunnelPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingIPTunnel:mode: @@ -634,7 +631,8 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) PROP_LOCAL, NM_SETTING_PARAM_INFERRABLE, NMSettingIPTunnelPrivate, - local); + local, + .direct_string_allow_empty = TRUE); /** * NMSettingIPTunnel:remote: @@ -650,7 +648,8 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) PROP_REMOTE, NM_SETTING_PARAM_INFERRABLE, NMSettingIPTunnelPrivate, - remote); + remote, + .direct_string_allow_empty = TRUE); /** * NMSettingIPTunnel:ttl @@ -720,7 +719,8 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) PROP_INPUT_KEY, NM_SETTING_PARAM_INFERRABLE, NMSettingIPTunnelPrivate, - input_key); + input_key, + .direct_string_allow_empty = TRUE); /** * NMSettingIPTunnel:output-key: @@ -736,7 +736,8 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) PROP_OUTPUT_KEY, NM_SETTING_PARAM_INFERRABLE, NMSettingIPTunnelPrivate, - output_key); + output_key, + .direct_string_allow_empty = TRUE); /** * NMSettingIPTunnel:encapsulation-limit: @@ -861,5 +862,5 @@ nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass) NM_META_SETTING_TYPE_IP_TUNNEL, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingIPTunnel, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index 9ed39507..c79d0fdf 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -56,20 +56,18 @@ typedef struct { * IPv4 Settings */ struct _NMSettingIP4Config { - NMSettingIPConfig parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSettingIPConfig parent; + NMSettingIP4ConfigPrivate _priv; }; struct _NMSettingIP4ConfigClass { NMSettingIPConfigClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG) #define NM_SETTING_IP4_CONFIG_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigPrivate)) + _NM_GET_PRIVATE(o, NMSettingIP4Config, NM_IS_SETTING_IP4_CONFIG, NMSettingIPConfig, NMSetting) /*****************************************************************************/ @@ -165,17 +163,17 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_assert(method); if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - if (nm_setting_ip_config_get_num_addresses(s_ip) == 0) { + if (nm_setting_ip_config_get_num_addresses(s_ip) == 0 + && nm_setting_ip_config_get_num_routes(s_ip) == 0) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("this property cannot be empty for '%s=%s'"), - NM_SETTING_IP_CONFIG_METHOD, + _("method '%s' requires at least an address or a route"), method); g_prefix_error(error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_METHOD); return FALSE; } } else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) @@ -405,6 +403,8 @@ ip4_dns_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) } strv = nm_utils_ip4_dns_from_variant(value); + nm_assert(strv); + g_object_set(setting, NM_SETTING_IP_CONFIG_DNS, strv, NULL); return TRUE; } @@ -425,31 +425,24 @@ ip4_addresses_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *addrs = NULL; gs_unref_variant GVariant *s_ip4 = NULL; - gs_free const char **labels = NULL; + gs_unref_variant GVariant *labels = NULL; gs_free char *gateway = NULL; - guint i; - - /* FIXME: properly handle errors */ + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); if (!_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) { *out_is_modified = FALSE; return TRUE; } - addrs = nm_utils_ip4_addresses_from_variant(value, &gateway); - s_ip4 = g_variant_lookup_value(connection_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); - if (g_variant_lookup(s_ip4, "address-labels", "^a&s", &labels)) { - for (i = 0; i < addrs->len && labels[i]; i++) { - if (*labels[i]) { - nm_ip_address_set_attribute(addrs->pdata[i], - NM_IP_ADDRESS_ATTRIBUTE_LABEL, - g_variant_new_string(labels[i])); - } - } - } + + labels = g_variant_lookup_value(s_ip4, "address-labels", NULL); + + addrs = _nm_utils_ip4_addresses_from_variant(value, labels, &gateway, strict, error); + if (!addrs) + return FALSE; g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, @@ -514,9 +507,8 @@ ip4_address_data_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil) static gboolean ip4_address_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { - gs_unref_ptrarray GPtrArray *addrs = NULL; - - /* FIXME: properly handle errors */ + gs_unref_ptrarray GPtrArray *addrs = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); /* Ignore 'address-data' if we're going to process 'addresses' */ if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) { @@ -524,7 +516,10 @@ ip4_address_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) return TRUE; } - addrs = nm_utils_ip_addresses_from_variant(value, AF_INET); + addrs = _nm_utils_ip_addresses_from_variant(value, AF_INET, strict, error); + if (!addrs) + return FALSE; + g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); return TRUE; } @@ -542,15 +537,17 @@ static gboolean ip4_routes_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *routes = NULL; - - /* FIXME: properly handle errors */ + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); if (!_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) { *out_is_modified = FALSE; return TRUE; } - routes = nm_utils_ip4_routes_from_variant(value); + routes = _nm_utils_ip4_routes_from_variant(value, strict, error); + if (!routes) + return FALSE; + g_object_set(setting, property_info->name, routes, NULL); return TRUE; } @@ -571,8 +568,7 @@ static gboolean ip4_route_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *routes = NULL; - - /* FIXME: properly handle errors */ + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); /* Ignore 'route-data' if we're going to process 'routes' */ if (_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) { @@ -580,7 +576,10 @@ ip4_route_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) return TRUE; } - routes = nm_utils_ip_routes_from_variant(value, AF_INET); + routes = _nm_utils_ip_routes_from_variant(value, AF_INET, strict, error); + if (!routes) + return FALSE; + g_object_set(setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); return TRUE; } @@ -616,14 +615,12 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(AF_INET); - g_type_class_add_private(klass, sizeof(NMSettingIP4ConfigPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; setting_class->verify = verify; - setting_ip_config_class->private_offset = g_type_class_get_instance_private_offset(klass); + setting_ip_config_class->private_offset = G_STRUCT_OFFSET(NMSettingIP4Config, _priv); setting_ip_config_class->is_ipv4 = TRUE; setting_ip_config_class->addr_family = AF_INET; @@ -703,6 +700,15 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * route2=7.7.0.0/16 * ---end--- */ + /* ---keyfile--- + * property: routes (attributes) + * variable: route1_options, route2_options, ... + * format: key=val[,key=val...] + * description: Attributes defined for the routes, if any. The supported + * attributes are explained in ipv4.routes entry in `man nm-settings-nmcli`. + * example: route1_options=mtu=1000,onlink=true + * ---end--- + */ /* ---ifcfg-rh--- * property: routes * variable: ADDRESS1, NETMASK1, GATEWAY1, METRIC1, OPTIONS1, ... @@ -711,6 +717,16 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * ---end--- */ + /* ---keyfile--- + * property: routing-rules + * variable: routing-rule1, routing-rule2, ... + * format: routing rule string + * description: Routing rules as defined with `ip rule add`, but with mandatory + * fixed priority. + * example: routing-rule1=priority 5 from 192.167.4.0/24 table 45 + * ---end--- + */ + /* ---ifcfg-rh--- * property: ignore-auto-routes * variable: PEERROUTES(+) @@ -875,9 +891,20 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a * per-device key. * - * If unset, a globally configured default is used. If still unset, the default - * depends on the DHCP plugin. + * The special value "none" prevents any client identifier from being sent. Note that + * this is normally not recommended. + * + * If unset, a globally configured default from NetworkManager.conf is + * used. If still unset, the default depends on the DHCP plugin. The + * internal dhcp client will default to "mac" and the dhclient plugin will + * try to use one from its config file if present, or won't sent any + * client-id otherwise. **/ + /* ---nmcli--- + * property: dhcp-client-id + * special-values: mac, perm-mac, duid, ipv6-duid, stable, none + * ---end--- + */ /* ---ifcfg-rh--- * property: dhcp-client-id * variable: DHCP_CLIENT_ID(+) @@ -892,7 +919,8 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) PROP_DHCP_CLIENT_ID, NM_SETTING_PARAM_NONE, NMSettingIP4ConfigPrivate, - dhcp_client_id); + dhcp_client_id, + .direct_string_allow_empty = TRUE); /* ---ifcfg-rh--- * property: dad-timeout @@ -945,7 +973,8 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) PROP_DHCP_FQDN, NM_SETTING_PARAM_NONE, NMSettingIP4ConfigPrivate, - dhcp_fqdn); + dhcp_fqdn, + .direct_string_allow_empty = TRUE); /** * NMSettingIP4Config:dhcp-vendor-class-identifier: @@ -972,7 +1001,8 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) PROP_DHCP_VENDOR_CLASS_IDENTIFIER, NM_SETTING_PARAM_NONE, NMSettingIP4ConfigPrivate, - dhcp_vendor_class_identifier); + dhcp_vendor_class_identifier, + .direct_string_allow_empty = TRUE); /** * NMSettingIP4Config:link-local: @@ -1288,5 +1318,5 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) NM_META_SETTING_TYPE_IP4_CONFIG, NULL, properties_override, - setting_ip_config_class->private_offset); + G_STRUCT_OFFSET(NMSettingIP4Config, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index 661a451e..4ad09932 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -65,20 +65,18 @@ typedef struct { * IPv6 Settings */ struct _NMSettingIP6Config { - NMSettingIPConfig parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSettingIPConfig parent; + NMSettingIP6ConfigPrivate _priv; }; struct _NMSettingIP6ConfigClass { NMSettingIPConfigClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG) #define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate)) + _NM_GET_PRIVATE(o, NMSettingIP6Config, NM_IS_SETTING_IP6_CONFIG, NMSettingIPConfig, NMSetting) /*****************************************************************************/ @@ -230,17 +228,17 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_assert(method); if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - if (nm_setting_ip_config_get_num_addresses(s_ip) == 0) { + if (nm_setting_ip_config_get_num_addresses(s_ip) == 0 + && nm_setting_ip_config_get_num_routes(s_ip) == 0) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("this property cannot be empty for '%s=%s'"), - NM_SETTING_IP_CONFIG_METHOD, + _("method '%s' requires at least an address or a route"), method); g_prefix_error(error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_METHOD); return FALSE; } } else if (NM_IN_STRSET(method, @@ -437,14 +435,18 @@ ip6_dns_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil) static gboolean ip6_dns_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { - gs_strfreev char **strv = NULL; + gs_strfreev char **strv = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); if (!_nm_setting_use_legacy_property(setting, connection_dict, "dns", "dns-data")) { *out_is_modified = FALSE; return TRUE; } - strv = nm_utils_ip6_dns_from_variant(value); + strv = _nm_utils_ip6_dns_from_variant(value, strict, error); + if (!strv) + return FALSE; + g_object_set(setting, NM_SETTING_IP_CONFIG_DNS, strv, NULL); return TRUE; } @@ -465,13 +467,16 @@ ip6_addresses_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *addrs = NULL; gs_free char *gateway = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); if (!_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) { *out_is_modified = FALSE; return TRUE; } - addrs = nm_utils_ip6_addresses_from_variant(value, &gateway); + addrs = _nm_utils_ip6_addresses_from_variant(value, &gateway, strict, error); + if (!addrs) + return FALSE; g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, @@ -497,7 +502,8 @@ ip6_address_data_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil) static gboolean ip6_address_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { - gs_unref_ptrarray GPtrArray *addrs = NULL; + gs_unref_ptrarray GPtrArray *addrs = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); /* Ignore 'address-data' if we're going to process 'addresses' */ if (_nm_setting_use_legacy_property(setting, connection_dict, "addresses", "address-data")) { @@ -505,7 +511,10 @@ ip6_address_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) return TRUE; } - addrs = nm_utils_ip_addresses_from_variant(value, AF_INET6); + addrs = _nm_utils_ip_addresses_from_variant(value, AF_INET6, strict, error); + if (!addrs) + return FALSE; + g_object_set(setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); return TRUE; } @@ -523,13 +532,17 @@ static gboolean ip6_routes_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *routes = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); if (!_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) { *out_is_modified = FALSE; return TRUE; } - routes = nm_utils_ip6_routes_from_variant(value); + routes = _nm_utils_ip6_routes_from_variant(value, strict, error); + if (!routes) + return FALSE; + g_object_set(setting, property_info->name, routes, NULL); return TRUE; } @@ -550,6 +563,7 @@ static gboolean ip6_route_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) { gs_unref_ptrarray GPtrArray *routes = NULL; + bool strict = NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT); /* Ignore 'route-data' if we're going to process 'routes' */ if (_nm_setting_use_legacy_property(setting, connection_dict, "routes", "route-data")) { @@ -557,7 +571,10 @@ ip6_route_data_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil) return TRUE; } - routes = nm_utils_ip_routes_from_variant(value, AF_INET6); + routes = _nm_utils_ip_routes_from_variant(value, AF_INET6, strict, error); + if (!routes) + return FALSE; + g_object_set(setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); return TRUE; } @@ -628,14 +645,12 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(AF_INET6); - g_type_class_add_private(klass, sizeof(NMSettingIP6ConfigPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; setting_class->verify = verify; - setting_ip_config_class->private_offset = g_type_class_get_instance_private_offset(klass); + setting_ip_config_class->private_offset = G_STRUCT_OFFSET(NMSettingIP6Config, _priv); setting_ip_config_class->is_ipv4 = FALSE; setting_ip_config_class->addr_family = AF_INET6; @@ -714,6 +729,15 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403 * ---end--- */ + /* ---keyfile--- + * property: routes (attributes) + * variable: route1_options, route2_options, ... + * format: key=val[,key=val...] + * description: Attributes defined for the routes, if any. The supported + * attributes are explained in ipv6.routes entry in `man nm-settings-nmcli`. + * example: route1_options=mtu=1000,onlink=true + * ---end--- + */ /* ---ifcfg-rh--- * property: routes * variable: (none) @@ -722,6 +746,16 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * ---end--- */ + /* ---keyfile--- + * property: routing-rules + * variable: routing-rule1, routing-rule2, ... + * format: routing rule string + * description: Routing rules as defined with `ip rule add`, but with mandatory + * fixed priority. + * example: routing-rule1=priority 5 from 2001:4860:4860::/64 table 45 + * ---end--- + */ + /* ---ifcfg-rh--- * property: ignore-auto-routes * variable: IPV6_PEERROUTES(+) @@ -1035,7 +1069,8 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) PROP_TOKEN, NM_SETTING_PARAM_INFERRABLE, NMSettingIP6ConfigPrivate, - token); + token, + .direct_string_allow_empty = TRUE); /** * NMSettingIP6Config:ra-timeout: @@ -1138,7 +1173,8 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) PROP_DHCP_DUID, NM_SETTING_PARAM_NONE, NMSettingIP6ConfigPrivate, - dhcp_duid); + dhcp_duid, + .direct_string_allow_empty = TRUE); /** * NMSettingIP6Config:dhcp-pd-hint: @@ -1166,8 +1202,9 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) NM_SETTING_PARAM_NONE, NMSettingIP6ConfigPrivate, dhcp_pd_hint, - .direct_hook.set_string_fcn = - _set_string_fcn_dhcp_pd_hint); + .direct_set_fcn.set_string = + _set_string_fcn_dhcp_pd_hint, + .direct_string_allow_empty = TRUE); /* IP6-specific property overrides */ @@ -1425,5 +1462,5 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) NM_META_SETTING_TYPE_IP6_CONFIG, NULL, properties_override, - setting_ip_config_class->private_offset); + G_STRUCT_OFFSET(NMSettingIP6Config, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-loopback.c b/src/libnm-core-impl/nm-setting-loopback.c index 1451b411..b329c74a 100644 --- a/src/libnm-core-impl/nm-setting-loopback.c +++ b/src/libnm-core-impl/nm-setting-loopback.c @@ -125,7 +125,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } if ((s_con = nm_connection_get_setting_connection(connection))) { - if (nm_setting_connection_get_slave_type(s_con) + if (nm_setting_connection_get_port_type(s_con) || nm_setting_connection_get_master(s_con)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -134,9 +134,9 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - nm_setting_connection_get_slave_type(s_con) - ? NM_SETTING_CONNECTION_SLAVE_TYPE - : NM_SETTING_CONNECTION_MASTER); + nm_setting_connection_get_port_type(s_con) + ? NM_SETTING_CONNECTION_PORT_TYPE + : NM_SETTING_CONNECTION_CONTROLLER); return FALSE; } } diff --git a/src/libnm-core-impl/nm-setting-macsec.c b/src/libnm-core-impl/nm-setting-macsec.c index bf48f049..f66fc52a 100644 --- a/src/libnm-core-impl/nm-setting-macsec.c +++ b/src/libnm-core-impl/nm-setting-macsec.c @@ -55,20 +55,18 @@ typedef struct { * MACSec Settings */ struct _NMSettingMacsec { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingMacsecPrivate _priv; }; struct _NMSettingMacsecClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingMacsec, nm_setting_macsec, NM_TYPE_SETTING) #define NM_SETTING_MACSEC_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_MACSEC, NMSettingMacsecPrivate)) + _NM_GET_PRIVATE(o, NMSettingMacsec, NM_IS_SETTING_MACSEC, NMSetting) /*****************************************************************************/ @@ -306,7 +304,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) if (s_con) { const char *master = NULL, *slave_type = NULL; - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (!g_strcmp0(slave_type, NM_SETTING_MACSEC_SETTING_NAME)) master = nm_setting_connection_get_master(s_con); @@ -316,7 +314,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' value doesn't match '%s=%s'"), priv->parent, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, master); g_prefix_error(error, "%s.%s: ", @@ -436,8 +434,6 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingMacsecPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -460,7 +456,8 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingMacsecPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingMacsec:mode: @@ -511,7 +508,8 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass) PROP_MKA_CAK, NM_SETTING_PARAM_SECRET, NMSettingMacsecPrivate, - mka_cak); + mka_cak, + .direct_string_allow_empty = TRUE); /** * NMSettingMacsec:mka-cak-flags: @@ -543,7 +541,8 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass) PROP_MKA_CKN, NM_SETTING_PARAM_NONE, NMSettingMacsecPrivate, - mka_ckn); + mka_ckn, + .direct_string_allow_empty = TRUE); /** * NMSettingMacsec:port: @@ -604,5 +603,5 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass) NM_META_SETTING_TYPE_MACSEC, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingMacsec, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-macvlan.c b/src/libnm-core-impl/nm-setting-macvlan.c index d26a8086..2adecdfe 100644 --- a/src/libnm-core-impl/nm-setting-macvlan.c +++ b/src/libnm-core-impl/nm-setting-macvlan.c @@ -40,20 +40,18 @@ typedef struct { * MAC VLAN Settings */ struct _NMSettingMacvlan { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingMacvlanPrivate _priv; }; struct _NMSettingMacvlanClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING) #define NM_SETTING_MACVLAN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate)) + _NM_GET_PRIVATE(o, NMSettingMacvlan, NM_IS_SETTING_MACVLAN, NMSetting) /*****************************************************************************/ @@ -207,8 +205,6 @@ nm_setting_macvlan_class_init(NMSettingMacvlanClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingMacvlanPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -230,7 +226,8 @@ nm_setting_macvlan_class_init(NMSettingMacvlanClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingMacvlanPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingMacvlan:mode: @@ -289,5 +286,5 @@ nm_setting_macvlan_class_init(NMSettingMacvlanClass *klass) NM_META_SETTING_TYPE_MACVLAN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingMacvlan, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-match.c b/src/libnm-core-impl/nm-setting-match.c index 0ece65f1..7736b7c0 100644 --- a/src/libnm-core-impl/nm-setting-match.c +++ b/src/libnm-core-impl/nm-setting-match.c @@ -68,6 +68,8 @@ nm_setting_match_get_num_interface_names(NMSettingMatch *setting) * @setting: the #NMSettingMatch * @idx: index number of the DNS search domain to return * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the interface name at index @idx * * Since: 1.14 @@ -77,11 +79,7 @@ nm_setting_match_get_interface_name(NMSettingMatch *setting, int idx) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - g_return_val_if_fail(setting->interface_name.arr && idx >= 0 - && idx < setting->interface_name.arr->len, - NULL); - - return nm_strvarray_get_idx(setting->interface_name.arr, idx); + return nm_strvarray_get_idxnull_or_greturn(setting->interface_name.arr, idx); } /** @@ -99,7 +97,7 @@ nm_setting_match_add_interface_name(NMSettingMatch *setting, const char *interfa g_return_if_fail(NM_IS_SETTING_MATCH(setting)); g_return_if_fail(interface_name); - nm_strvarray_add(nm_strvarray_ensure(&setting->interface_name.arr), interface_name); + nm_strvarray_ensure_and_add(&setting->interface_name.arr, interface_name); _notify(setting, PROP_INTERFACE_NAME); } @@ -120,7 +118,7 @@ nm_setting_match_remove_interface_name(NMSettingMatch *setting, int idx) g_return_if_fail(setting->interface_name.arr && idx >= 0 && idx < setting->interface_name.arr->len); - g_array_remove_index(setting->interface_name.arr, idx); + nm_strvarray_remove_index(setting->interface_name.arr, idx); _notify(setting, PROP_INTERFACE_NAME); } @@ -141,12 +139,11 @@ nm_setting_match_remove_interface_name_by_value(NMSettingMatch *setting, const c g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); g_return_val_if_fail(interface_name, FALSE); - if (nm_strvarray_remove_first(setting->interface_name.arr, interface_name)) { - _notify(setting, PROP_INTERFACE_NAME); - return TRUE; - } + if (!nm_strvarray_remove_first(setting->interface_name.arr, interface_name)) + return FALSE; - return FALSE; + _notify(setting, PROP_INTERFACE_NAME); + return TRUE; } /** @@ -162,10 +159,8 @@ nm_setting_match_clear_interface_names(NMSettingMatch *setting) { g_return_if_fail(NM_IS_SETTING_MATCH(setting)); - if (nm_g_array_len(setting->interface_name.arr) != 0) { - nm_clear_pointer(&setting->interface_name.arr, g_array_unref); + if (nm_strvarray_clear(&setting->interface_name.arr)) _notify(setting, PROP_INTERFACE_NAME); - } } /** @@ -187,7 +182,7 @@ nm_setting_match_get_interface_names(NMSettingMatch *setting, guint *length) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - return nm_strvarray_get_strv(&setting->interface_name.arr, length); + return nm_strvarray_get_strv_notnull(setting->interface_name.arr, length); } /*****************************************************************************/ @@ -213,6 +208,8 @@ nm_setting_match_get_num_kernel_command_lines(NMSettingMatch *setting) * @setting: the #NMSettingMatch * @idx: index number of the kernel command line argument to return * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the kernel command line argument at index @idx * * Since: 1.26 @@ -222,11 +219,7 @@ nm_setting_match_get_kernel_command_line(NMSettingMatch *setting, guint idx) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - g_return_val_if_fail(setting->kernel_command_line.arr - && idx < setting->kernel_command_line.arr->len, - NULL); - - return nm_strvarray_get_idx(setting->kernel_command_line.arr, idx); + return nm_strvarray_get_idxnull_or_greturn(setting->kernel_command_line.arr, idx); } /** @@ -244,7 +237,7 @@ nm_setting_match_add_kernel_command_line(NMSettingMatch *setting, const char *ke g_return_if_fail(NM_IS_SETTING_MATCH(setting)); g_return_if_fail(kernel_command_line); - nm_strvarray_add(nm_strvarray_ensure(&setting->kernel_command_line.arr), kernel_command_line); + nm_strvarray_ensure_and_add(&setting->kernel_command_line.arr, kernel_command_line); _notify(setting, PROP_KERNEL_COMMAND_LINE); } @@ -265,7 +258,7 @@ nm_setting_match_remove_kernel_command_line(NMSettingMatch *setting, guint idx) g_return_if_fail(setting->kernel_command_line.arr && idx < setting->kernel_command_line.arr->len); - g_array_remove_index(setting->kernel_command_line.arr, idx); + nm_strvarray_remove_index(setting->kernel_command_line.arr, idx); _notify(setting, PROP_KERNEL_COMMAND_LINE); } @@ -287,12 +280,11 @@ nm_setting_match_remove_kernel_command_line_by_value(NMSettingMatch *setting, g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); g_return_val_if_fail(kernel_command_line, FALSE); - if (nm_strvarray_remove_first(setting->kernel_command_line.arr, kernel_command_line)) { - _notify(setting, PROP_KERNEL_COMMAND_LINE); - return TRUE; - } + if (!nm_strvarray_remove_first(setting->kernel_command_line.arr, kernel_command_line)) + return FALSE; - return FALSE; + _notify(setting, PROP_KERNEL_COMMAND_LINE); + return TRUE; } /** @@ -308,10 +300,8 @@ nm_setting_match_clear_kernel_command_lines(NMSettingMatch *setting) { g_return_if_fail(NM_IS_SETTING_MATCH(setting)); - if (nm_g_array_len(setting->kernel_command_line.arr) != 0) { - nm_clear_pointer(&setting->kernel_command_line.arr, g_array_unref); + if (nm_strvarray_clear(&setting->kernel_command_line.arr)) _notify(setting, PROP_KERNEL_COMMAND_LINE); - } } /** @@ -330,7 +320,7 @@ nm_setting_match_get_kernel_command_lines(NMSettingMatch *setting, guint *length { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - return nm_strvarray_get_strv(&setting->kernel_command_line.arr, length); + return nm_strvarray_get_strv_notnull(setting->kernel_command_line.arr, length); } /*****************************************************************************/ @@ -356,6 +346,8 @@ nm_setting_match_get_num_drivers(NMSettingMatch *setting) * @setting: the #NMSettingMatch * @idx: index number of the DNS search domain to return * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the driver at index @idx * * Since: 1.26 @@ -365,9 +357,7 @@ nm_setting_match_get_driver(NMSettingMatch *setting, guint idx) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - g_return_val_if_fail(setting->driver.arr && idx < setting->driver.arr->len, NULL); - - return nm_strvarray_get_idx(setting->driver.arr, idx); + return nm_strvarray_get_idxnull_or_greturn(setting->driver.arr, idx); } /** @@ -385,7 +375,7 @@ nm_setting_match_add_driver(NMSettingMatch *setting, const char *driver) g_return_if_fail(NM_IS_SETTING_MATCH(setting)); g_return_if_fail(driver); - nm_strvarray_add(nm_strvarray_ensure(&setting->driver.arr), driver); + nm_strvarray_ensure_and_add(&setting->driver.arr, driver); _notify(setting, PROP_DRIVER); } @@ -405,7 +395,7 @@ nm_setting_match_remove_driver(NMSettingMatch *setting, guint idx) g_return_if_fail(setting->driver.arr && idx < setting->driver.arr->len); - g_array_remove_index(setting->driver.arr, idx); + nm_strvarray_remove_index(setting->driver.arr, idx); _notify(setting, PROP_DRIVER); } @@ -426,12 +416,11 @@ nm_setting_match_remove_driver_by_value(NMSettingMatch *setting, const char *dri g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); g_return_val_if_fail(driver, FALSE); - if (nm_strvarray_remove_first(setting->driver.arr, driver)) { - _notify(setting, PROP_DRIVER); - return TRUE; - } + if (!nm_strvarray_remove_first(setting->driver.arr, driver)) + return FALSE; - return FALSE; + _notify(setting, PROP_DRIVER); + return TRUE; } /** @@ -447,10 +436,8 @@ nm_setting_match_clear_drivers(NMSettingMatch *setting) { g_return_if_fail(NM_IS_SETTING_MATCH(setting)); - if (nm_g_array_len(setting->driver.arr) != 0) { - nm_clear_pointer(&setting->driver.arr, g_array_unref); + if (nm_strvarray_clear(&setting->driver.arr)) _notify(setting, PROP_DRIVER); - } } /** @@ -469,7 +456,7 @@ nm_setting_match_get_drivers(NMSettingMatch *setting, guint *length) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - return nm_strvarray_get_strv(&setting->driver.arr, length); + return nm_strvarray_get_strv_notnull(setting->driver.arr, length); } /*****************************************************************************/ @@ -495,6 +482,8 @@ nm_setting_match_get_num_paths(NMSettingMatch *setting) * @setting: the #NMSettingMatch * @idx: index number of the path to return * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the path at index @idx * * Since: 1.26 @@ -504,9 +493,7 @@ nm_setting_match_get_path(NMSettingMatch *setting, guint idx) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - g_return_val_if_fail(setting->path.arr && idx < setting->path.arr->len, NULL); - - return nm_strvarray_get_idx(setting->path.arr, idx); + return nm_strvarray_get_idxnull_or_greturn(setting->path.arr, idx); } /** @@ -524,7 +511,7 @@ nm_setting_match_add_path(NMSettingMatch *setting, const char *path) g_return_if_fail(NM_IS_SETTING_MATCH(setting)); g_return_if_fail(path); - nm_strvarray_add(nm_strvarray_ensure(&setting->path.arr), path); + nm_strvarray_ensure_and_add(&setting->path.arr, path); _notify(setting, PROP_PATH); } @@ -544,7 +531,7 @@ nm_setting_match_remove_path(NMSettingMatch *setting, guint idx) g_return_if_fail(setting->path.arr && idx < setting->path.arr->len); - g_array_remove_index(setting->path.arr, idx); + nm_strvarray_remove_index(setting->path.arr, idx); _notify(setting, PROP_PATH); } @@ -565,12 +552,11 @@ nm_setting_match_remove_path_by_value(NMSettingMatch *setting, const char *path) g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), FALSE); g_return_val_if_fail(path, FALSE); - if (nm_strvarray_remove_first(setting->path.arr, path)) { - _notify(setting, PROP_PATH); - return TRUE; - } + if (!nm_strvarray_remove_first(setting->path.arr, path)) + return FALSE; - return FALSE; + _notify(setting, PROP_PATH); + return TRUE; } /** @@ -586,10 +572,8 @@ nm_setting_match_clear_paths(NMSettingMatch *setting) { g_return_if_fail(NM_IS_SETTING_MATCH(setting)); - if (nm_g_array_len(setting->path.arr) != 0) { - nm_clear_pointer(&setting->path.arr, g_array_unref); + if (nm_strvarray_clear(&setting->path.arr)) _notify(setting, PROP_PATH); - } } /** @@ -608,7 +592,7 @@ nm_setting_match_get_paths(NMSettingMatch *setting, guint *length) { g_return_val_if_fail(NM_IS_SETTING_MATCH(setting), NULL); - return nm_strvarray_get_strv(&setting->path.arr, length); + return nm_strvarray_get_strv_notnull(setting->path.arr, length); } /*****************************************************************************/ @@ -719,19 +703,6 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } static void -finalize(GObject *object) -{ - NMSettingMatch *self = NM_SETTING_MATCH(object); - - nm_clear_pointer(&self->interface_name.arr, g_array_unref); - nm_clear_pointer(&self->kernel_command_line.arr, g_array_unref); - nm_clear_pointer(&self->driver.arr, g_array_unref); - nm_clear_pointer(&self->path.arr, g_array_unref); - - G_OBJECT_CLASS(nm_setting_match_parent_class)->finalize(object); -} - -static void nm_setting_match_class_init(NMSettingMatchClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); @@ -740,7 +711,6 @@ nm_setting_match_class_init(NMSettingMatchClass *klass) object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; - object_class->finalize = finalize; setting_class->verify = verify; diff --git a/src/libnm-core-impl/nm-setting-olpc-mesh.c b/src/libnm-core-impl/nm-setting-olpc-mesh.c index fe6d3842..1b13d99a 100644 --- a/src/libnm-core-impl/nm-setting-olpc-mesh.c +++ b/src/libnm-core-impl/nm-setting-olpc-mesh.c @@ -39,20 +39,18 @@ typedef struct { * OLPC Wireless Mesh Settings */ struct _NMSettingOlpcMesh { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingOlpcMeshPrivate _priv; }; struct _NMSettingOlpcMeshClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING) #define NM_SETTING_OLPC_MESH_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshPrivate)) + _NM_GET_PRIVATE(o, NMSettingOlpcMesh, NM_IS_SETTING_OLPC_MESH, NMSetting) /*****************************************************************************/ @@ -171,8 +169,6 @@ nm_setting_olpc_mesh_class_init(NMSettingOlpcMeshClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingOlpcMeshPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -231,5 +227,5 @@ nm_setting_olpc_mesh_class_init(NMSettingOlpcMeshClass *klass) NM_META_SETTING_TYPE_OLPC_MESH, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingOlpcMesh, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-ovs-bridge.c b/src/libnm-core-impl/nm-setting-ovs-bridge.c index 8e850157..bc5dd04a 100644 --- a/src/libnm-core-impl/nm-setting-ovs-bridge.c +++ b/src/libnm-core-impl/nm-setting-ovs-bridge.c @@ -162,7 +162,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER); + NM_SETTING_CONNECTION_CONTROLLER); return FALSE; } } @@ -242,7 +242,8 @@ nm_setting_ovs_bridge_class_init(NMSettingOvsBridgeClass *klass) PROP_FAIL_MODE, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsBridge, - fail_mode); + fail_mode, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsBridge:mcast-snooping-enable: @@ -305,7 +306,8 @@ nm_setting_ovs_bridge_class_init(NMSettingOvsBridgeClass *klass) PROP_DATAPATH_TYPE, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsBridge, - datapath_type); + datapath_type, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-ovs-dpdk.c b/src/libnm-core-impl/nm-setting-ovs-dpdk.c index 87e9a3e8..53931f46 100644 --- a/src/libnm-core-impl/nm-setting-ovs-dpdk.c +++ b/src/libnm-core-impl/nm-setting-ovs-dpdk.c @@ -190,7 +190,8 @@ nm_setting_ovs_dpdk_class_init(NMSettingOvsDpdkClass *klass) PROP_DEVARGS, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsDpdk, - devargs); + devargs, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsDpdk:n-rxq: diff --git a/src/libnm-core-impl/nm-setting-ovs-interface.c b/src/libnm-core-impl/nm-setting-ovs-interface.c index 34e66480..88379087 100644 --- a/src/libnm-core-impl/nm-setting-ovs-interface.c +++ b/src/libnm-core-impl/nm-setting-ovs-interface.c @@ -312,16 +312,16 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("A connection with a '%s' setting must have a master."), + _("A connection with a '%s' setting must have a controller."), NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER); + NM_SETTING_CONNECTION_CONTROLLER); return FALSE; } - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type && !nm_streq(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -334,7 +334,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } @@ -394,7 +394,8 @@ nm_setting_ovs_interface_class_init(NMSettingOvsInterfaceClass *klass) PROP_TYPE, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsInterface, - type); + type, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsInterface:ofport-request: * diff --git a/src/libnm-core-impl/nm-setting-ovs-patch.c b/src/libnm-core-impl/nm-setting-ovs-patch.c index 2781d435..e44646a6 100644 --- a/src/libnm-core-impl/nm-setting-ovs-patch.c +++ b/src/libnm-core-impl/nm-setting-ovs-patch.c @@ -138,7 +138,8 @@ nm_setting_ovs_patch_class_init(NMSettingOvsPatchClass *klass) PROP_PEER, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsPatch, - peer); + peer, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); diff --git a/src/libnm-core-impl/nm-setting-ovs-port.c b/src/libnm-core-impl/nm-setting-ovs-port.c index 190f1e5d..f2071d43 100644 --- a/src/libnm-core-impl/nm-setting-ovs-port.c +++ b/src/libnm-core-impl/nm-setting-ovs-port.c @@ -349,7 +349,7 @@ verify_trunks(GPtrArray *ranges, GError **error) } for (vlan = range->start; vlan <= range->end; vlan++) { - if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(vlan))) { + if (!g_hash_table_add(h, GUINT_TO_POINTER(vlan))) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -422,16 +422,16 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER); + NM_SETTING_CONNECTION_CONTROLLER); return FALSE; } - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type && strcmp(slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("A connection with a '%s' setting must have the slave-type set to '%s'. " + _("A connection with a '%s' setting must have the port-type set to '%s'. " "Instead it is '%s'"), NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_BRIDGE_SETTING_NAME, @@ -439,7 +439,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } @@ -614,7 +614,8 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass) PROP_VLAN_MODE, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsPort, - vlan_mode); + vlan_mode, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsPort:tag: @@ -672,7 +673,8 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass) PROP_LACP, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsPort, - lacp); + lacp, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsPort:bond-mode: @@ -687,7 +689,8 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass) PROP_BOND_MODE, NM_SETTING_PARAM_INFERRABLE, NMSettingOvsPort, - bond_mode); + bond_mode, + .direct_string_allow_empty = TRUE); /** * NMSettingOvsPort:bond-updelay: diff --git a/src/libnm-core-impl/nm-setting-ppp.c b/src/libnm-core-impl/nm-setting-ppp.c index a9d2b9a2..2ac276b4 100644 --- a/src/libnm-core-impl/nm-setting-ppp.c +++ b/src/libnm-core-impl/nm-setting-ppp.c @@ -68,20 +68,17 @@ typedef struct { * Point-to-Point Protocol Settings */ struct _NMSettingPpp { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingPppPrivate _priv; }; struct _NMSettingPppClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING) -#define NM_SETTING_PPP_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PPP, NMSettingPppPrivate)) +#define NM_SETTING_PPP_GET_PRIVATE(o) _NM_GET_PRIVATE(o, NMSettingPpp, NM_IS_SETTING_PPP, NMSetting) /*****************************************************************************/ @@ -402,8 +399,6 @@ nm_setting_ppp_class_init(NMSettingPppClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingPppPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -698,5 +693,5 @@ nm_setting_ppp_class_init(NMSettingPppClass *klass) NM_META_SETTING_TYPE_PPP, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingPpp, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-pppoe.c b/src/libnm-core-impl/nm-setting-pppoe.c index 5c4f3c28..48da78e7 100644 --- a/src/libnm-core-impl/nm-setting-pppoe.c +++ b/src/libnm-core-impl/nm-setting-pppoe.c @@ -43,20 +43,18 @@ typedef struct { * PPP-over-Ethernet Settings */ struct _NMSettingPppoe { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingPppoePrivate _priv; }; struct _NMSettingPppoeClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING) #define NM_SETTING_PPPOE_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate)) + _NM_GET_PRIVATE(o, NMSettingPppoe, NM_IS_SETTING_PPPOE, NMSetting) /*****************************************************************************/ @@ -220,8 +218,6 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingPppoePrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -244,7 +240,8 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingPppoePrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingPppoe:service: @@ -260,7 +257,8 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) PROP_SERVICE, NM_SETTING_PARAM_NONE, NMSettingPppoePrivate, - service); + service, + .direct_string_allow_empty = TRUE); /** * NMSettingPppoe:username: @@ -273,7 +271,8 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) PROP_USERNAME, NM_SETTING_PARAM_NONE, NMSettingPppoePrivate, - username); + username, + .direct_string_allow_empty = TRUE); /** * NMSettingPppoe:password: @@ -286,7 +285,8 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) PROP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSettingPppoePrivate, - password); + password, + .direct_string_allow_empty = TRUE); /** * NMSettingPppoe:password-flags: @@ -306,5 +306,5 @@ nm_setting_pppoe_class_init(NMSettingPppoeClass *klass) NM_META_SETTING_TYPE_PPPOE, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingPppoe, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index fff6c1cc..9fe49de4 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -6,7 +6,7 @@ #ifndef __NM_SETTING_PRIVATE_H__ #define __NM_SETTING_PRIVATE_H__ -#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) +#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) #error Cannot use this header. #endif @@ -20,6 +20,14 @@ /*****************************************************************************/ +/* This holds a property of type NM_VALUE_TYPE_STRV. You probably want + * to use nm_strvarray_*() API with this. */ +typedef struct { + GArray *arr; +} NMValueStrv; + +/*****************************************************************************/ + struct _NMRefString; typedef struct { @@ -80,6 +88,8 @@ void _nm_connection_private_clear(NMConnectionPrivate *priv); /*****************************************************************************/ +struct _NMSettingPrivate; + /** * NMSetting: * @@ -87,15 +97,13 @@ void _nm_connection_private_clear(NMConnectionPrivate *priv); * It should only be accessed through the functions described below. */ struct _NMSetting { - GObject parent; - /* In the past, this struct was public API. Preserve ABI! */ + GObject parent; + struct _NMSettingPrivate *_priv; }; struct _NMSettingClass { GObjectClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - int (*verify)(NMSetting *setting, NMConnection *connection, GError **error); gboolean (*verify_secrets)(NMSetting *setting, NMConnection *connection, GError **error); @@ -120,8 +128,6 @@ struct _NMSettingClass { NMSettingClearSecretsWithFlagsFn func, gpointer user_data); - void (*padding_1)(void); - void (*duplicate_copy_properties)(const struct _NMSettInfoSetting *sett_info, NMSetting *src, NMSetting *dst); @@ -158,58 +164,41 @@ struct _NMSettingClass { */ struct _NMSettingIPConfig { NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ }; struct _NMSettingIPConfigClass { NMSettingClass parent; - - /* In the past, this struct was public API. Preserve ABI! */ - - union { - gpointer _dummy1; - int private_offset; - }; - - union { - gpointer _dummy2; - gint8 addr_family; - }; - - union { - gpointer _dummy3; - bool is_ipv4; - }; - - gpointer padding[5]; + int private_offset; + gint8 addr_family; + bool is_ipv4; }; typedef struct { - GPtrArray *dns; /* array of IP address strings */ - GPtrArray *dns_search; /* array of domain name strings */ - GPtrArray *dns_options; /* array of DNS options */ - GPtrArray *addresses; /* array of NMIPAddress */ - GPtrArray *routes; /* array of NMIPRoute */ - GPtrArray *routing_rules; - GArray *dhcp_reject_servers; - char *method; - char *gateway; - char *dhcp_hostname; - char *dhcp_iaid; - gint64 route_metric; - int auto_route_ext_gw; - int replace_local_rule; - gint32 required_timeout; - gint32 dad_timeout; - gint32 dhcp_timeout; - gint32 dns_priority; - guint32 route_table; - guint32 dhcp_hostname_flags; - bool ignore_auto_routes; - bool ignore_auto_dns; - bool dhcp_send_hostname; - bool never_default; - bool may_fail; + NMValueStrv dns_search; /* array of domain name strings */ + NMValueStrv dhcp_reject_servers; + NMValueStrv dns_options; /* array of DNS options */ + GPtrArray *dns; /* array of IP address strings */ + GPtrArray *addresses; /* array of NMIPAddress */ + GPtrArray *routes; /* array of NMIPRoute */ + GPtrArray *routing_rules; + char *method; + char *gateway; + char *dhcp_hostname; + char *dhcp_iaid; + gint64 route_metric; + int auto_route_ext_gw; + int replace_local_rule; + gint32 required_timeout; + gint32 dad_timeout; + gint32 dhcp_timeout; + gint32 dns_priority; + guint32 route_table; + guint32 dhcp_hostname_flags; + bool ignore_auto_routes; + bool ignore_auto_dns; + bool dhcp_send_hostname; + bool never_default; + bool may_fail; } NMSettingIPConfigPrivate; void _nm_setting_ip_config_private_init(gpointer self, NMSettingIPConfigPrivate *priv); @@ -296,14 +285,6 @@ gboolean _nm_setting_clear_secrets(NMSetting *setting, /*****************************************************************************/ -/* This holds a property of type NM_VALUE_TYPE_STRV. You probably want - * to use nm_strvarray_*() API with this. */ -typedef struct { - GArray *arr; -} NMValueStrv; - -/*****************************************************************************/ - struct _NMRange { int refcount; guint64 start; @@ -350,6 +331,7 @@ 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; +extern const NMSettInfoPropertType nm_sett_info_propert_type_gprop_strv_oldstyle; extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_boolean; extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_int32; @@ -417,6 +399,18 @@ gboolean _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_ gboolean _nm_setting_property_from_dbus_fcn_gprop(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil); +gboolean _nm_setting_connection_controller_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil); + +GVariant *_nm_setting_connection_controller_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil); + +gboolean _nm_setting_connection_master_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil); + +gboolean _nm_setting_connection_port_type_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil); + +GVariant *_nm_setting_connection_port_type_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil); + +gboolean _nm_setting_connection_slave_type_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil); + GVariant *_nm_setting_to_dbus(NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags, @@ -438,11 +432,7 @@ const NMSettInfoProperty * _nm_sett_info_property_lookup_by_param_spec(const NMSettInfoSetting *sett_info, const GParamSpec *param_spec); -static inline GArray * -_nm_sett_info_property_override_create_array_sized(guint reserved_size) -{ - return g_array_sized_new(FALSE, FALSE, sizeof(NMSettInfoProperty), reserved_size); -} +GArray *_nm_sett_info_property_override_create_array_sized(guint reserved_size); static inline GArray * _nm_sett_info_property_override_create_array(void) @@ -497,23 +487,30 @@ void _nm_setting_class_commit(NMSettingClass *setting_class, gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info); -static inline void +static inline guint _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *prop_info) { nm_assert(properties_override); nm_assert(_nm_properties_override_assert(prop_info)); g_array_append_vals(properties_override, prop_info, 1); + return properties_override->len - 1u; } -#define _nm_properties_override_gobj(properties_override, \ - p_param_spec, \ - p_property_type, \ - ... /* extra NMSettInfoProperty fields */) \ - _nm_properties_override((properties_override), \ - NM_SETT_INFO_PROPERTY(.name = NULL, \ - .param_spec = (p_param_spec), \ - .property_type = (p_property_type), \ - __VA_ARGS__)) +#define _nm_properties_override_gobj(properties_override, \ + p_param_spec, \ + p_property_type, \ + ... /* extra NMSettInfoProperty fields */) \ + ({ \ + GParamSpec *const _p_param_spec_2 = (p_param_spec); \ + \ + nm_assert(_p_param_spec_2); \ + \ + _nm_properties_override((properties_override), \ + NM_SETT_INFO_PROPERTY(.name = _p_param_spec_2->name, \ + .param_spec = _p_param_spec_2, \ + .property_type = (p_property_type), \ + __VA_ARGS__)); \ + }) #define _nm_properties_override_dbus(properties_override, \ p_name, \ @@ -557,12 +554,12 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p \ nm_assert(NM_IN_SET(_default_value, 0, 1)); \ \ - _param_spec = \ - g_param_spec_boolean("" prop_name "", \ - "", \ - "", \ - _default_value, \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_boolean("" prop_name "", \ + "", \ + "", \ + _default_value, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -600,14 +597,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) <= (guint64) (max_value)); \ G_STATIC_ASSERT((max_value) <= (guint64) G_MAXUINT32); \ \ - _param_spec = \ - g_param_spec_uint("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_uint("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -646,14 +643,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) <= (gint64) (max_value)); \ G_STATIC_ASSERT((max_value) <= (gint64) G_MAXUINT32); \ \ - _param_spec = \ - g_param_spec_int("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_int("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -692,14 +689,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) <= (max_value)); \ G_STATIC_ASSERT((max_value) <= G_MAXINT64); \ \ - _param_spec = \ - g_param_spec_int64("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_int64("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -737,14 +734,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT((default_value) == 0 || (default_value) -1u < (max_value)); \ G_STATIC_ASSERT((max_value) <= G_MAXUINT64); \ \ - _param_spec = \ - g_param_spec_uint64("" prop_name "", \ - "", \ - "", \ - (min_value), \ - (max_value), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_uint64("" prop_name "", \ + "", \ + "", \ + (min_value), \ + (max_value), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -769,8 +766,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p private_struct_type, \ private_struct_field, \ ... /* extra NMSettInfoProperty fields */) \ - G_STMT_START \ - { \ + ({ \ GParamSpec *_param_spec; \ const NMSettInfoPropertType *_property_type = (property_type); \ \ @@ -782,14 +778,17 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p nm_assert(_property_type); \ nm_assert(g_variant_type_equal(_property_type->dbus_type, "s")); \ nm_assert(_property_type->direct_type == NM_VALUE_TYPE_STRING); \ - nm_assert(_property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_direct); \ + nm_assert(NM_IN_SET(_property_type->to_dbus_fcn, \ + _nm_setting_property_to_dbus_fcn_direct, \ + _nm_setting_connection_controller_to_dbus, \ + _nm_setting_connection_port_type_to_dbus)); \ \ - _param_spec = \ - g_param_spec_string("" prop_name "", \ - "", \ - "", \ - NULL, \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_string("" prop_name "", \ + "", \ + "", \ + NULL, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -800,8 +799,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p .direct_offset = \ NM_STRUCT_OFFSET_ENSURE_TYPE(char *, private_struct_type, private_struct_field), \ __VA_ARGS__); \ - } \ - G_STMT_END + }) #define _nm_setting_property_define_direct_string(properties_override, \ obj_properties, \ @@ -839,12 +837,12 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p ~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_INFERRABLE \ | NM_SETTING_PARAM_FUZZY_IGNORE))); \ \ - _param_spec = \ - g_param_spec_boxed("" prop_name "", \ - "", \ - "", \ - G_TYPE_BYTES, \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_boxed("" prop_name "", \ + "", \ + "", \ + G_TYPE_BYTES, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -874,12 +872,12 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p \ G_STATIC_ASSERT(!NM_FLAGS_ANY((param_flags), ~(NM_SETTING_PARAM_FUZZY_IGNORE))); \ \ - _param_spec = \ - g_param_spec_boxed("" prop_name "", \ - "", \ - "", \ - G_TYPE_STRV, \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_boxed("" prop_name "", \ + "", \ + "", \ + G_TYPE_STRV, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -915,13 +913,13 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p ~(NM_SETTING_PARAM_REAPPLY_IMMEDIATELY | NM_SETTING_PARAM_FUZZY_IGNORE \ | NM_SETTING_PARAM_INFERRABLE))); \ \ - _param_spec = \ - g_param_spec_enum("" prop_name "", \ - "", \ - "", \ - (gtype_enum), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_enum("" prop_name "", \ + "", \ + "", \ + (gtype_enum), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -976,13 +974,13 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p !NM_FLAGS_ANY((param_flags), \ ~(NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_INFERRABLE))); \ \ - _param_spec = \ - g_param_spec_flags("" prop_name "", \ - "", \ - "", \ - (gtype_flags), \ - (default_value), \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_flags("" prop_name "", \ + "", \ + "", \ + (gtype_flags), \ + (default_value), \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -1035,12 +1033,12 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p | NM_SETTING_PARAM_INFERRABLE \ | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \ \ - _param_spec = \ - g_param_spec_string("" prop_name "", \ - "", \ - "", \ - NULL, \ - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + _param_spec = g_param_spec_string("" prop_name "", \ + "", \ + "", \ + NULL, \ + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY \ + | G_PARAM_STATIC_STRINGS | (param_flags)); \ \ (obj_properties)[(prop_id)] = _param_spec; \ \ @@ -1054,6 +1052,38 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p } \ G_STMT_END +/* This should not be used for new strv properties. Use _nm_setting_property_define_direct_strv(). + * + * FIXME: existing properties should migrate to _nm_setting_property_define_direct_strv(). */ +#define _nm_setting_property_define_gprop_strv_oldstyle(properties_override, \ + obj_properties, \ + prop_name, \ + prop_id, \ + param_flags) \ + G_STMT_START \ + { \ + GParamSpec *_param_spec; \ + \ + G_STATIC_ASSERT(!NM_FLAGS_ANY((param_flags), \ + ~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_FUZZY_IGNORE \ + | NM_SETTING_PARAM_INFERRABLE \ + | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \ + \ + _param_spec = \ + g_param_spec_boxed("" prop_name "", \ + "", \ + "", \ + G_TYPE_STRV, \ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \ + \ + (obj_properties)[(prop_id)] = _param_spec; \ + \ + _nm_properties_override_gobj((properties_override), \ + _param_spec, \ + &nm_sett_info_propert_type_gprop_strv_oldstyle); \ + } \ + G_STMT_END + /*****************************************************************************/ gboolean _nm_setting_use_legacy_property(NMSetting *setting, @@ -1098,4 +1128,11 @@ _nm_sett_info_prop_from_dbus_fcn_cloned_mac_address(_NM_SETT_INFO_PROP_FROM_DBUS /*****************************************************************************/ +void _nm_setting_wireless_normalize_mac_address_randomization( + NMSettingWireless *s_wifi, + const char **out_cloned_mac_address, + NMSettingMacRandomization *out_mac_address_randomization); + +/*****************************************************************************/ + #endif /* NM_SETTING_PRIVATE_H */ diff --git a/src/libnm-core-impl/nm-setting-proxy.c b/src/libnm-core-impl/nm-setting-proxy.c index 8b91210b..e50721df 100644 --- a/src/libnm-core-impl/nm-setting-proxy.c +++ b/src/libnm-core-impl/nm-setting-proxy.c @@ -41,19 +41,18 @@ typedef struct { * WWW Proxy Settings */ struct _NMSettingProxy { - NMSetting parent; + NMSetting parent; + NMSettingProxyPrivate _priv; }; struct _NMSettingProxyClass { NMSettingClass parent; - - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingProxy, nm_setting_proxy, NM_TYPE_SETTING) #define NM_SETTING_PROXY_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_PROXY, NMSettingProxyPrivate)) + _NM_GET_PRIVATE(o, NMSettingProxy, NM_IS_SETTING_PROXY, NMSetting) /*****************************************************************************/ @@ -233,8 +232,6 @@ nm_setting_proxy_class_init(NMSettingProxyClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingProxyPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -310,7 +307,8 @@ nm_setting_proxy_class_init(NMSettingProxyClass *klass) PROP_PAC_URL, NM_SETTING_PARAM_NONE, NMSettingProxyPrivate, - pac_url); + pac_url, + .direct_string_allow_empty = TRUE); /** * NMSettingProxy:pac-script: @@ -342,7 +340,8 @@ nm_setting_proxy_class_init(NMSettingProxyClass *klass) PROP_PAC_SCRIPT, NM_SETTING_PARAM_NONE, NMSettingProxyPrivate, - pac_script); + pac_script, + .direct_string_allow_empty = TRUE); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); @@ -350,5 +349,5 @@ nm_setting_proxy_class_init(NMSettingProxyClass *klass) NM_META_SETTING_TYPE_PROXY, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingProxy, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-serial.c b/src/libnm-core-impl/nm-setting-serial.c index 6fe3e487..ab2a8319 100644 --- a/src/libnm-core-impl/nm-setting-serial.c +++ b/src/libnm-core-impl/nm-setting-serial.c @@ -42,20 +42,18 @@ typedef struct { * Serial Link Settings */ struct _NMSettingSerial { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingSerialPrivate _priv; }; struct _NMSettingSerialClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING) #define NM_SETTING_SERIAL_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_SERIAL, NMSettingSerialPrivate)) + _NM_GET_PRIVATE(o, NMSettingSerial, NM_IS_SETTING_SERIAL, NMSetting) /*****************************************************************************/ @@ -226,8 +224,6 @@ nm_setting_serial_class_init(NMSettingSerialClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingSerialPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; @@ -341,5 +337,5 @@ nm_setting_serial_class_init(NMSettingSerialClass *klass) NM_META_SETTING_TYPE_SERIAL, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingSerial, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-team-port.c b/src/libnm-core-impl/nm-setting-team-port.c index 816d85d9..a881ec5f 100644 --- a/src/libnm-core-impl/nm-setting-team-port.c +++ b/src/libnm-core-impl/nm-setting-team-port.c @@ -41,20 +41,18 @@ typedef struct { * Team Port Settings */ struct _NMSettingTeamPort { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingTeamPortPrivate _priv; }; struct _NMSettingTeamPortClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING) #define NM_SETTING_TEAM_PORT_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortPrivate)) + _NM_GET_PRIVATE(o, NMSettingTeamPort, NM_IS_SETTING_TEAM_PORT, NMSetting) /*****************************************************************************/ @@ -325,7 +323,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (slave_type && strcmp(slave_type, NM_SETTING_TEAM_SETTING_NAME)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -338,7 +336,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE); + NM_SETTING_CONNECTION_PORT_TYPE); return FALSE; } } @@ -532,8 +530,6 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingTeamPortPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -702,5 +698,5 @@ nm_setting_team_port_class_init(NMSettingTeamPortClass *klass) NM_META_SETTING_TYPE_TEAM_PORT, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingTeamPort, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-team.c b/src/libnm-core-impl/nm-setting-team.c index 83de8b6f..2195757f 100644 --- a/src/libnm-core-impl/nm-setting-team.c +++ b/src/libnm-core-impl/nm-setting-team.c @@ -745,20 +745,18 @@ typedef struct { * Teaming Settings */ struct _NMSettingTeam { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingTeamPrivate _priv; }; struct _NMSettingTeamClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingTeam, nm_setting_team, NM_TYPE_SETTING) #define NM_SETTING_TEAM_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TEAM, NMSettingTeamPrivate)) + _NM_GET_PRIVATE(o, NMSettingTeam, NM_IS_SETTING_TEAM, NMSetting) /*****************************************************************************/ @@ -1386,8 +1384,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) break; case NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH: v_ptrarr = priv->team_setting->d.master.runner_tx_hash; - g_value_take_boxed(value, - v_ptrarr ? _nm_utils_ptrarray_to_strv((GPtrArray *) v_ptrarr) : NULL); + g_value_take_boxed(value, nm_strv_ptrarray_to_strv_full(v_ptrarr, FALSE)); break; case NM_TEAM_ATTRIBUTE_LINK_WATCHERS: g_value_take_boxed(value, @@ -1498,8 +1495,6 @@ nm_setting_team_class_init(NMSettingTeamClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingTeamPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -1842,5 +1837,5 @@ nm_setting_team_class_init(NMSettingTeamClass *klass) NM_META_SETTING_TYPE_TEAM, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingTeam, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-tun.c b/src/libnm-core-impl/nm-setting-tun.c index ec095155..05460104 100644 --- a/src/libnm-core-impl/nm-setting-tun.c +++ b/src/libnm-core-impl/nm-setting-tun.c @@ -46,20 +46,17 @@ typedef struct { * Tunnel Settings */ struct _NMSettingTun { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingTunPrivate _priv; }; struct _NMSettingTunClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingTun, nm_setting_tun, NM_TYPE_SETTING) -#define NM_SETTING_TUN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_TUN, NMSettingTunPrivate)) +#define NM_SETTING_TUN_GET_PRIVATE(o) _NM_GET_PRIVATE(o, NMSettingTun, NM_IS_SETTING_TUN, NMSetting) /*****************************************************************************/ @@ -223,8 +220,6 @@ nm_setting_tun_class_init(NMSettingTunClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingTunPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -265,7 +260,8 @@ nm_setting_tun_class_init(NMSettingTunClass *klass) PROP_OWNER, NM_SETTING_PARAM_INFERRABLE, NMSettingTunPrivate, - owner); + owner, + .direct_string_allow_empty = TRUE); /** * NMSettingTun:group: @@ -281,7 +277,8 @@ nm_setting_tun_class_init(NMSettingTunClass *klass) PROP_GROUP, NM_SETTING_PARAM_INFERRABLE, NMSettingTunPrivate, - group); + group, + .direct_string_allow_empty = TRUE); /** * NMSettingTun:pi: @@ -342,5 +339,5 @@ nm_setting_tun_class_init(NMSettingTunClass *klass) NM_META_SETTING_TYPE_TUN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingTun, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-veth.c b/src/libnm-core-impl/nm-setting-veth.c index 40e3c961..6b84233d 100644 --- a/src/libnm-core-impl/nm-setting-veth.c +++ b/src/libnm-core-impl/nm-setting-veth.c @@ -146,7 +146,8 @@ nm_setting_veth_class_init(NMSettingVethClass *klass) PROP_PEER, NM_SETTING_PARAM_INFERRABLE, NMSettingVeth, - _priv.peer); + _priv.peer, + .direct_string_allow_empty = 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 e5a99ce9..534ed713 100644 --- a/src/libnm-core-impl/nm-setting-vlan.c +++ b/src/libnm-core-impl/nm-setting-vlan.c @@ -49,20 +49,18 @@ typedef struct { * VLAN Settings */ struct _NMSettingVlan { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingVlanPrivate _priv; }; struct _NMSettingVlanClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING) #define NM_SETTING_VLAN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VLAN, NMSettingVlanPrivate)) + _NM_GET_PRIVATE(o, NMSettingVlan, NM_IS_SETTING_VLAN, NMSetting) /*****************************************************************************/ @@ -616,7 +614,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) if (s_con) { const char *master = NULL, *slave_type = NULL; - slave_type = nm_setting_connection_get_slave_type(s_con); + slave_type = nm_setting_connection_get_port_type(s_con); if (!g_strcmp0(slave_type, NM_SETTING_VLAN_SETTING_NAME)) master = nm_setting_connection_get_master(s_con); @@ -626,7 +624,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' value doesn't match '%s=%s'"), priv->parent, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, master); g_prefix_error(error, "%s.%s: ", @@ -848,8 +846,6 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingVlanPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -876,7 +872,8 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingVlanPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingVlan:id: @@ -967,7 +964,8 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) NM_SETTING_PARAM_INFERRABLE, NMSettingVlanPrivate, protocol, - .direct_string_is_refstr = TRUE); + .direct_string_is_refstr = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingVlan:ingress-priority-map: @@ -983,12 +981,11 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) * example: VLAN_INGRESS_PRIORITY_MAP=4:2,3:5 * ---end--- */ - obj_properties[PROP_INGRESS_PRIORITY_MAP] = g_param_spec_boxed( - NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, + PROP_INGRESS_PRIORITY_MAP, + NM_SETTING_PARAM_INFERRABLE); /** * NMSettingVlan:egress-priority-map: @@ -1004,12 +1001,11 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) * example: VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7 * ---end--- */ - obj_properties[PROP_EGRESS_PRIORITY_MAP] = g_param_spec_boxed( - NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, + PROP_EGRESS_PRIORITY_MAP, + NM_SETTING_PARAM_INFERRABLE); /* ---ifcfg-rh--- * property: interface-name @@ -1039,5 +1035,5 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) NM_META_SETTING_TYPE_VLAN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingVlan, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-vpn.c b/src/libnm-core-impl/nm-setting-vpn.c index 5984f773..b867d018 100644 --- a/src/libnm-core-impl/nm-setting-vpn.c +++ b/src/libnm-core-impl/nm-setting-vpn.c @@ -80,20 +80,17 @@ typedef struct { * VPN Settings */ struct _NMSettingVpn { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingVpnPrivate _priv; }; struct _NMSettingVpnClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING) -#define NM_SETTING_VPN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VPN, NMSettingVpnPrivate)) +#define NM_SETTING_VPN_GET_PRIVATE(o) _NM_GET_PRIVATE(o, NMSettingVpn, NM_IS_SETTING_VPN, NMSetting) /*****************************************************************************/ @@ -1067,8 +1064,6 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingVpnPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -1095,7 +1090,8 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) PROP_SERVICE_TYPE, NM_SETTING_PARAM_NONE, NMSettingVpnPrivate, - service_type); + service_type, + .direct_string_allow_empty = TRUE); /** * NMSettingVpn:user-name: @@ -1113,7 +1109,8 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) PROP_USER_NAME, NM_SETTING_PARAM_NONE, NMSettingVpnPrivate, - user_name); + user_name, + .direct_string_allow_empty = TRUE); /** * NMSettingVpn:persistent: @@ -1211,5 +1208,5 @@ nm_setting_vpn_class_init(NMSettingVpnClass *klass) NM_META_SETTING_TYPE_VPN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingVpn, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-vxlan.c b/src/libnm-core-impl/nm-setting-vxlan.c index 3fb4c48d..50abd883 100644 --- a/src/libnm-core-impl/nm-setting-vxlan.c +++ b/src/libnm-core-impl/nm-setting-vxlan.c @@ -66,20 +66,18 @@ typedef struct { * VXLAN Settings */ struct _NMSettingVxlan { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingVxlanPrivate _priv; }; struct _NMSettingVxlanClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING) #define NM_SETTING_VXLAN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_VXLAN, NMSettingVxlanPrivate)) + _NM_GET_PRIVATE(o, NMSettingVxlan, NM_IS_SETTING_VXLAN, NMSetting) /*****************************************************************************/ @@ -428,8 +426,6 @@ nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingVxlanPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -448,7 +444,8 @@ nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) PROP_PARENT, NM_SETTING_PARAM_INFERRABLE, NMSettingVxlanPrivate, - parent); + parent, + .direct_string_allow_empty = TRUE); /** * NMSettingVxlan:id: @@ -484,7 +481,8 @@ nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) NMSettingVxlanPrivate, local, .direct_set_string_ip_address_addr_family = - AF_UNSPEC + 1); + AF_UNSPEC + 1, + .direct_string_allow_empty = TRUE); /** * NMSettingVxlan:remote: @@ -503,7 +501,8 @@ nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) NMSettingVxlanPrivate, remote, .direct_set_string_ip_address_addr_family = - AF_UNSPEC + 1); + AF_UNSPEC + 1, + .direct_string_allow_empty = TRUE); /** * NMSettingVxlan:source-port-min: @@ -722,5 +721,5 @@ nm_setting_vxlan_class_init(NMSettingVxlanClass *klass) NM_META_SETTING_TYPE_VXLAN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingVxlan, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-wifi-p2p.c b/src/libnm-core-impl/nm-setting-wifi-p2p.c index e8ce4bdc..31dbea5c 100644 --- a/src/libnm-core-impl/nm-setting-wifi-p2p.c +++ b/src/libnm-core-impl/nm-setting-wifi-p2p.c @@ -201,7 +201,8 @@ nm_setting_wifi_p2p_class_init(NMSettingWifiP2PClass *setting_wifi_p2p_class) PROP_PEER, NM_SETTING_PARAM_NONE, NMSettingWifiP2P, - _priv.peer); + _priv.peer, + .direct_string_allow_empty = TRUE); /** * NMSettingWifiP2P:wps-method: diff --git a/src/libnm-core-impl/nm-setting-wimax.c b/src/libnm-core-impl/nm-setting-wimax.c index c33ad3ea..e68aeb3d 100644 --- a/src/libnm-core-impl/nm-setting-wimax.c +++ b/src/libnm-core-impl/nm-setting-wimax.c @@ -41,20 +41,18 @@ typedef struct { * WiMax Settings */ struct _NMSettingWimax { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingWimaxPrivate _priv; }; struct _NMSettingWimaxClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING) #define NM_SETTING_WIMAX_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate)) + _NM_GET_PRIVATE(o, NMSettingWimax, NM_IS_SETTING_WIMAX, NMSetting) /*****************************************************************************/ @@ -157,8 +155,6 @@ nm_setting_wimax_class_init(NMSettingWimaxClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingWimaxPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -179,7 +175,8 @@ nm_setting_wimax_class_init(NMSettingWimaxClass *klass) NM_SETTING_PARAM_NONE, NMSettingWimaxPrivate, network_name, - .is_deprecated = TRUE, ); + .is_deprecated = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingWimax:mac-address: @@ -206,5 +203,5 @@ nm_setting_wimax_class_init(NMSettingWimaxClass *klass) NM_META_SETTING_TYPE_WIMAX, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingWimax, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-wired.c b/src/libnm-core-impl/nm-setting-wired.c index 1ee16df5..e09fd70d 100644 --- a/src/libnm-core-impl/nm-setting-wired.c +++ b/src/libnm-core-impl/nm-setting-wired.c @@ -75,20 +75,18 @@ typedef struct { * Wired Ethernet Settings */ struct _NMSettingWired { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingWiredPrivate _priv; }; struct _NMSettingWiredClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) #define NM_SETTING_WIRED_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIRED, NMSettingWiredPrivate)) + _NM_GET_PRIVATE(o, NMSettingWired, NM_IS_SETTING_WIRED, NMSetting) /*****************************************************************************/ @@ -314,6 +312,8 @@ nm_setting_wired_get_num_mac_blacklist_items(NMSettingWired *setting) * @setting: the #NMSettingWired * @idx: the zero-based index of the MAC address entry * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) * at index @idx **/ @@ -325,7 +325,12 @@ nm_setting_wired_get_mac_blacklist_item(NMSettingWired *setting, guint32 idx) g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); - g_return_val_if_fail(idx <= priv->mac_address_blacklist->len, NULL); + + if (idx == priv->mac_address_blacklist->len) { + return NULL; + } + + g_return_val_if_fail(idx < priv->mac_address_blacklist->len, NULL); return nm_g_array_index(priv->mac_address_blacklist, const char *, idx); } @@ -886,7 +891,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } } - if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address) + if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address, FALSE) && !nm_utils_hwaddr_valid(priv->cloned_mac_address, ETH_ALEN)) { g_set_error(error, NM_CONNECTION_ERROR, @@ -1172,8 +1177,6 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(klass, sizeof(NMSettingWiredPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; @@ -1200,7 +1203,8 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) PROP_PORT, NM_SETTING_PARAM_NONE, NMSettingWiredPrivate, - port); + port, + .direct_string_allow_empty = TRUE); /** * NMSettingWired:speed: @@ -1266,7 +1270,8 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) PROP_DUPLEX, NM_SETTING_PARAM_NONE, NMSettingWiredPrivate, - duplex); + duplex, + .direct_string_allow_empty = TRUE); /** * NMSettingWired:auto-negotiate: @@ -1455,7 +1460,8 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) PROP_GENERATE_MAC_ADDRESS_MASK, NM_SETTING_PARAM_FUZZY_IGNORE, NMSettingWiredPrivate, - generate_mac_address_mask); + generate_mac_address_mask, + .direct_string_allow_empty = TRUE); /** * NMSettingWired:mac-address-blacklist: @@ -1480,12 +1486,11 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) * example: HWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55" * ---end--- */ - obj_properties[PROP_MAC_ADDRESS_BLACKLIST] = g_param_spec_boxed( - NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, + PROP_MAC_ADDRESS_BLACKLIST, + NM_SETTING_PARAM_FUZZY_IGNORE); /** * NMSettingWired:mtu: @@ -1528,12 +1533,11 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) * example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00c * ---end--- */ - obj_properties[PROP_S390_SUBCHANNELS] = g_param_spec_boxed( - NM_SETTING_WIRED_S390_SUBCHANNELS, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRED_S390_SUBCHANNELS, + PROP_S390_SUBCHANNELS, + NM_SETTING_PARAM_INFERRABLE); /** * NMSettingWired:s390-nettype: @@ -1555,7 +1559,8 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) PROP_S390_NETTYPE, NM_SETTING_PARAM_INFERRABLE, NMSettingWiredPrivate, - s390_nettype); + s390_nettype, + .direct_string_allow_empty = TRUE); /** * NMSettingWired:s390-options: (type GHashTable(utf8,utf8)) @@ -1643,7 +1648,8 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) PROP_WAKE_ON_LAN_PASSWORD, NM_SETTING_PARAM_NONE, NMSettingWiredPrivate, - wol_password); + wol_password, + .direct_string_allow_empty = TRUE); /** * NMSettingWired:accept-all-mac-addresses: @@ -1675,5 +1681,5 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass) NM_META_SETTING_TYPE_WIRED, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingWired, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index b0e3f66c..1e7ed05b 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -1318,7 +1318,7 @@ _peers_set(NMSettingWireGuardPrivate *priv, }; g_ptr_array_add(priv->peers_arr, pd_same_key); - if (!nm_g_hash_table_add(priv->peers_hash, pd_same_key)) + if (!g_hash_table_add(priv->peers_hash, pd_same_key)) nm_assert_not_reached(); nm_assert(_peers_get(priv, pd_same_key->idx) == pd_same_key); @@ -2362,8 +2362,9 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) NM_SETTING_PARAM_SECRET, NMSettingWireGuard, _priv.private_key, - .direct_hook.set_string_fcn = - _set_string_fcn_public_key); + .direct_set_fcn.set_string = + _set_string_fcn_public_key, + .direct_string_allow_empty = TRUE); /** * NMSettingWireGuard:private-key-flags: diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c index a7d12df4..e420b32b 100644 --- a/src/libnm-core-impl/nm-setting-wireless-security.c +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -90,22 +90,18 @@ typedef struct { * Wi-Fi Security Settings */ struct _NMSettingWirelessSecurity { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingWirelessSecurityPrivate _priv; }; struct _NMSettingWirelessSecurityClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING) -#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), \ - NM_TYPE_SETTING_WIRELESS_SECURITY, \ - NMSettingWirelessSecurityPrivate)) +#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) \ + _NM_GET_PRIVATE(o, NMSettingWirelessSecurity, NM_IS_SETTING_WIRELESS_SECURITY, NMSetting) /*****************************************************************************/ @@ -1387,9 +1383,7 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray *properties_override = _nm_sett_info_property_override_create_array(); - - g_type_class_add_private(klass, sizeof(NMSettingWirelessSecurityPrivate)); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(25); object_class->get_property = get_property; object_class->set_property = set_property; @@ -1426,7 +1420,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) NM_SETTING_PARAM_REQUIRED, NMSettingWirelessSecurityPrivate, key_mgmt, - .direct_set_string_ascii_strdown = TRUE); + .direct_set_string_ascii_strdown = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-tx-keyidx: @@ -1479,7 +1474,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) NM_SETTING_PARAM_NONE, NMSettingWirelessSecurityPrivate, auth_alg, - .direct_set_string_ascii_strdown = TRUE); + .direct_set_string_ascii_strdown = TRUE, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:proto: @@ -1496,11 +1492,11 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) * description: Allowed WPA protocols, WPA and WPA2 (RSN). * ---end--- */ - obj_properties[PROP_PROTO] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_PROTO, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRELESS_SECURITY_PROTO, + PROP_PROTO, + NM_SETTING_PARAM_NONE); /** * NMSettingWirelessSecurity:pairwise: @@ -1518,11 +1514,11 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) * separated list. * ---end--- */ - obj_properties[PROP_PAIRWISE] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_PAIRWISE, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE, + PROP_PAIRWISE, + NM_SETTING_PARAM_NONE); /** * NMSettingWirelessSecurity:group: @@ -1540,11 +1536,11 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) * separated list. * ---end--- */ - obj_properties[PROP_GROUP] = g_param_spec_boxed(NM_SETTING_WIRELESS_SECURITY_GROUP, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRELESS_SECURITY_GROUP, + PROP_GROUP, + NM_SETTING_PARAM_NONE); /** * NMSettingWirelessSecurity:pmf: @@ -1597,7 +1593,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_LEAP_USERNAME, NM_SETTING_PARAM_NONE, NMSettingWirelessSecurityPrivate, - leap_username); + leap_username, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-key0: @@ -1617,7 +1614,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_WEP_KEY0, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - wep_key0); + wep_key0, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-key1: @@ -1637,7 +1635,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_WEP_KEY1, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - wep_key1); + wep_key1, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-key2: @@ -1657,7 +1656,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_WEP_KEY2, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - wep_key2); + wep_key2, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-key3: @@ -1677,7 +1677,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_WEP_KEY3, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - wep_key3); + wep_key3, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:wep-key-flags: @@ -1721,7 +1722,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_PSK, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - psk); + psk, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:psk-flags: @@ -1763,7 +1765,8 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) PROP_LEAP_PASSWORD, NM_SETTING_PARAM_SECRET, NMSettingWirelessSecurityPrivate, - leap_password); + leap_password, + .direct_string_allow_empty = TRUE); /** * NMSettingWirelessSecurity:leap-password-flags: @@ -1894,5 +1897,5 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) NM_META_SETTING_TYPE_WIRELESS_SECURITY, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingWirelessSecurity, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c index e2cd1f49..152bbde3 100644 --- a/src/libnm-core-impl/nm-setting-wireless.c +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -72,20 +72,18 @@ typedef struct { * Wi-Fi Settings */ struct _NMSettingWireless { - NMSetting parent; - /* In the past, this struct was public API. Preserve ABI! */ + NMSetting parent; + NMSettingWirelessPrivate _priv; }; struct _NMSettingWirelessClass { NMSettingClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; G_DEFINE_TYPE(NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING) #define NM_SETTING_WIRELESS_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessPrivate)) + _NM_GET_PRIVATE(o, NMSettingWireless, NM_IS_SETTING_WIRELESS, NMSetting) /*****************************************************************************/ @@ -499,6 +497,8 @@ nm_setting_wireless_get_num_mac_blacklist_items(NMSettingWireless *setting) * @setting: the #NMSettingWireless * @idx: the zero-based index of the MAC address entry * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) * at index @idx **/ @@ -510,7 +510,12 @@ nm_setting_wireless_get_mac_blacklist_item(NMSettingWireless *setting, guint32 i g_return_val_if_fail(NM_IS_SETTING_WIRELESS(setting), NULL); priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); - g_return_val_if_fail(idx <= priv->mac_address_blacklist->len, NULL); + + if (idx == priv->mac_address_blacklist->len) { + return NULL; + } + + g_return_val_if_fail(idx < priv->mac_address_blacklist->len, NULL); return nm_g_array_index(priv->mac_address_blacklist, const char *, idx); } @@ -824,6 +829,49 @@ nm_setting_wireless_get_ap_isolation(NMSettingWireless *setting) /*****************************************************************************/ +void +_nm_setting_wireless_normalize_mac_address_randomization( + NMSettingWireless *s_wifi, + const char **out_cloned_mac_address, + NMSettingMacRandomization *out_mac_address_randomization) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(s_wifi); + guint32 mac_address_randomization; + const char *cloned_mac_address; + + mac_address_randomization = priv->mac_address_randomization; + cloned_mac_address = priv->cloned_mac_address; + + if (cloned_mac_address) { + /* If cloned_mac_address is set, it takes precedence and determines + * mac_address_randomization. */ + if (nm_streq(cloned_mac_address, "random")) + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; + else if (nm_streq(cloned_mac_address, "permanent")) + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + else + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + } else if (!NM_IN_SET(mac_address_randomization, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_NEVER, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS)) { + /* cloned_mac_address is NULL and mac_address_randomization is invalid. Normalize + * mac_address_randomization to the default. */ + mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + } else if (mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { + /* mac_address_randomization is not (guint32)set to the default. cloned_mac_address gets + * overwritten. */ + cloned_mac_address = mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS + ? "random" + : "permanent"; + } + + *out_cloned_mac_address = cloned_mac_address; + *out_mac_address_randomization = mac_address_randomization; +} + +/*****************************************************************************/ + static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { @@ -837,6 +885,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) guint i; gsize length; GError *local = NULL; + const char *desired_cloned_mac_address; + NMSettingMacRandomization desired_mac_address_randomization; if (!priv->ssid) { g_set_error_literal(error, @@ -958,7 +1008,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address) + if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address, TRUE) && !nm_utils_hwaddr_valid(priv->cloned_mac_address, ETH_ALEN)) { g_set_error_literal(error, NM_CONNECTION_ERROR, @@ -1082,27 +1132,21 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) /* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */ - if (priv->cloned_mac_address) { - if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_ALWAYS - && nm_streq(priv->cloned_mac_address, "random")) - goto mac_addr_rand_ok; - if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_NEVER - && nm_streq(priv->cloned_mac_address, "permanent")) - goto mac_addr_rand_ok; - if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) - goto mac_addr_rand_ok; - } else if (priv->mac_address_randomization == NM_SETTING_MAC_RANDOMIZATION_DEFAULT) - goto mac_addr_rand_ok; - g_set_error(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("conflicting value of mac-address-randomization and cloned-mac-address")); - g_prefix_error(error, - "%s.%s: ", - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS); - return NM_SETTING_VERIFY_NORMALIZABLE; -mac_addr_rand_ok: + _nm_setting_wireless_normalize_mac_address_randomization(NM_SETTING_WIRELESS(setting), + &desired_cloned_mac_address, + &desired_mac_address_randomization); + if (desired_mac_address_randomization != priv->mac_address_randomization + || !nm_streq0(desired_cloned_mac_address, priv->cloned_mac_address)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("conflicting value of mac-address-randomization and cloned-mac-address")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS); + return NM_SETTING_VERIFY_NORMALIZABLE; + } if (priv->tx_power != 0 || priv->rate != 0) { g_set_error(error, @@ -1209,25 +1253,33 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(object); + NMSettingWireless *self = NM_SETTING_WIRELESS(object); + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(self); const char *const *blacklist; const char *mac; gboolean bool_val; + _PropertyEnums prop1 = PROP_0; + _PropertyEnums prop2 = PROP_0; switch (prop_id) { case PROP_CLONED_MAC_ADDRESS: bool_val = !!priv->cloned_mac_address; - g_free(priv->cloned_mac_address); - priv->cloned_mac_address = - _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); + + if (nm_strdup_reset_take( + &priv->cloned_mac_address, + _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN))) + prop1 = prop_id; + if (bool_val && !priv->cloned_mac_address) { /* cloned-mac-address was set before but was now explicitly cleared. * In this case, we also clear mac-address-randomization flag */ if (priv->mac_address_randomization != NM_SETTING_MAC_RANDOMIZATION_DEFAULT) { priv->mac_address_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; - _notify(NM_SETTING_WIRELESS(object), PROP_MAC_ADDRESS_RANDOMIZATION); + prop2 = PROP_MAC_ADDRESS_RANDOMIZATION; } } + + nm_gobject_notify_together(self, prop1, prop2); break; case PROP_MAC_ADDRESS_BLACKLIST: blacklist = g_value_get_boxed(value); @@ -1307,9 +1359,7 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray *properties_override = _nm_sett_info_property_override_create_array(); - - g_type_class_add_private(klass, sizeof(NMSettingWirelessPrivate)); + GArray *properties_override = _nm_sett_info_property_override_create_array_sized(25); object_class->set_property = set_property; object_class->get_property = get_property; @@ -1363,7 +1413,8 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) PROP_MODE, NM_SETTING_PARAM_NONE, NMSettingWirelessPrivate, - mode); + mode, + .direct_string_allow_empty = TRUE); /** * NMSettingWireless:band: @@ -1390,7 +1441,8 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) PROP_BAND, NM_SETTING_PARAM_NONE, NMSettingWirelessPrivate, - band); + band, + .direct_string_allow_empty = TRUE); /** * NMSettingWireless:channel: @@ -1539,12 +1591,14 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) * This is known as MAC cloning or spoofing. * * Beside explicitly specifying a MAC address, the special values "preserve", "permanent", - * "random" and "stable" are supported. + * "random", "stable" and "stable-ssid" are supported. * "preserve" means not to touch the MAC address on activation. * "permanent" means to use the permanent hardware address of the device. * "random" creates a random MAC address on each connect. * "stable" creates a hashed MAC address based on connection.stable-id and a * machine dependent key. + * "stable-ssid" creates a hashed MAC address based on the SSID, the same as setting the + * stable-id to "${NETWORK_SSID}". * * If unspecified, the value can be overwritten via global defaults, see manual * of NetworkManager.conf. If still unspecified, it defaults to "preserve" @@ -1576,12 +1630,13 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) * For libnm and nmcli, this field is called "cloned-mac-address". * ---end--- */ - obj_properties[PROP_CLONED_MAC_ADDRESS] = g_param_spec_string( - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - "", - "", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CLONED_MAC_ADDRESS] = + g_param_spec_string(NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY + | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); _nm_properties_override_gobj( properties_override, obj_properties[PROP_CLONED_MAC_ADDRESS], @@ -1654,7 +1709,8 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) PROP_GENERATE_MAC_ADDRESS_MASK, NM_SETTING_PARAM_FUZZY_IGNORE, NMSettingWirelessPrivate, - generate_mac_address_mask); + generate_mac_address_mask, + .direct_string_allow_empty = TRUE); /** * NMSettingWireless:mac-address-blacklist: @@ -1677,12 +1733,11 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) * is listed. * ---end--- */ - obj_properties[PROP_MAC_ADDRESS_BLACKLIST] = g_param_spec_boxed( - NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, - "", - "", - G_TYPE_STRV, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _nm_setting_property_define_gprop_strv_oldstyle(properties_override, + obj_properties, + NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, + PROP_MAC_ADDRESS_BLACKLIST, + NM_SETTING_PARAM_FUZZY_IGNORE); /** * NMSettingWireless:seen-bssids: @@ -1925,5 +1980,5 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) NM_META_SETTING_TYPE_WIRELESS, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingWireless, _priv)); } diff --git a/src/libnm-core-impl/nm-setting-wpan.c b/src/libnm-core-impl/nm-setting-wpan.c index bc84b01e..ba947a86 100644 --- a/src/libnm-core-impl/nm-setting-wpan.c +++ b/src/libnm-core-impl/nm-setting-wpan.c @@ -57,7 +57,8 @@ typedef struct { * Since: 1.14 */ struct _NMSettingWpan { - NMSetting parent; + NMSetting parent; + NMSettingWpanPrivate _priv; }; struct _NMSettingWpanClass { @@ -67,7 +68,7 @@ struct _NMSettingWpanClass { G_DEFINE_TYPE(NMSettingWpan, nm_setting_wpan, NM_TYPE_SETTING) #define NM_SETTING_WPAN_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WPAN, NMSettingWpanPrivate)) + _NM_GET_PRIVATE(o, NMSettingWpan, NM_IS_SETTING_WPAN, NMSetting) /*****************************************************************************/ @@ -228,8 +229,6 @@ nm_setting_wpan_class_init(NMSettingWpanClass *klass) NMSettingClass *setting_class = NM_SETTING_CLASS(klass); GArray *properties_override = _nm_sett_info_property_override_create_array(); - g_type_class_add_private(setting_class, sizeof(NMSettingWpanPrivate)); - object_class->get_property = _nm_setting_property_get_property_direct; object_class->set_property = _nm_setting_property_set_property_direct; @@ -256,7 +255,8 @@ nm_setting_wpan_class_init(NMSettingWpanClass *klass) NMSettingWpanPrivate, mac_address, .direct_set_string_mac_address_len = - IEEE802154_ADDR_LEN); + IEEE802154_ADDR_LEN, + .direct_string_allow_empty = TRUE); /** * NMSettingWpan:pan-id: @@ -334,5 +334,5 @@ nm_setting_wpan_class_init(NMSettingWpanClass *klass) NM_META_SETTING_TYPE_WPAN, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + G_STRUCT_OFFSET(NMSettingWpan, _priv)); } diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index 276dfd34..758338e5 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -11,7 +11,6 @@ #include "libnm-core-intern/nm-core-internal.h" #include "libnm-glib-aux/nm-ref-string.h" #include "libnm-glib-aux/nm-secret-utils.h" -#include "nm-property-compare.h" #include "nm-setting-private.h" #include "nm-utils-private.h" #include "nm-utils.h" @@ -58,14 +57,13 @@ typedef struct { NM_GOBJECT_PROPERTIES_DEFINE(NMSetting, PROP_NAME, ); -typedef struct { +typedef struct _NMSettingPrivate { GenData *gendata; } NMSettingPrivate; G_DEFINE_ABSTRACT_TYPE(NMSetting, nm_setting, G_TYPE_OBJECT) -#define NM_SETTING_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING, NMSettingPrivate)) +#define NM_SETTING_GET_PRIVATE(o) _NM_GET_PRIVATE_PTR(o, NMSetting, NM_IS_SETTING) /*****************************************************************************/ @@ -165,7 +163,7 @@ _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_ty /*****************************************************************************/ -static const NMSettInfoProperty * +_nm_unused static const NMSettInfoProperty * _nm_sett_info_property_find_in_array(const NMSettInfoProperty *properties, guint len, const char *name) @@ -184,9 +182,8 @@ _nm_properties_override_assert(const NMSettInfoProperty *prop_info) { #if NM_MORE_ASSERTS nm_assert(prop_info); - nm_assert((!!prop_info->name) != (!!prop_info->param_spec)); - nm_assert(!prop_info->param_spec || !prop_info->name - || nm_streq0(prop_info->name, prop_info->param_spec->name)); + nm_assert(prop_info->name); + nm_assert(!prop_info->param_spec || prop_info->name == prop_info->param_spec->name); if (prop_info->property_type) { const NMSettInfoPropertType *property_type = prop_info->property_type; @@ -209,6 +206,34 @@ _nm_properties_override_assert(const NMSettInfoProperty *prop_info) return TRUE; } +GArray * +_nm_sett_info_property_override_create_array_sized(guint reserved_size) +{ + GArray *properties_override; + GParamSpec *param_spec; + + /* pre-allocate a relatively large buffer to avoid frequent re-allocations. + * Note that the buffer is only short-lived and will be destroyed by + * _nm_setting_class_commit(). */ + properties_override = + g_array_sized_new(FALSE, FALSE, sizeof(NMSettInfoProperty), reserved_size); + + /* The "name" property is special because it's defined in the + * parent class NMSetting. We add the property info right here. + */ + param_spec = obj_properties[PROP_NAME]; + nm_assert(param_spec); + nm_assert(nm_streq0(param_spec->name, NM_SETTING_NAME)); + nm_assert(param_spec + == g_object_class_find_property(g_type_class_peek(NM_TYPE_SETTING), NM_SETTING_NAME)); + nm_assert(!NM_FLAGS_HAS(param_spec->flags, G_PARAM_WRITABLE)); + _nm_properties_override_gobj(properties_override, + param_spec, + &nm_sett_info_propert_type_setting_name); + + return properties_override; +} + static NMSettInfoSetting _sett_info_settings[_NM_META_SETTING_TYPE_NUM]; const NMSettInfoSetting * @@ -224,10 +249,8 @@ _property_infos_sort_cmp_setting_connection(gconstpointer p_a, { const NMSettInfoProperty *a = *((const NMSettInfoProperty *const *) p_a); const NMSettInfoProperty *b = *((const NMSettInfoProperty *const *) p_b); - int c_name; - c_name = strcmp(a->name, b->name); - nm_assert(c_name != 0); + nm_assert(a->name && b->name && !nm_streq(a->name, b->name)); #define CMP_AND_RETURN(n_a, n_b, name) \ G_STMT_START \ @@ -240,15 +263,14 @@ _property_infos_sort_cmp_setting_connection(gconstpointer p_a, G_STMT_END /* for [connection], report first id, uuid, type in that order. */ - if (c_name != 0) { - CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_ID); - CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_UUID); - CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_TYPE); - } + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_ID); + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_UUID); + CMP_AND_RETURN(a->name, b->name, NM_SETTING_CONNECTION_TYPE); #undef CMP_AND_RETURN - return c_name; + NM_CMP_FIELD_STR(a, b, name); + return nm_assert_unreachable_val(0); } static const NMSettInfoProperty *const * @@ -306,12 +328,14 @@ _nm_setting_class_commit(NMSettingClass *setting_class, GArray *properties_override, gint16 private_offset) { - NMSettInfoSetting *sett_info; - gs_free GParamSpec **property_specs = NULL; - guint n_property_specs; + NMSettInfoSetting *sett_info; +#if NM_MORE_ASSERTS > 10 + gs_free GParamSpec **property_specs = NULL; + guint n_property_specs; + guint i; +#endif NMSettInfoPropertLookupByParamSpec *lookup_by_iter; guint override_len; - guint i; guint16 j; nm_assert(NM_IS_SETTING_CLASS(setting_class)); @@ -325,37 +349,28 @@ _nm_setting_class_commit(NMSettingClass *setting_class, nm_assert(!sett_info->property_infos_len); nm_assert(!sett_info->property_infos); - property_specs = - g_object_class_list_properties(G_OBJECT_CLASS(setting_class), &n_property_specs); - - if (!properties_override) { - override_len = 0; - properties_override = _nm_sett_info_property_override_create_array_sized(n_property_specs); - } else { - override_len = properties_override->len; + if (!properties_override) + properties_override = _nm_sett_info_property_override_create_array_sized(1); - for (i = 0; i < override_len; i++) { - NMSettInfoProperty *p = &nm_g_array_index(properties_override, NMSettInfoProperty, i); + override_len = properties_override->len; - nm_assert((!!p->name) != (!!p->param_spec)); - - if (!p->name) { - nm_assert(p->param_spec); - p->name = p->param_spec->name; - } else - nm_assert(!p->param_spec); - } - } + nm_assert(override_len > 0); #if NM_MORE_ASSERTS > 10 + property_specs = + g_object_class_list_properties(G_OBJECT_CLASS(setting_class), &n_property_specs); + /* assert that properties_override is constructed consistently. */ for (i = 0; i < override_len; i++) { const NMSettInfoProperty *p = &nm_g_array_index(properties_override, NMSettInfoProperty, i); gboolean found = FALSE; guint k; + nm_assert(p->name); + nm_assert(!p->param_spec || p->name == p->param_spec->name); + nm_assert(!_nm_sett_info_property_find_in_array( - nm_g_array_index_p(properties_override, NMSettInfoProperty, 0), + nm_g_array_first_p(properties_override, NMSettInfoProperty), i, p->name)); for (k = 0; k < n_property_specs; k++) { @@ -367,79 +382,38 @@ _nm_setting_class_commit(NMSettingClass *setting_class, } nm_assert(found == (p->param_spec != NULL)); } -#endif for (i = 0; i < n_property_specs; i++) { - const char *name = property_specs[i]->name; - NMSettInfoProperty *p; - - if (_nm_sett_info_property_find_in_array( - nm_g_array_index_p(properties_override, NMSettInfoProperty, 0), - override_len, - name)) - continue; - - p = nm_g_array_append_new(properties_override, NMSettInfoProperty); - memset(p, 0, sizeof(*p)); - p->name = name; - p->param_spec = property_specs[i]; + const GParamSpec *param_spec = property_specs[i]; + const char *name = param_spec->name; + const NMSettInfoProperty *p; + + p = _nm_sett_info_property_find_in_array( + nm_g_array_first_p(properties_override, NMSettInfoProperty), + override_len, + name); + nm_assert(p); + nm_assert(p->param_spec); + nm_assert(p->param_spec == param_spec); } for (i = 0; i < properties_override->len; i++) { NMSettInfoProperty *p = &nm_g_array_index(properties_override, NMSettInfoProperty, i); - GType vtype; - - if (p->property_type) - goto has_property_type; - - nm_assert(p->param_spec); - - vtype = p->param_spec->value_type; - if (vtype == G_TYPE_STRING) { - /* The "name" property is a bit special because it's defined in the - * parent class NMSetting. We set the property_type here, because - * it's more convenient (albeit a bit ugly). - * - * FIXME: let _nm_sett_info_property_override_create_array() always add - * the handling of the name property.*/ - nm_assert(nm_streq(p->name, NM_SETTING_NAME)); - nm_assert(!NM_FLAGS_HAS(p->param_spec->flags, G_PARAM_WRITABLE)); - p->property_type = &nm_sett_info_propert_type_setting_name; - goto has_property_type; - } - - if (vtype == G_TYPE_STRV) - p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP( - G_VARIANT_TYPE_STRING_ARRAY, - .compare_fcn = _nm_setting_property_compare_fcn_default, - .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, - .from_dbus_is_full = TRUE); - else - nm_assert_not_reached(); - -has_property_type: nm_assert(p->property_type); nm_assert(p->property_type->dbus_type); nm_assert(g_variant_type_string_is_valid((const char *) p->property_type->dbus_type)); + nm_assert(p->name); + nm_assert(!p->param_spec || nm_streq0(p->name, p->param_spec->name)); } +#endif G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMSettInfoProperty, name) == 0); g_array_sort(properties_override, nm_strcmp_p); setting_class->setting_info = &nm_meta_setting_infos[meta_type]; sett_info->setting_class = setting_class; - - if (private_offset == NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS) { - int o; - - o = g_type_class_get_instance_private_offset(setting_class); - nm_assert(o != NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); - nm_assert(o > G_MININT16); - nm_assert(o < 0); - private_offset = o; - } - sett_info->private_offset = private_offset; + sett_info->private_offset = private_offset; if (detail) sett_info->detail = *detail; @@ -708,10 +682,10 @@ _property_direct_set_string(const NMSettInfoSetting *sett_info, + (!!property_info->direct_string_is_refstr) + (property_info->direct_set_string_mac_address_len > 0) + (property_info->direct_set_string_ip_address_addr_family != 0)) - <= (property_info->direct_hook.set_string_fcn ? 0 : 1)); + <= (property_info->direct_set_fcn.set_string ? 0 : 1)); - if (property_info->direct_hook.set_string_fcn) { - return property_info->direct_hook.set_string_fcn(sett_info, property_info, setting, src); + if (property_info->direct_set_fcn.set_string) { + return property_info->direct_set_fcn.set_string(sett_info, property_info, setting, src); } dst = _nm_setting_get_private_field(setting, sett_info, property_info); @@ -754,6 +728,24 @@ out_take: return nm_strdup_reset_take(dst, s); } +static gboolean +_property_direct_set_strv(const NMSettInfoSetting *sett_info, + const NMSettInfoProperty *property_info, + NMSetting *setting, + const char *const *strv) +{ + NMValueStrv *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); + + if (!property_info->direct_strv_preserve_empty && strv && !strv[0]) + strv = NULL; + + if (nm_strvarray_equal_strv(p_val->arr, strv, -1)) + return FALSE; + + nm_strvarray_set_strv_full(&p_val->arr, strv, property_info->direct_strv_preserve_empty); + return TRUE; +} + void _nm_setting_property_get_property_direct(GObject *object, guint prop_id, @@ -842,14 +834,19 @@ _nm_setting_property_get_property_direct(GObject *object, { const NMValueStrv *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); - g_value_take_boxed(value, nm_strvarray_get_strv_non_empty_dup(p_val->arr, NULL)); + g_value_take_boxed( + value, + nm_strvarray_get_strv_full_dup(p_val->arr, + NULL, + FALSE, + property_info->direct_strv_preserve_empty)); return; } default: goto out_fail; } - return; + nm_assert_not_reached(); out_fail: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -981,28 +978,22 @@ _nm_setting_property_set_property_direct(GObject *object, goto out_notify; } case NM_VALUE_TYPE_STRV: - { - NMValueStrv *p_val = _nm_setting_get_private_field(setting, sett_info, property_info); - const char *const *v; - - v = g_value_get_boxed(value); - if (nm_strvarray_equal_strv(p_val->arr, v, -1)) + if (!_property_direct_set_strv(sett_info, property_info, setting, g_value_get_boxed(value))) return; - - nm_strvarray_set_strv(&p_val->arr, v); goto out_notify; - } default: goto out_fail; } - return; + nm_assert_not_reached(); out_notify: - /* If explicit-notify would be set, we would need to emit g_object_notify_by_pspec(). - * - * Currently we never set that, also because we still support glib 2.40. */ - nm_assert(!NM_FLAGS_HAS(pspec->flags, 1 << 30 /* G_PARAM_EXPLICIT_NOTIFY */)); + nm_assert(NM_FLAGS_HAS(pspec->flags, G_PARAM_EXPLICIT_NOTIFY)); + + nm_gobject_notify_together_by_pspec(object, + property_info->param_spec, + property_info->direct_also_notify); + return; out_fail: @@ -1306,6 +1297,11 @@ _nm_setting_property_to_dbus_fcn_direct(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_ (const NMValueStrv *) _nm_setting_get_private_field(setting, sett_info, property_info); if (!val->arr) return NULL; + if (!property_info->direct_strv_preserve_empty && val->arr->len == 0) { + /* This property does not treat empty strv arrays special. No need + * to export the value on D-Bus. */ + return NULL; + } return g_variant_new_strv(nm_g_array_data(val->arr), val->arr->len); } default: @@ -1393,7 +1389,9 @@ _nm_setting_property_from_dbus_fcn_direct_mac_address(_NM_SETT_INFO_PROP_FROM_DB if (nm_strdup_reset_take(_nm_setting_get_private_field(setting, sett_info, property_info), length > 0 ? nm_utils_hwaddr_ntoa(array, length) : NULL)) { - g_object_notify_by_pspec(G_OBJECT(setting), property_info->param_spec); + nm_gobject_notify_together_by_pspec(setting, + property_info->param_spec, + property_info->direct_also_notify); } else *out_is_modified = FALSE; @@ -1670,7 +1668,6 @@ _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS } case NM_VALUE_TYPE_STRV: { - NMValueStrv *p_val; gs_free const char **ss = NULL; gsize ss_len; @@ -1681,13 +1678,10 @@ _nm_setting_property_from_dbus_fcn_direct(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS ss = g_variant_get_strv(value, &ss_len); nm_assert(ss_len <= G_MAXUINT); + nm_assert(NM_PTRARRAY_LEN(ss) == ss_len); - p_val = _nm_setting_get_private_field(setting, sett_info, property_info); - - if (nm_strvarray_equal_strv(p_val->arr, ss, ss_len)) + if (!_property_direct_set_strv(sett_info, property_info, setting, ss)) goto out_unchanged; - - nm_strvarray_set_strv(&p_val->arr, ss); goto out_notify; } default: @@ -1701,7 +1695,9 @@ out_unchanged: out_notify: *out_is_modified = TRUE; - g_object_notify_by_pspec(G_OBJECT(setting), property_info->param_spec); + nm_gobject_notify_together_by_pspec(setting, + property_info->param_spec, + property_info->direct_also_notify); return TRUE; out_error_wrong_dbus_type: @@ -2409,17 +2405,87 @@ nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error) return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; } +static gboolean +_verify_properties(NMSetting *setting, GError **error) +{ + NMSettingClass *klass = NM_SETTING_GET_CLASS(setting); + const NMSettInfoSetting *sett_info = _nm_setting_class_get_sett_info(klass); + guint16 i; + + if (!sett_info) + return TRUE; + + for (i = 0; i < sett_info->property_infos_len; i++) { + const NMSettInfoProperty *property_info = &sett_info->property_infos[i]; + + switch (property_info->property_type->direct_type) { + case NM_VALUE_TYPE_BOOL: + case NM_VALUE_TYPE_BYTES: + case NM_VALUE_TYPE_STRV: + case NM_VALUE_TYPE_ENUM: + case NM_VALUE_TYPE_FLAGS: + case NM_VALUE_TYPE_INT32: + case NM_VALUE_TYPE_INT64: + case NM_VALUE_TYPE_NONE: + case NM_VALUE_TYPE_UINT32: + case NM_VALUE_TYPE_UINT64: + break; + case NM_VALUE_TYPE_STRING: + { + const char *val; + + if (!property_info->direct_string_allow_empty + && (val = *((const char *const *) + _nm_setting_get_private_field(setting, sett_info, property_info))) + && val[0] == '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot be empty")); + g_prefix_error(error, + "%s.%s: ", + klass->setting_info->setting_name, + property_info->name); + return FALSE; + } + break; + } + default: + nm_assert_not_reached(); + } + } + + return TRUE; +} + NMSettingVerifyResult _nm_setting_verify(NMSetting *setting, NMConnection *connection, GError **error) { + NMSettingClass *klass; + NMSettingVerifyResult r; + g_return_val_if_fail(NM_IS_SETTING(setting), NM_SETTING_VERIFY_ERROR); g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), NM_SETTING_VERIFY_ERROR); g_return_val_if_fail(!error || *error == NULL, NM_SETTING_VERIFY_ERROR); - if (NM_SETTING_GET_CLASS(setting)->verify) - return NM_SETTING_GET_CLASS(setting)->verify(setting, connection, error); + klass = NM_SETTING_GET_CLASS(setting); - return NM_SETTING_VERIFY_SUCCESS; + if (!klass->verify) + return NM_SETTING_VERIFY_SUCCESS; + + r = klass->verify(setting, connection, error); + + if (r != NM_SETTING_VERIFY_ERROR) { + gs_free_error GError *local = NULL; + + if (!_verify_properties(setting, &local)) { + g_clear_error(error); + g_propagate_error(error, g_steal_pointer(&local)); + r = NM_SETTING_VERIFY_ERROR; + } + } + + return r; } /** @@ -2570,7 +2636,9 @@ _nm_setting_property_compare_fcn_direct(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_ nm_assert(NM_IN_SET(property_info->property_type->to_dbus_fcn, _nm_setting_property_to_dbus_fcn_direct, - _nm_setting_property_to_dbus_fcn_direct_mac_address)); + _nm_setting_property_to_dbus_fcn_direct_mac_address, + _nm_setting_connection_controller_to_dbus, + _nm_setting_connection_port_type_to_dbus)); if (!property_info->param_spec) return nm_assert_unreachable_val(NM_TERNARY_DEFAULT); @@ -2604,8 +2672,21 @@ _nm_setting_property_compare_fcn_direct(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_ case NM_VALUE_TYPE_BYTES: return nm_g_bytes_equal0(*((const GBytes *const *) p_a), *((const GBytes *const *) p_b)); case NM_VALUE_TYPE_STRV: - return nm_strvarray_equal(((const NMValueStrv *) p_a)->arr, - ((const NMValueStrv *) p_b)->arr); + { + const NMValueStrv *v_a = p_a; + const NMValueStrv *v_b = p_b; + const GArray *a = v_a->arr; + const GArray *b = v_b->arr; + + if (!property_info->direct_strv_preserve_empty) { + /* NULL and empty are treated identical. Coerce to NULL. */ + if (a && a->len == 0) + a = NULL; + if (b && b->len == 0) + b = NULL; + } + return nm_strvarray_equal(a, b); + } default: return nm_assert_unreachable_val(TRUE); } @@ -2643,7 +2724,7 @@ _nm_setting_property_compare_fcn_default(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE); - return nm_property_compare(value1, value2) == 0; + return nm_g_variant_equal(value1, value2); } } @@ -3617,6 +3698,15 @@ const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u = /* No functions set. This property type is to silently ignore the value on D-Bus. */ .compare_fcn = _nm_setting_property_compare_fcn_ignore); +/* This should not be used for new strv properties. Use nm_sett_info_propert_type_direct_strv. + * + * FIXME: existing properties should migrate to nm_sett_info_propert_type_direct_strv. */ +const NMSettInfoPropertType nm_sett_info_propert_type_gprop_strv_oldstyle = + NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(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); + 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, @@ -4374,7 +4464,13 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static void nm_setting_init(NMSetting *setting) -{} +{ + NMSettingPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(setting, NM_TYPE_SETTING, NMSettingPrivate); + + setting->_priv = priv; +} static void constructed(GObject *object) diff --git a/src/libnm-core-impl/nm-simple-connection.c b/src/libnm-core-impl/nm-simple-connection.c index a9c66dc7..7d4395ff 100644 --- a/src/libnm-core-impl/nm-simple-connection.c +++ b/src/libnm-core-impl/nm-simple-connection.c @@ -30,13 +30,10 @@ int _nm_simple_connection_private_offset; */ struct _NMSimpleConnection { GObject parent; - /* In the past, this struct was public API. Preserve ABI! */ }; struct _NMSimpleConnectionClass { GObjectClass parent; - /* In the past, this struct was public API. Preserve ABI! */ - gpointer padding[4]; }; static void nm_simple_connection_interface_init(NMConnectionInterface *iface); diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c index 2f62f6c6..6f2f5dd2 100644 --- a/src/libnm-core-impl/nm-team-utils.c +++ b/src/libnm-core-impl/nm-team-utils.c @@ -2244,7 +2244,7 @@ _team_setting_verify_properties(const NMTeamSetting *self, GError **error) } else if (attr_data->value_type == NM_VALUE_TYPE_STRING) { const char *v = *((const char *const *) p_field); - if (nm_strv_find_first(attr_data->range.r_string.valid_names, -1, v) < 0) { + if (!nm_strv_contains(attr_data->range.r_string.valid_names, -1, v)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, @@ -2263,7 +2263,7 @@ _team_setting_verify_properties(const NMTeamSetting *self, GError **error) for (i = 0; i < self->d.master.runner_tx_hash->len; i++) { const char *val = self->d.master.runner_tx_hash->pdata[i]; - if (!val || (nm_strv_find_first(_valid_names_runner_tx_hash, -1, val) < 0)) { + if (!val || !nm_strv_contains(_valid_names_runner_tx_hash, -1, val)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, @@ -2289,7 +2289,7 @@ _team_setting_verify_properties(const NMTeamSetting *self, GError **error) if (!_team_setting_has_field(self, attr_data)) continue; if (self->d.master.runner - && (nm_strv_find_first(e->valid_runners, -1, self->d.master.runner) >= 0)) + && nm_strv_contains(e->valid_runners, -1, self->d.master.runner)) continue; if (e->valid_runners[1] == NULL) { g_set_error(error, @@ -2812,9 +2812,9 @@ nm_team_setting_new(gboolean is_port, const char *js_str) gsize l; G_STATIC_ASSERT_EXPR(sizeof(*self) == sizeof(self->_data_priv)); - G_STATIC_ASSERT_EXPR(sizeof(*self) - == NM_CONST_MAX(nm_offsetofend(NMTeamSetting, d.master), - nm_offsetofend(NMTeamSetting, d.port))); + G_STATIC_ASSERT_EXPR( + sizeof(*self) + == NM_MAX(nm_offsetofend(NMTeamSetting, d.master), nm_offsetofend(NMTeamSetting, d.port))); l = is_port ? nm_offsetofend(NMTeamSetting, d.port) : nm_offsetofend(NMTeamSetting, d.master); diff --git a/src/libnm-core-impl/nm-team-utils.h b/src/libnm-core-impl/nm-team-utils.h index 06fa6cc8..0210cb26 100644 --- a/src/libnm-core-impl/nm-team-utils.h +++ b/src/libnm-core-impl/nm-team-utils.h @@ -6,7 +6,7 @@ #ifndef __NM_TEAM_UITLS_H__ #define __NM_TEAM_UITLS_H__ -#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) +#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) #error Cannot use this header. #endif @@ -48,7 +48,8 @@ typedef enum { NM_TEAM_ATTRIBUTE_PORT_LACP_KEY, _NM_TEAM_ATTRIBUTE_PORT_NUM, - _NM_TEAM_ATTRIBUTE_NUM = MAX(_NM_TEAM_ATTRIBUTE_MASTER_NUM, _NM_TEAM_ATTRIBUTE_PORT_NUM), + _NM_TEAM_ATTRIBUTE_NUM = + NM_MAX_CONST(_NM_TEAM_ATTRIBUTE_MASTER_NUM, _NM_TEAM_ATTRIBUTE_PORT_NUM), } NMTeamAttribute; diff --git a/src/libnm-core-impl/nm-utils-private.h b/src/libnm-core-impl/nm-utils-private.h index e2e1aff7..1521c0f9 100644 --- a/src/libnm-core-impl/nm-utils-private.h +++ b/src/libnm-core-impl/nm-utils-private.h @@ -6,7 +6,7 @@ #ifndef __NM_UTILS_PRIVATE_H__ #define __NM_UTILS_PRIVATE_H__ -#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) +#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE) #error Cannot use this header. #endif diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 2bd8936d..88df3291 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -36,6 +36,7 @@ #include "nm-setting-vlan.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" +#include "nm-errors.h" /** * SECTION:nm-utils @@ -654,8 +655,13 @@ nm_utils_is_empty_ssid(const guint8 *ssid, gsize len) * representation of that character. Intended for debugging only, should not * be used for display of SSIDs. * + * Warning: this function uses a static buffer. It is not thread-safe. Don't + * use this function. + * * Returns: pointer to the escaped SSID, which uses an internal static buffer * and will be overwritten by subsequent calls to this function + * + * Deprecated: 1.46: use nm_utils_ssid_to_utf8() or nm_utils_bin2hexstr(). **/ const char * nm_utils_escape_ssid(const guint8 *ssid, gsize len) @@ -669,7 +675,7 @@ nm_utils_escape_ssid(const guint8 *ssid, gsize len) return escaped; } - len = MIN(len, (guint32) NM_IW_ESSID_MAX_SIZE); + len = NM_MIN(len, (guint32) NM_IW_ESSID_MAX_SIZE); while (len--) { if (*s == '\0') { *d++ = '\\'; @@ -897,42 +903,6 @@ _nm_utils_slist_to_strv(const GSList *slist, gboolean deep_copy) return strv; } -GPtrArray * -nm_strv_to_ptrarray(char **strv) -{ - GPtrArray *ptrarray; - gsize i, l; - - l = NM_PTRARRAY_LEN(strv); - - ptrarray = g_ptr_array_new_full(l, g_free); - - if (strv) { - for (i = 0; strv[i]; i++) - g_ptr_array_add(ptrarray, g_strdup(strv[i])); - } - - return ptrarray; -} - -char ** -_nm_utils_ptrarray_to_strv(const GPtrArray *ptrarray) -{ - char **strv; - guint i; - - if (!ptrarray) - return g_new0(char *, 1); - - strv = g_new(char *, ptrarray->len + 1); - - for (i = 0; i < ptrarray->len; i++) - strv[i] = g_strdup(ptrarray->pdata[i]); - strv[i] = NULL; - - return strv; -} - /*****************************************************************************/ static gboolean @@ -1356,17 +1326,49 @@ nm_utils_dns_to_variant(int addr_family, const char *const *dns, gssize len) * Utility function to convert a #GVariant of type 'au' representing a list of * IPv4 addresses into an array of IP address strings. * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) + * * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. **/ char ** nm_utils_ip4_dns_from_variant(GVariant *value) { + return _nm_utils_ip4_dns_from_variant(value, FALSE, NULL); +} + +/** + * _nm_utils_ip4_dns_from_variant: + * @value: a #GVariant of type 'au' + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip4_dns_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address + * strings. In strict mode, %NULL is returned on error. + */ +char ** +_nm_utils_ip4_dns_from_variant(GVariant *value, bool strict, GError **error) +{ const guint32 *array; gsize length; char **dns; gsize i; - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("au")), NULL); + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("au"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"au\"")); + return NULL; + } + dns = g_new(char *, 1); + dns[0] = NULL; + return dns; + } array = g_variant_get_fixed_array(value, &length, sizeof(guint32)); dns = g_new(char *, length + 1u); @@ -1437,7 +1439,11 @@ nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway) * NetworkManager IPv4 addresses (which are tuples of address, prefix, and * gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field of * the first address (if set) will be returned in @out_gateway; the "gateway" fields - * of the other addresses are ignored. + * of the other addresses are ignored. Note that invalid addresses are discarded + * but the valid addresses are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPAddress): a newly allocated * #GPtrArray of #NMIPAddress objects @@ -1445,46 +1451,132 @@ nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway) GPtrArray * nm_utils_ip4_addresses_from_variant(GVariant *value, char **out_gateway) { - GPtrArray *addresses; - GVariantIter iter; - GVariant *addr_var; + return _nm_utils_ip4_addresses_from_variant(value, NULL, out_gateway, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aau")), NULL); +/** + * _nm_utils_ip4_addresses_from_variant: + * @value: a #GVariant of type 'aau' + * @labels: (optional) (nullable): a #GVariant of the type 'as'. If not-NULL, + * each element must contain a string with the labels that corresponds to each + * IP address in @value. + * @out_gateway: (out) (optional) (nullable) (transfer full): on return, will + * contain the IP gateway + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip4_addresses_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. It also + * allows to parse the address-labels at the same time than the addresses. + * + * The labels need to be processed at the same time than the addresses, inside + * this function, because if there are invalid addresses they are filtered out, + * and the returned array of addresses contains less elements than the original + * array. If that happens, the caller don't know what label corresponds to what + * address, because they are matched by position in the array. If you are not + * interested in the labels, just set @labels to NULL. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects. In strict mode, %NULL is returned on error. + */ +GPtrArray * +_nm_utils_ip4_addresses_from_variant(GVariant *value, + GVariant *labels, + char **out_gateway, + bool strict, + GError **error) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + GVariantIter iter; + GVariant *item; + const guint32 *addr_array; + gsize length; + NMIPAddress *addr; + const char *label; + gsize n_labels = 0; + guint i; + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); if (out_gateway) *out_gateway = NULL; + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aau"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"aau\"")); + return NULL; + } + return g_steal_pointer(&addresses); + } + + if (labels && !g_variant_is_of_type(labels, G_VARIANT_TYPE("as"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected \"address-labels\" of type \"as\"")); + return NULL; + } + /* We still can parse the addresses, without the labels */ + labels = NULL; + } + + if (labels) + n_labels = g_variant_n_children(labels); + g_variant_iter_init(&iter, value); - addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); - while (g_variant_iter_next(&iter, "@au", &addr_var)) { - const guint32 *addr_array; - gsize length; - NMIPAddress *addr; - GError *error = NULL; + for (i = 0; g_variant_iter_next(&iter, "@au", &item); i++) { + gs_unref_variant GVariant *addr_var = item; + gs_free_error GError *local_error = NULL; addr_array = g_variant_get_fixed_array(addr_var, &length, sizeof(guint32)); if (length < 3) { - g_warning("Ignoring invalid IP4 address"); - g_variant_unref(addr_var); + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Incomplete IPv4 address (idx=%u)"), + i); + return NULL; + } + continue; + } + + addr = nm_ip_address_new_binary(AF_INET, &addr_array[0], addr_array[1], &local_error); + if (!addr) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } continue; } - addr = nm_ip_address_new_binary(AF_INET, &addr_array[0], addr_array[1], &error); - if (addr) { - g_ptr_array_add(addresses, addr); + /* We were accepting address-labels to be shorter than addresses, so + * let's continue doing so and not consider it as an error */ + if (labels && i < n_labels) { + g_variant_get_child(labels, i, "&s", &label); - if (addr_array[2] && out_gateway && !*out_gateway) - *out_gateway = nm_inet4_ntop_dup(addr_array[2]); - } else { - g_warning("Ignoring invalid IP4 address: %s", error->message); - g_clear_error(&error); + if (label && label[0]) { + nm_ip_address_set_attribute(addr, + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string(label)); + } } - g_variant_unref(addr_var); + g_ptr_array_add(addresses, addr); + if (addr_array[2] && out_gateway && !*out_gateway) + *out_gateway = nm_inet4_ntop_dup(addr_array[2]); } - return addresses; + return g_steal_pointer(&addresses); } /** @@ -1518,7 +1610,7 @@ nm_utils_ip4_routes_to_variant(GPtrArray *routes) array[1] = nm_ip_route_get_prefix(route); nm_ip_route_get_next_hop_binary(route, &array[2]); /* The old routes format uses "0" for default, not "-1" */ - array[3] = MAX(0, nm_ip_route_get_metric(route)); + array[3] = NM_MAX(0, nm_ip_route_get_metric(route)); g_variant_builder_add(&builder, "@au", nm_g_variant_new_au(array, 4)); } @@ -1533,7 +1625,11 @@ nm_utils_ip4_routes_to_variant(GPtrArray *routes) * * Utility function to convert a #GVariant of type 'aau' representing an array * of NetworkManager IPv4 routes (which are tuples of route, prefix, next hop, - * and metric) into a #GPtrArray of #NMIPRoute objects. + * and metric) into a #GPtrArray of #NMIPRoute objects. Note that invalid routes + * are discarded but the valid routes are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPRoute): a newly allocated * #GPtrArray of #NMIPRoute objects @@ -1541,25 +1637,61 @@ nm_utils_ip4_routes_to_variant(GPtrArray *routes) GPtrArray * nm_utils_ip4_routes_from_variant(GVariant *value) { - GVariantIter iter; - GVariant *route_var; - GPtrArray *routes; + return _nm_utils_ip4_routes_from_variant(value, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aau")), NULL); +/** + * _nm_utils_ip4_routes_from_variant: + * @value: #GVariant of type 'aau' + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip4_routes_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects. In strict mode, NULL is returned on error. + */ +GPtrArray * +_nm_utils_ip4_routes_from_variant(GVariant *value, bool strict, GError **error) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + GVariantIter iter; + GVariant *item; + const guint32 *route_array; + gsize length; + NMIPRoute *route; + guint i; - g_variant_iter_init(&iter, value); routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); - while (g_variant_iter_next(&iter, "@au", &route_var)) { - const guint32 *route_array; - gsize length; - NMIPRoute *route; - GError *error = NULL; + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aau"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"aau\"")); + return NULL; + } + return g_steal_pointer(&routes); + } + + g_variant_iter_init(&iter, value); + + for (i = 0; g_variant_iter_next(&iter, "@au", &item); i++) { + gs_unref_variant GVariant *route_var = item; + gs_free_error GError *local_error = NULL; route_array = g_variant_get_fixed_array(route_var, &length, sizeof(guint32)); if (length < 4) { - g_warning("Ignoring invalid IP4 route"); - g_variant_unref(route_var); + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Incomplete IPv4 route (idx=%u)"), + i); + return NULL; + } continue; } @@ -1569,17 +1701,24 @@ nm_utils_ip4_routes_from_variant(GVariant *value) &route_array[2], /* The old routes format uses "0" for default, not "-1" */ route_array[3] ? (gint64) route_array[3] : -1, - &error); - if (route) - g_ptr_array_add(routes, route); - else { - g_warning("Ignoring invalid IP4 route: %s", error->message); - g_clear_error(&error); + &local_error); + if (!route) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } + continue; } - g_variant_unref(route_var); + + g_ptr_array_add(routes, route); } - return routes; + return g_steal_pointer(&routes); } /** @@ -1641,34 +1780,79 @@ nm_utils_ip4_get_default_prefix(guint32 ip) * a IPv6 address in binary form (16 bytes long). Invalid entries are silently * ignored. * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) + * * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. **/ char ** nm_utils_ip6_dns_from_variant(GVariant *value) { - GVariantIter iter; - GVariant *ip_var; - char **dns; - gsize i; + return _nm_utils_ip6_dns_from_variant(value, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aay")), NULL); +/** + * _nm_utils_ip6_dns_from_variant: + * @value: a #GVariant of type 'aay' + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip6_dns_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address + * strings. In strict mode, %NULL is returned on error. + **/ +char ** +_nm_utils_ip6_dns_from_variant(GVariant *value, bool strict, GError **error) +{ + gs_strfreev char **dns = NULL; + GVariantIter iter; + GVariant *item; + guint i, j; + + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aay"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"aay\"")); + return NULL; + } + dns = g_new(char *, 1); + dns[0] = NULL; + return g_steal_pointer(&dns); + } - dns = g_new(char *, g_variant_n_children(value) + 1); + dns = g_new(char *, g_variant_n_children(value) + 1); + dns[0] = NULL; g_variant_iter_init(&iter, value); - i = 0; - while (g_variant_iter_next(&iter, "@ay", &ip_var)) { - gsize length; - const struct in6_addr *ip = g_variant_get_fixed_array(ip_var, &length, 1); - if (length == sizeof(struct in6_addr)) - dns[i++] = nm_inet6_ntop_dup(ip); + for (i = 0, j = 0; g_variant_iter_next(&iter, "@ay", &item); i++) { + gs_unref_variant GVariant *ip_var = item; + const struct in6_addr *ip; + gsize length; - g_variant_unref(ip_var); + ip = g_variant_get_fixed_array(ip_var, &length, 1); + + if (length != sizeof(struct in6_addr)) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Invalid IPv6 DNS address length (idx=%u)"), + i); + return NULL; + } + continue; + } + + dns[j] = nm_inet6_ntop_dup(ip); + dns[++j] = NULL; } - dns[i] = NULL; - return dns; + return g_steal_pointer(&dns); } /** @@ -1733,7 +1917,11 @@ nm_utils_ip6_addresses_to_variant(GPtrArray *addresses, const char *gateway) * list of NetworkManager IPv6 addresses (which are tuples of address, prefix, * and gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field * of the first address (if set) will be returned in @out_gateway; the "gateway" - * fields of the other addresses are ignored. + * fields of the other addresses are ignored. Note that invalid addresses are + * discarded but the valid addresses are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPAddress): a newly allocated * #GPtrArray of #NMIPAddress objects @@ -1741,63 +1929,123 @@ nm_utils_ip6_addresses_to_variant(GPtrArray *addresses, const char *gateway) GPtrArray * nm_utils_ip6_addresses_from_variant(GVariant *value, char **out_gateway) { - GVariantIter iter; - GVariant *addr_var, *gateway_var; - guint32 prefix; - GPtrArray *addresses; + return _nm_utils_ip6_addresses_from_variant(value, out_gateway, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuay)")), NULL); +/** + * _nm_utils_ip6_addresses_from_variant: + * @value: a #GVariant of type 'a(ayuay)' + * @out_gateway: (out) (optional) (nullable) (transfer full): on return, will + * contain the IP gateway + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip6_addresses_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects. In strict mode, %NULL is returned on error. + **/ +GPtrArray * +_nm_utils_ip6_addresses_from_variant(GVariant *value, + char **out_gateway, + bool strict, + GError **error) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + GVariantIter iter; + GVariant *addr_item; + GVariant *gateway_item; + guint32 prefix; + guint i; + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); if (out_gateway) *out_gateway = NULL; + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuay)"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"a(ayuay)\"")); + return NULL; + } + return g_steal_pointer(&addresses); + } + g_variant_iter_init(&iter, value); - addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); - while (g_variant_iter_next(&iter, "(@ayu@ay)", &addr_var, &prefix, &gateway_var)) { - NMIPAddress *addr; - const struct in6_addr *addr_bytes, *gateway_bytes; - gsize addr_len, gateway_len; - GError *error = NULL; + for (i = 0; g_variant_iter_next(&iter, "(@ayu@ay)", &addr_item, &prefix, &gateway_item); i++) { + gs_unref_variant GVariant *addr_var = addr_item; + gs_unref_variant GVariant *gateway_var = gateway_item; + gs_free_error GError *local_error = NULL; + NMIPAddress *addr; + const struct in6_addr *addr_bytes, *gateway_bytes; + gsize addr_len, gateway_len; if (!g_variant_is_of_type(addr_var, G_VARIANT_TYPE_BYTESTRING) || !g_variant_is_of_type(gateway_var, G_VARIANT_TYPE_BYTESTRING)) { - g_warning("%s: ignoring invalid IP6 address structure", __func__); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"(ayuay)\" (idx=%u)"), + i); + return NULL; + } + continue; } addr_bytes = g_variant_get_fixed_array(addr_var, &addr_len, 1); if (addr_len != 16) { - g_warning("%s: ignoring invalid IP6 address of length %d", __func__, (int) addr_len); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("IPv6 address with invalid length (idx=%u)"), + i); + return NULL; + } + continue; + } + + addr = nm_ip_address_new_binary(AF_INET6, addr_bytes, prefix, &local_error); + if (!addr) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } + continue; } - addr = nm_ip_address_new_binary(AF_INET6, addr_bytes, prefix, &error); - if (addr) { - g_ptr_array_add(addresses, addr); + g_ptr_array_add(addresses, addr); - if (out_gateway && !*out_gateway) { - gateway_bytes = g_variant_get_fixed_array(gateway_var, &gateway_len, 1); - if (gateway_len != 16) { - g_warning("%s: ignoring invalid IP6 address of length %d", - __func__, - (int) gateway_len); - goto next; + if (out_gateway && !*out_gateway) { + gateway_bytes = g_variant_get_fixed_array(gateway_var, &gateway_len, 1); + if (gateway_len != 16) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("IPv6 gateway with invalid length (idx=%u)"), + i); + return NULL; } - if (!IN6_IS_ADDR_UNSPECIFIED(gateway_bytes)) - *out_gateway = nm_inet6_ntop_dup(gateway_bytes); + continue; } - } else { - g_warning("Ignoring invalid IP6 address: %s", error->message); - g_clear_error(&error); - } -next: - g_variant_unref(addr_var); - g_variant_unref(gateway_var); + if (!IN6_IS_ADDR_UNSPECIFIED(gateway_bytes)) + NM_SET_OUT(out_gateway, nm_inet6_ntop_dup(gateway_bytes)); + } } - return addresses; + return g_steal_pointer(&addresses); } /** @@ -1853,7 +2101,11 @@ nm_utils_ip6_routes_to_variant(GPtrArray *routes) * * Utility function to convert a #GVariant of type 'a(ayuayu)' representing an * array of NetworkManager IPv6 routes (which are tuples of route, prefix, next - * hop, and metric) into a #GPtrArray of #NMIPRoute objects. + * hop, and metric) into a #GPtrArray of #NMIPRoute objects. Note that invalid + * routes are ignored but the valid ones are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPRoute): a newly allocated * #GPtrArray of #NMIPRoute objects @@ -1861,40 +2113,93 @@ nm_utils_ip6_routes_to_variant(GPtrArray *routes) GPtrArray * nm_utils_ip6_routes_from_variant(GVariant *value) { - GPtrArray *routes; - GVariantIter iter; - GVariant *dest_var, *next_hop_var; - const struct in6_addr *dest, *next_hop; - gsize dest_len, next_hop_len; - guint32 prefix, metric; + return _nm_utils_ip6_routes_from_variant(value, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuayu)")), NULL); +/** + * _nm_utils_ip6_routes_from_variant: + * @value: #GVariant of type 'a(ayuayu)' + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip6_routes_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects. In strict mode, %NULL is returned on error. + **/ +GPtrArray * +_nm_utils_ip6_routes_from_variant(GVariant *value, bool strict, GError **error) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + GVariantIter iter; + GVariant *dest_item; + GVariant *next_hop_item; + guint32 prefix, metric; + guint i; routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("a(ayuayu)"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"a(ayuayu)\"")); + return NULL; + } + return g_steal_pointer(&routes); + } + g_variant_iter_init(&iter, value); - while (g_variant_iter_next(&iter, "(@ayu@ayu)", &dest_var, &prefix, &next_hop_var, &metric)) { - NMIPRoute *route; - GError *error = NULL; + + for (i = 0; + g_variant_iter_next(&iter, "(@ayu@ayu)", &dest_item, &prefix, &next_hop_item, &metric); + i++) { + gs_unref_variant GVariant *dest_var = dest_item; + gs_unref_variant GVariant *next_hop_var = next_hop_item; + gs_free_error GError *local_error = NULL; + NMIPRoute *route; + const struct in6_addr *dest, *next_hop; + gsize dest_len, next_hop_len; if (!g_variant_is_of_type(dest_var, G_VARIANT_TYPE_BYTESTRING) || !g_variant_is_of_type(next_hop_var, G_VARIANT_TYPE_BYTESTRING)) { - g_warning("%s: ignoring invalid IP6 address structure", __func__); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"(ayuayu)\" (idx=%u)"), + i); + return NULL; + } + continue; } dest = g_variant_get_fixed_array(dest_var, &dest_len, 1); if (dest_len != 16) { - g_warning("%s: ignoring invalid IP6 address of length %d", __func__, (int) dest_len); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("IPv6 dest address with invalid length (idx=%u)"), + i); + return NULL; + } + continue; } next_hop = g_variant_get_fixed_array(next_hop_var, &next_hop_len, 1); if (next_hop_len != 16) { - g_warning("%s: ignoring invalid IP6 address of length %d", - __func__, - (int) next_hop_len); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("IPv6 next-hop address with invalid length (idx=%u)"), + i); + return NULL; + } + continue; } route = nm_ip_route_new_binary(AF_INET6, @@ -1902,20 +2207,24 @@ nm_utils_ip6_routes_from_variant(GVariant *value) prefix, next_hop, metric ? (gint64) metric : -1, - &error); - if (route) - g_ptr_array_add(routes, route); - else { - g_warning("Ignoring invalid IP6 route: %s", error->message); - g_clear_error(&error); + &local_error); + if (!route) { + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } + continue; } -next: - g_variant_unref(dest_var); - g_variant_unref(next_hop_var); + g_ptr_array_add(routes, route); } - return routes; + return g_steal_pointer(&routes); } /** @@ -1980,7 +2289,11 @@ nm_utils_ip_addresses_to_variant(GPtrArray *addresses) * Utility function to convert a #GVariant representing a list of new-style * NetworkManager IPv4 or IPv6 addresses (as described in the documentation for * nm_utils_ip_addresses_to_variant()) into a #GPtrArray of #NMIPAddress - * objects. + * objects. Note that invalid addresses are discarded but the valid addresses + * are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPAddress): a newly allocated * #GPtrArray of #NMIPAddress objects @@ -1990,49 +2303,92 @@ nm_utils_ip_addresses_to_variant(GPtrArray *addresses) GPtrArray * nm_utils_ip_addresses_from_variant(GVariant *value, int family) { - GPtrArray *addresses; - GVariantIter iter, attrs_iter; - GVariant *addr_var; - const char *ip; - guint32 prefix; - const char *attr_name; - GVariant *attr_val; - NMIPAddress *addr; - GError *error = NULL; + return _nm_utils_ip_addresses_from_variant(value, family, FALSE, NULL); +} + +/** + * _nm_utils_ip_addresses_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip_addresses_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects. In strict mode, %NULL is returned on error. + */ +GPtrArray * +_nm_utils_ip_addresses_from_variant(GVariant *value, int family, bool strict, GError **error) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + GVariantIter iter, attrs_iter; + GVariant *item; + const char *ip; + guint32 prefix; + NMIPAddress *addr; + const char *attr_name; + guint i; - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"aa{sv}\"")); + return NULL; + } + return g_steal_pointer(&addresses); + } g_variant_iter_init(&iter, value); - addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); - while (g_variant_iter_next(&iter, "@a{sv}", &addr_var)) { + for (i = 0; g_variant_iter_next(&iter, "@a{sv}", &item); i++) { + gs_unref_variant GVariant *addr_var = item; + gs_free_error GError *local_error = NULL; + if (!g_variant_lookup(addr_var, "address", "&s", &ip) || !g_variant_lookup(addr_var, "prefix", "u", &prefix)) { - g_warning("Ignoring invalid address"); - g_variant_unref(addr_var); + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("IP address requires fields \"dest\" and \"prefix\" (idx=%u)"), + i); + return NULL; + } continue; } - addr = nm_ip_address_new(family, ip, prefix, &error); + addr = nm_ip_address_new(family, ip, prefix, &local_error); if (!addr) { - g_warning("Ignoring invalid address: %s", error->message); - g_clear_error(&error); - g_variant_unref(addr_var); + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } continue; } g_variant_iter_init(&attrs_iter, addr_var); - while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &item)) { + gs_unref_variant GVariant *attr_val = item; + if (!NM_IN_STRSET(attr_name, "address", "prefix")) nm_ip_address_set_attribute(addr, attr_name, attr_val); - g_variant_unref(attr_val); } - g_variant_unref(addr_var); g_ptr_array_add(addresses, addr); } - return addresses; + return g_steal_pointer(&addresses); } /** @@ -2041,8 +2397,11 @@ nm_utils_ip_addresses_from_variant(GVariant *value, int family) * * Utility function to convert a #GPtrArray of #NMIPRoute objects representing * IPv4 or IPv6 routes into a #GVariant of type 'aa{sv}' representing an array - * of new-style NetworkManager IP routes (which are tuples of destination, - * prefix, next hop, metric, and additional attributes). + * of new-style NetworkManager IP routes. All routes will include "dest" (an IP + * address string), "prefix" (an uint) and optionally "next-hop" (an IP address + * string) and "metric" (an uint). Some routes may include additional attributes. + * Note that invalid routes are discarded and only a warning is emitted, but the + * valid routes are still returned. * * Returns: (transfer none): a new floating #GVariant representing @routes. * @@ -2107,9 +2466,12 @@ nm_utils_ip_routes_to_variant(GPtrArray *routes) * @family: an IP address family * * Utility function to convert a #GVariant representing a list of new-style - * NetworkManager IPv4 or IPv6 addresses (which are tuples of destination, - * prefix, next hop, metric, and additional attributes) into a #GPtrArray of - * #NMIPRoute objects. + * NetworkManager IPv4 or IPv6 addresses (as described in the documentation for + * nm_utils_ip_routes_to_variant()) into a #GPtrArray of #NMIPRoute objects. + * Invalid routes are discarded but the valid routes are still returned. + * + * Since 1.46, an empty list is returned if the variant type is not valid + * (before it was checked as assertion) * * Returns: (transfer full) (element-type NMIPRoute): a newly allocated * #GPtrArray of #NMIPRoute objects @@ -2119,27 +2481,65 @@ nm_utils_ip_routes_to_variant(GPtrArray *routes) GPtrArray * nm_utils_ip_routes_from_variant(GVariant *value, int family) { - GPtrArray *routes; - GVariantIter iter, attrs_iter; - GVariant *route_var; - const char *dest, *next_hop; - guint32 prefix, metric32; - gint64 metric; - const char *attr_name; - GVariant *attr_val; - NMIPRoute *route; - GError *error = NULL; + return _nm_utils_ip_routes_from_variant(value, family, FALSE, NULL); +} - g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL); +/** + * _nm_utils_ip_routes_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * @strict: whether to parse in strict mode or best-effort mode + * @error: the error location + * + * Like #nm_utils_ip_routes_from_variant, but allows to parse in strict mode. In + * strict mode, parsing is aborted on first error and %NULL is returned. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects. In strict mode %NULL is returned on error. + */ +GPtrArray * +_nm_utils_ip_routes_from_variant(GVariant *value, int family, bool strict, GError **error) +{ + gs_unref_ptrarray GPtrArray *routes = NULL; + GVariantIter iter, attrs_iter; + GVariant *item; + const char *dest, *next_hop; + guint32 prefix, metric32; + gint64 metric; + const char *attr_name; + NMIPRoute *route; + guint i; - g_variant_iter_init(&iter, value); routes = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_route_unref); - while (g_variant_iter_next(&iter, "@a{sv}", &route_var)) { + if (!g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}"))) { + if (strict) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Expected value of type \"aa{sv}\"")); + return NULL; + } + return g_steal_pointer(&routes); + } + + g_variant_iter_init(&iter, value); + + for (i = 0; g_variant_iter_next(&iter, "@a{sv}", &item); i++) { + gs_unref_variant GVariant *route_var = item; + gs_free_error GError *local_error = NULL; + if (!g_variant_lookup(route_var, "dest", "&s", &dest) || !g_variant_lookup(route_var, "prefix", "u", &prefix)) { - g_warning("Ignoring invalid address"); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Route requires fields \"dest\" and \"prefix\" (idx=%u)"), + i); + return NULL; + } + continue; } if (!g_variant_lookup(route_var, "next-hop", "&s", &next_hop)) next_hop = NULL; @@ -2148,26 +2548,32 @@ nm_utils_ip_routes_from_variant(GVariant *value, int family) else metric = -1; - route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &error); + route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &local_error); if (!route) { - g_warning("Ignoring invalid route: %s", error->message); - g_clear_error(&error); - goto next; + if (strict) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s (idx=%u)"), + local_error->message, + i); + return NULL; + } + continue; } g_variant_iter_init(&attrs_iter, route_var); - while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + while (g_variant_iter_next(&attrs_iter, "{&sv}", &attr_name, &item)) { + gs_unref_variant GVariant *attr_val = item; + if (!NM_IN_STRSET(attr_name, "dest", "prefix", "next-hop", "metric")) nm_ip_route_set_attribute(route, attr_name, attr_val); - g_variant_unref(attr_val); } g_ptr_array_add(routes, route); -next: - g_variant_unref(route_var); } - return routes; + return g_steal_pointer(&routes); } /*****************************************************************************/ @@ -4694,7 +5100,7 @@ _nm_utils_strstrdictkey_create(const char *v1, const char *v2) static gboolean validate_dns_option(const char *name, gboolean numeric, - gboolean ipv6, + int addr_family, const NMUtilsDNSOptionDesc *option_descs) { const NMUtilsDNSOptionDesc *desc; @@ -4703,8 +5109,15 @@ validate_dns_option(const char *name, return !!*name; for (desc = option_descs; desc->name; desc++) { - if (nm_streq(name, desc->name) && numeric == desc->numeric && (!desc->ipv6_only || ipv6)) - return TRUE; + if (!nm_streq(name, desc->name)) + continue; + if ((!!numeric) != (!!desc->numeric)) + continue; + if (addr_family != AF_UNSPEC) { + if (desc->ipv6_only && addr_family != AF_INET6) + continue; + } + return TRUE; } return FALSE; @@ -4715,7 +5128,9 @@ validate_dns_option(const char *name, * @option: option string * @out_name: (out) (optional) (nullable): the option name * @out_value: (out) (optional): the option value - * @ipv6: whether the option refers to a IPv6 configuration + * @addr_family: AF_INET/AF_INET6 to only allow options for the specified address + * family. AF_UNSPEC to allow either. This argument is ignored, if @option_descs + * is NULL. * @option_descs: (nullable): an array of NMUtilsDNSOptionDesc which describes the * valid options * @@ -4731,7 +5146,7 @@ gboolean _nm_utils_dns_option_validate(const char *option, char **out_name, long *out_value, - gboolean ipv6, + int addr_family, const NMUtilsDNSOptionDesc *option_descs) { gs_free char *option0_free = NULL; @@ -4742,6 +5157,8 @@ _nm_utils_dns_option_validate(const char *option, g_return_val_if_fail(option != NULL, FALSE); + nm_assert_addr_family_or_unspec(addr_family); + NM_SET_OUT(out_name, NULL); NM_SET_OUT(out_value, -1); @@ -4750,7 +5167,7 @@ _nm_utils_dns_option_validate(const char *option, delim = strchr(option, ':'); if (!delim) { - if (!validate_dns_option(option, FALSE, ipv6, option_descs)) + if (!validate_dns_option(option, FALSE, addr_family, option_descs)) return FALSE; NM_SET_OUT(out_name, g_strdup(option)); return TRUE; @@ -4765,7 +5182,7 @@ _nm_utils_dns_option_validate(const char *option, option0 = nm_strndup_a(300, option, delim - option, &option0_free); - if (!validate_dns_option(option0, TRUE, ipv6, option_descs)) + if (!validate_dns_option(option0, TRUE, addr_family, option_descs)) return FALSE; option1_num = _nm_utils_ascii_str_to_int64(option1, 10, 0, G_MAXINT32, -1); @@ -4779,7 +5196,8 @@ _nm_utils_dns_option_validate(const char *option, /** * _nm_utils_dns_option_find_idx: - * @array: an array of strings + * @strv: an array of strings of length @strv_len + * @strv_len: the length of @strv, or -1 for a NULL terminated strv array. * @option: a dns option string * * Searches for an option in an array of strings. The match is @@ -4789,18 +5207,28 @@ _nm_utils_dns_option_validate(const char *option, * found. */ gssize -_nm_utils_dns_option_find_idx(GPtrArray *array, const char *option) +_nm_utils_dns_option_find_idx(const char *const *strv, gssize strv_len, const char *option) { gs_free char *option_name = NULL; - guint i; + gsize l; + gsize i; - if (!_nm_utils_dns_option_validate(option, &option_name, NULL, FALSE, NULL)) + if (strv_len >= 0) + l = strv_len; + else + l = NM_PTRARRAY_LEN(strv); + + if (l == 0) return -1; - for (i = 0; i < array->len; i++) { + if (!_nm_utils_dns_option_validate(option, &option_name, NULL, AF_UNSPEC, NULL)) + return -1; + + for (i = 0; i < l; i++) { + const char *str = strv[i]; gs_free char *tmp_name = NULL; - if (_nm_utils_dns_option_validate(array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { + if (_nm_utils_dns_option_validate(str, &tmp_name, NULL, AF_UNSPEC, NULL)) { if (nm_streq(tmp_name, option_name)) return i; } @@ -5548,7 +5976,7 @@ _nm_utils_bridge_vlan_verify_list(GPtrArray *vlans, nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); for (v = vid_start; v <= vid_end; v++) { - if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(v))) { + if (!g_hash_table_add(h, GUINT_TO_POINTER(v))) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/src/libnm-core-impl/nm-vpn-editor-plugin.c b/src/libnm-core-impl/nm-vpn-editor-plugin.c index 6c9aff43..6181368a 100644 --- a/src/libnm-core-impl/nm-vpn-editor-plugin.c +++ b/src/libnm-core-impl/nm-vpn-editor-plugin.c @@ -209,7 +209,7 @@ nm_vpn_editor_plugin_get_vt(NMVpnEditorPlugin *plugin, NMVpnEditorPluginVT *vt, if (!p_vt) p_vt_size = 0; g_return_val_if_fail(p_vt_size, 0); - memcpy(vt, p_vt, MIN(vt_size, p_vt_size)); + memcpy(vt, p_vt, NM_MIN(vt_size, p_vt_size)); } return p_vt_size; diff --git a/src/libnm-core-impl/nm-vpn-plugin-info.c b/src/libnm-core-impl/nm-vpn-plugin-info.c index d2ce9ed8..223d8ab3 100644 --- a/src/libnm-core-impl/nm-vpn-plugin-info.c +++ b/src/libnm-core-impl/nm-vpn-plugin-info.c @@ -181,8 +181,8 @@ _sort_files(LoadDirInfo *a, LoadDirInfo *b) { time_t ta, tb; - ta = MAX(a->stat.st_mtime, a->stat.st_ctime); - tb = MAX(b->stat.st_mtime, b->stat.st_ctime); + ta = NM_MAX(a->stat.st_mtime, a->stat.st_ctime); + tb = NM_MAX(b->stat.st_mtime, b->stat.st_ctime); if (ta < tb) return 1; if (ta > tb) @@ -337,7 +337,7 @@ nm_vpn_plugin_info_list_load(void) uid = getuid(); for (i = 0; i < G_N_ELEMENTS(dir); i++) { - if (!dir[i] || nm_strv_find_first(dir, i, dir[i]) >= 0) + if (!dir[i] || nm_strv_contains(dir, i, dir[i])) continue; infos = _nm_vpn_plugin_info_list_load_dir(dir[i], TRUE, uid, NULL, NULL); @@ -552,7 +552,7 @@ _list_find_by_service(GSList *list, const char *name, const char *service) if (name && !nm_streq(name, priv->name)) continue; if (service && !nm_streq(priv->service, service) - && (nm_strv_find_first(priv->aliases, -1, service) < 0)) + && !nm_strv_contains(priv->aliases, -1, service)) continue; return list->data; @@ -639,7 +639,7 @@ nm_vpn_plugin_info_list_find_service_type(GSList *list, const char *name) /* check the hard-coded list of short-names. They all have the same * well-known prefix org.freedesktop.NetworkManager and the name. */ - if (nm_strv_find_first(known_names, G_N_ELEMENTS(known_names), name) >= 0) + if (nm_strv_contains(known_names, G_N_ELEMENTS(known_names), name)) return g_strdup_printf("%s.%s", NM_DBUS_INTERFACE, name); /* try, if there exists a plugin with @name under org.freedesktop.NetworkManager. @@ -728,7 +728,7 @@ nm_vpn_plugin_info_list_get_service_types(GSList *list, if (l->len <= 0) { g_ptr_array_free(l, TRUE); - return g_new0(char *, 1); + return nm_strv_empty_new(); } /* sort the result and remove duplicates. */ diff --git a/src/libnm-core-impl/tests/meson.build b/src/libnm-core-impl/tests/meson.build index 988c60db..80b58827 100644 --- a/src/libnm-core-impl/tests/meson.build +++ b/src/libnm-core-impl/tests/meson.build @@ -8,7 +8,6 @@ enum_sources = gnome.mkenums_simple( ) test_units = [ - 'test-compare', 'test-crypto', 'test-general', 'test-keyfile', diff --git a/src/libnm-core-impl/tests/test-compare.c b/src/libnm-core-impl/tests/test-compare.c deleted file mode 100644 index 77d2e17b..00000000 --- a/src/libnm-core-impl/tests/test-compare.c +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2007 - 2014 Red Hat, Inc. - * Copyright (C) 2007 - 2008 Novell, Inc. - */ - -#include "libnm-core-impl/nm-default-libnm-core.h" - -#include <arpa/inet.h> -#include <netinet/in.h> - -#include "nm-property-compare.h" - -#include "libnm-glib-aux/nm-test-utils.h" - -static void -compare_ints(void) -{ - GVariant *value1, *value2; - - value1 = g_variant_new_int32(5); - value2 = g_variant_new_int32(5); - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - value2 = g_variant_new_int32(10); - g_assert(nm_property_compare(value1, value2) < 0); - - g_variant_unref(value2); - value2 = g_variant_new_int32(-1); - g_assert(nm_property_compare(value1, value2) > 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -static void -compare_strings(void) -{ - GVariant *value1, *value2; - const char *str1 = "hello"; - const char *str2 = "world"; - - value1 = g_variant_new_string(str1); - value2 = g_variant_new_string(str1); - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - value2 = g_variant_new_string(str2); - g_assert(nm_property_compare(value1, value2) < 0); - - g_assert(nm_property_compare(value2, value1) > 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -static void -compare_strv(void) -{ - GVariant *value1, *value2; - const char *const strv1[] = {"foo", "bar", "baz", NULL}; - const char *const strv2[] = {"foo", "bar", "bar", NULL}; - const char *const strv3[] = {"foo", "bar", NULL}; - const char *const strv4[] = {"foo", "bar", "baz", "bam", NULL}; - - value1 = g_variant_new_strv(strv1, -1); - value2 = g_variant_new_strv(strv1, -1); - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - value2 = g_variant_new_strv(strv2, -1); - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value2); - value2 = g_variant_new_strv(strv3, -1); - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value2); - value2 = g_variant_new_strv(strv4, -1); - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -static void -compare_arrays(void) -{ - GVariant *value1, *value2; - guint32 array[] = {0, 1, 2, 3, 4}; - - value1 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - array, - G_N_ELEMENTS(array), - sizeof(guint32)); - value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - array, - G_N_ELEMENTS(array), - sizeof(guint32)); - - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - array + 1, - G_N_ELEMENTS(array) - 1, - sizeof(guint32)); - g_assert(nm_property_compare(value1, value2) != 0); - - array[0] = 7; - g_variant_unref(value2); - value2 = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - array, - G_N_ELEMENTS(array), - sizeof(guint32)); - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -static void -compare_str_hash(void) -{ - GVariant *value1, *value2; - GVariantBuilder builder; - - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); - g_variant_builder_add(&builder, "{ss}", "key1", "hello"); - g_variant_builder_add(&builder, "{ss}", "key2", "world"); - g_variant_builder_add(&builder, "{ss}", "key3", "!"); - value1 = g_variant_builder_end(&builder); - - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); - g_variant_builder_add(&builder, "{ss}", "key3", "!"); - g_variant_builder_add(&builder, "{ss}", "key2", "world"); - g_variant_builder_add(&builder, "{ss}", "key1", "hello"); - value2 = g_variant_builder_end(&builder); - - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); - g_variant_builder_add(&builder, "{ss}", "key1", "hello"); - g_variant_builder_add(&builder, "{ss}", "key3", "!"); - value2 = g_variant_builder_end(&builder); - - g_assert(nm_property_compare(value1, value2) != 0); - g_assert(nm_property_compare(value2, value1) != 0); - - g_variant_unref(value2); - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}")); - g_variant_builder_add(&builder, "{ss}", "key1", "hello"); - g_variant_builder_add(&builder, "{ss}", "key2", "moon"); - g_variant_builder_add(&builder, "{ss}", "key3", "!"); - value2 = g_variant_builder_end(&builder); - - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -static void -compare_ip6_addresses(void) -{ - GVariant *value1, *value2; - struct in6_addr addr1; - struct in6_addr addr2; - struct in6_addr addr3; - guint32 prefix1 = 64; - guint32 prefix2 = 64; - guint32 prefix3 = 0; - - inet_pton(AF_INET6, "1:2:3:4:5:6:7:8", &addr1); - inet_pton(AF_INET6, "ffff:2:3:4:5:6:7:8", &addr2); - inet_pton(AF_INET6, "::", &addr3); - - value1 = g_variant_new( - "(@ayu@ay)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr1.s6_addr, 16, 1), - prefix1, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); - - value2 = g_variant_new( - "(@ayu@ay)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr1.s6_addr, 16, 1), - prefix1, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); - - g_assert(nm_property_compare(value1, value2) == 0); - - g_variant_unref(value2); - value2 = g_variant_new( - "(@ayu@ay)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr2.s6_addr, 16, 1), - prefix2, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); - - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value2); - value2 = g_variant_new( - "(@ayu@ay)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1), - prefix3, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (guint8 *) addr3.s6_addr, 16, 1)); - - g_assert(nm_property_compare(value1, value2) != 0); - - g_variant_unref(value1); - g_variant_unref(value2); -} - -NMTST_DEFINE(); - -int -main(int argc, char *argv[]) -{ - nmtst_init(&argc, &argv, TRUE); - - g_test_add_func("/libnm/compare/ints", compare_ints); - g_test_add_func("/libnm/compare/strings", compare_strings); - g_test_add_func("/libnm/compare/strv", compare_strv); - g_test_add_func("/libnm/compare/arrays", compare_arrays); - g_test_add_func("/libnm/compare/str_hash", compare_str_hash); - g_test_add_func("/libnm/compare/ip6_addresses", compare_ip6_addresses); - - return g_test_run(); -} diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index 30b1ca5d..4acf33e0 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -292,6 +292,7 @@ test_device_wifi_capabilities(void) _E(NM_WIFI_DEVICE_CAP_FREQ_VALID); _E(NM_WIFI_DEVICE_CAP_FREQ_2GHZ); _E(NM_WIFI_DEVICE_CAP_FREQ_5GHZ); + _E(NM_WIFI_DEVICE_CAP_FREQ_6GHZ); _E(NM_WIFI_DEVICE_CAP_MESH); _E(NM_WIFI_DEVICE_CAP_IBSS_RSN); #undef _E @@ -556,6 +557,21 @@ test_nm_hash(void) #endif NM_STATIC_ASSERT_EXPR_VOID(NM_HASH_COMBINE_BOOLS(int, 1, 0, 1) == 5); + + g_assert_cmpmem(NM_HASH_SEED_16(55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + 16, + ((guint8[16]){55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}), + 16); + + g_assert_cmpmem(NM_HASH_SEED_16_U64(1), 16, ((guint8[16]){0, 0, 0, 0, 0, 0, 0, 1, 0}), 16); + g_assert_cmpmem(NM_HASH_SEED_16_U64(0x1234567890ABCDEFu), + 16, + ((guint8[16]){0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0}), + 16); + + g_assert_cmpint(c_siphash_hash(NM_HASH_SEED_16_U64(0x780E21E45489CC6Fu), (guint8 *) "foo", 3), + ==, + 0XA5A41E5C1B4153BFu); } /*****************************************************************************/ @@ -2627,7 +2643,7 @@ test_setting_gsm_apn_bad_chars(void) /* Make sure a valid APN works */ g_object_set(s_gsm, NM_SETTING_GSM_APN, "foobar123.-baz", NULL); - g_assert(nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + nmtst_assert_setting_verifies(s_gsm); /* Random invalid chars */ g_object_set(s_gsm, NM_SETTING_GSM_APN, "@#%$@#%@#%", NULL); @@ -2639,7 +2655,7 @@ test_setting_gsm_apn_bad_chars(void) /* 0 characters long */ g_object_set(s_gsm, NM_SETTING_GSM_APN, "", NULL); - g_assert(nm_setting_verify(NM_SETTING(s_gsm), NULL, NULL)); + nmtst_assert_setting_verifies(s_gsm); /* 65-character long */ g_object_set(s_gsm, @@ -3946,7 +3962,7 @@ typedef struct { typedef struct { const char *name; - DiffKey keys[30]; + DiffKey keys[31]; } DiffSetting; #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) @@ -4003,7 +4019,9 @@ test_connection_diff_a_only(void) {NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_CONTROLLER, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, @@ -5295,6 +5313,7 @@ test_setting_ip4_changed_signal(void) NMIPAddress *addr; NMIPRoute *route; GError *error = NULL; + gs_strfreev char **strv = NULL; connection = nm_simple_connection_new(); g_signal_connect(connection, @@ -5319,7 +5338,8 @@ test_setting_ip4_changed_signal(void) ASSERT_CHANGED(nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com")); ASSERT_CHANGED(nm_setting_ip_config_remove_dns_search(s_ip4, 0)); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_search->len)); + NMTST_EXPECT_LIBNM_CRITICAL( + NMTST_G_RETURN_MSG(idx >= 0 && idx < nm_g_array_len(priv->dns_search.arr))); ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_search(s_ip4, 1)); g_test_assert_expected_messages(); @@ -5351,10 +5371,51 @@ test_setting_ip4_changed_signal(void) nm_setting_ip_config_add_route(s_ip4, route); ASSERT_CHANGED(nm_setting_ip_config_clear_routes(s_ip4)); + g_assert(!nm_setting_ip_config_has_dns_options(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip4), ==, 0); + + g_object_get(s_ip4, NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert_null(strv); + + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); + g_test_assert_expected_messages(); + ASSERT_CHANGED(nm_setting_ip_config_add_dns_option(s_ip4, "debug")); + + g_assert(nm_setting_ip_config_has_dns_options(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip4), ==, 1); + + g_object_get(s_ip4, NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert_nonnull(strv); + g_assert_cmpstr(strv[0], ==, "debug"); + g_assert_cmpstr(strv[1], ==, NULL); + nm_clear_pointer(&strv, g_strfreev); + + g_assert_cmpstr(nm_setting_ip_config_get_dns_option(s_ip4, 0), ==, "debug"); + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 2)); + g_test_assert_expected_messages(); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns_option(s_ip4, 0)); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_options->len)); + g_assert(nm_setting_ip_config_has_dns_options(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip4), ==, 0); + + g_object_get(s_ip4, NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); + g_assert_nonnull(strv); + g_assert_cmpstr(strv[0], ==, NULL); + nm_clear_pointer(&strv, g_strfreev); + + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 0)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); + g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL( + NMTST_G_RETURN_MSG(idx >= 0 && idx < nm_g_array_len(priv->dns_options.arr))); ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_option(s_ip4, 1)); g_test_assert_expected_messages(); @@ -5366,6 +5427,7 @@ test_setting_ip4_changed_signal(void) static void test_setting_ip6_changed_signal(void) { + gs_strfreev char **strv = NULL; NMConnection *connection; gboolean changed = FALSE; NMSettingIPConfig *s_ip6; @@ -5393,10 +5455,35 @@ test_setting_ip6_changed_signal(void) nm_setting_ip_config_add_dns(s_ip6, "1:2:3::4:5:6"); ASSERT_CHANGED(nm_setting_ip_config_clear_dns(s_ip6)); + g_object_get(s_ip6, NM_SETTING_IP_CONFIG_DNS_SEARCH, &strv, NULL); + g_assert_null(strv); + ASSERT_CHANGED(nm_setting_ip_config_add_dns_search(s_ip6, "foobar.com")); + + g_object_get(s_ip6, NM_SETTING_IP_CONFIG_DNS_SEARCH, &strv, NULL); + g_assert_nonnull(strv); + g_assert_cmpstr(strv[0], ==, "foobar.com"); + g_assert_cmpstr(strv[1], ==, NULL); + nm_clear_pointer(&strv, g_strfreev); + + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 0), ==, "foobar.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 1), ==, NULL); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, -1), ==, NULL); + g_test_assert_expected_messages(); + + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 2), ==, NULL); + g_test_assert_expected_messages(); + ASSERT_CHANGED(nm_setting_ip_config_remove_dns_search(s_ip6, 0)); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_search->len)); + g_object_get(s_ip6, NM_SETTING_IP_CONFIG_DNS_SEARCH, &strv, NULL); + g_assert_null(strv); + + NMTST_EXPECT_LIBNM_CRITICAL( + NMTST_G_RETURN_MSG(idx >= 0 && idx < nm_g_array_len(priv->dns_search.arr))); ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_search(s_ip6, 1)); g_test_assert_expected_messages(); @@ -5591,9 +5678,13 @@ test_setting_wireless_security_changed_signal(void) "wep-key0", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_UNCHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), + "wep-key1", + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL))); ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), "wep-key1", - NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL))); ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), "wep-key2", @@ -5601,7 +5692,7 @@ test_setting_wireless_security_changed_signal(void) NULL))); ASSERT_CHANGED(g_assert(nm_setting_set_secret_flags(NM_SETTING(s_wsec), "wep-key3", - NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL))); g_object_unref(connection); @@ -6146,9 +6237,9 @@ test_connection_normalize_slave_type_1(void) &s_con); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, "invalid-type", NULL); @@ -6157,7 +6248,7 @@ test_connection_normalize_slave_type_1(void) NM_CONNECTION_ERROR_INVALID_PROPERTY); g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); - g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_PORT_TYPE, "bridge", NULL); g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); nmtst_assert_connection_verifies_after_normalization(con, @@ -6165,9 +6256,7 @@ test_connection_normalize_slave_type_1(void) NM_CONNECTION_ERROR_MISSING_SETTING); nmtst_connection_normalize(con); g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), - ==, - NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); } static void @@ -6182,9 +6271,9 @@ test_connection_normalize_slave_type_2(void) &s_con); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, "invalid-type", NULL); @@ -6193,19 +6282,17 @@ test_connection_normalize_slave_type_2(void) NM_CONNECTION_ERROR_INVALID_PROPERTY); g_assert(!nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); - g_object_set(s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_PORT_TYPE, NULL, NULL); nm_connection_add_setting(con, nm_setting_bridge_port_new()); g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NULL); + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NULL); nmtst_assert_connection_verifies_after_normalization(con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); nmtst_connection_normalize(con); g_assert(nm_connection_get_setting_by_name(con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), - ==, - NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); } static void @@ -6483,9 +6570,9 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) switch (TEST_CASE) { case 1: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -6504,9 +6591,9 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) break; case 2: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -6527,9 +6614,9 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) break; case 3: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -6545,9 +6632,9 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) break; case 4: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -6561,7 +6648,7 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) NM_CONNECTION_ERROR_INVALID_PROPERTY); break; case 5: - g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_CONTROLLER, "master0", NULL); s_ovs_if = NM_SETTING_OVS_INTERFACE(nm_setting_ovs_interface_new()); nm_connection_add_setting(con, NM_SETTING(s_ovs_if)); @@ -6576,15 +6663,15 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); break; case 6: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, NULL); @@ -6598,9 +6685,9 @@ test_connection_normalize_ovs_interface_type_system(gconstpointer test_data) break; case 7: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, NULL); @@ -6646,7 +6733,7 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_CONNECTION_ERROR_INVALID_PROPERTY); break; case 2: - g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_CONTROLLER, "master0", NULL); nmtst_assert_connection_verifies_after_normalization(con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); @@ -6659,16 +6746,16 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); break; case 3: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); nmtst_assert_connection_verifies_after_normalization(con, @@ -6683,13 +6770,13 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); break; case 4: - g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, "master0", NULL); + g_object_set(s_con, NM_SETTING_CONNECTION_CONTROLLER, "master0", NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); nmtst_assert_connection_verifies_after_normalization(con, NM_CONNECTION_ERROR, @@ -6703,16 +6790,16 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); break; case 5: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); @@ -6733,9 +6820,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 6: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "internal", NULL); @@ -6749,16 +6836,16 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_SETTING_OVS_INTERFACE_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "internal"); break; case 7: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "system", NULL); @@ -6768,9 +6855,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 8: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "bogus", NULL); @@ -6780,9 +6867,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 9: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); @@ -6792,9 +6879,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 10: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); g_object_set(s_ovs_if, NM_SETTING_OVS_INTERFACE_TYPE, "patch", NULL); @@ -6805,9 +6892,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 11: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf", @@ -6820,9 +6907,9 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da break; case 12: g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf", @@ -6842,7 +6929,7 @@ test_connection_normalize_ovs_interface_type_ovs_interface(gconstpointer test_da NM_SETTING_OVS_PATCH_SETTING_NAME); g_assert(s_con == nm_connection_get_setting_connection(con)); g_assert(s_ovs_if == nm_connection_get_setting_ovs_interface(con)); - g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + g_assert_cmpstr(nm_setting_connection_get_port_type(s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME); g_assert_cmpstr(nm_setting_ovs_interface_get_interface_type(s_ovs_if), ==, "patch"); @@ -8713,23 +8800,35 @@ test_nm_ptrarray_len(void) static void test_nm_utils_dns_option_validate_do(char *option, - gboolean ipv6, + int addr_family, const NMUtilsDNSOptionDesc *descs, gboolean exp_result, char *exp_name, gboolean exp_value) { - char *name; - long value = 0; - gboolean result; + gs_free char *name = NULL; + long value = 0; + gboolean result; + + if (!descs) { + g_assert(addr_family == AF_UNSPEC); + addr_family = nmtst_rand_select(AF_UNSPEC, AF_INET, AF_INET6); + } - result = _nm_utils_dns_option_validate(option, &name, &value, ipv6, descs); + result = _nm_utils_dns_option_validate(option, &name, &value, addr_family, descs); g_assert(result == exp_result); g_assert_cmpstr(name, ==, exp_name); g_assert(value == exp_value); - g_free(name); + nm_clear_g_free(&name); + + if (result && descs) { + result = _nm_utils_dns_option_validate(option, &name, &value, AF_UNSPEC, descs); + g_assert(result == exp_result); + g_assert_cmpstr(name, ==, exp_name); + g_assert(value == exp_value); + } } static const NMUtilsDNSOptionDesc opt_descs[] = { @@ -8743,57 +8842,56 @@ static const NMUtilsDNSOptionDesc opt_descs[] = { static void test_nm_utils_dns_option_validate(void) { - /* opt ipv6 descs result name value */ - test_nm_utils_dns_option_validate_do("", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do(":", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do(":1", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do(":val", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt", FALSE, NULL, TRUE, "opt", -1); - test_nm_utils_dns_option_validate_do("opt:", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt:12", FALSE, NULL, TRUE, "opt", 12); - test_nm_utils_dns_option_validate_do("opt:12 ", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt:val", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt:2val", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt:2:3", FALSE, NULL, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt-6", FALSE, NULL, TRUE, "opt-6", -1); + /* (opt, addr_family, descs, result, name, value) */ + test_nm_utils_dns_option_validate_do("", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":1", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do(":val", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt", AF_UNSPEC, NULL, TRUE, "opt", -1); + test_nm_utils_dns_option_validate_do("opt:", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:12", AF_UNSPEC, NULL, TRUE, "opt", 12); + test_nm_utils_dns_option_validate_do("opt:12 ", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:val", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:2val", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt:2:3", AF_UNSPEC, NULL, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt-6", AF_UNSPEC, NULL, TRUE, "opt-6", -1); - test_nm_utils_dns_option_validate_do("opt1", FALSE, opt_descs, TRUE, "opt1", -1); - test_nm_utils_dns_option_validate_do("opt1", TRUE, opt_descs, TRUE, "opt1", -1); - test_nm_utils_dns_option_validate_do("opt1:3", FALSE, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt1", AF_INET, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do("opt1", AF_INET6, opt_descs, TRUE, "opt1", -1); + test_nm_utils_dns_option_validate_do("opt1:3", AF_INET, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt2", FALSE, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt2:5", FALSE, opt_descs, TRUE, "opt2", 5); + test_nm_utils_dns_option_validate_do("opt2", AF_INET, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt2:5", AF_INET, opt_descs, TRUE, "opt2", 5); - test_nm_utils_dns_option_validate_do("opt3", FALSE, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt3", TRUE, opt_descs, TRUE, "opt3", -1); + test_nm_utils_dns_option_validate_do("opt3", AF_INET, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt3", AF_INET6, opt_descs, TRUE, "opt3", -1); - test_nm_utils_dns_option_validate_do("opt4", FALSE, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt4", TRUE, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt4:40", FALSE, opt_descs, FALSE, NULL, -1); - test_nm_utils_dns_option_validate_do("opt4:40", TRUE, opt_descs, TRUE, "opt4", 40); + test_nm_utils_dns_option_validate_do("opt4", AF_INET, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4", AF_INET6, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4:40", AF_INET, opt_descs, FALSE, NULL, -1); + test_nm_utils_dns_option_validate_do("opt4:40", AF_INET6, opt_descs, TRUE, "opt4", 40); } static void test_nm_utils_dns_option_find_idx(void) { - GPtrArray *options; - - options = g_ptr_array_new(); - - g_ptr_array_add(options, "debug"); - g_ptr_array_add(options, "timeout:5"); - g_ptr_array_add(options, "edns0"); + const char *const options[] = { + "debug", + "timeout:5", + "edns0", + }; - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug"), ==, 0); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug:1"), ==, 0); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:5"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:2"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "edns0"), ==, 2); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "rotate"), ==, -1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, ""), ==, -1); +#define _find_idx(options, option) \ + _nm_utils_dns_option_find_idx((options), G_N_ELEMENTS(options), ("" option "")) - g_ptr_array_free(options, TRUE); + g_assert_cmpint(_find_idx(options, "debug"), ==, 0); + g_assert_cmpint(_find_idx(options, "debug:1"), ==, 0); + g_assert_cmpint(_find_idx(options, "timeout"), ==, 1); + g_assert_cmpint(_find_idx(options, "timeout:5"), ==, 1); + g_assert_cmpint(_find_idx(options, "timeout:2"), ==, 1); + g_assert_cmpint(_find_idx(options, "edns0"), ==, 2); + g_assert_cmpint(_find_idx(options, "rotate"), ==, -1); + g_assert_cmpint(_find_idx(options, ""), ==, -1); } /*****************************************************************************/ @@ -10601,9 +10699,9 @@ test_connection_ovs_ifname(gconstpointer test_data) &s_con); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_BRIDGE_SETTING_NAME, NULL); @@ -10619,9 +10717,9 @@ test_connection_ovs_ifname(gconstpointer test_data) g_assert(s_ovs_iface); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -10646,9 +10744,9 @@ test_connection_ovs_ifname(gconstpointer test_data) g_assert(s_ovs_iface); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -10662,9 +10760,9 @@ test_connection_ovs_ifname(gconstpointer test_data) &s_con); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); @@ -10688,9 +10786,9 @@ test_connection_ovs_ifname(gconstpointer test_data) g_assert(s_ovs_iface); g_object_set(s_con, - NM_SETTING_CONNECTION_MASTER, + NM_SETTING_CONNECTION_CONTROLLER, "master0", - NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_CONNECTION_PORT_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME, NULL); diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index b30758ff..4b1aa2c1 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -2303,6 +2303,79 @@ test_ethtool_pause(void) g_assert_true(out_value); } +static void +test_ethtool_eee(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection *s_con; + NMSettingEthtool *s_ethtool; + NMSettingEthtool *s_ethtool2; + NMSettingEthtool *s_ethtool3; + gboolean out_value; + + con = + nmtst_create_minimal_connection("ethtool-eee", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_connection_add_setting(con, NM_SETTING(s_ethtool)); + + nm_setting_option_set_boolean(NM_SETTING(s_ethtool), NM_ETHTOOL_OPTNAME_EEE_ENABLED, FALSE); + + g_assert_true(nm_setting_option_get_boolean(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_EEE_ENABLED, + &out_value)); + g_assert_true(!out_value); + + nmtst_connection_normalize(con); + + variant = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_boolean(NM_SETTING(s_ethtool2), + NM_ETHTOOL_OPTNAME_EEE_ENABLED, + &out_value)); + g_assert_true(!out_value); + + nmtst_assert_connection_verifies_without_normalization(con2); + + nmtst_assert_connection_equals(con, FALSE, con2, FALSE); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + keyfile = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(keyfile, error); + + con3 = nm_keyfile_read(keyfile, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con3, error); + + nm_keyfile_read_ensure_id(con3, "unused-because-already-has-id"); + nm_keyfile_read_ensure_uuid(con3, "unused-because-already-has-uuid"); + + nmtst_connection_normalize(con3); + + nmtst_assert_connection_equals(con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_boolean(NM_SETTING(s_ethtool3), + NM_ETHTOOL_OPTNAME_EEE_ENABLED, + &out_value)); + g_assert_true(!out_value); +} /*****************************************************************************/ static void @@ -4492,7 +4565,7 @@ test_setting_metadata(void) GArray *property_types_data; guint prop_idx_val; gboolean can_set_including_default = FALSE; - gboolean can_have_direct_hook = FALSE; + gboolean can_have_direct_set_fcn = FALSE; int n_special_options; g_assert(sip->name); @@ -4633,9 +4706,11 @@ test_setting_metadata(void) INFINIBAND_ALEN)); } else { g_assert(g_variant_type_equal(sip->property_type->dbus_type, "s")); - g_assert(sip->property_type->to_dbus_fcn - == _nm_setting_property_to_dbus_fcn_direct); - can_have_direct_hook = TRUE; + g_assert(NM_IN_SET(sip->property_type->to_dbus_fcn, + _nm_setting_property_to_dbus_fcn_direct, + _nm_setting_connection_controller_to_dbus, + _nm_setting_connection_port_type_to_dbus)); + can_have_direct_set_fcn = TRUE; } g_assert(sip->param_spec); g_assert(sip->param_spec->value_type == G_TYPE_STRING); @@ -4663,6 +4738,11 @@ test_setting_metadata(void) g_assert(sip->param_spec); g_assert(!NM_FLAGS_HAS(sip->param_spec->flags, NM_SETTING_PARAM_SECRET)); } + if (sip->direct_strv_preserve_empty) + g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRV); + if (sip->direct_string_allow_empty) { + g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING); + } if (sip->direct_set_string_mac_address_len != 0) { g_assert(NM_IN_SET(sip->property_type, @@ -4671,8 +4751,26 @@ test_setting_metadata(void) g_assert(sip->property_type->direct_type == NM_VALUE_TYPE_STRING); } - if (!can_have_direct_hook) - g_assert(!sip->direct_hook.set_string_fcn); + if (!can_have_direct_set_fcn) + g_assert(!sip->direct_set_fcn.set_string); + + if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE) + g_assert(!sip->direct_also_notify); + else { + if (sip->direct_also_notify) { + guint prop_idx2; + guint cnt = 0; + + for (prop_idx2 = 0; prop_idx2 < sis->property_infos_len; prop_idx2++) { + const NMSettInfoProperty *sip2 = &sis->property_infos[prop_idx2]; + + if (sip2->param_spec == sip->direct_also_notify) + cnt++; + } + g_assert_cmpint(cnt, ==, 1u); + g_assert(sip->param_spec != sip->direct_also_notify); + } + } n_special_options = (sip->direct_set_string_mac_address_len != 0) + (!!sip->direct_set_string_strip) @@ -4754,6 +4852,10 @@ check_done:; g_assert(NM_IN_SET(sip->property_type->from_dbus_fcn, _nm_setting_property_from_dbus_fcn_direct_ip_config_gateway, _nm_setting_property_from_dbus_fcn_direct_mac_address, + _nm_setting_connection_controller_from_dbus, + _nm_setting_connection_master_from_dbus, + _nm_setting_connection_slave_type_from_dbus, + _nm_setting_connection_port_type_from_dbus, _nm_setting_property_from_dbus_fcn_direct)); } } @@ -4775,7 +4877,9 @@ check_done:; g_assert(sip->property_type->direct_type != NM_VALUE_TYPE_NONE); g_assert(NM_IN_SET(sip->property_type->to_dbus_fcn, _nm_setting_property_to_dbus_fcn_direct, - _nm_setting_property_to_dbus_fcn_direct_mac_address)); + _nm_setting_property_to_dbus_fcn_direct_mac_address, + _nm_setting_connection_controller_to_dbus, + _nm_setting_connection_port_type_to_dbus)); } 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, @@ -4810,6 +4914,17 @@ check_done:; g_array_append_val(property_types_data, prop_idx_val); if (sip->param_spec) { + /* All "direct" properties use G_PARAM_EXPLICIT_NOTIFY. + * + * Warning: this is potentially dangerous, because implementations MUST remember + * to notify the property change in set_property(). Optimally, the property uses + * _nm_setting_property_set_property_direct(), which takes care of that. + */ + if (sip->property_type->direct_type != NM_VALUE_TYPE_NONE) + g_assert(NM_FLAGS_HAS(sip->param_spec->flags, G_PARAM_EXPLICIT_NOTIFY)); + } + + if (sip->param_spec) { nm_auto_unset_gvalue GValue val = G_VALUE_INIT; g_assert_cmpstr(sip->name, ==, sip->param_spec->name); @@ -4998,6 +5113,50 @@ check_done:; /*****************************************************************************/ static void +test_setting_connection_empty_address_and_route(void) +{ + NMSettingIPConfig *s_ip4; + NMIPRoute *route; + NMIPAddress *addr; + gs_unref_object NMConnection *con = NULL; + gs_free_error GError *error = NULL; + gboolean success; + + /* IP4 setting */ + con = nmtst_create_minimal_connection("wired", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(con, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + g_assert(s_ip4 != NULL); + g_assert(NM_IS_SETTING_IP4_CONFIG(s_ip4)); + success = nm_setting_verify((NMSetting *) s_ip4, con, &error); + nmtst_assert_no_success(success, error); + nm_clear_error(&error); + + route = nm_ip_route_new(AF_INET, "192.168.12.0", 24, NULL, 0, NULL); + nm_setting_ip_config_add_route(s_ip4, route); + success = nm_setting_verify((NMSetting *) s_ip4, con, &error); + nmtst_assert_success(success, error); + nm_clear_error(&error); + + nm_setting_ip_config_clear_routes(s_ip4); + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, NULL); + nm_setting_ip_config_add_address(s_ip4, addr); + success = nm_setting_verify((NMSetting *) s_ip4, con, &error); + nmtst_assert_success(success, error); + nm_clear_error(&error); + + nm_setting_ip_config_add_route(s_ip4, route); + success = nm_setting_verify((NMSetting *) s_ip4, con, &error); + nmtst_assert_success(success, error); + nm_ip_address_unref(addr); + nm_ip_route_unref(route); + nm_clear_error(&error); +} + +/*****************************************************************************/ + +static void test_setting_connection_secondaries_verify(void) { gs_unref_object NMConnection *con = NULL; @@ -5035,44 +5194,42 @@ test_setting_connection_secondaries_verify(void) g_object_set(s_con, NM_SETTING_CONNECTION_SECONDARIES, arr->pdata, NULL); -#define _assert_secondaries(s_con, expected) \ - G_STMT_START \ - { \ - NMSettingConnection *const _s_con = (s_con); \ - const char *const *_expected = (expected); \ - GArray *_secondaries; \ - const guint _expected_len = NM_PTRARRAY_LEN(_expected); \ - gs_strfreev char **_sec_strv = NULL; \ - guint _i; \ - \ - g_assert(_expected); \ - \ - if (nmtst_get_rand_bool()) { \ - _secondaries = _nm_setting_connection_get_secondaries(_s_con); \ - g_assert_cmpint(_expected_len, ==, nm_g_array_len(_secondaries)); \ - g_assert((_expected_len == 0) == (!_secondaries)); \ - g_assert(nm_strv_equal(_expected, \ - _secondaries ? nm_strvarray_get_strv(&_secondaries, NULL) \ - : NM_PTRARRAY_EMPTY(const char *))); \ - } \ - \ - if (nmtst_get_rand_bool()) { \ - g_object_get(_s_con, NM_SETTING_CONNECTION_SECONDARIES, &_sec_strv, NULL); \ - g_assert_cmpint(_expected_len, ==, NM_PTRARRAY_LEN(_sec_strv)); \ - g_assert((_expected_len == 0) == (!_sec_strv)); \ - g_assert(nm_strv_equal(_expected, _sec_strv ?: NM_STRV_EMPTY())); \ - } \ - \ - g_assert_cmpint(nm_setting_connection_get_num_secondaries(_s_con), ==, _expected_len); \ - if (nmtst_get_rand_bool()) { \ - for (_i = 0; _i < _expected_len; _i++) { \ - g_assert_cmpstr(nm_setting_connection_get_secondary(_s_con, _i), \ - ==, \ - _expected[_i]); \ - } \ - g_assert_null(nm_setting_connection_get_secondary(_s_con, _expected_len)); \ - } \ - } \ +#define _assert_secondaries(s_con, expected) \ + G_STMT_START \ + { \ + NMSettingConnection *const _s_con = (s_con); \ + const char *const *_expected = (expected); \ + GArray *_secondaries; \ + const guint _expected_len = NM_PTRARRAY_LEN(_expected); \ + gs_strfreev char **_sec_strv = NULL; \ + guint _i; \ + \ + g_assert(_expected); \ + \ + if (nmtst_get_rand_bool()) { \ + _secondaries = _nm_setting_connection_get_secondaries(_s_con); \ + g_assert_cmpint(_expected_len, ==, nm_g_array_len(_secondaries)); \ + g_assert((_expected_len == 0) == (!_secondaries)); \ + g_assert(nm_strv_equal(_expected, nm_strvarray_get_strv_notnull(_secondaries, NULL))); \ + } \ + \ + if (nmtst_get_rand_bool()) { \ + g_object_get(_s_con, NM_SETTING_CONNECTION_SECONDARIES, &_sec_strv, NULL); \ + g_assert_cmpint(_expected_len, ==, NM_PTRARRAY_LEN(_sec_strv)); \ + g_assert((_expected_len == 0) == (!_sec_strv)); \ + g_assert(nm_strv_equal(_expected, _sec_strv ?: NM_STRV_EMPTY())); \ + } \ + \ + g_assert_cmpint(nm_setting_connection_get_num_secondaries(_s_con), ==, _expected_len); \ + if (nmtst_get_rand_bool()) { \ + for (_i = 0; _i < _expected_len; _i++) { \ + g_assert_cmpstr(nm_setting_connection_get_secondary(_s_con, _i), \ + ==, \ + _expected[_i]); \ + } \ + g_assert_null(nm_setting_connection_get_secondary(_s_con, _expected_len)); \ + } \ + } \ G_STMT_END _assert_secondaries(s_con, (const char *const *) arr->pdata); @@ -5307,6 +5464,8 @@ main(int argc, char **argv) test_8021x); g_test_add_data_func("/libnm/setting-8021x/pkcs12", "test-cert.p12, test", test_8021x); + g_test_add_func("/libnm/settings/test_setting_connection_empty_address_and_route", + test_setting_connection_empty_address_and_route); g_test_add_func("/libnm/settings/test_setting_connection_secondaries_verify", test_setting_connection_secondaries_verify); @@ -5326,6 +5485,7 @@ main(int argc, char **argv) g_test_add_func("/libnm/settings/ethtool/coalesce", test_ethtool_coalesce); g_test_add_func("/libnm/settings/ethtool/ring", test_ethtool_ring); g_test_add_func("/libnm/settings/ethtool/pause", test_ethtool_pause); + g_test_add_func("/libnm/settings/ethtool/eee", test_ethtool_eee); g_test_add_func("/libnm/settings/6lowpan/1", test_6lowpan_1); |