mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 07:50:17 +01:00
merge: branch 'bg/bond-reapply-rh1348198'
https://bugzilla.redhat.com/show_bug.cgi?id=1348198
This commit is contained in:
commit
6b7419c780
9 changed files with 298 additions and 102 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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, "", "",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue