merge: branch 'bg/bond-reapply-rh1348198'

https://bugzilla.redhat.com/show_bug.cgi?id=1348198
This commit is contained in:
Beniamino Galvani 2017-03-06 10:38:01 +01:00
commit 6b7419c780
9 changed files with 298 additions and 102 deletions

View file

@ -391,6 +391,7 @@ enslave_slave (NMDevice *device,
NMDeviceBond *self = NM_DEVICE_BOND (device);
gboolean success = TRUE, no_firmware = FALSE;
const char *slave_iface = nm_device_get_ip_iface (slave);
NMConnection *master_con;
nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND);
@ -405,6 +406,25 @@ enslave_slave (NMDevice *device,
return FALSE;
_LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface);
/* The active_slave option can be set only after the interface is enslaved */
master_con = nm_device_get_applied_connection (device);
if (master_con) {
NMSettingBond *s_bond = nm_connection_get_setting_bond (master_con);
const char *active;
if (s_bond) {
active = nm_setting_bond_get_option_by_name (s_bond, "active_slave");
if (active && nm_streq0 (active, nm_device_get_iface (slave))) {
nm_platform_sysctl_master_set_option (NM_PLATFORM_GET,
nm_device_get_ifindex (device),
"active_slave",
active);
_LOGD (LOGD_BOND, "setting slave %s as active one for master %s",
active, nm_device_get_iface (device));
}
}
}
} else
_LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface);
@ -478,6 +498,116 @@ create_and_realize (NMDevice *device,
return TRUE;
}
static gboolean
check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error)
{
guint i, num;
const char *name, *value_a, *value_b;
/* Check that options in @s_a have compatible changes in @s_b */
num = nm_setting_bond_get_num_options (s_a);
for (i = 0; i < num; i++) {
nm_setting_bond_get_option (s_a, i, &name, &value_a);
/* We support changes to these */
if (NM_IN_STRSET (name,
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE,
NM_SETTING_BOND_OPTION_PRIMARY)) {
continue;
}
/* Missing in @s_b, but has a default value in @s_a */
value_b = nm_setting_bond_get_option_by_name (s_b, name);
if ( !value_b
&& nm_streq0 (value_a, nm_setting_bond_get_option_default (s_a, name))) {
continue;
}
/* Reject any other changes */
if (!nm_streq0 (value_a, value_b)) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply '%s' bond option",
name);
return FALSE;
}
}
return TRUE;
}
static gboolean
can_reapply_change (NMDevice *device,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error)
{
NMDeviceClass *device_class;
NMSettingBond *s_bond_old, *s_bond_new;
/* Only handle bond setting here, delegate other settings to parent class */
if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) {
if (!nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_BOND_SETTING_NAME,
error,
NM_SETTING_BOND_OPTIONS))
return FALSE;
s_bond_old = NM_SETTING_BOND (s_old);
s_bond_new = NM_SETTING_BOND (s_new);
if ( !check_changed_options (s_bond_old, s_bond_new, error)
|| !check_changed_options (s_bond_new, s_bond_old, error)) {
return FALSE;
}
return TRUE;
}
device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class);
return device_class->can_reapply_change (device,
setting_name,
s_old,
s_new,
diffs,
error);
}
static void
reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_new)
{
NMDeviceBond *self = NM_DEVICE_BOND (device);
const char *value;
NMSettingBond *s_bond;
NMBondMode mode;
NM_DEVICE_CLASS (nm_device_bond_parent_class)->reapply_connection (device,
con_old,
con_new);
_LOGD (LOGD_BOND, "reapplying bond settings");
s_bond = nm_connection_get_setting_bond (con_new);
g_return_if_fail (s_bond);
value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
if (!value)
value = "balance-rr";
mode = _nm_setting_bond_mode_from_string (value);
g_return_if_fail (mode != NM_BOND_MODE_UNKNOWN);
/* Primary */
value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_PRIMARY, value ? value : "");
/* Active slave */
set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
}
/*****************************************************************************/
static void
@ -506,6 +636,8 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
parent_class->enslave_slave = enslave_slave;
parent_class->release_slave = release_slave;
parent_class->can_reapply_change = can_reapply_change;
parent_class->reapply_connection = reapply_connection;
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_BOND_SKELETON,

View file

@ -134,4 +134,9 @@ guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is
NM_DEVICE_CLASS (klass)->link_types = link_types; \
}
gboolean _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name,
GError **error, const char **argv);
#define nm_device_hash_check_invalid_keys(hash, setting_name, error, ...) \
_nm_device_hash_check_invalid_keys (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL }))
#endif /* NM_DEVICE_PRIVATE_H */

View file

@ -8331,12 +8331,14 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
addrconf6_cleanup (self);
}
static gboolean
_hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GError **error, const char **argv)
gboolean
_nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name,
GError **error, const char **argv)
{
guint found_keys = 0;
guint i;
nm_assert (hash && g_hash_table_size (hash) > 0);
nm_assert (argv && argv[0]);
#if NM_MORE_ASSERTS > 10
@ -8352,9 +8354,6 @@ _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GErro
}
#endif
if (!hash || g_hash_table_size (hash) == 0)
return TRUE;
for (i = 0; argv[i]; i++) {
if (g_hash_table_contains (hash, argv[i]))
found_keys++;
@ -8395,7 +8394,6 @@ _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GErro
return TRUE;
}
#define _hash_check_invalid_keys(hash, setting_name, error, ...) _hash_check_invalid_keys_impl (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL }))
void
nm_device_reactivate_ip4_config (NMDevice *self,
@ -8473,12 +8471,55 @@ nm_device_reactivate_ip6_config (NMDevice *self,
}
}
static gboolean
can_reapply_change (NMDevice *self, const char *setting_name,
NMSetting *s_old, NMSetting *s_new,
GHashTable *diffs, GError **error)
{
if (!NM_IN_STRSET (setting_name,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_CONNECTION_SETTING_NAME)) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply any changes to '%s' setting",
setting_name);
return FALSE;
}
/* reapply_connection:
/* whitelist allowed properties from "connection" setting which are allowed to differ.
*
* This includes UUID, there is no principal problem with reapplying a connection
* and changing it's UUID. In fact, disallowing it makes it cumbersome for the user
* to reapply any connection but the original settings-connection. */
if ( nm_streq0 (setting_name, NM_SETTING_CONNECTION_SETTING_NAME)
&& !nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_CONNECTION_SETTING_NAME,
error,
NM_SETTING_CONNECTION_ID,
NM_SETTING_CONNECTION_UUID,
NM_SETTING_CONNECTION_STABLE_ID,
NM_SETTING_CONNECTION_AUTOCONNECT,
NM_SETTING_CONNECTION_ZONE,
NM_SETTING_CONNECTION_METERED))
return FALSE;
return TRUE;
}
static void
reapply_connection (NMDevice *self, NMConnection *con_old, NMConnection *con_new)
{
}
/* check_and_reapply_connection:
* @connection: the new connection settings to be applied or %NULL to reapply
* the current settings connection
* @version_id: either zero, or the current version id for the applied
* connection.
* @audit_args: on return, a string representing the changes
* @error: the error if %FALSE is returned
*
* Change configuration of an already configured device if possible.
@ -8487,11 +8528,13 @@ nm_device_reactivate_ip6_config (NMDevice *self,
* Return: %FALSE if the new configuration can not be reapplied.
*/
static gboolean
reapply_connection (NMDevice *self,
NMConnection *connection,
guint64 version_id,
GError **error)
check_and_reapply_connection (NMDevice *self,
NMConnection *connection,
guint64 version_id,
char **audit_args,
GError **error)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMConnection *applied = nm_device_get_applied_connection (self);
gs_unref_object NMConnection *applied_clone = NULL;
@ -8499,6 +8542,7 @@ reapply_connection (NMDevice *self,
NMConnection *con_old, *con_new;
NMSettingIPConfig *s_ip4_old, *s_ip4_new;
NMSettingIPConfig *s_ip6_old, *s_ip6_new;
GHashTableIter iter;
if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
g_set_error_literal (error,
@ -8514,30 +8558,27 @@ reapply_connection (NMDevice *self,
NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS,
&diffs);
if (nm_audit_manager_audit_enabled (nm_audit_manager_get ()))
*audit_args = nm_utils_format_con_diff_for_audit (diffs);
/**************************************************************************
* check for unsupported changes and reject to reapply
*************************************************************************/
if (!_hash_check_invalid_keys (diffs, NULL, error,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_CONNECTION_SETTING_NAME))
return FALSE;
if (diffs) {
char *setting_name;
GHashTable *setting_diff;
/* whitelist allowed properties from "connection" setting which are allowed to differ.
*
* This includes UUID, there is no principal problem with reapplying a connection
* and changing it's UUID. In fact, disallowing it makes it cumbersome for the user
* to reapply any connection but the original settings-connection. */
if (!_hash_check_invalid_keys (diffs ? g_hash_table_lookup (diffs, NM_SETTING_CONNECTION_SETTING_NAME) : NULL,
NM_SETTING_CONNECTION_SETTING_NAME,
error,
NM_SETTING_CONNECTION_ID,
NM_SETTING_CONNECTION_UUID,
NM_SETTING_CONNECTION_STABLE_ID,
NM_SETTING_CONNECTION_AUTOCONNECT,
NM_SETTING_CONNECTION_ZONE,
NM_SETTING_CONNECTION_METERED))
return FALSE;
g_hash_table_iter_init (&iter, diffs);
while (g_hash_table_iter_next (&iter, (gpointer *) &setting_name, (gpointer *) &setting_diff)) {
if (!klass->can_reapply_change (self,
setting_name,
nm_connection_get_setting_by_name (applied, setting_name),
nm_connection_get_setting_by_name (connection, setting_name),
setting_diff,
error))
return FALSE;
}
}
if ( version_id != 0
&& version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) {
@ -8567,7 +8608,7 @@ reapply_connection (NMDevice *self,
NMSettingConnection *s_con_a, *s_con_n;
/* we allow re-applying a connection with differing ID, UUID, STABLE_ID and AUTOCONNECT.
* This is for convenience but these values are not actually changable. So, check
* This is for convenience but these values are not actually changeable. So, check
* if they changed, and if the did revert to the original values. */
s_con_a = nm_connection_get_setting_connection (applied);
s_con_n = nm_connection_get_setting_connection (connection);
@ -8595,18 +8636,19 @@ reapply_connection (NMDevice *self,
} else
con_old = con_new = applied;
s_ip4_new = nm_connection_get_setting_ip4_config (con_new);
s_ip4_old = nm_connection_get_setting_ip4_config (con_old);
s_ip6_new = nm_connection_get_setting_ip6_config (con_new);
s_ip6_old = nm_connection_get_setting_ip6_config (con_old);
/**************************************************************************
* Reapply changes
*************************************************************************/
klass->reapply_connection (self, con_old, con_new);
nm_device_update_firewall_zone (self);
nm_device_update_metered (self);
s_ip4_old = nm_connection_get_setting_ip4_config (con_old);
s_ip4_new = nm_connection_get_setting_ip4_config (con_new);
s_ip6_old = nm_connection_get_setting_ip6_config (con_old);
s_ip6_new = nm_connection_get_setting_ip6_config (con_new);
nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new);
nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new);
@ -8629,6 +8671,7 @@ reapply_cb (NMDevice *self,
guint64 version_id = 0;
gs_unref_object NMConnection *connection = NULL;
GError *local = NULL;
gs_free char *audit_args = NULL;
if (reapply_data) {
connection = reapply_data->connection;
@ -8637,20 +8680,21 @@ reapply_cb (NMDevice *self,
}
if (error) {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, subject, error->message);
g_dbus_method_invocation_return_gerror (context, error);
return;
}
if (!reapply_connection (self,
connection ? : (NMConnection *) nm_device_get_settings_connection (self),
version_id,
&local)) {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message);
if (!check_and_reapply_connection (self,
connection ? : (NMConnection *) nm_device_get_settings_connection (self),
version_id,
&audit_args,
&local)) {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, audit_args, subject, local->message);
g_dbus_method_invocation_take_error (context, local);
local = NULL;
} else {
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, subject, NULL);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL);
g_dbus_method_invocation_return_value (context, NULL);
}
}
@ -8673,7 +8717,7 @@ impl_device_reapply (NMDevice *self,
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"Invalid flags specified");
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message);
g_dbus_method_invocation_take_error (context, error);
return;
}
@ -8682,7 +8726,7 @@ impl_device_reapply (NMDevice *self,
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message);
g_dbus_method_invocation_take_error (context, error);
return;
}
@ -8698,7 +8742,7 @@ impl_device_reapply (NMDevice *self,
&error);
if (!connection) {
g_prefix_error (&error, "The settings specified are invalid: ");
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message);
g_dbus_method_invocation_take_error (context, error);
return;
}
@ -8828,7 +8872,7 @@ disconnect_cb (NMDevice *self,
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, error->message);
return;
}
@ -8837,7 +8881,7 @@ disconnect_cb (NMDevice *self,
local = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not active");
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, local->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, local->message);
g_dbus_method_invocation_take_error (context, local);
} else {
nm_device_set_autoconnect_intern (self, FALSE);
@ -8846,7 +8890,7 @@ disconnect_cb (NMDevice *self,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_USER_REQUESTED);
g_dbus_method_invocation_return_value (context, NULL);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, subject, NULL);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, NULL, subject, NULL);
}
}
@ -8897,12 +8941,12 @@ delete_cb (NMDevice *self,
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, NULL, subject, error->message);
return;
}
/* Authorized */
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, NULL, subject, NULL);
if (nm_device_unrealize (self, TRUE, &local))
g_dbus_method_invocation_return_value (context, NULL);
else
@ -13607,6 +13651,8 @@ nm_device_class_init (NMDeviceClass *klass)
klass->unmanaged_on_quit = unmanaged_on_quit;
klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr;
klass->parent_changed_notify = parent_changed_notify;
klass->can_reapply_change = can_reapply_change;
klass->reapply_connection = reapply_connection;
obj_properties[PROP_UDI] =
g_param_spec_string (NM_DEVICE_UDI, "", "",

View file

@ -380,6 +380,17 @@ typedef struct {
NMConnection * (* new_default_connection) (NMDevice *self);
gboolean (* unmanaged_on_quit) (NMDevice *self);
gboolean (* can_reapply_change) (NMDevice *self,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error);
void (* reapply_connection) (NMDevice *self,
NMConnection *con_old,
NMConnection *con_new);
} NMDeviceClass;
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,

View file

@ -302,11 +302,11 @@ _nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file, guint
void
_nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint line,
const char *func, const char *op, NMDevice *device,
gboolean result, gpointer subject_context,
gboolean result, const char *args, gpointer subject_context,
const char *reason)
{
gs_unref_ptrarray GPtrArray *fields = NULL;
AuditField interface_field = { }, ifindex_field = { };
AuditField interface_field = { }, ifindex_field = { }, args_field = { };
int ifindex;
g_return_if_fail (op);
@ -324,6 +324,11 @@ _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint l
g_ptr_array_add (fields, &ifindex_field);
}
if (args) {
_audit_field_init_string (&args_field, "args", args, FALSE, BACKEND_ALL);
g_ptr_array_add (fields, &args_field);
}
_audit_log_helper (self, fields, file, line, func, op, result, subject_context, reason);
}

View file

@ -83,13 +83,13 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self);
} \
} G_STMT_END
#define nm_audit_log_device_op(op, device, result, subject_context, reason) \
#define nm_audit_log_device_op(op, device, result, args, subject_context, reason) \
G_STMT_START { \
NMAuditManager *_audit = nm_audit_manager_get (); \
\
if (nm_audit_manager_audit_enabled (_audit)) { \
_nm_audit_manager_log_device_op (_audit, __FILE__, __LINE__, G_STRFUNC, \
(op), (device), (result), (subject_context), (reason)); \
(op), (device), (result), (args), (subject_context), (reason)); \
} \
} G_STMT_END
@ -114,6 +114,7 @@ void _nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file
void _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint line,
const char *func, const char *op, NMDevice *device,
gboolean result, gpointer subject_context, const char *reason);
gboolean result, const char *args, gpointer subject_context,
const char *reason);
#endif /* __NM_AUDIT_MANAGER_H__ */

View file

@ -4311,3 +4311,31 @@ skip:
return result;
}
char *
nm_utils_format_con_diff_for_audit (GHashTable *diff)
{
GHashTable *setting_diff;
char *setting_name, *prop_name;
GHashTableIter iter, iter2;
GString *str;
str = g_string_sized_new (32);
g_hash_table_iter_init (&iter, diff);
while (g_hash_table_iter_next (&iter,
(gpointer *) &setting_name,
(gpointer *) &setting_diff)) {
if (!setting_diff)
continue;
g_hash_table_iter_init (&iter2, setting_diff);
while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL))
g_string_append_printf (str, "%s.%s,", setting_name, prop_name);
}
if (str->len)
str->str[str->len - 1] = '\0';
return g_string_free (str, FALSE);
}

View file

@ -469,5 +469,7 @@ struct stat;
gboolean nm_utils_validate_plugin (const char *path, struct stat *stat, GError **error);
char **nm_utils_read_plugin_paths (const char *dirname, const char *prefix);
char *nm_utils_format_con_diff_for_audit (GHashTable *diff);
#endif /* __NM_CORE_UTILS_H__ */

View file

@ -1653,49 +1653,6 @@ con_update_cb (NMSettingsConnection *self,
update_complete (self, info, error);
}
static char *
con_list_changed_props (NMConnection *old, NMConnection *new)
{
gs_unref_hashtable GHashTable *diff = NULL;
GHashTable *setting_diff;
char *setting_name, *prop_name;
GHashTableIter iter, iter2;
gboolean same;
GString *str;
same = nm_connection_diff (old, new,
NM_SETTING_COMPARE_FLAG_EXACT |
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT,
&diff);
if (same || !diff)
return NULL;
str = g_string_sized_new (32);
g_hash_table_iter_init (&iter, diff);
while (g_hash_table_iter_next (&iter,
(gpointer *) &setting_name,
(gpointer *) &setting_diff)) {
if (!setting_diff)
continue;
g_hash_table_iter_init (&iter2, setting_diff);
while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL)) {
g_string_append (str, setting_name);
g_string_append_c (str, '.');
g_string_append (str, prop_name);
g_string_append_c (str, ',');
}
}
if (str->len)
str->str[str->len - 1] = '\0';
return g_string_free (str, FALSE);
}
static void
update_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
@ -1736,8 +1693,17 @@ update_auth_cb (NMSettingsConnection *self,
update_agent_secrets_cache (self, info->new_settings);
}
if (nm_audit_manager_audit_enabled (nm_audit_manager_get ()))
info->audit_args = con_list_changed_props (NM_CONNECTION (self), info->new_settings);
if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) {
gs_unref_hashtable GHashTable *diff = NULL;
gboolean same;
same = nm_connection_diff (NM_CONNECTION (self), info->new_settings,
NM_SETTING_COMPARE_FLAG_EXACT |
NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT,
&diff);
if (!same && diff)
info->audit_args = nm_utils_format_con_diff_for_audit (diff);
}
if (info->save_to_disk) {
nm_settings_connection_replace_and_commit (self,