From 1d2df314cc9cbe242b3b1533777b834c6418408d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 28 Jun 2019 08:28:15 +0200 Subject: [PATCH 1/7] shared: add nm_c_list_free_all() macro --- shared/nm-glib-aux/nm-c-list.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shared/nm-glib-aux/nm-c-list.h b/shared/nm-glib-aux/nm-c-list.h index 36f1ff755b..96b0279469 100644 --- a/shared/nm-glib-aux/nm-c-list.h +++ b/shared/nm-glib-aux/nm-c-list.h @@ -159,4 +159,14 @@ nm_c_list_move_after (CList *lst, CList *elem) } #define nm_c_list_move_front(lst, elem) nm_c_list_move_after (lst, elem) +#define nm_c_list_free_all(lst, type, member, destroy_fcn) \ + G_STMT_START { \ + CList *const _lst = (lst); \ + type *_elem; \ + \ + while ((_elem = c_list_first_entry (_lst, type, member))) { \ + destroy_fcn (_elem); \ + } \ + } G_STMT_END + #endif /* __NM_C_LIST_H__ */ From b4fe51b5faa259f971a9e3d23cfba844526f6c13 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 10:33:14 +0200 Subject: [PATCH 2/7] shared: add nm_utils_strv_dup() util --- shared/nm-glib-aux/nm-shared-utils.c | 56 ++++++++++++++++++++++++++++ shared/nm-glib-aux/nm-shared-utils.h | 2 + 2 files changed, 58 insertions(+) diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 472a4c484f..7362dfc930 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -2345,6 +2345,62 @@ nm_utils_strv_make_deep_copied_n (const char **strv, gsize len) return (char **) strv; } +/** + * @strv: the strv array to copy. It may be %NULL if @len + * is negative or zero (in which case %NULL will be returned). + * @len: the length of strings in @str. If negative, strv is assumed + * to be a NULL terminated array. + * + * Like g_strdupv(), with two differences: + * + * - accepts a @len parameter for non-null terminated strv array. + * + * - this never returns an empty strv array, but always %NULL if + * there are no strings. + * + * Note that if @len is non-negative, then it still must not + * contain any %NULL pointers within the first @len elements. + * Otherwise you would leak elements if you try to free the + * array with g_strfreev(). Allowing that would be error prone. + * + * Returns: (transfer full): a clone of the strv array. Always + * %NULL terminated. + */ +char ** +nm_utils_strv_dup (gpointer strv, gssize len) +{ + gsize i, l; + char **v; + const char *const *const src = strv; + + if (len < 0) + l = NM_PTRARRAY_LEN (src); + else + l = len; + if (l == 0) { + /* this function never returns an empty strv array. If you + * need that, handle it yourself. */ + return NULL; + } + + v = g_new (char *, l + 1); + for (i = 0; i < l; i++) { + + if (G_UNLIKELY (!src[i])) { + /* NULL strings are not allowed. Clear the remainder of the array + * and return it (with assertion failure). */ + l++; + for (; i < l; i++) + v[i] = NULL; + g_return_val_if_reached (v); + } + + v[i] = g_strdup (src[i]); + } + v[l] = NULL; + return v; +} + /*****************************************************************************/ gssize diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index e65d1be683..7de6c06208 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -979,6 +979,8 @@ nm_utils_strv_make_deep_copied_nonnull (const char **strv) return nm_utils_strv_make_deep_copied (strv) ?: g_new0 (char *, 1); } +char **nm_utils_strv_dup (gpointer strv, gssize len); + /*****************************************************************************/ GSList *nm_utils_g_slist_find_str (const GSList *list, From 4d03b16f9d4025e3171174d169af5b726372f392 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 10:08:54 +0200 Subject: [PATCH 3/7] libnm: track wifi.seen-bssids in a GPtrArray instead of a GSList GPtrArray allows direct lookup by index. Since the NMSettingWireless API is based on lookup by index, this is a common operation. Note that nm_setting_wireless_add_seen_bssid() is still O(n), meaning to add n elements, it takes O(n^2). That's not great but no worse than before. The cases where GSList is the best choice for a data type are few. --- libnm-core/nm-setting-wireless.c | 112 ++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 80fc7e9b27..f858cfa0ec 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -71,8 +71,8 @@ typedef struct { char *cloned_mac_address; char *generate_mac_address_mask; GArray *mac_address_blacklist; + GPtrArray *seen_bssids; guint32 mtu; - GSList *seen_bssids; gboolean hidden; guint32 powersave; NMSettingMacRandomization mac_address_randomization; @@ -658,33 +658,27 @@ nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, const char *bssid) { NMSettingWirelessPrivate *priv; - char *lower_bssid; - GSList *iter; - gboolean found = FALSE; + gs_free char *lower_bssid = NULL; g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); g_return_val_if_fail (bssid != NULL, FALSE); - lower_bssid = g_ascii_strdown (bssid, -1); - if (!lower_bssid) - return FALSE; - priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); - for (iter = priv->seen_bssids; iter; iter = iter->next) { - if (!strcmp ((char *) iter->data, lower_bssid)) { - found = TRUE; - break; - } + lower_bssid = g_ascii_strdown (bssid, -1); + + if (!priv->seen_bssids) { + priv->seen_bssids = g_ptr_array_new_with_free_func (g_free); + } else { + if (nm_utils_strv_find_first ((char **) priv->seen_bssids->pdata, + priv->seen_bssids->len, + lower_bssid) >= 0) + return FALSE; } - if (!found) { - priv->seen_bssids = g_slist_prepend (priv->seen_bssids, lower_bssid); - _notify (setting, PROP_SEEN_BSSIDS); - } else - g_free (lower_bssid); - - return !found; + g_ptr_array_add (priv->seen_bssids, g_steal_pointer (&lower_bssid)); + _notify (setting, PROP_SEEN_BSSIDS); + return TRUE; } /** @@ -696,9 +690,15 @@ nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, guint32 nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting) { + NMSettingWirelessPrivate *priv; + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); - return g_slist_length (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids); + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + + return priv->seen_bssids + ? priv->seen_bssids->len + : 0u; } /** @@ -712,9 +712,17 @@ const char * nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, guint32 i) { - g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + NMSettingWirelessPrivate *priv; - return (const char *) g_slist_nth_data (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids, i); + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + + if ( !priv->seen_bssids + || i >= priv->seen_bssids->len) + return NULL; + + return priv->seen_bssids->pdata[i]; } static gboolean @@ -723,8 +731,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); const char *valid_modes[] = { NM_SETTING_WIRELESS_MODE_INFRA, NM_SETTING_WIRELESS_MODE_ADHOC, NM_SETTING_WIRELESS_MODE_AP, NULL }; const char *valid_bands[] = { "a", "bg", NULL }; - GSList *iter; - int i; + guint i; gsize length; GError *local = NULL; @@ -846,15 +853,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - for (iter = priv->seen_bssids; iter; iter = iter->next) { - if (!nm_utils_hwaddr_valid (iter->data, ETH_ALEN)) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("'%s' is not a valid MAC address"), - (const char *) iter->data); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SEEN_BSSIDS); - return FALSE; + if (priv->seen_bssids) { + for (i = 0; i < priv->seen_bssids->len; i++) { + const char *b; + + b = priv->seen_bssids->pdata[i]; + if (!nm_utils_hwaddr_valid (b, ETH_ALEN)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + b); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SEEN_BSSIDS); + return FALSE; + } } } @@ -1030,7 +1042,11 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, nm_setting_wireless_get_mtu (setting)); break; case PROP_SEEN_BSSIDS: - g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->seen_bssids, TRUE)); + g_value_take_boxed (value, + priv->seen_bssids + ? nm_utils_strv_dup (priv->seen_bssids->pdata, + priv->seen_bssids->len) + : NULL); break; case PROP_HIDDEN: g_value_set_boolean (value, nm_setting_wireless_get_hidden (setting)); @@ -1058,7 +1074,6 @@ set_property (GObject *object, guint prop_id, const char * const *blacklist; const char *mac; gboolean bool_val; - int i; switch (prop_id) { case PROP_SSID: @@ -1113,7 +1128,9 @@ set_property (GObject *object, guint prop_id, case PROP_MAC_ADDRESS_BLACKLIST: blacklist = g_value_get_boxed (value); g_array_set_size (priv->mac_address_blacklist, 0); - if (blacklist && *blacklist) { + if (blacklist && blacklist[0]) { + gsize i; + for (i = 0; blacklist[i]; i++) { mac = _nm_utils_hwaddr_canonical_or_invalid (blacklist[i], ETH_ALEN); g_array_append_val (priv->mac_address_blacklist, mac); @@ -1123,10 +1140,23 @@ set_property (GObject *object, guint prop_id, case PROP_MTU: priv->mtu = g_value_get_uint (value); break; - case PROP_SEEN_BSSIDS: - g_slist_free_full (priv->seen_bssids, g_free); - priv->seen_bssids = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE); + case PROP_SEEN_BSSIDS: { + gs_unref_ptrarray GPtrArray *arr_old = NULL; + const char *const*strv; + + arr_old = g_steal_pointer (&priv->seen_bssids); + + strv = g_value_get_boxed (value); + if (strv && strv[0]) { + gsize i, l; + + l = NM_PTRARRAY_LEN (strv); + priv->seen_bssids = g_ptr_array_new_full (l, g_free); + for (i = 0; i < l; i++) + g_ptr_array_add (priv->seen_bssids, g_strdup (strv[i])); + } break; + } case PROP_HIDDEN: priv->hidden = g_value_get_boolean (value); break; @@ -1185,7 +1215,7 @@ finalize (GObject *object) g_free (priv->cloned_mac_address); g_free (priv->generate_mac_address_mask); g_array_unref (priv->mac_address_blacklist); - g_slist_free_full (priv->seen_bssids, g_free); + nm_clear_pointer (&priv->seen_bssids, g_ptr_array_unref); G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object); } From 31c4c111d3e35d2273c77bb15c876856d27778e5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 08:41:58 +0200 Subject: [PATCH 4/7] settings: cleanup handling of seen-bssids list in NMSettingsConnection - most connections are not Wi-Fi connections and thus don't have a seen-bssids list. Only create the seen_bssids hash when required. This avoids allocating the hash in common cases and avoids checking the hash for the content (which is often empty). - nm_settings_connection_get_seen_bssids() should return a sorted list. Leaving the sort order undefined is ugly. - in try_fill_ssid_for_hidden_ap(), we need to check all NMSettingsConnection instances whether they know this bssid. Reorder the checks, to first call nm_settings_connection_has_seen_bssid(), which is faster and in most cases returns a negative result (shortcutting the rest). --- src/devices/wifi/nm-device-wifi.c | 13 ++--- src/settings/nm-settings-connection.c | 71 ++++++++++++++++----------- src/settings/nm-settings-connection.h | 2 +- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 22c4194f9e..aff631f889 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1513,13 +1513,14 @@ try_fill_ssid_for_hidden_ap (NMDeviceWifi *self, NMSettingsConnection *sett_conn = connections[i]; NMSettingWireless *s_wifi; + if (!nm_settings_connection_has_seen_bssid (sett_conn, bssid)) + continue; s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn)); - if (s_wifi) { - if (nm_settings_connection_has_seen_bssid (sett_conn, bssid)) { - nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); - break; - } - } + if (!s_wifi) + continue; + + nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + break; } } diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 663e630656..5f3f6498a4 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -169,6 +169,14 @@ static const NMDBusInterfaceInfoExtended interface_info_settings_connection; /*****************************************************************************/ +static GHashTable * +_seen_bssids_hash_new (void) +{ + return g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); +} + +/*****************************************************************************/ + NMConnection * nm_settings_connection_get_connection (NMSettingsConnection *self) { @@ -1398,7 +1406,7 @@ get_settings_auth_cb (NMSettingsConnection *self, NMSettingConnection *s_con; NMSettingWireless *s_wifi; guint64 timestamp = 0; - gs_free char **bssids = NULL; + gs_free const char **bssids = NULL; dupl_con = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); @@ -1418,9 +1426,11 @@ get_settings_auth_cb (NMSettingsConnection *self, * return settings too. */ bssids = nm_settings_connection_get_seen_bssids (self); - s_wifi = nm_connection_get_setting_wireless (dupl_con); - if (bssids && bssids[0] && s_wifi) - g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); + if (bssids) { + s_wifi = nm_connection_get_setting_wireless (dupl_con); + if (s_wifi) + g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); + } /* Secrets should *never* be returned by the GetSettings method, they * get returned by the GetSecrets method which can be better @@ -2347,13 +2357,16 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, tmp_strv = nm_key_file_db_get_string_list (priv->kf_db_seen_bssids, connection_uuid, &len); - if (tmp_strv) { + nm_clear_pointer (&priv->seen_bssids, g_hash_table_unref); + + if (len > 0) { _LOGT ("read %zu seen-bssids from keyfile database \"%s\"", - NM_PTRARRAY_LEN (tmp_strv), + len, nm_key_file_db_get_filename (priv->kf_db_seen_bssids)); - g_hash_table_remove_all (priv->seen_bssids); + priv->seen_bssids = _seen_bssids_hash_new (); for (i = len; i > 0; ) g_hash_table_add (priv->seen_bssids, g_steal_pointer (&tmp_strv[--i])); + nm_clear_g_free (&tmp_strv); } else { NMSettingWireless *s_wifi; @@ -2368,10 +2381,13 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (self)); if (s_wifi) { len = nm_setting_wireless_get_num_seen_bssids (s_wifi); - for (i = 0; i < len; i++) { - const char *bssid = nm_setting_wireless_get_seen_bssid (s_wifi, i); + if (len > 0) { + priv->seen_bssids = _seen_bssids_hash_new (); + for (i = 0; i < len; i++) { + const char *bssid = nm_setting_wireless_get_seen_bssid (s_wifi, i); - g_hash_table_add (priv->seen_bssids, g_strdup (bssid)); + g_hash_table_add (priv->seen_bssids, g_strdup (bssid)); + } } } } @@ -2387,25 +2403,14 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, * Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation). * The caller is responsible for freeing the list, but not the content. **/ -char ** +const char ** nm_settings_connection_get_seen_bssids (NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - GHashTableIter iter; - char **bssids, *bssid; - int i; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); - bssids = g_new (char *, g_hash_table_size (priv->seen_bssids) + 1); - - i = 0; - g_hash_table_iter_init (&iter, priv->seen_bssids); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &bssid)) - bssids[i++] = bssid; - bssids[i] = NULL; - - return bssids; + return nm_utils_strdict_get_keys (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, + TRUE, + NULL); } /** @@ -2419,10 +2424,15 @@ gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, const char *bssid) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); - g_return_val_if_fail (bssid != NULL, FALSE); + NMSettingsConnectionPrivate *priv; - return !!g_hash_table_lookup (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, bssid); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail (bssid, FALSE); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + return priv->seen_bssids + && g_hash_table_contains (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, bssid); } /** @@ -2443,6 +2453,9 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *self, g_return_if_fail (seen_bssid != NULL); + if (!priv->seen_bssids) + priv->seen_bssids = _seen_bssids_hash_new (); + g_hash_table_add (priv->seen_bssids, g_strdup (seen_bssid)); if (!priv->kf_db_seen_bssids) @@ -2718,8 +2731,6 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); - priv->seen_bssids = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; priv->connection = nm_simple_connection_new (); diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index ebed798c31..38e34d8fa5 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -228,7 +228,7 @@ gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *self, void nm_settings_connection_update_timestamp (NMSettingsConnection *self, guint64 timestamp); -char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *self); +const char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *self); gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, const char *bssid); From 441dd1f3c837a0a280a2f127f8797807c2ebda22 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 09:07:16 +0200 Subject: [PATCH 5/7] libnm: add nm_connection_to_dbus_full() with options argument No options are implemented yet. --- libnm-core/nm-connection.c | 13 ++++++++++++- libnm-core/nm-core-internal.h | 11 ++++++++++- libnm-core/nm-setting-ip-config.c | 3 ++- libnm-core/nm-setting-ip4-config.c | 15 ++++++++++----- libnm-core/nm-setting-ip6-config.c | 12 ++++++++---- libnm-core/nm-setting-private.h | 6 ++++-- libnm-core/nm-setting-sriov.c | 3 ++- libnm-core/nm-setting-tc-config.c | 6 ++++-- libnm-core/nm-setting-vlan.c | 3 ++- libnm-core/nm-setting-wired.c | 3 ++- libnm-core/nm-setting-wireguard.c | 3 ++- libnm-core/nm-setting-wireless.c | 3 ++- libnm-core/nm-setting.c | 21 ++++++++++++++------- libnm-core/nm-team-utils.c | 3 ++- libnm-core/nm-team-utils.h | 3 ++- libnm-core/nm-utils-private.h | 9 ++++++--- libnm-core/nm-utils.c | 9 ++++++--- libnm-core/tests/test-general.c | 16 ++++++++-------- libnm-core/tests/test-setting.c | 2 +- shared/nm-utils/nm-test-utils.h | 2 +- 20 files changed, 100 insertions(+), 46 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index c45f29b467..615faae7d1 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -2239,6 +2239,14 @@ _nm_connection_find_secret (NMConnection *self, GVariant * nm_connection_to_dbus (NMConnection *connection, NMConnectionSerializationFlags flags) +{ + return nm_connection_to_dbus_full (connection, flags, NULL); +} + +GVariant * +nm_connection_to_dbus_full (NMConnection *connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMConnectionPrivate *priv; GVariantBuilder builder; @@ -2252,11 +2260,14 @@ nm_connection_to_dbus (NMConnection *connection, g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); /* Add each setting's hash to the main hash */ + + /* FIXME: the order of serialized settings must be stable. */ + g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, NULL, &data)) { NMSetting *setting = NM_SETTING (data); - setting_dict = _nm_setting_to_dbus (setting, connection, flags); + setting_dict = _nm_setting_to_dbus (setting, connection, flags, options); if (setting_dict) g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_dict); } diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 60e13937de..7547044a9d 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -164,6 +164,14 @@ gpointer _nm_connection_check_main_setting (NMConnection *connection, const char *setting_name, GError **error); +typedef struct { + int dummy; +} NMConnectionSerializationOptions; + +GVariant *nm_connection_to_dbus_full (NMConnection *connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); + typedef enum { /* whether the connection has any secrets. * @@ -681,7 +689,8 @@ typedef GVariant *(*NMSettInfoPropToDBusFcn) (const NMSettInfoSetting guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); typedef gboolean (*NMSettInfoPropFromDBusFcn) (NMSetting *setting, GVariant *connection_dict, const char *property, diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 38e565bd44..51dbd12b98 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -4550,7 +4550,8 @@ _routing_rules_dbus_only_synth (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingIPConfig *self = NM_SETTING_IP_CONFIG (setting); NMSettingIPConfigPrivate *priv; diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 34a26b37d3..73ba4b7406 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -255,7 +255,8 @@ ip4_addresses_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *addrs = NULL; const char *gateway; @@ -308,7 +309,8 @@ ip4_address_labels_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); gboolean have_labels = FALSE; @@ -351,7 +353,8 @@ ip4_address_data_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *addrs = NULL; @@ -389,7 +392,8 @@ ip4_routes_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *routes = NULL; @@ -423,7 +427,8 @@ ip4_route_data_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *routes = NULL; diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 64fe2a329c..bafdb373ce 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -317,7 +317,8 @@ ip6_addresses_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *addrs = NULL; const char *gateway; @@ -359,7 +360,8 @@ ip6_address_data_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *addrs = NULL; @@ -397,7 +399,8 @@ ip6_routes_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *routes = NULL; @@ -431,7 +434,8 @@ ip6_route_data_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *routes = NULL; diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 70e4bdce5e..c4c0bb4821 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -87,7 +87,8 @@ GVariant *_nm_setting_get_deprecated_virtual_interface_name (const NMSettInfoSet guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); NMSettingVerifyResult _nm_setting_verify (NMSetting *setting, NMConnection *connection, @@ -106,7 +107,8 @@ gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **o GVariant *_nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); NMSetting *_nm_setting_new_from_dbus (GType setting_type, GVariant *setting_dict, diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c index 5fbaecd71d..94583b09fc 100644 --- a/libnm-core/nm-setting-sriov.c +++ b/libnm-core/nm-setting-sriov.c @@ -905,7 +905,8 @@ vfs_to_dbus (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *vfs = NULL; GVariantBuilder builder; diff --git a/libnm-core/nm-setting-tc-config.c b/libnm-core/nm-setting-tc-config.c index 494183a488..fe8e695cc8 100644 --- a/libnm-core/nm-setting-tc-config.c +++ b/libnm-core/nm-setting-tc-config.c @@ -1487,7 +1487,8 @@ tc_qdiscs_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *qdiscs = NULL; @@ -1672,7 +1673,8 @@ tc_tfilters_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *tfilters = NULL; diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 2a2125ac62..a7debbf1d7 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -681,7 +681,8 @@ _override_flags_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { return g_variant_new_uint32 (nm_setting_vlan_get_flags ((NMSettingVlan *) setting)); } diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 4978654640..ccdbc2b5ed 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -930,7 +930,8 @@ _override_autoneg_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { return g_variant_new_boolean (nm_setting_wired_get_auto_negotiate ((NMSettingWired *) setting)); } diff --git a/libnm-core/nm-setting-wireguard.c b/libnm-core/nm-setting-wireguard.c index 64a9b1a228..9e67454d0d 100644 --- a/libnm-core/nm-setting-wireguard.c +++ b/libnm-core/nm-setting-wireguard.c @@ -1460,7 +1460,8 @@ _peers_dbus_only_synth (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingWireGuard *self = NM_SETTING_WIREGUARD (setting); NMSettingWireGuardPrivate *priv; diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index f858cfa0ec..08373df35e 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -957,7 +957,8 @@ nm_setting_wireless_get_security (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { if (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) return NULL; diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index dfb2393ca3..4323b83c08 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -686,6 +686,7 @@ property_to_dbus (const NMSettInfoSetting *sett_info, NMConnection *connection, NMSetting *setting, NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options, gboolean ignore_flags, gboolean ignore_default) { @@ -727,7 +728,7 @@ property_to_dbus (const NMSettInfoSetting *sett_info, } if (property->to_dbus_fcn) { - variant = property->to_dbus_fcn (sett_info, property_idx, connection, setting, flags); + variant = property->to_dbus_fcn (sett_info, property_idx, connection, setting, flags, options); nm_g_variant_take_ref (variant); } else { nm_auto_unset_gvalue GValue prop_value = { 0, }; @@ -796,6 +797,8 @@ set_property_from_dbus (const NMSettInfoProperty *property, * @setting: the #NMSetting * @connection: the #NMConnection containing @setting * @flags: hash flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * @options: the #NMConnectionSerializationOptions options to control + * what/how gets serialized. * * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING * mapping each setting property name to a value describing that property, @@ -805,7 +808,10 @@ set_property_from_dbus (const NMSettInfoProperty *property, * properties **/ GVariant * -_nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags) +_nm_setting_to_dbus (NMSetting *setting, + NMConnection *connection, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingPrivate *priv; GVariantBuilder builder; @@ -831,7 +837,7 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS for (i = 0; i < sett_info->property_infos_len; i++) { gs_unref_variant GVariant *dbus_value = NULL; - dbus_value = property_to_dbus (sett_info, i, connection, setting, flags, FALSE, TRUE); + dbus_value = property_to_dbus (sett_info, i, connection, setting, flags, options, FALSE, TRUE); if (dbus_value) { g_variant_builder_add (&builder, "{sv}", @@ -1455,8 +1461,8 @@ compare_property (const NMSettInfoSetting *sett_info, gs_unref_variant GVariant *value1 = NULL; gs_unref_variant GVariant *value2 = NULL; - value1 = property_to_dbus (sett_info, property_idx, con_a, set_a, NM_CONNECTION_SERIALIZE_ALL, TRUE, TRUE); - value2 = property_to_dbus (sett_info, property_idx, con_b, set_b, NM_CONNECTION_SERIALIZE_ALL, TRUE, TRUE); + value1 = property_to_dbus (sett_info, property_idx, con_a, set_a, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE, TRUE); + value2 = property_to_dbus (sett_info, property_idx, con_b, set_b, NM_CONNECTION_SERIALIZE_ALL, NULL, TRUE, TRUE); if (nm_property_compare (value1, value2) != 0) return NM_TERNARY_FALSE; } @@ -2382,7 +2388,7 @@ nm_setting_to_string (NMSetting *setting) string = g_string_new (nm_setting_get_name (setting)); g_string_append_c (string, '\n'); - variant = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL); + variant = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_variant_iter_init (&iter, variant); while ((child = g_variant_iter_next_value (&iter))) { @@ -2404,7 +2410,8 @@ _nm_setting_get_deprecated_virtual_interface_name (const NMSettInfoSetting *sett guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMSettingConnection *s_con; diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c index dd67efae8c..ac834d7408 100644 --- a/libnm-core/nm-team-utils.c +++ b/libnm-core/nm-team-utils.c @@ -2439,7 +2439,8 @@ _nm_team_settings_property_to_dbus (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { NMTeamSetting *self = _nm_setting_get_team_setting (setting); const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, sett_info->property_infos[property_idx].param_spec->param_id); diff --git a/libnm-core/nm-team-utils.h b/libnm-core/nm-team-utils.h index 0e897da96a..7da42a3f43 100644 --- a/libnm-core/nm-team-utils.h +++ b/libnm-core/nm-team-utils.h @@ -298,7 +298,8 @@ GVariant *_nm_team_settings_property_to_dbus (const NMSettInfoSetting *sett_info guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); void _nm_team_settings_property_from_dbus_link_watchers (GVariant *dbus_value, GValue *prop_value); diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index 004782eb60..22943edd9c 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -65,7 +65,8 @@ GVariant *_nm_utils_hwaddr_cloned_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); gboolean _nm_utils_hwaddr_cloned_set (NMSetting *setting, GVariant *connection_dict, const char *property, @@ -81,7 +82,8 @@ GVariant * _nm_utils_hwaddr_cloned_data_synth (const NMSettInfoSetting *sett_in guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); gboolean _nm_utils_hwaddr_cloned_data_set (NMSetting *setting, GVariant *connection_dict, const char *property, @@ -113,7 +115,8 @@ GVariant * _nm_utils_bridge_vlans_to_dbus (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags); + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options); gboolean _nm_utils_bridge_vlans_from_dbus (NMSetting *setting, GVariant *connection_dict, diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 44b1703e11..b390b4f99f 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4320,7 +4320,8 @@ _nm_utils_hwaddr_cloned_get (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_free char *addr = NULL; @@ -4378,7 +4379,8 @@ _nm_utils_hwaddr_cloned_data_synth (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_free char *addr = NULL; @@ -5885,7 +5887,8 @@ _nm_utils_bridge_vlans_to_dbus (const NMSettInfoSetting *sett_info, guint property_idx, NMConnection *connection, NMSetting *setting, - NMConnectionSerializationFlags flags) + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) { gs_unref_ptrarray GPtrArray *vlans = NULL; GVariantBuilder builder; diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index ca900de25d..1ee48cc70e 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -1855,7 +1855,7 @@ test_setting_to_dbus_all (void) s_wsec = make_test_wsec_setting ("setting-to-dbus-all"); - dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); /* Make sure all keys are there */ g_assert (_variant_contains (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); @@ -1875,7 +1875,7 @@ test_setting_to_dbus_no_secrets (void) s_wsec = make_test_wsec_setting ("setting-to-dbus-no-secrets"); - dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS, NULL); /* Make sure non-secret keys are there */ g_assert (_variant_contains (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); @@ -1897,7 +1897,7 @@ test_setting_to_dbus_only_secrets (void) s_wsec = make_test_wsec_setting ("setting-to-dbus-only-secrets"); - dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS, NULL); /* Make sure non-secret keys are not there */ g_assert (!_variant_contains (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)); @@ -1928,7 +1928,7 @@ test_setting_to_dbus_transform (void) g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); - dict = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_assert (dict != NULL); val = g_variant_lookup_value (dict, NM_SETTING_WIRED_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING); @@ -1957,7 +1957,7 @@ test_setting_to_dbus_enum (void) NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NULL); - dict = _nm_setting_to_dbus (s_ip6, NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (s_ip6, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_assert (dict != NULL); val = g_variant_lookup_value (dict, NM_SETTING_IP6_CONFIG_IP6_PRIVACY, G_VARIANT_TYPE_INT32); @@ -1976,7 +1976,7 @@ test_setting_to_dbus_enum (void) NM_SETTING_SECRET_FLAG_NOT_SAVED), NULL); - dict = _nm_setting_to_dbus (s_wsec, NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (s_wsec, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_assert (dict != NULL); val = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, G_VARIANT_TYPE_UINT32); @@ -1999,7 +1999,7 @@ test_setting_to_dbus_enum (void) NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_ODD, NULL); - dict = _nm_setting_to_dbus (s_serial, NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (s_serial, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_assert (dict != NULL); val = g_variant_lookup_value (dict, NM_SETTING_SERIAL_PARITY, G_VARIANT_TYPE_BYTE); @@ -2114,7 +2114,7 @@ test_setting_new_from_dbus (void) GVariant *dict; s_wsec = make_test_wsec_setting ("setting-new-from-dbus"); - dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); g_object_unref (s_wsec); s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, NM_SETTING_PARSE_FLAGS_NONE, NULL); diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index 1484cbf1ab..aa9de5a03d 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -1418,7 +1418,7 @@ _check_team_setting (NMSetting *setting) nm_setting_team_get_runner_sys_prio (NM_SETTING_TEAM (setting)), NULL); } - variant2 = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL); + variant2 = _nm_setting_to_dbus (setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); variant3 = nm_utils_gvariant_vardict_filter_drop_one (variant2, "config"); setting2 = nmtst_assert_setting_dbus_new (G_OBJECT_TYPE (setting), variant3); nmtst_assert_setting_is_equal (setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index e54bc88386..b2d103f18a 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -1992,7 +1992,7 @@ nmtst_assert_setting_dbus_roundtrip (gconstpointer /* const NMSetting * */ setti g_assert (NM_IS_SETTING (setting)); - variant = _nm_setting_to_dbus ((NMSetting *) setting, NULL, NM_CONNECTION_SERIALIZE_ALL); + variant = _nm_setting_to_dbus ((NMSetting *) setting, NULL, NM_CONNECTION_SERIALIZE_ALL, NULL); setting2 = nmtst_assert_setting_dbus_new (G_OBJECT_TYPE (setting), variant); nmtst_assert_setting_is_equal (setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT); } From df2ba4226dfbd1b8b36150758bdbe0579b6a3935 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 09:09:06 +0200 Subject: [PATCH 6/7] libnm: implement serialization options (inject timestamp/seen-bssids) for nm_connection_to_dbus_full() --- libnm-core/nm-core-internal.h | 8 ++++++- libnm-core/nm-setting-connection.c | 27 +++++++++++++++++++++++ libnm-core/nm-setting-wireless.c | 35 ++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 7547044a9d..ad17a1d01d 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -165,7 +165,13 @@ gpointer _nm_connection_check_main_setting (NMConnection *connection, GError **error); typedef struct { - int dummy; + struct { + guint64 val; + bool has; + } timestamp; + + const char **seen_bssids; + } NMConnectionSerializationOptions; GVariant *nm_connection_to_dbus_full (NMConnection *connection, diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 6653ea37c7..6461ac9aeb 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -590,6 +590,26 @@ nm_setting_connection_get_timestamp (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->timestamp; } +static GVariant * +_to_dbus_fcn_timestamp (const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection *connection, + NMSetting *setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + guint64 v; + + v = options && options->timestamp.has + ? options->timestamp.val + : NM_SETTING_CONNECTION_GET_PRIVATE (setting)->timestamp; + + if (v == 0u) + return NULL; + + return g_variant_new_uint64 (v); +} + /** * nm_setting_connection_get_read_only: * @setting: the #NMSettingConnection @@ -1875,6 +1895,13 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _properties_override_add_override (properties_override, + obj_properties[PROP_TIMESTAMP], + G_VARIANT_TYPE_UINT64, + _to_dbus_fcn_timestamp, + NULL, + NULL); + /** * NMSettingConnection:read-only: * diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 08373df35e..cfcc72b49d 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -725,6 +725,34 @@ nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, return priv->seen_bssids->pdata[i]; } +static GVariant * +_to_dbus_fcn_seen_bssids (const NMSettInfoSetting *sett_info, + guint property_idx, + NMConnection *connection, + NMSetting *setting, + NMConnectionSerializationFlags flags, + const NMConnectionSerializationOptions *options) +{ + NMSettingWirelessPrivate *priv; + + if ( options + && options->seen_bssids) { + return options->seen_bssids[0] + ? g_variant_new_strv (options->seen_bssids, -1) + : NULL; + } + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + + if ( !priv->seen_bssids + || priv->seen_bssids->len == 0) + return NULL; + + return g_variant_new_strv ((const char *const*) priv->seen_bssids->pdata, priv->seen_bssids->len); +} + +/*****************************************************************************/ + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -1605,6 +1633,13 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass) NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); + _properties_override_add_override (properties_override, + obj_properties[PROP_SEEN_BSSIDS], + G_VARIANT_TYPE_STRING_ARRAY, + _to_dbus_fcn_seen_bssids, + NULL, + NULL); + /** * NMSettingWireless:mtu: * From 0d58cab4a096e5c9e909aceebb065a2e2eee748a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Jun 2019 09:09:29 +0200 Subject: [PATCH 7/7] settings: use nm_connection_to_dbus_full() to avoid cloning the connection during GetSettings() --- src/settings/nm-settings-connection.c | 73 ++++++++++++--------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 5f3f6498a4..6368b3d5a0 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1398,48 +1398,41 @@ get_settings_auth_cb (NMSettingsConnection *self, GError *error, gpointer data) { - if (error) + gs_free const char **seen_bssids = NULL; + NMConnectionSerializationOptions options = { + }; + GVariant *settings; + + if (error) { g_dbus_method_invocation_return_gerror (context, error); - else { - gs_unref_object NMConnection *dupl_con = NULL; - GVariant *settings; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - guint64 timestamp = 0; - gs_free const char **bssids = NULL; - - dupl_con = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); - - /* Timestamp is not updated in connection's 'timestamp' property, - * because it would force updating the connection and in turn - * writing to /etc periodically, which we want to avoid. Rather real - * timestamps are kept track of in a private variable. So, substitute - * timestamp property with the real one here before returning the settings. - */ - nm_settings_connection_get_timestamp (self, ×tamp); - if (timestamp) { - s_con = nm_connection_get_setting_connection (dupl_con); - g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL); - } - /* Seen BSSIDs are not updated in 802-11-wireless 'seen-bssids' property - * from the same reason as timestamp. Thus we put it here to GetSettings() - * return settings too. - */ - bssids = nm_settings_connection_get_seen_bssids (self); - if (bssids) { - s_wifi = nm_connection_get_setting_wireless (dupl_con); - if (s_wifi) - g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); - } - - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - settings = nm_connection_to_dbus (dupl_con, NM_CONNECTION_SERIALIZE_NO_SECRETS); - g_dbus_method_invocation_return_value (context, - g_variant_new ("(@a{sa{sv}})", settings)); + return; } + + /* Timestamp is not updated in connection's 'timestamp' property, + * because it would force updating the connection and in turn + * writing to /etc periodically, which we want to avoid. Rather real + * timestamps are kept track of in a private variable. So, substitute + * timestamp property with the real one here before returning the settings. + */ + options.timestamp.has = TRUE; + nm_settings_connection_get_timestamp (self, &options.timestamp.val); + + /* Seen BSSIDs are not updated in 802-11-wireless 'seen-bssids' property + * from the same reason as timestamp. Thus we put it here to GetSettings() + * return settings too. + */ + seen_bssids = nm_settings_connection_get_seen_bssids (self); + options.seen_bssids = seen_bssids; + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + settings = nm_connection_to_dbus_full (nm_settings_connection_get_connection (self), + NM_CONNECTION_SERIALIZE_NO_SECRETS, + &options); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(@a{sa{sv}})", settings)); } static void