merge branch 'th/bgo737380_log_connection_diff'
https://bugzilla.gnome.org/show_bug.cgi?id=737380 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
@@ -1104,7 +1104,7 @@ nm_connection_need_secrets (NMConnection *connection,
|
||||
GPtrArray *secrets;
|
||||
|
||||
setting = NM_SETTING (iter->data);
|
||||
secrets = nm_setting_need_secrets (setting);
|
||||
secrets = _nm_setting_need_secrets (setting);
|
||||
if (secrets) {
|
||||
if (hints)
|
||||
*hints = secrets;
|
||||
|
@@ -60,6 +60,9 @@ gboolean _nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *s
|
||||
NM_SETTING_SECRET_FLAG_NOT_SAVED | \
|
||||
NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
|
||||
|
||||
guint32 _nm_setting_get_setting_priority (NMSetting *setting);
|
||||
|
||||
gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value);
|
||||
|
||||
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
||||
|
||||
|
@@ -158,4 +158,6 @@ void _nm_setting_class_transform_property (NMSettingClass *setting_class,
|
||||
NMSettingPropertyTransformToFunc to_dbus,
|
||||
NMSettingPropertyTransformFromFunc from_dbus);
|
||||
|
||||
GPtrArray *_nm_setting_need_secrets (NMSetting *setting);
|
||||
|
||||
#endif /* NM_SETTING_PRIVATE_H */
|
||||
|
@@ -539,29 +539,31 @@ get_secret_flags (NMSetting *setting,
|
||||
char *flags_key;
|
||||
gpointer val;
|
||||
unsigned long tmp;
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
flags_key = g_strdup_printf ("%s-flags", secret_name);
|
||||
if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) {
|
||||
errno = 0;
|
||||
tmp = strtoul ((const char *) val, NULL, 10);
|
||||
if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) {
|
||||
if (out_flags)
|
||||
*out_flags = (guint32) tmp;
|
||||
flags = (NMSettingSecretFlags) tmp;
|
||||
success = TRUE;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"Failed to convert '%s' value '%s' to uint",
|
||||
_("Failed to convert '%s' value '%s' to uint"),
|
||||
flags_key, (const char *) val);
|
||||
}
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_NOT_FOUND,
|
||||
"Secret flags property '%s' not found", flags_key);
|
||||
_("Secret flags property '%s' not found"), flags_key);
|
||||
}
|
||||
g_free (flags_key);
|
||||
if (out_flags)
|
||||
*out_flags = flags;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "nm-setting-private.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-property-compare.h"
|
||||
|
||||
@@ -209,6 +210,17 @@ _get_setting_type_priority (GType type)
|
||||
return info->priority;
|
||||
}
|
||||
|
||||
guint32
|
||||
_nm_setting_get_setting_priority (NMSetting *setting)
|
||||
{
|
||||
NMSettingPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), G_MAXUINT32);
|
||||
priv = NM_SETTING_GET_PRIVATE (setting);
|
||||
_ensure_setting_info (setting, priv);
|
||||
return priv->info->priority;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_type_is_base_type (GType type)
|
||||
{
|
||||
@@ -279,8 +291,8 @@ _nm_setting_compare_priority (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
guint32 prio_a, prio_b;
|
||||
|
||||
prio_a = _get_setting_type_priority (G_OBJECT_TYPE (a));
|
||||
prio_b = _get_setting_type_priority (G_OBJECT_TYPE (b));
|
||||
prio_a = _nm_setting_get_setting_priority ((NMSetting *) a);
|
||||
prio_b = _nm_setting_get_setting_priority ((NMSetting *) b);
|
||||
|
||||
if (prio_a < prio_b)
|
||||
return -1;
|
||||
@@ -872,6 +884,27 @@ _nm_setting_new_from_dbus (GType setting_type,
|
||||
return setting;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value)
|
||||
{
|
||||
GParamSpec *prop_spec;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (property_name, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name);
|
||||
|
||||
if (!prop_spec) {
|
||||
g_value_unset (value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_value_init (value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (setting), property_name, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
duplicate_setting (NMSetting *setting,
|
||||
const char *name,
|
||||
@@ -1002,8 +1035,12 @@ compare_property (NMSetting *setting,
|
||||
NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL);
|
||||
nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL);
|
||||
g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE);
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (!nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
/* If the secret flags aren't the same the settings aren't the same */
|
||||
if (a_secret_flags != b_secret_flags)
|
||||
@@ -1108,7 +1145,16 @@ should_compare_prop (NMSetting *setting,
|
||||
if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
return FALSE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL);
|
||||
if ( NM_IS_SETTING_VPN (setting)
|
||||
&& g_strcmp0 (prop_name, NM_SETTING_VPN_SECRETS) == 0) {
|
||||
/* FIXME: NMSettingVPN:NM_SETTING_VPN_SECRETS has NM_SETTING_PARAM_SECRET.
|
||||
* nm_setting_get_secret_flags() quite possibly fails, but it might succeed if the
|
||||
* setting accidently uses a key "secrets". */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
@@ -1160,6 +1206,8 @@ nm_setting_diff (NMSetting *a,
|
||||
guint i;
|
||||
NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
NMSettingDiffResult a_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT;
|
||||
NMSettingDiffResult b_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT;
|
||||
gboolean results_created = FALSE;
|
||||
|
||||
g_return_val_if_fail (results != NULL, FALSE);
|
||||
@@ -1169,6 +1217,12 @@ nm_setting_diff (NMSetting *a,
|
||||
g_return_val_if_fail (G_OBJECT_TYPE (a) == G_OBJECT_TYPE (b), FALSE);
|
||||
}
|
||||
|
||||
if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) ==
|
||||
(NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) {
|
||||
/* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */
|
||||
flags &= ~NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT;
|
||||
}
|
||||
|
||||
/* If the caller is calling this function in a pattern like this to get
|
||||
* complete diffs:
|
||||
*
|
||||
@@ -1181,6 +1235,8 @@ nm_setting_diff (NMSetting *a,
|
||||
if (invert_results) {
|
||||
a_result = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
b_result = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
a_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT;
|
||||
b_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT;
|
||||
}
|
||||
|
||||
if (*results == NULL) {
|
||||
@@ -1193,8 +1249,7 @@ nm_setting_diff (NMSetting *a,
|
||||
|
||||
for (i = 0; i < n_property_specs; i++) {
|
||||
GParamSpec *prop_spec = property_specs[i];
|
||||
NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN, tmp;
|
||||
gboolean different = TRUE;
|
||||
NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN;
|
||||
|
||||
/* Handle compare flags */
|
||||
if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags))
|
||||
@@ -1203,28 +1258,58 @@ nm_setting_diff (NMSetting *a,
|
||||
continue;
|
||||
|
||||
if (b) {
|
||||
gboolean different;
|
||||
|
||||
different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags);
|
||||
if (different) {
|
||||
gboolean a_is_default, b_is_default;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= a_result;
|
||||
a_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_reset (&value);
|
||||
g_object_get_property (G_OBJECT (b), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= b_result;
|
||||
b_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) {
|
||||
if (!a_is_default)
|
||||
r |= a_result;
|
||||
if (!b_is_default)
|
||||
r |= b_result;
|
||||
} else {
|
||||
r |= a_result | b_result;
|
||||
if (a_is_default)
|
||||
r |= a_result_default;
|
||||
if (b_is_default)
|
||||
r |= b_result_default;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0)
|
||||
r = a_result; /* only in A */
|
||||
else {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
if (different) {
|
||||
tmp = GPOINTER_TO_UINT (g_hash_table_lookup (*results, prop_spec->name));
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (tmp | r));
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= a_result;
|
||||
else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)
|
||||
r |= a_result | a_result_default;
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) {
|
||||
void *p;
|
||||
|
||||
if (g_hash_table_lookup_extended (*results, prop_spec->name, NULL, &p)) {
|
||||
if ((r & GPOINTER_TO_UINT (p)) != r)
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r | GPOINTER_TO_UINT (p)));
|
||||
} else
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r));
|
||||
}
|
||||
}
|
||||
g_free (property_specs);
|
||||
@@ -1274,19 +1359,15 @@ nm_setting_enumerate_values (NMSetting *setting,
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_clear_secrets:
|
||||
* _nm_setting_clear_secrets:
|
||||
* @setting: the #NMSetting
|
||||
*
|
||||
* Resets and clears any secrets in the setting. Secrets should be added to the
|
||||
* setting only when needed, and cleared immediately after use to prevent
|
||||
* leakage of information.
|
||||
*
|
||||
* Returns: %TRUE if the setting changed at all
|
||||
**/
|
||||
void
|
||||
nm_setting_clear_secrets (NMSetting *setting)
|
||||
{
|
||||
_nm_setting_clear_secrets (setting);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_clear_secrets (NMSetting *setting)
|
||||
{
|
||||
@@ -1330,8 +1411,12 @@ clear_secrets_with_flags (NMSetting *setting,
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE);
|
||||
|
||||
/* Clear the secret if the user function says to do so */
|
||||
nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if (func (setting, pspec->name, flags, user_data) == TRUE) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
@@ -1349,22 +1434,16 @@ clear_secrets_with_flags (NMSetting *setting,
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_clear_secrets_with_flags:
|
||||
* _nm_setting_clear_secrets_with_flags:
|
||||
* @setting: the #NMSetting
|
||||
* @func: (scope call): function to be called to determine whether a
|
||||
* specific secret should be cleared or not
|
||||
* @user_data: caller-supplied data passed to @func
|
||||
*
|
||||
* Clears and frees secrets determined by @func.
|
||||
*
|
||||
* Returns: %TRUE if the setting changed at all
|
||||
**/
|
||||
void
|
||||
nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
||||
NMSettingClearSecretsWithFlagsFn func,
|
||||
gpointer user_data)
|
||||
{
|
||||
_nm_setting_clear_secrets_with_flags (setting, func, user_data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
||||
NMSettingClearSecretsWithFlagsFn func,
|
||||
@@ -1394,7 +1473,7 @@ _nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_need_secrets:
|
||||
* _nm_setting_need_secrets:
|
||||
* @setting: the #NMSetting
|
||||
*
|
||||
* Returns an array of property names for each secret which may be required
|
||||
@@ -1408,7 +1487,7 @@ _nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
||||
* free the elements.
|
||||
**/
|
||||
GPtrArray *
|
||||
nm_setting_need_secrets (NMSetting *setting)
|
||||
_nm_setting_need_secrets (NMSetting *setting)
|
||||
{
|
||||
GPtrArray *secrets = NULL;
|
||||
|
||||
@@ -1549,8 +1628,11 @@ get_secret_flags (NMSetting *setting,
|
||||
char *flags_prop;
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
if (verify_secret)
|
||||
g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE);
|
||||
if (verify_secret && !is_secret_prop (setting, secret_name, error)) {
|
||||
if (out_flags)
|
||||
*out_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
flags_prop = g_strdup_printf ("%s-flags", secret_name);
|
||||
g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL);
|
||||
|
@@ -125,6 +125,20 @@ typedef enum { /*< flags >*/
|
||||
* @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which
|
||||
* the secret's flags indicate the secret should not be saved to persistent
|
||||
* storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT: if this flag is set,
|
||||
* nm_setting_diff() and nm_connection_diff() will also include properties that
|
||||
* are set to their default value. See also @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT.
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT: if this flag is set,
|
||||
* nm_setting_diff() and nm_connection_diff() will not include properties that
|
||||
* are set to their default value. This is the opposite of
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. If both flags are set together,
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT wins. If both flags are unset,
|
||||
* this means to exclude default properties if there is a setting to compare,
|
||||
* but include all properties, if the setting 'b' is missing. This is the legacy
|
||||
* behaviour of libnm-util, where nm_setting_diff() behaved differently depending
|
||||
* on whether the setting 'b' was available. If @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT
|
||||
* is set, nm_setting_diff() will also set the flags @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT
|
||||
* and @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, if the values are default values.
|
||||
*
|
||||
* These flags modify the comparison behavior when comparing two settings or
|
||||
* two connections.
|
||||
@@ -136,7 +150,9 @@ typedef enum {
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010,
|
||||
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT = 0x00000020,
|
||||
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040,
|
||||
|
||||
/* 0x80000000 is used for a private flag */
|
||||
} NMSettingCompareFlags;
|
||||
@@ -247,6 +263,10 @@ gboolean nm_setting_compare (NMSetting *a,
|
||||
* @NM_SETTING_DIFF_RESULT_UNKNOWN: unknown result
|
||||
* @NM_SETTING_DIFF_RESULT_IN_A: the property is present in setting A
|
||||
* @NM_SETTING_DIFF_RESULT_IN_B: the property is present in setting B
|
||||
* @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT: the property is present in
|
||||
* setting A but is set to the default value. This flag is only set,
|
||||
* if you specify @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT.
|
||||
* @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT: analog to @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT.
|
||||
*
|
||||
* These values indicate the result of a setting difference operation.
|
||||
**/
|
||||
@@ -254,6 +274,8 @@ typedef enum {
|
||||
NM_SETTING_DIFF_RESULT_UNKNOWN = 0x00000000,
|
||||
NM_SETTING_DIFF_RESULT_IN_A = 0x00000001,
|
||||
NM_SETTING_DIFF_RESULT_IN_B = 0x00000002,
|
||||
NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004,
|
||||
NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000004,
|
||||
} NMSettingDiffResult;
|
||||
|
||||
gboolean nm_setting_diff (NMSetting *a,
|
||||
@@ -269,14 +291,6 @@ void nm_setting_enumerate_values (NMSetting *setting,
|
||||
char *nm_setting_to_string (NMSetting *setting);
|
||||
|
||||
/* Secrets */
|
||||
void nm_setting_clear_secrets (NMSetting *setting);
|
||||
|
||||
void nm_setting_clear_secrets_with_flags (NMSetting *setting,
|
||||
NMSettingClearSecretsWithFlagsFn func,
|
||||
gpointer user_data);
|
||||
|
||||
GPtrArray *nm_setting_need_secrets (NMSetting *setting);
|
||||
|
||||
gboolean nm_setting_get_secret_flags (NMSetting *setting,
|
||||
const char *secret_name,
|
||||
NMSettingSecretFlags *out_flags,
|
||||
|
@@ -55,10 +55,13 @@ void _nm_register_setting (const char *name,
|
||||
|
||||
gboolean _nm_setting_is_base_type (NMSetting *setting);
|
||||
gboolean _nm_setting_type_is_base_type (GType type);
|
||||
guint32 _nm_setting_get_setting_priority (NMSetting *setting);
|
||||
GType _nm_setting_lookup_setting_type (const char *name);
|
||||
GType _nm_setting_lookup_setting_type_by_quark (GQuark error_quark);
|
||||
gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b);
|
||||
|
||||
gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value);
|
||||
|
||||
typedef enum NMSettingUpdateSecretResult {
|
||||
NM_SETTING_UPDATE_SECRET_ERROR = FALSE,
|
||||
NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE,
|
||||
|
@@ -545,29 +545,31 @@ get_secret_flags (NMSetting *setting,
|
||||
char *flags_key;
|
||||
gpointer val;
|
||||
unsigned long tmp;
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
flags_key = g_strdup_printf ("%s-flags", secret_name);
|
||||
if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) {
|
||||
errno = 0;
|
||||
tmp = strtoul ((const char *) val, NULL, 10);
|
||||
if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) {
|
||||
if (out_flags)
|
||||
*out_flags = (guint32) tmp;
|
||||
flags = (NMSettingSecretFlags) tmp;
|
||||
success = TRUE;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
|
||||
"Failed to convert '%s' value '%s' to uint",
|
||||
_("Failed to convert '%s' value '%s' to uint"),
|
||||
flags_key, (const char *) val);
|
||||
}
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_SETTING_ERROR,
|
||||
NM_SETTING_ERROR_PROPERTY_NOT_FOUND,
|
||||
"Secret flags property '%s' not found", flags_key);
|
||||
_("Secret flags property '%s' not found"), flags_key);
|
||||
}
|
||||
g_free (flags_key);
|
||||
if (out_flags)
|
||||
*out_flags = flags;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@@ -209,6 +209,17 @@ _get_setting_type_priority (GType type)
|
||||
return info->priority;
|
||||
}
|
||||
|
||||
guint32
|
||||
_nm_setting_get_setting_priority (NMSetting *setting)
|
||||
{
|
||||
NMSettingPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), G_MAXUINT32);
|
||||
priv = NM_SETTING_GET_PRIVATE (setting);
|
||||
_ensure_setting_info (setting, priv);
|
||||
return priv->info->priority;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_type_is_base_type (GType type)
|
||||
{
|
||||
@@ -260,8 +271,8 @@ _nm_setting_compare_priority (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
guint32 prio_a, prio_b;
|
||||
|
||||
prio_a = _get_setting_type_priority (G_OBJECT_TYPE (a));
|
||||
prio_b = _get_setting_type_priority (G_OBJECT_TYPE (b));
|
||||
prio_a = _nm_setting_get_setting_priority ((NMSetting *) a);
|
||||
prio_b = _nm_setting_get_setting_priority ((NMSetting *) b);
|
||||
|
||||
if (prio_a < prio_b)
|
||||
return -1;
|
||||
@@ -412,6 +423,27 @@ nm_setting_new_from_hash (GType setting_type, GHashTable *hash)
|
||||
return setting;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value)
|
||||
{
|
||||
GParamSpec *prop_spec;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
|
||||
g_return_val_if_fail (property_name, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name);
|
||||
|
||||
if (!prop_spec) {
|
||||
g_value_unset (value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_value_init (value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (setting), property_name, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
duplicate_setting (NMSetting *setting,
|
||||
const char *name,
|
||||
@@ -542,8 +574,12 @@ compare_property (NMSetting *setting,
|
||||
NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL);
|
||||
nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL);
|
||||
g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE);
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (!nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
/* If the secret flags aren't the same the settings aren't the same */
|
||||
if (a_secret_flags != b_secret_flags)
|
||||
@@ -648,7 +684,16 @@ should_compare_prop (NMSetting *setting,
|
||||
if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
|
||||
return FALSE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL);
|
||||
if ( NM_IS_SETTING_VPN (setting)
|
||||
&& g_strcmp0 (prop_name, NM_SETTING_VPN_SECRETS) == 0) {
|
||||
/* FIXME: NMSettingVPN:NM_SETTING_VPN_SECRETS has NM_SETTING_PARAM_SECRET.
|
||||
* nm_setting_get_secret_flags() quite possibly fails, but it might succeed if the
|
||||
* setting accidently uses a key "secrets". */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
|
||||
&& (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
|
||||
@@ -700,6 +745,8 @@ nm_setting_diff (NMSetting *a,
|
||||
guint i;
|
||||
NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
NMSettingDiffResult a_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT;
|
||||
NMSettingDiffResult b_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT;
|
||||
gboolean results_created = FALSE;
|
||||
|
||||
g_return_val_if_fail (results != NULL, FALSE);
|
||||
@@ -709,6 +756,12 @@ nm_setting_diff (NMSetting *a,
|
||||
g_return_val_if_fail (G_OBJECT_TYPE (a) == G_OBJECT_TYPE (b), FALSE);
|
||||
}
|
||||
|
||||
if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) ==
|
||||
(NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) {
|
||||
/* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */
|
||||
flags &= ~NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT;
|
||||
}
|
||||
|
||||
/* If the caller is calling this function in a pattern like this to get
|
||||
* complete diffs:
|
||||
*
|
||||
@@ -721,6 +774,8 @@ nm_setting_diff (NMSetting *a,
|
||||
if (invert_results) {
|
||||
a_result = NM_SETTING_DIFF_RESULT_IN_B;
|
||||
b_result = NM_SETTING_DIFF_RESULT_IN_A;
|
||||
a_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT;
|
||||
b_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT;
|
||||
}
|
||||
|
||||
if (*results == NULL) {
|
||||
@@ -733,8 +788,7 @@ nm_setting_diff (NMSetting *a,
|
||||
|
||||
for (i = 0; i < n_property_specs; i++) {
|
||||
GParamSpec *prop_spec = property_specs[i];
|
||||
NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN, tmp;
|
||||
gboolean different = TRUE;
|
||||
NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN;
|
||||
|
||||
/* Handle compare flags */
|
||||
if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags))
|
||||
@@ -743,28 +797,58 @@ nm_setting_diff (NMSetting *a,
|
||||
continue;
|
||||
|
||||
if (b) {
|
||||
gboolean different;
|
||||
|
||||
different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags);
|
||||
if (different) {
|
||||
gboolean a_is_default, b_is_default;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= a_result;
|
||||
a_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_reset (&value);
|
||||
g_object_get_property (G_OBJECT (b), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= b_result;
|
||||
b_is_default = g_param_value_defaults (prop_spec, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) {
|
||||
if (!a_is_default)
|
||||
r |= a_result;
|
||||
if (!b_is_default)
|
||||
r |= b_result;
|
||||
} else {
|
||||
r |= a_result | b_result;
|
||||
if (a_is_default)
|
||||
r |= a_result_default;
|
||||
if (b_is_default)
|
||||
r |= b_result_default;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0)
|
||||
r = a_result; /* only in A */
|
||||
else {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
if (different) {
|
||||
tmp = GPOINTER_TO_UINT (g_hash_table_lookup (*results, prop_spec->name));
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (tmp | r));
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
g_object_get_property (G_OBJECT (a), prop_spec->name, &value);
|
||||
if (!g_param_value_defaults (prop_spec, &value))
|
||||
r |= a_result;
|
||||
else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT)
|
||||
r |= a_result | a_result_default;
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) {
|
||||
void *p;
|
||||
|
||||
if (g_hash_table_lookup_extended (*results, prop_spec->name, NULL, &p)) {
|
||||
if ((r & GPOINTER_TO_UINT (p)) != r)
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r | GPOINTER_TO_UINT (p)));
|
||||
} else
|
||||
g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r));
|
||||
}
|
||||
}
|
||||
g_free (property_specs);
|
||||
@@ -870,8 +954,12 @@ clear_secrets_with_flags (NMSetting *setting,
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE);
|
||||
|
||||
/* Clear the secret if the user function says to do so */
|
||||
nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if (func (setting, pspec->name, flags, user_data) == TRUE) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
@@ -1090,8 +1178,11 @@ get_secret_flags (NMSetting *setting,
|
||||
char *flags_prop;
|
||||
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
if (verify_secret)
|
||||
g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE);
|
||||
if (verify_secret && !is_secret_prop (setting, secret_name, error)) {
|
||||
if (out_flags)
|
||||
*out_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
flags_prop = g_strdup_printf ("%s-flags", secret_name);
|
||||
g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL);
|
||||
|
@@ -124,6 +124,20 @@ typedef enum {
|
||||
* @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which
|
||||
* the secret's flags indicate the secret should not be saved to persistent
|
||||
* storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT: if this flag is set,
|
||||
* nm_setting_diff() and nm_connection_diff() will also include properties that
|
||||
* are set to their default value. See also @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT.
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT: if this flag is set,
|
||||
* nm_setting_diff() and nm_connection_diff() will not include properties that
|
||||
* are set to their default value. This is the opposite of
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. If both flags are set together,
|
||||
* @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT wins. If both flags are unset,
|
||||
* this means to exclude default properties if there is a setting to compare,
|
||||
* but include all properties, if the setting 'b' is missing. This is the legacy
|
||||
* behaviour of libnm-util, where nm_setting_diff() behaved differently depending
|
||||
* on whether the setting 'b' was available. If @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT
|
||||
* is set, nm_setting_diff() will also set the flags @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT
|
||||
* and @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, if the values are default values.
|
||||
*
|
||||
* These flags modify the comparison behavior when comparing two settings or
|
||||
* two connections.
|
||||
@@ -135,7 +149,9 @@ typedef enum {
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008,
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010
|
||||
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010,
|
||||
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT = 0x00000020,
|
||||
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040,
|
||||
|
||||
/* 0x80000000 is used for a private flag */
|
||||
} NMSettingCompareFlags;
|
||||
@@ -267,6 +283,10 @@ gboolean nm_setting_compare (NMSetting *a,
|
||||
* @NM_SETTING_DIFF_RESULT_UNKNOWN: unknown result
|
||||
* @NM_SETTING_DIFF_RESULT_IN_A: the property is present in setting A
|
||||
* @NM_SETTING_DIFF_RESULT_IN_B: the property is present in setting B
|
||||
* @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT: the property is present in
|
||||
* setting A but is set to the default value. This flag is only set,
|
||||
* if you specify @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT.
|
||||
* @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT: analog to @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT.
|
||||
*
|
||||
* These values indicate the result of a setting difference operation.
|
||||
**/
|
||||
@@ -274,6 +294,8 @@ typedef enum {
|
||||
NM_SETTING_DIFF_RESULT_UNKNOWN = 0x00000000,
|
||||
NM_SETTING_DIFF_RESULT_IN_A = 0x00000001,
|
||||
NM_SETTING_DIFF_RESULT_IN_B = 0x00000002,
|
||||
NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004,
|
||||
NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000004,
|
||||
} NMSettingDiffResult;
|
||||
|
||||
gboolean nm_setting_diff (NMSetting *a,
|
||||
|
@@ -521,8 +521,6 @@ global:
|
||||
nm_setting_cdma_get_type;
|
||||
nm_setting_cdma_get_username;
|
||||
nm_setting_cdma_new;
|
||||
nm_setting_clear_secrets;
|
||||
nm_setting_clear_secrets_with_flags;
|
||||
nm_setting_compare;
|
||||
nm_setting_compare_flags_get_type;
|
||||
nm_setting_connection_add_permission;
|
||||
@@ -689,7 +687,6 @@ global:
|
||||
nm_setting_ip6_config_remove_route_by_value;
|
||||
nm_setting_lookup_type;
|
||||
nm_setting_lookup_type_by_quark;
|
||||
nm_setting_need_secrets;
|
||||
nm_setting_olpc_mesh_error_get_type;
|
||||
nm_setting_olpc_mesh_error_quark;
|
||||
nm_setting_olpc_mesh_get_channel;
|
||||
|
@@ -1881,6 +1881,254 @@ nm_utils_get_monotonic_timestamp_s (void)
|
||||
return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
NMSetting *setting;
|
||||
NMSetting *diff_base_setting;
|
||||
GHashTable *setting_diff;
|
||||
} LogConnectionSettingData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *item_name;
|
||||
NMSettingDiffResult diff_result;
|
||||
} LogConnectionSettingItem;
|
||||
|
||||
static gint
|
||||
_log_connection_sort_hashes_fcn (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const LogConnectionSettingData *v1 = a;
|
||||
const LogConnectionSettingData *v2 = b;
|
||||
guint32 p1, p2;
|
||||
NMSetting *s1, *s2;
|
||||
|
||||
s1 = v1->setting ? v1->setting : v1->diff_base_setting;
|
||||
s2 = v2->setting ? v2->setting : v2->diff_base_setting;
|
||||
|
||||
g_assert (s1 && s2);
|
||||
|
||||
p1 = _nm_setting_get_setting_priority (s1);
|
||||
p2 = _nm_setting_get_setting_priority (s2);
|
||||
|
||||
if (p1 != p2)
|
||||
return p1 > p2 ? 1 : -1;
|
||||
|
||||
return strcmp (v1->name, v2->name);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
_log_connection_sort_hashes (NMConnection *connection, NMConnection *diff_base, GHashTable *connection_diff)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GArray *sorted_hashes;
|
||||
LogConnectionSettingData setting_data;
|
||||
|
||||
sorted_hashes = g_array_sized_new (TRUE, FALSE, sizeof (LogConnectionSettingData), g_hash_table_size (connection_diff));
|
||||
|
||||
g_hash_table_iter_init (&iter, connection_diff);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &setting_data.name, (gpointer) &setting_data.setting_diff)) {
|
||||
setting_data.setting = nm_connection_get_setting_by_name (connection, setting_data.name);
|
||||
setting_data.diff_base_setting = diff_base ? nm_connection_get_setting_by_name (diff_base, setting_data.name) : NULL;
|
||||
g_assert (setting_data.setting || setting_data.diff_base_setting);
|
||||
g_array_append_val (sorted_hashes, setting_data);
|
||||
}
|
||||
|
||||
g_array_sort (sorted_hashes, _log_connection_sort_hashes_fcn);
|
||||
return sorted_hashes;
|
||||
}
|
||||
|
||||
static gint
|
||||
_log_connection_sort_names_fcn (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const LogConnectionSettingItem *v1 = a;
|
||||
const LogConnectionSettingItem *v2 = b;
|
||||
|
||||
/* we want to first show the items, that disappeared, then the one that changed and
|
||||
* then the ones that were added. */
|
||||
|
||||
if ((v1->diff_result & NM_SETTING_DIFF_RESULT_IN_A) != (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_A))
|
||||
return (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_A) ? -1 : 1;
|
||||
if ((v1->diff_result & NM_SETTING_DIFF_RESULT_IN_B) != (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_B))
|
||||
return (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_B) ? 1 : -1;
|
||||
return strcmp (v1->item_name, v2->item_name);
|
||||
}
|
||||
|
||||
static char *
|
||||
_log_connection_get_property (NMSetting *setting, const char *name)
|
||||
{
|
||||
GValue val = G_VALUE_INIT;
|
||||
char *s;
|
||||
|
||||
g_return_val_if_fail (setting, NULL);
|
||||
|
||||
if ( !NM_IS_SETTING_VPN (setting)
|
||||
&& nm_setting_get_secret_flags (setting, name, NULL, NULL))
|
||||
return g_strdup ("****");
|
||||
|
||||
if (!_nm_setting_get_property (setting, name, &val))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
if (G_VALUE_HOLDS_STRING (&val)) {
|
||||
const char *val_s;
|
||||
|
||||
val_s = g_value_get_string (&val);
|
||||
if (!val_s) {
|
||||
/* for NULL, we want to return the unquoted string "NULL". */
|
||||
s = g_strdup ("NULL");
|
||||
} else {
|
||||
char *escaped = g_strescape (val_s, "'");
|
||||
|
||||
s = g_strdup_printf ("'%s'", escaped);
|
||||
g_free (escaped);
|
||||
}
|
||||
} else {
|
||||
s = g_strdup_value_contents (&val);
|
||||
if (s == NULL)
|
||||
s = g_strdup ("NULL");
|
||||
else {
|
||||
char *escaped = g_strescape (s, "'");
|
||||
|
||||
g_free (s);
|
||||
s = escaped;
|
||||
}
|
||||
}
|
||||
g_value_unset(&val);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
_log_connection_sort_names (LogConnectionSettingData *setting_data, GArray *sorted_names)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
LogConnectionSettingItem item;
|
||||
gpointer p;
|
||||
|
||||
g_array_set_size (sorted_names, 0);
|
||||
|
||||
g_hash_table_iter_init (&iter, setting_data->setting_diff);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &item.item_name, &p)) {
|
||||
item.diff_result = GPOINTER_TO_UINT (p);
|
||||
g_array_append_val (sorted_names, item);
|
||||
}
|
||||
|
||||
g_array_sort (sorted_names, _log_connection_sort_names_fcn);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix)
|
||||
{
|
||||
GHashTable *connection_diff = NULL;
|
||||
GArray *sorted_hashes;
|
||||
GArray *sorted_names = NULL;
|
||||
int i, j;
|
||||
gboolean connection_diff_are_same;
|
||||
gboolean print_header = TRUE;
|
||||
gboolean print_setting_header;
|
||||
GString *str1;
|
||||
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
g_return_if_fail (!diff_base || (NM_IS_CONNECTION (diff_base) && diff_base != connection));
|
||||
|
||||
/* For VPN setting types, this is broken, because we cannot (generically) print the content of data/secrets. Bummer... */
|
||||
|
||||
if (!nm_logging_enabled (level, domain))
|
||||
return;
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
if (!name)
|
||||
name = "";
|
||||
|
||||
connection_diff_are_same = nm_connection_diff (connection, diff_base, NM_SETTING_COMPARE_FLAG_EXACT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, &connection_diff);
|
||||
if (connection_diff_are_same) {
|
||||
if (diff_base)
|
||||
nm_log (level, domain, "%sconnection '%s' (%p and %p): no difference", prefix, name, connection, diff_base);
|
||||
else
|
||||
nm_log (level, domain, "%sconnection '%s' (%p): no properties set", prefix, name, connection);
|
||||
g_assert (!connection_diff);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: it doesn't nicely show the content of NMSettingVpn, becuase nm_connection_diff() does not
|
||||
* expand the hash values. */
|
||||
|
||||
sorted_hashes = _log_connection_sort_hashes (connection, diff_base, connection_diff);
|
||||
if (sorted_hashes->len <= 0)
|
||||
goto out;
|
||||
|
||||
sorted_names = g_array_new (FALSE, FALSE, sizeof (LogConnectionSettingItem));
|
||||
str1 = g_string_new (NULL);
|
||||
|
||||
for (i = 0; i < sorted_hashes->len; i++) {
|
||||
LogConnectionSettingData *setting_data = &g_array_index (sorted_hashes, LogConnectionSettingData, i);
|
||||
|
||||
_log_connection_sort_names (setting_data, sorted_names);
|
||||
print_setting_header = TRUE;
|
||||
for (j = 0; j < sorted_names->len; j++) {
|
||||
char *str_conn, *str_diff;
|
||||
LogConnectionSettingItem *item = &g_array_index (sorted_names, LogConnectionSettingItem, j);
|
||||
|
||||
str_conn = (item->diff_result & NM_SETTING_DIFF_RESULT_IN_A)
|
||||
? _log_connection_get_property (setting_data->setting, item->item_name)
|
||||
: NULL;
|
||||
str_diff = (item->diff_result & NM_SETTING_DIFF_RESULT_IN_B)
|
||||
? _log_connection_get_property (setting_data->diff_base_setting, item->item_name)
|
||||
: NULL;
|
||||
|
||||
if (print_header) {
|
||||
GError *err_verify = NULL;
|
||||
|
||||
if (diff_base)
|
||||
nm_log (level, domain, "%sconnection '%s' (%p < %p):", prefix, name, connection, diff_base);
|
||||
else
|
||||
nm_log (level, domain, "%sconnection '%s' (%p):", prefix, name, connection);
|
||||
print_header = FALSE;
|
||||
|
||||
if (!nm_connection_verify (connection, &err_verify)) {
|
||||
nm_log (level, domain, "%sconnection %p does not verify: %s", prefix, connection, err_verify->message);
|
||||
g_clear_error (&err_verify);
|
||||
}
|
||||
}
|
||||
#define _NM_LOG_ALIGN "-25"
|
||||
if (print_setting_header) {
|
||||
if (diff_base) {
|
||||
if (setting_data->setting && setting_data->diff_base_setting)
|
||||
g_string_printf (str1, "%p < %p", setting_data->setting, setting_data->diff_base_setting);
|
||||
else if (setting_data->diff_base_setting)
|
||||
g_string_printf (str1, "*missing* < %p", setting_data->diff_base_setting);
|
||||
else
|
||||
g_string_printf (str1, "%p < *missing*", setting_data->setting);
|
||||
nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s [ %s ]", prefix, setting_data->name, str1->str);
|
||||
} else
|
||||
nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s [ %p ]", prefix, setting_data->name, setting_data->setting);
|
||||
print_setting_header = FALSE;
|
||||
}
|
||||
g_string_printf (str1, "%s.%s", setting_data->name, item->item_name);
|
||||
switch (item->diff_result & (NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B)) {
|
||||
case NM_SETTING_DIFF_RESULT_IN_B:
|
||||
nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s < %s", prefix, str1->str, str_diff ? str_diff : "NULL");
|
||||
break;
|
||||
case NM_SETTING_DIFF_RESULT_IN_A:
|
||||
nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s = %s", prefix, str1->str, str_conn ? str_conn : "NULL");
|
||||
break;
|
||||
default:
|
||||
nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s = %s < %s", prefix, str1->str, str_conn ? str_conn : "NULL", str_diff ? str_diff : "NULL");
|
||||
break;
|
||||
#undef _NM_LOG_ALIGN
|
||||
}
|
||||
g_free (str_conn);
|
||||
g_free (str_diff);
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (sorted_names, TRUE);
|
||||
g_string_free (str1, TRUE);
|
||||
out:
|
||||
g_hash_table_destroy (connection_diff);
|
||||
g_array_free (sorted_hashes, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nm_utils_ip6_property_path:
|
||||
|
@@ -140,6 +140,8 @@ NMConnection *nm_utils_match_connection (GSList *connections,
|
||||
|
||||
int nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection **b);
|
||||
|
||||
void nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix);
|
||||
|
||||
gint64 nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
|
||||
|
||||
#define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000)
|
||||
|
@@ -2053,10 +2053,11 @@ need_new_8021x_secrets (NMDeviceWifi *self,
|
||||
|
||||
s_8021x = nm_connection_get_setting_802_1x (connection);
|
||||
if (s_8021x) {
|
||||
nm_setting_get_secret_flags (NM_SETTING (s_8021x),
|
||||
NM_SETTING_802_1X_PASSWORD,
|
||||
&secret_flags,
|
||||
NULL);
|
||||
if (!nm_setting_get_secret_flags (NM_SETTING (s_8021x),
|
||||
NM_SETTING_802_1X_PASSWORD,
|
||||
&secret_flags,
|
||||
NULL))
|
||||
g_assert_not_reached ();
|
||||
if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
*setting_name = NM_SETTING_802_1X_SETTING_NAME;
|
||||
return *setting_name ? TRUE : FALSE;
|
||||
@@ -2064,10 +2065,11 @@ need_new_8021x_secrets (NMDeviceWifi *self,
|
||||
|
||||
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
||||
if (s_wsec) {
|
||||
nm_setting_get_secret_flags (NM_SETTING (s_wsec),
|
||||
NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
|
||||
&secret_flags,
|
||||
NULL);
|
||||
if (!nm_setting_get_secret_flags (NM_SETTING (s_wsec),
|
||||
NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
|
||||
&secret_flags,
|
||||
NULL))
|
||||
g_assert_not_reached ();
|
||||
if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
||||
*setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
|
||||
return *setting_name ? TRUE : FALSE;
|
||||
|
@@ -1010,7 +1010,8 @@ check_system_secrets_cb (NMSetting *setting,
|
||||
*has_system = TRUE;
|
||||
}
|
||||
} else {
|
||||
nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL))
|
||||
g_return_if_reached ();
|
||||
if (secret_flags == NM_SETTING_SECRET_FLAG_NONE)
|
||||
*has_system = TRUE;
|
||||
}
|
||||
|
@@ -144,6 +144,7 @@ typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter,
|
||||
static void
|
||||
for_each_secret (NMConnection *connection,
|
||||
GHashTable *secrets,
|
||||
gboolean remove_non_secrets,
|
||||
ForEachSecretFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
@@ -167,6 +168,8 @@ for_each_secret (NMConnection *connection,
|
||||
* each time.
|
||||
*/
|
||||
|
||||
g_return_if_fail (callback);
|
||||
|
||||
/* Walk through the list of setting hashes */
|
||||
g_hash_table_iter_init (&iter, secrets);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
|
||||
@@ -175,6 +178,9 @@ for_each_secret (NMConnection *connection,
|
||||
const char *secret_name;
|
||||
GValue *val;
|
||||
|
||||
if (g_hash_table_size (setting_hash) == 0)
|
||||
continue;
|
||||
|
||||
/* Get the actual NMSetting from the connection so we can get secret flags
|
||||
* from the connection data, since flags aren't secrets. What we're
|
||||
* iterating here is just the secrets, not a whole connection.
|
||||
@@ -203,7 +209,11 @@ for_each_secret (NMConnection *connection,
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
|
||||
if (remove_non_secrets)
|
||||
g_hash_table_iter_remove (&secret_iter);
|
||||
continue;
|
||||
}
|
||||
if (callback (&secret_iter, secret_flags, callback_data) == FALSE)
|
||||
return;
|
||||
}
|
||||
@@ -460,6 +470,8 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
|
||||
*/
|
||||
g_signal_handlers_block_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE));
|
||||
|
||||
nm_utils_log_connection_diff (new_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, "update connection", "++ ");
|
||||
|
||||
nm_connection_replace_settings_from_connection (NM_CONNECTION (self), new_connection);
|
||||
nm_settings_connection_set_flags (self,
|
||||
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
|
||||
@@ -764,7 +776,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
||||
* save those system-owned secrets. If not, discard them and use the
|
||||
* existing secrets, or fail the connection.
|
||||
*/
|
||||
for_each_secret (NM_CONNECTION (self), secrets, has_system_owned_secrets, &agent_had_system);
|
||||
for_each_secret (NM_CONNECTION (self), secrets, TRUE, has_system_owned_secrets, &agent_had_system);
|
||||
if (agent_had_system) {
|
||||
if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) {
|
||||
/* No user interaction was allowed when requesting secrets; the
|
||||
@@ -776,7 +788,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
||||
call_id,
|
||||
agent_dbus_owner);
|
||||
|
||||
for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL);
|
||||
for_each_secret (NM_CONNECTION (self), secrets, FALSE, clear_nonagent_secrets, NULL);
|
||||
} else if (agent_has_modify == FALSE) {
|
||||
/* Agent didn't successfully authenticate; clear system-owned secrets
|
||||
* from the secrets the agent returned.
|
||||
@@ -786,7 +798,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
||||
setting_name,
|
||||
call_id);
|
||||
|
||||
for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL);
|
||||
for_each_secret (NM_CONNECTION (self), secrets, FALSE, clear_nonagent_secrets, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -805,7 +817,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
||||
* came back. Unsaved secrets by definition require user interaction.
|
||||
*/
|
||||
if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
|
||||
for_each_secret (NM_CONNECTION (self), secrets, clear_unsaved_secrets, NULL);
|
||||
for_each_secret (NM_CONNECTION (self), secrets, TRUE, clear_unsaved_secrets, NULL);
|
||||
|
||||
/* Update the connection with our existing secrets from backing storage */
|
||||
nm_connection_clear_secrets (NM_CONNECTION (self));
|
||||
|
@@ -874,6 +874,8 @@ claim_connection (NMSettings *self,
|
||||
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)),
|
||||
g_object_ref (connection));
|
||||
|
||||
nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ");
|
||||
|
||||
/* Only emit the individual connection-added signal after connections
|
||||
* have been initially loaded.
|
||||
*/
|
||||
|
@@ -2846,7 +2846,8 @@ check_unsupported_secrets (NMSetting *setting,
|
||||
if (flags & NM_SETTING_PARAM_SECRET) {
|
||||
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL))
|
||||
g_return_if_reached ();
|
||||
if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
|
||||
*unsupported_secret = TRUE;
|
||||
}
|
||||
@@ -2869,17 +2870,6 @@ ifnet_can_write_connection (NMConnection *connection, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the connection has flagged secrets, ignore
|
||||
* it as this plugin does not deal with user agent service */
|
||||
nm_connection_for_each_setting_value (connection,
|
||||
check_unsupported_secrets,
|
||||
&has_unsupported_secrets);
|
||||
if (has_unsupported_secrets) {
|
||||
g_set_error_literal (error, IFNET_PLUGIN_ERROR, 0,
|
||||
"The ifnet plugin only supports persistent system secrets.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Only support wired, wifi, and PPPoE */
|
||||
if ( !nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)
|
||||
&& !nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)
|
||||
@@ -2891,6 +2881,17 @@ ifnet_can_write_connection (NMConnection *connection, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the connection has flagged secrets, ignore
|
||||
* it as this plugin does not deal with user agent service */
|
||||
nm_connection_for_each_setting_value (connection,
|
||||
check_unsupported_secrets,
|
||||
&has_unsupported_secrets);
|
||||
if (has_unsupported_secrets) {
|
||||
g_set_error_literal (error, IFNET_PLUGIN_ERROR, 0,
|
||||
"The ifnet plugin only supports persistent system secrets.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -797,7 +797,8 @@ write_setting_value (NMSetting *setting,
|
||||
if (pspec && (pspec->flags & NM_SETTING_PARAM_SECRET) && !NM_IS_SETTING_VPN (setting)) {
|
||||
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
||||
|
||||
nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
|
||||
if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL))
|
||||
g_assert_not_reached ();
|
||||
if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
|
||||
return;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-utils.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
|
||||
@@ -226,6 +227,59 @@ test_nm_utils_ip6_address_clear_host_address (void)
|
||||
g_rand_free (r);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_nm_utils_log_connection_diff()
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMConnection *connection2;
|
||||
|
||||
/* if logging is disabled (the default), nm_utils_log_connection_diff() returns
|
||||
* early without doing anything. Hence, in the normal testing, this test does nothing.
|
||||
* It only gets interesting, when run verbosely with NMTST_DEBUG=debug ... */
|
||||
|
||||
nm_log (LOGL_DEBUG, LOGD_CORE, "START TEST test_nm_utils_log_connection_diff...");
|
||||
|
||||
connection = nm_simple_connection_new ();
|
||||
nm_connection_add_setting (connection, nm_setting_connection_new ());
|
||||
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test1", ">>> ");
|
||||
|
||||
nm_connection_add_setting (connection, nm_setting_wired_new ());
|
||||
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test2", ">>> ");
|
||||
|
||||
connection2 = nm_simple_connection_new_clone (connection);
|
||||
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test3", ">>> ");
|
||||
|
||||
g_object_set (nm_connection_get_setting_connection (connection),
|
||||
NM_SETTING_CONNECTION_ID, "id",
|
||||
NM_SETTING_CONNECTION_UUID, "uuid",
|
||||
NULL);
|
||||
g_object_set (nm_connection_get_setting_connection (connection2),
|
||||
NM_SETTING_CONNECTION_ID, "id2",
|
||||
NM_SETTING_CONNECTION_MASTER, "master2",
|
||||
NULL);
|
||||
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test4", ">>> ");
|
||||
|
||||
nm_connection_add_setting (connection, nm_setting_802_1x_new ());
|
||||
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test5", ">>> ");
|
||||
|
||||
g_object_set (nm_connection_get_setting_802_1x (connection),
|
||||
NM_SETTING_802_1X_PASSWORD, "id2",
|
||||
NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED,
|
||||
NULL);
|
||||
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test6", ">>> ");
|
||||
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test7", ">>> ");
|
||||
nm_utils_log_connection_diff (connection2, connection, LOGL_DEBUG, LOGD_CORE, "test8", ">>> ");
|
||||
|
||||
g_clear_object (&connection);
|
||||
g_clear_object (&connection2);
|
||||
|
||||
connection = nmtst_create_minimal_connection ("id-vpn-1", NULL, NM_SETTING_VPN_SETTING_NAME, NULL);
|
||||
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test-vpn-1", ">>> ");
|
||||
|
||||
g_clear_object (&connection);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
static NMConnection *
|
||||
@@ -690,6 +744,7 @@ main (int argc, char **argv)
|
||||
|
||||
g_test_add_func ("/general/nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
|
||||
g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address);
|
||||
g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff);
|
||||
|
||||
g_test_add_func ("/general/connection-match/basic", test_connection_match_basic);
|
||||
g_test_add_func ("/general/connection-match/ip6-method", test_connection_match_ip6_method);
|
||||
|
Reference in New Issue
Block a user