about summary refs log tree commit diff
path: root/libnm-core/nm-setting.c
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2019-03-12 15:16:42 +0100
committerSebastien Bacher <seb128@ubuntu.com>2019-03-12 15:16:42 +0100
commitcc4ab276f923ded9f415c1c2bf192994367ab0bb (patch)
treeac3a7775665992b27d07eb44186d38ff961a8cd7 /libnm-core/nm-setting.c
parentbb1cf58350bb34463e9ffc5f96ac4f9b6bf46d28 (diff)
parentdd428301eb6f02542015121d7b08d9997f137e50 (diff)
Update upstream source from tag 'upstream/1.15.91'
Update to upstream version '1.15.91'
with Debian dir 74de38245314cab529c6c94cd9d0b874ce0c2994
Diffstat (limited to 'libnm-core/nm-setting.c')
-rw-r--r--libnm-core/nm-setting.c184
1 files changed, 127 insertions, 57 deletions
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 976f7f00..2e9081df 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -24,23 +24,12 @@
 
 #include "nm-setting.h"
 
-#include <string.h>
-
 #include "nm-setting-private.h"
 #include "nm-utils.h"
 #include "nm-core-internal.h"
 #include "nm-utils-private.h"
 #include "nm-property-compare.h"
 
-#include "nm-setting-connection.h"
-#include "nm-setting-bond.h"
-#include "nm-setting-bridge.h"
-#include "nm-setting-bridge-port.h"
-#include "nm-setting-pppoe.h"
-#include "nm-setting-team.h"
-#include "nm-setting-team-port.h"
-#include "nm-setting-vpn.h"
-
 /**
  * SECTION:nm-setting
  * @short_description: Describes related configuration information
@@ -67,7 +56,7 @@ typedef struct {
 	NMSettingPriority priority;
 } SettingInfo;
 
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMSetting,
 	PROP_NAME,
 );
 
@@ -553,6 +542,35 @@ _nm_setting_class_get_sett_info (NMSettingClass *setting_class)
 
 /*****************************************************************************/
 
+void
+_nm_setting_emit_property_changed (NMSetting *setting)
+{
+	/* Some settings have "properties" that are not implemented as GObject properties.
+	 *
+	 * For example:
+	 *
+	 *   - gendata-base settings like NMSettingEthtool. Here properties are just
+	 *     GVariant values in the gendata hash.
+	 *
+	 *   - NMSettingWireGuard's peers are not backed by a GObject property. Instead
+	 *     there is C-API to access/modify peers.
+	 *
+	 * We still want to emit property-changed notifications for such properties,
+	 * in particular because NMConnection registers to such signals to re-emit
+	 * it as NM_CONNECTION_CHANGED signal. In fact, there are unlikely any other
+	 * uses of such a property-changed signal, because generally it doesn't make
+	 * too much sense.
+	 *
+	 * So, instead of adding yet another (artificial) signal "setting-changed",
+	 * hijack the "notify" signal and just notify about changes of the "name".
+	 * Of course, the "name" doesn't really ever change, because it's tied to
+	 * the GObject's type.
+	 */
+	_notify (setting, PROP_NAME);
+}
+
+/*****************************************************************************/
+
 gboolean
 _nm_setting_use_legacy_property (NMSetting *setting,
                                  GVariant *connection_dict,
@@ -1082,6 +1100,8 @@ duplicate_copy_properties (const NMSettInfoSetting *sett_info,
 	if (sett_info->detail.gendata_info) {
 		GenData *gendata = _gendata_hash (src, FALSE);
 
+		nm_assert (!_gendata_hash (dst, FALSE));
+
 		if (   gendata
 		    && g_hash_table_size (gendata->hash) > 0) {
 			GHashTableIter iter;
@@ -1303,7 +1323,7 @@ _nm_setting_should_compare_secret_property (NMSetting *setting,
 	 *   - @other also has the secret flat to be ignored.
 	 *
 	 * This makes the check symmetric (aside the fact that @setting must
-	 * have the secret while @other may not -- which is asymetric). */
+	 * have the secret while @other may not -- which is asymmetric). */
 	if (   NM_FLAGS_HAS (flags, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
 	    && NM_FLAGS_HAS (a_secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED)
 	    && (   !other
@@ -1602,7 +1622,7 @@ nm_setting_diff (NMSetting *a,
 				 *
 				 * Note that compare_property() called with two settings will ignore secrets
 				 * based on the flags, but it will do so if *both* settings have the flag we
-				 * look for. So that is symetric behavior and good.
+				 * look for. So that is symmetric behavior and good.
 				 *
 				 * But for the purpose of diff(), we do a asymmetric comparison because and
 				 * we want to skip testing the property if setting @a alone indicates to do
@@ -1698,6 +1718,27 @@ nm_setting_diff (NMSetting *a,
 	}
 }
 
+static void
+enumerate_values (const NMSettInfoProperty *property_info,
+                  NMSetting *setting,
+                  NMSettingValueIterFn func,
+                  gpointer user_data)
+{
+	GValue value = G_VALUE_INIT;
+
+	if (!property_info->param_spec)
+		return;
+
+	g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (property_info->param_spec));
+	g_object_get_property (G_OBJECT (setting), property_info->param_spec->name, &value);
+	func (setting,
+	      property_info->param_spec->name,
+	      &value,
+	      property_info->param_spec->flags,
+	      user_data);
+	g_value_unset (&value);
+}
+
 /**
  * nm_setting_enumerate_values:
  * @setting: the #NMSetting
@@ -1753,50 +1794,24 @@ nm_setting_enumerate_values (NMSetting *setting,
 	}
 
 	for (i = 0; i < sett_info->property_infos_len; i++) {
-		GParamSpec *prop_spec = _nm_sett_info_property_info_get_sorted (sett_info, i)->param_spec;
-		GValue value = G_VALUE_INIT;
-
-		if (!prop_spec)
-			continue;
-
-		g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (prop_spec));
-		g_object_get_property (G_OBJECT (setting), prop_spec->name, &value);
-		func (setting, prop_spec->name, &value, prop_spec->flags, user_data);
-		g_value_unset (&value);
+		NM_SETTING_GET_CLASS (setting)->enumerate_values (_nm_sett_info_property_info_get_sorted (sett_info, i),
+		                                                  setting,
+		                                                  func,
+		                                                  user_data);
 	}
 }
 
-/**
- * _nm_setting_aggregate:
- * @setting: the #NMSetting to aggregate.
- * @type: the #NMConnectionAggregateType aggregate type.
- * @arg: the in/out arguments for aggregation. They depend on @type.
- *
- * This is the implementation detail of _nm_connection_aggregate(). It
- * makes no sense to call this function directly outside of _nm_connection_aggregate().
- *
- * Returns: %TRUE if afterwards the aggregation is complete. That means,
- *   the only caller _nm_connection_aggregate() will not visit other settings
- *   after a setting returns %TRUE (indicating that there is nothing further
- *   to aggregate). Note that is very different from the boolean return
- *   argument of _nm_connection_aggregate(), which serves a different purpose.
- */
-gboolean
-_nm_setting_aggregate (NMSetting *setting,
-                       NMConnectionAggregateType type,
-                       gpointer arg)
+static gboolean
+aggregate (NMSetting *setting,
+           int type_i,
+           gpointer arg)
 {
+	NMConnectionAggregateType type = type_i;
 	const NMSettInfoSetting *sett_info;
 	guint i;
 
-	g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
-	g_return_val_if_fail (arg, FALSE);
-	g_return_val_if_fail (NM_IN_SET (type, NM_CONNECTION_AGGREGATE_ANY_SECRETS,
-	                                       NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS),
-	                      FALSE);
-
-	if (NM_IS_SETTING_VPN (setting))
-		return _nm_setting_vpn_aggregate (NM_SETTING_VPN (setting), type, arg);
+	nm_assert (NM_IN_SET (type, NM_CONNECTION_AGGREGATE_ANY_SECRETS,
+	                            NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS));
 
 	sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
 	for (i = 0; i < sett_info->property_infos_len; i++) {
@@ -1840,6 +1855,35 @@ _nm_setting_aggregate (NMSetting *setting,
 	return FALSE;
 }
 
+/**
+ * _nm_setting_aggregate:
+ * @setting: the #NMSetting to aggregate.
+ * @type: the #NMConnectionAggregateType aggregate type.
+ * @arg: the in/out arguments for aggregation. They depend on @type.
+ *
+ * This is the implementation detail of _nm_connection_aggregate(). It
+ * makes no sense to call this function directly outside of _nm_connection_aggregate().
+ *
+ * Returns: %TRUE if afterwards the aggregation is complete. That means,
+ *   the only caller _nm_connection_aggregate() will not visit other settings
+ *   after a setting returns %TRUE (indicating that there is nothing further
+ *   to aggregate). Note that is very different from the boolean return
+ *   argument of _nm_connection_aggregate(), which serves a different purpose.
+ */
+gboolean
+_nm_setting_aggregate (NMSetting *setting,
+                       NMConnectionAggregateType type,
+                       gpointer arg)
+{
+	g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
+	g_return_val_if_fail (arg, FALSE);
+	g_return_val_if_fail (NM_IN_SET (type, NM_CONNECTION_AGGREGATE_ANY_SECRETS,
+	                                       NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS),
+	                      FALSE);
+
+	return NM_SETTING_GET_CLASS (setting)->aggregate (setting, type, arg);
+}
+
 static gboolean
 clear_secrets (const NMSettInfoSetting *sett_info,
                guint property_idx,
@@ -2023,7 +2067,7 @@ _nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **erro
 		int success;
 
 		success = NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error);
-		g_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error)));
+		nm_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error)));
 
 		g_variant_unref (secret_value);
 
@@ -2040,6 +2084,26 @@ _nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **erro
 }
 
 static void
+for_each_secret (NMSetting *setting,
+                 const char *secret_name,
+                 GVariant *val,
+                 gboolean remove_non_secrets,
+                 _NMConnectionForEachSecretFunc callback,
+                 gpointer callback_data,
+                 GVariantBuilder *setting_builder)
+{
+	NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+	if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
+		if (!remove_non_secrets)
+			g_variant_builder_add (setting_builder, "{sv}", secret_name, val);
+		return;
+	}
+	if (callback (secret_flags, callback_data))
+		g_variant_builder_add (setting_builder, "{sv}", secret_name, val);
+}
+
+static void
 _set_error_secret_property_not_found (GError **error,
                                       NMSetting *setting,
                                       const char *secret_name)
@@ -2293,7 +2357,7 @@ _nm_setting_gendata_notify (NMSetting *setting,
 
 	gendata = _gendata_hash (setting, FALSE);
 	if (!gendata)
-		return;
+		goto out;
 
 	nm_clear_g_free (&gendata->values);
 
@@ -2303,7 +2367,7 @@ _nm_setting_gendata_notify (NMSetting *setting,
 		nm_clear_g_free (&gendata->names);
 	}
 
-	/* Note, that currently there is now way to notify the subclass when gendata changed.
+	/* Note, currently there is no way to notify the subclass when gendata changed.
 	 * gendata is only changed in two situations:
 	 *   1) from within NMSetting itself, for example when creating a NMSetting instance
 	 *      from keyfile or a D-Bus GVariant.
@@ -2316,6 +2380,9 @@ _nm_setting_gendata_notify (NMSetting *setting,
 	 *
 	 * If we ever need it, then we would need to call a virtual function to notify the subclass
 	 * that gendata changed. */
+
+out:
+	_nm_setting_emit_property_changed (setting);
 }
 
 GVariant *
@@ -2382,7 +2449,7 @@ out_zero:
 /**
  * nm_setting_gendata_get_all_names:
  * @setting: the #NMSetting
- * @out_len: (allow-none): (out):
+ * @out_len: (allow-none) (out):
  *
  * Gives the number of generic data elements and optionally returns all their
  * key names and values. This API is low level access and unless you know what you
@@ -2438,7 +2505,7 @@ nm_setting_gendata_get_all_values (NMSetting *setting)
 
 void
 _nm_setting_gendata_to_gvalue (NMSetting *setting,
-                                GValue *value)
+                               GValue *value)
 {
 	GenData *gendata;
 	GHashTable *new;
@@ -2490,7 +2557,7 @@ _nm_setting_gendata_reset_from_hash (NMSetting *setting,
 	}
 
 	/* let's not bother to find out whether the new hash has any different
-	 * content the the current gendata. Just replace it. */
+	 * content the current gendata. Just replace it. */
 	g_hash_table_remove_all (gendata->hash);
 	if (num > 0) {
 		g_hash_table_iter_init (&iter, new);
@@ -2571,7 +2638,10 @@ nm_setting_class_init (NMSettingClass *setting_class)
 	setting_class->set_secret_flags          = set_secret_flags;
 	setting_class->compare_property          = compare_property;
 	setting_class->clear_secrets             = clear_secrets;
+	setting_class->for_each_secret           = for_each_secret;
 	setting_class->duplicate_copy_properties = duplicate_copy_properties;
+	setting_class->enumerate_values          = enumerate_values;
+	setting_class->aggregate                 = aggregate;
 
 	/**
 	 * NMSetting:name: