summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-10-25 14:06:52 +0200
committerThomas Haller <thaller@redhat.com>2017-10-25 14:06:52 +0200
commitfda635f5e971d7713cf0d38257c3687fd080b432 (patch)
tree406255092c958b3e6635901061506b66fb51aa04
parentc4f74fcfb6aeff95d6ce697f705438e63e8a52a9 (diff)
parent7028818a8302be6e2b31dbcdc914b9020403f64e (diff)
downloadNetworkManager-fda635f5e971d7713cf0d38257c3687fd080b432.tar.gz
ifcfg-rh: merge branch 'th/ifcfg-rule-write-rh1384799'
https://bugzilla.redhat.com/show_bug.cgi?id=1384799
-rw-r--r--libnm-core/nm-core-internal.h12
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c2
-rw-r--r--src/nm-checkpoint.c4
-rw-r--r--src/nm-manager.c9
-rw-r--r--src/settings/nm-settings-connection.c500
-rw-r--r--src/settings/nm-settings-connection.h54
-rw-r--r--src/settings/nm-settings.c3
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c104
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c86
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h11
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c23
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h2
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c649
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h30
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c92
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.h9
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c34
-rw-r--r--src/settings/plugins/ifnet/nms-ifnet-connection.c76
-rw-r--r--src/settings/plugins/ifnet/nms-ifnet-plugin.c32
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-plugin.c7
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-connection.c74
22 files changed, 940 insertions, 877 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 5d81d059d2..b6be4794e8 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -431,4 +431,16 @@ gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, g
/*****************************************************************************/
+static inline int
+nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
+{
+ if (NM_IS_SETTING_IP4_CONFIG (s_ip))
+ return AF_INET;
+ if (NM_IS_SETTING_IP6_CONFIG (s_ip))
+ return AF_INET6;
+ g_return_val_if_reached (AF_UNSPEC);
+}
+
+/*****************************************************************************/
+
#endif
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index 573cb44e78..182527d9f5 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -1219,7 +1219,7 @@ dispose (GObject *object)
if (to_delete) {
nm_log_dbg (LOGD_BT, "bluez[%s] removing Bluetooth connection for NAP device: '%s' (%s)", priv->path,
nm_connection_get_id (to_delete), nm_connection_get_uuid (to_delete));
- nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL, NULL);
+ nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL);
g_object_unref (to_delete);
}
diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c
index 2dd76d590f..c3a2e74360 100644
--- a/src/nm-checkpoint.c
+++ b/src/nm-checkpoint.c
@@ -259,8 +259,8 @@ activate:
nm_connection_replace_settings_from_connection (NM_CONNECTION (connection),
dev_checkpoint->settings_connection);
nm_settings_connection_commit_changes (connection,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL);
}
} else {
@@ -343,7 +343,7 @@ next_dev:
nm_settings_connection_get_uuid (con))) {
_LOGD ("rollback: deleting new connection %s",
nm_settings_connection_get_uuid (con));
- nm_settings_connection_delete (con, NULL, NULL);
+ nm_settings_connection_delete (con, NULL);
}
}
}
diff --git a/src/nm-manager.c b/src/nm-manager.c
index fa67ee7842..46214130b3 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -339,7 +339,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active)
if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
- nm_settings_connection_delete (connection, NULL, NULL);
+ nm_settings_connection_delete (connection, NULL);
}
g_object_unref (connection);
}
@@ -1990,7 +1990,7 @@ recheck_assume_connection (NMManager *self,
if (generated) {
_LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed");
- nm_settings_connection_delete (connection, NULL, NULL);
+ nm_settings_connection_delete (connection, NULL);
} else {
if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
@@ -4035,8 +4035,9 @@ activation_add_done (NMSettings *settings,
if (_internal_activate_generic (self, active, &local)) {
nm_settings_connection_commit_changes (new_connection,
+ NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
- NULL, NULL);
+ NULL);
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(oo)",
@@ -4056,7 +4057,7 @@ activation_add_done (NMSettings *settings,
g_assert (error);
_internal_activation_failed (self, active, error->message);
if (new_connection)
- nm_settings_connection_delete (new_connection, NULL, NULL);
+ nm_settings_connection_delete (new_connection, NULL);
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
NULL,
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 768f55f8cb..8dec0bde32 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -510,18 +510,12 @@ connection_changed_cb (NMSettingsConnection *self, gpointer unused)
_emit_updated (self, FALSE);
}
-/* Update the settings of this connection to match that of 'new_connection',
- * taking care to make a private copy of secrets.
- */
gboolean
-nm_settings_connection_replace_settings (NMSettingsConnection *self,
- NMConnection *new_connection,
- gboolean update_unsaved,
- const char *log_diff_name,
- GError **error)
+nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ GError **error)
{
NMSettingsConnectionPrivate *priv;
- gboolean success = FALSE;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
@@ -540,6 +534,30 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
return FALSE;
}
+ return TRUE;
+}
+
+gboolean
+nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ gboolean prepare_new_connection,
+ gboolean update_unsaved,
+ const char *log_diff_name,
+ GError **error)
+{
+ NMSettingsConnectionPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
+
+ priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ if ( prepare_new_connection
+ && !nm_settings_connection_replace_settings_prepare (self,
+ new_connection,
+ error))
+ return FALSE;
+
/* Do nothing if there's nothing to update */
if (nm_connection_compare (NM_CONNECTION (self),
new_connection,
@@ -567,7 +585,6 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
* nm_connection_clear_secrets() and clears them.
*/
update_system_secrets_cache (self);
- success = TRUE;
/* Add agent and always-ask secrets back; they won't necessarily be
* in the replacement connection data if it was eg reread from disk.
@@ -594,114 +611,101 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
_emit_updated (self, TRUE);
- return success;
-}
-
-static void
-ignore_cb (NMSettingsConnection *self,
- GError *error,
- gpointer user_data)
-{
+ return TRUE;
}
-/* Replaces the settings in this connection with those in 'new_connection'. If
- * any changes are made, commits them to permanent storage and to any other
- * subsystems watching this connection. Before returning, 'callback' is run
- * with the given 'user_data' along with any errors encountered.
+/* Update the settings of this connection to match that of 'new_connection',
+ * taking care to make a private copy of secrets.
*/
-static void
-replace_and_commit (NMSettingsConnection *self,
- NMConnection *new_connection,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+gboolean
+nm_settings_connection_replace_settings (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ gboolean update_unsaved,
+ const char *log_diff_name,
+ GError **error)
{
- GError *error = NULL;
- NMSettingsConnectionCommitReason commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION;
-
- if (g_strcmp0 (nm_connection_get_id (NM_CONNECTION (self)),
- nm_connection_get_id (new_connection)) != 0)
- commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED;
-
- if (nm_settings_connection_replace_settings (self, new_connection, TRUE, "replace-and-commit-disk", &error))
- nm_settings_connection_commit_changes (self, commit_reason, callback, user_data);
- else {
- g_assert (error);
- if (callback)
- callback (self, error, user_data);
- g_clear_error (&error);
- }
+ return nm_settings_connection_replace_settings_full (self,
+ new_connection,
+ TRUE,
+ update_unsaved,
+ log_diff_name,
+ error);
}
-void
-nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
- NMConnection *new_connection,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+gboolean
+nm_settings_connection_commit_changes (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ NMSettingsConnectionCommitReason commit_reason,
+ GError **error)
{
- g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
- g_return_if_fail (NM_IS_CONNECTION (new_connection));
+ NMSettingsConnectionClass *klass;
+ gs_free_error GError *local = NULL;
+ gs_unref_object NMConnection *reread_connection = NULL;
+ gs_free char *logmsg_change = NULL;
- NM_SETTINGS_CONNECTION_GET_CLASS (self)->replace_and_commit (self, new_connection, callback, user_data);
-}
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
-static void
-commit_changes (NMSettingsConnection *self,
- NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
-{
- /* Subclasses only call this function if the save was successful, so at
- * this point the connection is synced to disk and no longer unsaved.
- */
- set_unsaved (self, FALSE);
+ klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
+ if (!klass->commit_changes) {
+ _LOGW ("write: setting plugin %s does not support to write connection",
+ G_OBJECT_TYPE_NAME (self));
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_FAILED,
+ "writing settings not supported");
+ return FALSE;
+ }
- g_object_ref (self);
- callback (self, NULL, user_data);
- g_object_unref (self);
-}
+ if ( new_connection
+ && !nm_settings_connection_replace_settings_prepare (self,
+ new_connection,
+ &local)) {
+ _LOGW ("write: failed to prepare connection for writing: %s",
+ local->message);
+ g_propagate_error (error, g_steal_pointer (&local));
+ return FALSE;
+ }
-void
-nm_settings_connection_commit_changes (NMSettingsConnection *self,
- NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
-{
- g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
+ if (!klass->commit_changes (self,
+ new_connection,
+ commit_reason,
+ &reread_connection,
+ &logmsg_change,
+ &local)) {
+ _LOGW ("write: failure to write setting: %s",
+ local->message);
+ g_propagate_error (error, g_steal_pointer (&local));
+ return FALSE;
+ }
- if (NM_SETTINGS_CONNECTION_GET_CLASS (self)->commit_changes) {
- NM_SETTINGS_CONNECTION_GET_CLASS (self)->commit_changes (self,
- commit_reason,
- callback ? callback : ignore_cb,
- user_data);
- } else {
- GError *error = g_error_new (NM_SETTINGS_ERROR,
- NM_SETTINGS_ERROR_FAILED,
- "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__);
- if (callback)
- callback (self, error, user_data);
- g_error_free (error);
+ if (reread_connection || new_connection) {
+ if (!nm_settings_connection_replace_settings_full (self,
+ reread_connection ?: new_connection,
+ !reread_connection,
+ FALSE,
+ new_connection
+ ? "update-during-write"
+ : "replace-and-commit-disk",
+ &local)) {
+ /* this can't really happen, because at this point replace-settings
+ * is no longer supposed to fail. It's a bug. */
+ _LOGE ("write: replacing setting failed: %s",
+ local->message);
+ g_propagate_error (error, g_steal_pointer (&local));
+ g_return_val_if_reached (FALSE);
+ }
}
-}
-void
-nm_settings_connection_delete (NMSettingsConnection *self,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data)
-{
- g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
+ set_unsaved (self, FALSE);
- if (NM_SETTINGS_CONNECTION_GET_CLASS (self)->delete) {
- NM_SETTINGS_CONNECTION_GET_CLASS (self)->delete (self,
- callback ? callback : ignore_cb,
- user_data);
- } else {
- GError *error = g_error_new (NM_SETTINGS_ERROR,
- NM_SETTINGS_ERROR_FAILED,
- "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__);
- if (callback)
- callback (self, error, user_data);
- g_error_free (error);
- }
+ if (reread_connection)
+ _LOGI ("write: successfully updated (%s), connection was modified in the process", logmsg_change);
+ else if (new_connection)
+ _LOGI ("write: successfully updated (%s)", logmsg_change);
+ else
+ _LOGI ("write: successfully commited (%s)", logmsg_change);
+
+ return TRUE;
}
static void
@@ -740,15 +744,32 @@ remove_entry_from_db (NMSettingsConnection *self, const char* db_name)
g_key_file_free (key_file);
}
-static void
-do_delete (NMSettingsConnection *self,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data)
+gboolean
+nm_settings_connection_delete (NMSettingsConnection *self,
+ GError **error)
{
+ gs_unref_object NMSettingsConnection *self_keep_alive = NULL;
+ NMSettingsConnectionClass *klass;
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMConnection *for_agents;
- g_object_ref (self);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
+
+ klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
+
+ self_keep_alive = g_object_ref (self);
+
+ if (!klass->delete) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_FAILED,
+ "delete not supported");
+ return FALSE;
+ }
+ if (!klass->delete (self,
+ error))
+ return FALSE;
+
set_visible (self, FALSE);
/* Tell agents to remove secrets for this connection */
@@ -766,12 +787,10 @@ do_delete (NMSettingsConnection *self,
remove_entry_from_db (self, "seen-bssids");
nm_settings_connection_signal_remove (self, FALSE);
-
- callback (self, NULL, user_data);
-
- g_object_unref (self);
+ return TRUE;
}
+
/*****************************************************************************/
@@ -887,15 +906,6 @@ secret_is_system_owned (NMSettingSecretFlags flags,
}
static void
-new_secrets_commit_cb (NMSettingsConnection *self,
- GError *error,
- gpointer user_data)
-{
- if (error)
- _LOGW ("Error saving new secrets to backing storage: %s", error->message);
-}
-
-static void
get_cmp_flags (NMSettingsConnection *self, /* only needed for logging */
GetSecretsInfo *info, /* only needed for logging */
NMConnection *connection,
@@ -993,9 +1003,11 @@ nm_settings_connection_new_secrets (NMSettingsConnection *self,
update_system_secrets_cache (self);
update_agent_secrets_cache (self, NULL);
- nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- new_secrets_commit_cb, NULL);
+ nm_settings_connection_commit_changes (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL);
return TRUE;
}
@@ -1109,7 +1121,10 @@ get_secrets_done_cb (NMAgentManager *manager,
setting_name,
info);
- nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, new_secrets_commit_cb, NULL);
+ nm_settings_connection_commit_changes (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL);
} else {
_LOGD ("(%s:%p) new agent secrets processed",
setting_name,
@@ -1570,11 +1585,6 @@ typedef struct {
char *audit_args;
} UpdateInfo;
-typedef struct {
- GDBusMethodInvocation *context;
- NMAuthSubject *subject;
-} CallbackInfo;
-
static void
has_some_secrets_cb (NMSetting *setting,
const char *key,
@@ -1651,33 +1661,6 @@ update_complete (NMSettingsConnection *self,
}
static void
-con_update_cb (NMSettingsConnection *self,
- GError *error,
- gpointer user_data)
-{
- UpdateInfo *info = user_data;
- NMConnection *for_agent;
-
- if (!error) {
- /* Dupe the connection so we can clear out non-agent-owned secrets,
- * as agent-owned secrets are the only ones we send back be saved.
- * Only send secrets to agents of the same UID that called update too.
- */
- for_agent = nm_simple_connection_new_clone (NM_CONNECTION (self));
- nm_connection_clear_secrets_with_flags (for_agent,
- secrets_filter_cb,
- GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
- nm_agent_manager_save_secrets (info->agent_mgr,
- nm_connection_get_path (NM_CONNECTION (self)),
- for_agent,
- info->subject);
- g_object_unref (for_agent);
- }
-
- update_complete (self, info, error);
-}
-
-static void
update_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
@@ -1685,63 +1668,93 @@ update_auth_cb (NMSettingsConnection *self,
gpointer data)
{
UpdateInfo *info = data;
- GError *local = NULL;
+ NMSettingsConnectionCommitReason commit_reason;
+ gs_free_error GError *local = NULL;
if (error) {
update_complete (self, info, error);
return;
}
- if (!info->new_settings) {
- /* We're just calling Save(). Just commit the existing connection. */
- if (info->save_to_disk) {
- nm_settings_connection_commit_changes (self,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION,
- con_update_cb,
- info);
+ if (info->new_settings) {
+ if (!any_secrets_present (info->new_settings)) {
+ /* If the new connection has no secrets, we do not want to remove all
+ * secrets, rather we keep all the existing ones. Do that by merging
+ * them in to the new connection.
+ */
+ cached_secrets_to_connection (self, info->new_settings);
+ } else {
+ /* Cache the new secrets from the agent, as stuff like inotify-triggered
+ * changes to connection's backing config files will blow them away if
+ * they're in the main connection.
+ */
+ update_agent_secrets_cache (self, info->new_settings);
}
- return;
- }
- if (!any_secrets_present (info->new_settings)) {
- /* If the new connection has no secrets, we do not want to remove all
- * secrets, rather we keep all the existing ones. Do that by merging
- * them in to the new connection.
- */
- cached_secrets_to_connection (self, info->new_settings);
- } else {
- /* Cache the new secrets from the agent, as stuff like inotify-triggered
- * changes to connection's backing config files will blow them away if
- * they're in the main connection.
- */
- update_agent_secrets_cache (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 (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) {
- gs_unref_hashtable GHashTable *diff = NULL;
- gboolean same;
+ if (!info->save_to_disk) {
+ if (info->new_settings) {
+ nm_settings_connection_replace_settings (self,
+ info->new_settings,
+ TRUE,
+ "replace-unsaved",
+ &local);
+ }
+ goto out;
+ }
- 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->new_settings) {
+ if (!nm_settings_connection_replace_settings_prepare (self,
+ info->new_settings,
+ &local))
+ goto out;
}
- if (info->save_to_disk) {
- nm_settings_connection_replace_and_commit (self,
- info->new_settings,
- con_update_cb,
- info);
- } else {
- if (!nm_settings_connection_replace_settings (self, info->new_settings, TRUE, "replace-and-commit-memory", &local))
- g_assert (local);
- con_update_cb (self, local, info);
- g_clear_error (&local);
+ commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION;
+ if ( info->new_settings
+ && !nm_streq0 (nm_connection_get_id (NM_CONNECTION (self)),
+ nm_connection_get_id (info->new_settings)))
+ commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED;
+
+ nm_settings_connection_commit_changes (self,
+ info->new_settings,
+ commit_reason,
+ &local);
+
+out:
+ if (!local) {
+ gs_unref_object NMConnection *for_agent = NULL;
+
+ /* Dupe the connection so we can clear out non-agent-owned secrets,
+ * as agent-owned secrets are the only ones we send back be saved.
+ * Only send secrets to agents of the same UID that called update too.
+ */
+ for_agent = nm_simple_connection_new_clone (NM_CONNECTION (self));
+ nm_connection_clear_secrets_with_flags (for_agent,
+ secrets_filter_cb,
+ GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
+ nm_agent_manager_save_secrets (info->agent_mgr,
+ nm_connection_get_path (NM_CONNECTION (self)),
+ for_agent,
+ info->subject);
}
+
+ update_complete (self, info, local);
}
+
static const char *
get_update_modify_permission (NMConnection *old, NMConnection *new)
{
@@ -1865,30 +1878,13 @@ impl_settings_connection_save (NMSettingsConnection *self,
}
static void
-con_delete_cb (NMSettingsConnection *self,
- GError *error,
- gpointer user_data)
-{
- CallbackInfo *info = user_data;
-
- if (error)
- g_dbus_method_invocation_return_gerror (info->context, error);
- else
- g_dbus_method_invocation_return_value (info->context, NULL);
-
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self,
- !error, NULL, info->subject, error ? error->message : NULL);
- g_free (info);
-}
-
-static void
delete_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
{
- CallbackInfo *info;
+ gs_free_error GError *local = NULL;
if (error) {
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject,
@@ -1897,11 +1893,15 @@ delete_auth_cb (NMSettingsConnection *self,
return;
}
- info = g_malloc0 (sizeof (*info));
- info->context = context;
- info->subject = subject;
+ nm_settings_connection_delete (self, &local);
+
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self,
+ !local, NULL, subject, local ? local->message : NULL);
- nm_settings_connection_delete (self, con_delete_cb, info);
+ if (local)
+ g_dbus_method_invocation_return_gerror (context, local);
+ else
+ g_dbus_method_invocation_return_value (context, NULL);
}
static const char *
@@ -2021,23 +2021,6 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
}
static void
-clear_secrets_cb (NMSettingsConnection *self,
- GError *error,
- gpointer user_data)
-{
- CallbackInfo *info = user_data;
-
- if (error)
- g_dbus_method_invocation_return_gerror (info->context, error);
- else
- g_dbus_method_invocation_return_value (info->context, NULL);
-
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
- !error, NULL, info->subject, error ? error->message : NULL);
- g_free (info);
-}
-
-static void
dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
@@ -2045,31 +2028,39 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
gpointer user_data)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
- CallbackInfo *info;
+ gs_free_error GError *local = NULL;
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
FALSE, NULL, subject, error->message);
- } else {
- /* Clear secrets in connection and caches */
- nm_connection_clear_secrets (NM_CONNECTION (self));
- if (priv->system_secrets)
- nm_connection_clear_secrets (priv->system_secrets);
- if (priv->agent_secrets)
- nm_connection_clear_secrets (priv->agent_secrets);
+ return;
+ }
- /* Tell agents to remove secrets for this connection */
- nm_agent_manager_delete_secrets (priv->agent_mgr,
- nm_connection_get_path (NM_CONNECTION (self)),
- NM_CONNECTION (self));
+ /* Clear secrets in connection and caches */
+ nm_connection_clear_secrets (NM_CONNECTION (self));
+ if (priv->system_secrets)
+ nm_connection_clear_secrets (priv->system_secrets);
+ if (priv->agent_secrets)
+ nm_connection_clear_secrets (priv->agent_secrets);
- info = g_malloc0 (sizeof (*info));
- info->context = context;
- info->subject = subject;
+ /* Tell agents to remove secrets for this connection */
+ nm_agent_manager_delete_secrets (priv->agent_mgr,
+ nm_connection_get_path (NM_CONNECTION (self)),
+ NM_CONNECTION (self));
- nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, clear_secrets_cb, info);
- }
+ nm_settings_connection_commit_changes (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ &local);
+
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
+ !local, NULL, subject, local ? local->message : NULL);
+
+ if (local)
+ g_dbus_method_invocation_return_gerror (context, local);
+ else
+ g_dbus_method_invocation_return_value (context, NULL);
}
static void
@@ -2902,9 +2893,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
object_class->get_property = get_property;
object_class->set_property = set_property;
- class->replace_and_commit = replace_and_commit;
- class->commit_changes = commit_changes;
- class->delete = do_delete;
class->supports_secrets = supports_secrets;
obj_properties[PROP_VISIBLE] =
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
index ecfac07905..67b3d9b92f 100644
--- a/src/settings/nm-settings-connection.h
+++ b/src/settings/nm-settings-connection.h
@@ -94,14 +94,6 @@ typedef struct _NMSettingsConnectionCallId *NMSettingsConnectionCallId;
typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
-typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *self,
- GError *error,
- gpointer user_data);
-
-typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *self,
- GError *error,
- gpointer user_data);
-
struct _NMSettingsConnectionPrivate;
struct _NMSettingsConnection {
@@ -112,20 +104,15 @@ struct _NMSettingsConnection {
struct _NMSettingsConnectionClass {
NMExportedObjectClass parent;
- /* virtual methods */
- void (*replace_and_commit) (NMSettingsConnection *self,
+ gboolean (*commit_changes) (NMSettingsConnection *self,
NMConnection *new_connection,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data);
+ NMSettingsConnectionCommitReason commit_reason,
+ NMConnection **out_reread_connection,
+ char **out_logmsg_change,
+ GError **error);
- void (*commit_changes) (NMSettingsConnection *self,
- NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data);
-
- void (*delete) (NMSettingsConnection *self,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data);
+ gboolean (*delete) (NMSettingsConnection *self,
+ GError **error);
gboolean (*supports_secrets) (NMSettingsConnection *self,
const char *setting_name);
@@ -137,10 +124,14 @@ gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsCon
NMConnection *applied_connection,
NMSettingCompareFlags compare_flage);
-void nm_settings_connection_commit_changes (NMSettingsConnection *self,
- NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data);
+gboolean nm_settings_connection_commit_changes (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ NMSettingsConnectionCommitReason commit_reason,
+ GError **error);
+
+gboolean nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ GError **error);
gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
NMConnection *new_connection,
@@ -148,14 +139,15 @@ gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
const char *log_diff_name,
GError **error);
-void nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
- NMConnection *new_connection,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data);
+gboolean nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ gboolean prepare_new_connection,
+ gboolean update_unsaved,
+ const char *log_diff_name,
+ GError **error);
-void nm_settings_connection_delete (NMSettingsConnection *self,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data);
+gboolean nm_settings_connection_delete (NMSettingsConnection *self,
+ GError **error);
typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self,
NMSettingsConnectionCallId call_id,
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 10c160cbc8..e2b467a24c 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -91,7 +91,6 @@ EXPORT(nm_inotify_helper_remove_watch)
EXPORT(nm_settings_connection_get_type)
EXPORT(nm_settings_connection_replace_settings)
-EXPORT(nm_settings_connection_replace_and_commit)
/*****************************************************************************/
@@ -1774,7 +1773,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quittin
* remains up and can be assumed if NM starts again.
*/
if (quitting == FALSE)
- nm_settings_connection_delete (connection, NULL, NULL);
+ nm_settings_connection_delete (connection, NULL);
}
}
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
index b54f9549a6..4c1d02ae08 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
@@ -306,75 +306,52 @@ nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self)
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unrecognized_spec;
}
-static void
-replace_and_commit (NMSettingsConnection *connection,
- NMConnection *new_connection,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
-{
- const char *filename;
- GError *error = NULL;
-
- filename = nm_settings_connection_get_filename (connection);
- if (filename && utils_has_complex_routes (filename)) {
- if (callback) {
- error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file");
- callback (connection, error, user_data);
- g_clear_error (&error);
- }
- return;
- }
-
- NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->replace_and_commit (connection, new_connection, callback, user_data);
-}
-
-static void
+static gboolean
commit_changes (NMSettingsConnection *connection,
+ NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+ NMConnection **out_reread_connection,
+ char **out_logmsg_change,
+ GError **error)
{
- GError *error = NULL;
- gboolean success = FALSE;
- char *ifcfg_path = NULL;
const char *filename;
+ gs_unref_object NMConnection *reread = NULL;
+ gboolean reread_same = TRUE;
+ const char *operation_message;
+ gs_free char *ifcfg_path = NULL;
- filename = nm_settings_connection_get_filename (connection);
- if (filename) {
- success = writer_update_connection (NM_CONNECTION (connection),
- IFCFG_DIR,
- filename,
- NULL,
- NULL,
- &error);
- } else {
- success = writer_new_connection (NM_CONNECTION (connection),
- IFCFG_DIR,
- &ifcfg_path,
- NULL,
- NULL,
- &error);
- if (success) {
- nm_settings_connection_set_filename (connection, ifcfg_path);
- g_free (ifcfg_path);
- }
- }
+ nm_assert (out_reread_connection && !*out_reread_connection);
+ nm_assert (!out_logmsg_change || !*out_logmsg_change);
- if (success) {
- /* Chain up to parent to handle success */
- NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, commit_reason, callback, user_data);
- } else {
- /* Otherwise immediate error */
- callback (connection, error, user_data);
- g_error_free (error);
- }
+ filename = nm_settings_connection_get_filename (connection);
+ if (!nms_ifcfg_rh_writer_write_connection (new_connection ?: NM_CONNECTION (connection),
+ IFCFG_DIR,
+ filename,
+ &ifcfg_path,
+ &reread,
+ &reread_same,
+ error))
+ return FALSE;
+
+ nm_assert ((!filename && ifcfg_path) || (filename && !ifcfg_path));
+ if (ifcfg_path) {
+ nm_settings_connection_set_filename (connection, ifcfg_path);
+ operation_message = "persist";
+ } else
+ operation_message = "update";
+
+ if (reread && !reread_same)
+ *out_reread_connection = g_steal_pointer (&reread);
+
+ NM_SET_OUT (out_logmsg_change,
+ g_strdup_printf ("ifcfg-rh: %s %s",
+ operation_message, filename));
+ return TRUE;
}
-static void
-do_delete (NMSettingsConnection *connection,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data)
+static gboolean
+delete (NMSettingsConnection *connection,
+ GError **error)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) connection);
const char *filename;
@@ -390,7 +367,7 @@ do_delete (NMSettingsConnection *connection,
g_unlink (priv->route6file);
}
- NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data);
+ return TRUE;
}
/*****************************************************************************/
@@ -529,8 +506,7 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
object_class->get_property = get_property;
object_class->dispose = dispose;
- settings_class->delete = do_delete;
- settings_class->replace_and_commit = replace_and_commit;
+ settings_class->delete = delete;
settings_class->commit_changes = commit_changes;
obj_properties[PROP_UNMANAGED_SPEC] =
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index f51a760d9c..1b69ab49d5 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -683,11 +683,11 @@ add_connection (NMSettingsPlugin *config,
/* Ensure we reject attempts to add the connection long before we're
* asked to write it to disk.
*/
- if (!writer_can_write_connection (connection, error))
+ if (!nms_ifcfg_rh_writer_can_write_connection (connection, error))
return NULL;
if (save_to_disk) {
- if (!writer_new_connection (connection, IFCFG_DIR, &path, NULL, NULL, error))
+ if (!nms_ifcfg_rh_writer_write_connection (connection, IFCFG_DIR, NULL, &path, NULL, NULL, error))
return NULL;
}
return NM_SETTINGS_CONNECTION (update_connection (self, connection, path, NULL, FALSE, NULL, error));
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index fcc0d6313b..9dca4fb83f 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -1175,6 +1175,7 @@ make_proxy_setting (shvarFile *ifcfg, GError **error)
static NMSetting *
make_ip4_setting (shvarFile *ifcfg,
const char *network_file,
+ gboolean routes_read,
gboolean *out_has_defroute,
GError **error)
{
@@ -1196,6 +1197,7 @@ make_ip4_setting (shvarFile *ifcfg,
gint priority;
char inet_buf[NM_UTILS_INET_ADDRSTRLEN];
const char *const *item;
+ guint32 route_table;
nm_assert (out_has_defroute && !*out_has_defroute);
@@ -1281,6 +1283,15 @@ make_ip4_setting (shvarFile *ifcfg,
return NULL;
}
+ /* the route table (policy routing) is ignored if we don't handle routes. */
+ route_table = svGetValueInt64 (ifcfg, "IPV4_ROUTE_TABLE", 10,
+ 0, G_MAXUINT32, 0);
+ if ( route_table != 0
+ && !routes_read) {
+ PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV4_ROUTE_TABLE) is ignored");
+ route_table = 0;
+ }
+
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, method,
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "PEERDNS", TRUE),
@@ -1289,8 +1300,7 @@ make_ip4_setting (shvarFile *ifcfg,
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", FALSE),
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10,
-1, G_MAXUINT32, -1),
- NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) svGetValueInt64 (ifcfg, "IPV4_ROUTE_TABLE", 10,
- 0, G_MAXUINT32, 0),
+ NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table,
NULL);
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
@@ -1326,7 +1336,7 @@ make_ip4_setting (shvarFile *ifcfg,
* added to the automatic ones. Note that this is not currently supported by
* the legacy 'network' service (ifup-eth).
*/
- for (i = -1; i < 256; i++) {
+ for (i = -1;; i++) {
NMIPAddress *addr = NULL;
/* gateway will only be set if still unset. Hence, we don't leak gateway
@@ -1424,13 +1434,13 @@ make_ip4_setting (shvarFile *ifcfg,
/* Static routes - route-<name> file */
route_path = utils_get_route_path (svFileGetName (ifcfg));
- if (utils_has_complex_routes (route_path)) {
- PARSE_WARNING ("'rule-' or 'rule6-' file is present; you will need to use a dispatcher script to apply these routes");
+ if (!routes_read) {
+ /* NOP */
} else if (utils_has_route_file_new_syntax (route_path)) {
/* Parse route file in new syntax */
route_ifcfg = utils_get_route_ifcfg (svFileGetName (ifcfg), FALSE);
if (route_ifcfg) {
- for (i = 0; i < 256; i++) {
+ for (i = 0;; i++) {
NMIPRoute *route = NULL;
if (!read_one_ip4_route (route_ifcfg, i, &route, error)) {
@@ -1591,6 +1601,7 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file
static NMSetting *
make_ip6_setting (shvarFile *ifcfg,
const char *network_file,
+ gboolean routes_read,
GError **error)
{
NMSettingIPConfig *s_ip6 = NULL;
@@ -1612,6 +1623,7 @@ make_ip6_setting (shvarFile *ifcfg,
gboolean never_default = FALSE;
gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip;
NMSettingIP6ConfigPrivacy ip6_privacy_val;
+ guint32 route_table;
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
@@ -1713,6 +1725,15 @@ make_ip6_setting (shvarFile *ifcfg,
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
g_free (str_value);
+ /* the route table (policy routing) is ignored if we don't handle routes. */
+ route_table = svGetValueInt64 (ifcfg, "IPV6_ROUTE_TABLE", 10,
+ 0, G_MAXUINT32, 0);
+ if ( route_table != 0
+ && !routes_read) {
+ PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV6_ROUTE_TABLE) is ignored");
+ route_table = 0;
+ }
+
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, method,
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "IPV6_PEERDNS", TRUE),
@@ -1721,8 +1742,7 @@ make_ip6_setting (shvarFile *ifcfg,
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10,
-1, G_MAXUINT32, -1),
- NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) svGetValueInt64 (ifcfg, "IPV6_ROUTE_TABLE", 10,
- 0, G_MAXUINT32, 0),
+ NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table,
NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val,
NULL);
@@ -1847,12 +1867,13 @@ make_ip6_setting (shvarFile *ifcfg,
/* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */
- if (!utils_has_complex_routes (svFileGetName (ifcfg))) {
+ if (!routes_read) {
+ /* NOP */
+ } else {
/* Read static routes from route6-<interface> file */
route6_path = utils_get_route6_path (svFileGetName (ifcfg));
if (!read_route_file (AF_INET6, route6_path, s_ip6, error))
goto error;
-
g_free (route6_path);
}
@@ -5158,6 +5179,8 @@ connection_from_file_full (const char *filename,
NMSetting *s_ip4, *s_ip6, *s_proxy, *s_port, *s_dcb = NULL, *s_user;
const char *ifcfg_name = NULL;
gboolean has_ip4_defroute = FALSE;
+ gboolean has_complex_routes_v4;
+ gboolean has_complex_routes_v6;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (out_unhandled && !*out_unhandled, NULL);
@@ -5369,13 +5392,32 @@ connection_from_file_full (const char *filename,
if (!connection)
return NULL;
- s_ip6 = make_ip6_setting (parsed, network_file, error);
+ has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET);
+ has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6);
+
+ if (has_complex_routes_v4 || has_complex_routes_v6) {
+ if (has_complex_routes_v4 && !has_complex_routes_v6)
+ PARSE_WARNING ("'rule-' file is present; you will need to use a dispatcher script to apply these routes");
+ else if (has_complex_routes_v6 && !has_complex_routes_v4)
+ PARSE_WARNING ("'rule6-' file is present; you will need to use a dispatcher script to apply these routes");
+ else
+ PARSE_WARNING ("'rule-' and 'rule6-' files are present; you will need to use a dispatcher script to apply these routes");
+ }
+
+ s_ip6 = make_ip6_setting (parsed,
+ network_file,
+ !has_complex_routes_v4 && !has_complex_routes_v6,
+ error);
if (!s_ip6)
return NULL;
else
nm_connection_add_setting (connection, s_ip6);
- s_ip4 = make_ip4_setting (parsed, network_file, &has_ip4_defroute, error);
+ s_ip4 = make_ip4_setting (parsed,
+ network_file,
+ !has_complex_routes_v4 && !has_complex_routes_v6,
+ &has_ip4_defroute,
+ error);
if (!s_ip4)
return NULL;
else {
@@ -5433,11 +5475,11 @@ connection_from_file (const char *filename,
}
NMConnection *
-connection_from_file_test (const char *filename,
- const char *network_file,
- const char *test_type,
- char **out_unhandled,
- GError **error)
+nmtst_connection_from_file (const char *filename,
+ const char *network_file,
+ const char *test_type,
+ char **out_unhandled,
+ GError **error)
{
return connection_from_file_full (filename,
network_file,
@@ -5451,7 +5493,6 @@ guint
devtimeout_from_file (const char *filename)
{
shvarFile *ifcfg;
- char *devtimeout_str;
guint devtimeout;
g_return_val_if_fail (filename != NULL, 0);
@@ -5460,14 +5501,7 @@ devtimeout_from_file (const char *filename)
if (!ifcfg)
return 0;
- devtimeout_str = svGetValueStr_cp (ifcfg, "DEVTIMEOUT");
- if (devtimeout_str) {
- devtimeout = _nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0);
- g_free (devtimeout_str);
- } else
- devtimeout = 0;
-
+ devtimeout = svGetValueInt64 (ifcfg, "DEVTIMEOUT", 10, 0, G_MAXUINT, 0);
svCloseFile (ifcfg);
-
return devtimeout;
}
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
index 4c519a0835..a8937ac868 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
@@ -30,11 +30,10 @@ NMConnection *connection_from_file (const char *filename,
guint devtimeout_from_file (const char *filename);
-/* for test-ifcfg-rh */
-NMConnection *connection_from_file_test (const char *filename,
- const char *network_file,
- const char *test_type,
- char **out_unhandled,
- GError **error);
+NMConnection *nmtst_connection_from_file (const char *filename,
+ const char *network_file,
+ const char *test_type,
+ char **out_unhandled,
+ GError **error);
#endif /* __READER_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index e82ef60c63..c58169e4c3 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -280,25 +280,22 @@ gone:
}
gboolean
-utils_has_complex_routes (const char *filename)
+utils_has_complex_routes (const char *filename, int addr_family)
{
- char *rules;
+ g_return_val_if_fail (filename, TRUE);
- g_return_val_if_fail (filename != NULL, TRUE);
+ if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) {
+ gs_free char *rules = utils_get_extra_path (filename, RULE_TAG);
- rules = utils_get_extra_path (filename, RULE_TAG);
- if (g_file_test (rules, G_FILE_TEST_EXISTS)) {
- g_free (rules);
- return TRUE;
+ if (g_file_test (rules, G_FILE_TEST_EXISTS))
+ return TRUE;
}
- g_free (rules);
- rules = utils_get_extra_path (filename, RULE6_TAG);
- if (g_file_test (rules, G_FILE_TEST_EXISTS)) {
- g_free (rules);
- return TRUE;
+ if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) {
+ gs_free char *rules = utils_get_extra_path (filename, RULE6_TAG);
+ if (g_file_test (rules, G_FILE_TEST_EXISTS))
+ return TRUE;
}
- g_free (rules);
return FALSE;
}
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
index 8e003ccf89..e7abf4d8d7 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
@@ -48,7 +48,7 @@ shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create);
shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create);
gboolean utils_has_route_file_new_syntax (const char *filename);
-gboolean utils_has_complex_routes (const char *filename);
+gboolean utils_has_complex_routes (const char *filename, int addr_family);
gboolean utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg);
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 60db801ccd..68eed84c87 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -108,45 +108,75 @@ save_secret_flags (shvarFile *ifcfg,
static void
set_secret (shvarFile *ifcfg,
+ GHashTable *secrets,
const char *key,
const char *value,
const char *flags_key,
NMSettingSecretFlags flags)
{
- shvarFile *keyfile;
- GError *error = NULL;
-
/* Clear the secret from the ifcfg and the associated "keys" file */
svUnsetValue (ifcfg, key);
/* Save secret flags */
save_secret_flags (ifcfg, flags_key, flags);
+ /* Only write the secret if it's system owned and supposed to be saved */
+ if (flags != NM_SETTING_SECRET_FLAG_NONE)
+ value = NULL;
+
+ g_hash_table_replace (secrets, g_strdup (key), g_strdup (value));
+}
+
+static gboolean
+write_secrets (shvarFile *ifcfg,
+ GHashTable *secrets,
+ GError **error)
+{
+ nm_auto_shvar_file_close shvarFile *keyfile = NULL;
+ gs_free const char **secrets_keys = NULL;
+ guint i, secrets_keys_n;
+ GError *local = NULL;
+ gboolean any_secrets = FALSE;
+
keyfile = utils_get_keys_ifcfg (svFileGetName (ifcfg), TRUE);
if (!keyfile) {
- _LOGW ("could not create ifcfg file for '%s'", svFileGetName (ifcfg));
- goto error;
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Failure to create secrets file for '%s'", svFileGetName (ifcfg));
+ return FALSE;
}
- /* Only write the secret if it's system owned and supposed to be saved */
- if (flags == NM_SETTING_SECRET_FLAG_NONE)
- svSetValueStr (keyfile, key, value);
- else
- svUnsetValue (keyfile, key);
+ /* we purge all existing secrets. */
+ svUnsetAll (keyfile, SV_KEY_TYPE_ANY);
- if (!svWriteFile (keyfile, 0600, &error)) {
- _LOGW ("could not update ifcfg file '%s': %s",
- svFileGetName (keyfile), error->message);
- g_clear_error (&error);
- svCloseFile (keyfile);
- goto error;
+ /* sort the keys. */
+ secrets_keys = (const char **) g_hash_table_get_keys_as_array (secrets, &secrets_keys_n);
+ if (secrets_keys) {
+ g_qsort_with_data (secrets_keys,
+ secrets_keys_n,
+ sizeof (const char *),
+ nm_strcmp_p_with_data,
+ NULL);
}
- svCloseFile (keyfile);
- return;
-error:
- /* Try setting the secret in the actual ifcfg */
- svSetValueStr (ifcfg, key, value);
+ for (i = 0; i < secrets_keys_n; i++) {
+ const char *k = secrets_keys[i];
+ const char *v = g_hash_table_lookup (secrets, k);
+
+ if (v) {
+ svSetValueStr (keyfile, k, v);
+ any_secrets = TRUE;
+ }
+ }
+
+ if (!any_secrets)
+ (void) unlink (svFileGetName (keyfile));
+ else if (!svWriteFile (keyfile, 0600, &local)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Failure to write secrets to '%s': %s", svFileGetName (keyfile), local->message);
+ return FALSE;
+ }
+
+ return TRUE;
}
typedef struct {
@@ -184,6 +214,8 @@ static const Setting8021xSchemeVtable setting_8021x_scheme_vtable[] = {
static gboolean
write_object (NMSetting8021x *s_8021x,
shvarFile *ifcfg,
+ GHashTable *secrets,
+ GHashTable *blobs,
const Setting8021xSchemeVtable *objtype,
GError **error)
{
@@ -222,7 +254,7 @@ write_object (NMSetting8021x *s_8021x,
secret_flags = g_strdup_printf ("%s_PASSWORD_FLAGS", objtype->ifcfg_rh_key);
password = (*(objtype->vtable->passwd_func))(s_8021x);
flags = (*(objtype->vtable->pwflag_func))(s_8021x);
- set_secret (ifcfg, secret_name, password, secret_flags, flags);
+ set_secret (ifcfg, secrets, secret_name, password, secret_flags, flags);
g_free (secret_name);
g_free (secret_flags);
@@ -238,7 +270,6 @@ write_object (NMSetting8021x *s_8021x,
*/
if (!value && !blob) {
char *standard_file;
- int ignored;
/* Since no cert/private key is now being used, delete any standard file
* that was created for this connection, but leave other files alone.
@@ -247,10 +278,7 @@ write_object (NMSetting8021x *s_8021x,
* will be deleted, but /etc/pki/tls/cert.pem will not.
*/
standard_file = utils_cert_path (svFileGetName (ifcfg), objtype->vtable->file_suffix, extension);
- if (g_file_test (standard_file, G_FILE_TEST_EXISTS))
- ignored = unlink (standard_file);
- g_free (standard_file);
-
+ g_hash_table_replace (blobs, standard_file, NULL);
svUnsetValue (ifcfg, objtype->ifcfg_rh_key);
return TRUE;
}
@@ -265,46 +293,60 @@ write_object (NMSetting8021x *s_8021x,
/* If it's raw certificate data, write the data out to the standard file */
if (blob) {
- gboolean success;
char *new_file;
- GError *write_error = NULL;
new_file = utils_cert_path (svFileGetName (ifcfg), objtype->vtable->file_suffix, extension);
- if (!new_file) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Could not create file path for %s / %s",
- NM_SETTING_802_1X_SETTING_NAME, objtype->vtable->setting_key);
- return FALSE;
+ g_hash_table_replace (blobs, new_file, g_bytes_ref (blob));
+ svSetValueStr (ifcfg, objtype->ifcfg_rh_key, new_file);
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+write_blobs (GHashTable *blobs, GError **error)
+{
+ GHashTableIter iter;
+ const char *filename;
+ GBytes *blob;
+
+ if (!blobs)
+ return TRUE;
+
+ g_hash_table_iter_init (&iter, blobs);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &filename, (gpointer *) &blob)) {
+ GError *write_error = NULL;
+
+ if (!blob) {
+ (void) unlink (filename);
+ continue;
}
/* Write the raw certificate data out to the standard file so that we
* can use paths from now on instead of pushing around the certificate
* data itself.
*/
- success = nm_utils_file_set_contents (new_file,
- (const char *) g_bytes_get_data (blob, NULL),
- g_bytes_get_size (blob),
- 0600,
- &write_error);
- if (success) {
- svSetValueStr (ifcfg, objtype->ifcfg_rh_key, new_file);
- g_free (new_file);
- return TRUE;
- } else {
+ if (!nm_utils_file_set_contents (filename,
+ (const char *) g_bytes_get_data (blob, NULL),
+ g_bytes_get_size (blob),
+ 0600,
+ &write_error)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Could not write certificate/key for %s / %s: %s",
- NM_SETTING_802_1X_SETTING_NAME, objtype->vtable->setting_key,
- (write_error && write_error->message) ? write_error->message : "(unknown)");
- g_clear_error (&write_error);
+ "Could not write certificate to file \"%s\": %s",
+ filename,
+ write_error->message);
+ return FALSE;
}
- g_free (new_file);
}
- return FALSE;
+ return TRUE;
}
static gboolean
write_8021x_certs (NMSetting8021x *s_8021x,
+ GHashTable *secrets,
+ GHashTable *blobs,
gboolean phase2,
shvarFile *ifcfg,
GError **error)
@@ -312,7 +354,7 @@ write_8021x_certs (NMSetting8021x *s_8021x,
const Setting8021xSchemeVtable *otype = NULL;
/* CA certificate */
- if (!write_object (s_8021x, ifcfg,
+ if (!write_object (s_8021x, ifcfg, secrets, blobs,
phase2
? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT]
: &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT],
@@ -326,7 +368,7 @@ write_8021x_certs (NMSetting8021x *s_8021x,
otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY];
/* Save the private key */
- if (!write_object (s_8021x, ifcfg, otype, error))
+ if (!write_object (s_8021x, ifcfg, secrets, blobs, otype, error))
return FALSE;
/* Client certificate */
@@ -339,7 +381,7 @@ write_8021x_certs (NMSetting8021x *s_8021x,
NULL);
} else {
/* Save the client certificate */
- if (!write_object (s_8021x, ifcfg,
+ if (!write_object (s_8021x, ifcfg, secrets, blobs,
phase2
? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT]
: &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT],
@@ -353,6 +395,8 @@ write_8021x_certs (NMSetting8021x *s_8021x,
static gboolean
write_8021x_setting (NMConnection *connection,
shvarFile *ifcfg,
+ GHashTable *secrets,
+ GHashTable *blobs,
gboolean wired,
GError **error)
{
@@ -393,6 +437,7 @@ write_8021x_setting (NMConnection *connection,
nm_setting_802_1x_get_anonymous_identity (s_8021x));
set_secret (ifcfg,
+ secrets,
"IEEE_8021X_PASSWORD",
nm_setting_802_1x_get_password (s_8021x),
"IEEE_8021X_PASSWORD_FLAGS",
@@ -506,11 +551,11 @@ write_8021x_setting (NMConnection *connection,
else
svUnsetValue (ifcfg, "IEEE_8021X_AUTH_TIMEOUT");
- if (!write_8021x_certs (s_8021x, FALSE, ifcfg, error))
+ if (!write_8021x_certs (s_8021x, secrets, blobs, FALSE, ifcfg, error))
return FALSE;
/* phase2/inner certs */
- if (!write_8021x_certs (s_8021x, TRUE, ifcfg, error))
+ if (!write_8021x_certs (s_8021x, secrets, blobs, TRUE, ifcfg, error))
return FALSE;
return TRUE;
@@ -519,6 +564,7 @@ write_8021x_setting (NMConnection *connection,
static gboolean
write_wireless_security_setting (NMConnection *connection,
shvarFile *ifcfg,
+ GHashTable *secrets,
gboolean adhoc,
gboolean *no_8021x,
GError **error)
@@ -573,6 +619,7 @@ write_wireless_security_setting (NMConnection *connection,
svSetValueStr (ifcfg, "IEEE_8021X_IDENTITY",
nm_setting_wireless_security_get_leap_username (s_wsec));
set_secret (ifcfg,
+ secrets,
"IEEE_8021X_PASSWORD",
nm_setting_wireless_security_get_leap_password (s_wsec),
"IEEE_8021X_PASSWORD_FLAGS",
@@ -591,17 +638,17 @@ write_wireless_security_setting (NMConnection *connection,
/* WEP keys */
/* Clear any default key */
- set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
/* Clear existing keys */
for (i = 0; i < 4; i++) {
char tag[64];
numbered_tag (tag, "KEY_PASSPHRASE", i + 1);
- set_secret (ifcfg, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
numbered_tag (tag, "KEY", i + 1);
- set_secret (ifcfg, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
}
/* And write the new ones out */
@@ -647,6 +694,7 @@ write_wireless_security_setting (NMConnection *connection,
if (key_valid) {
set_secret (ifcfg,
+ secrets,
tag,
key,
"WEP_KEY_FLAGS",
@@ -710,6 +758,7 @@ write_wireless_security_setting (NMConnection *connection,
psk = nm_setting_wireless_security_get_psk (s_wsec);
set_secret (ifcfg,
+ secrets,
"WPA_PSK",
psk,
"WPA_PSK_FLAGS",
@@ -729,6 +778,7 @@ write_wireless_security_setting (NMConnection *connection,
static gboolean
write_wireless_setting (NMConnection *connection,
shvarFile *ifcfg,
+ GHashTable *secrets,
gboolean *no_8021x,
GError **error)
{
@@ -862,27 +912,25 @@ write_wireless_setting (NMConnection *connection,
svUnsetValue (ifcfg, "SECURITYMODE");
if (nm_connection_get_setting_wireless_security (connection)) {
- if (!write_wireless_security_setting (connection, ifcfg, adhoc, no_8021x, error))
+ if (!write_wireless_security_setting (connection, ifcfg, secrets, adhoc, no_8021x, error))
return FALSE;
} else {
- char *keys_path;
-
/* Clear out wifi security keys */
svUnsetValue (ifcfg, "KEY_MGMT");
svUnsetValue (ifcfg, "IEEE_8021X_IDENTITY");
- set_secret (ifcfg, "IEEE_8021X_PASSWORD", NULL, "IEEE_8021X_PASSWORD_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, "IEEE_8021X_PASSWORD", NULL, "IEEE_8021X_PASSWORD_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
svUnsetValue (ifcfg, "SECURITYMODE");
/* Clear existing keys */
- set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
for (i = 0; i < 4; i++) {
char tag[64];
numbered_tag (tag, "KEY_PASSPHRASE", i + 1);
- set_secret (ifcfg, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
numbered_tag (tag, "KEY", i + 1);
- set_secret (ifcfg, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
+ set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
}
svUnsetValue (ifcfg, "DEFAULTKEY");
@@ -890,12 +938,7 @@ write_wireless_setting (NMConnection *connection,
svUnsetValue (ifcfg, "WPA_ALLOW_WPA2");
svUnsetValue (ifcfg, "CIPHER_PAIRWISE");
svUnsetValue (ifcfg, "CIPHER_GROUP");
- set_secret (ifcfg, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
-
- /* Kill any old keys file */
- keys_path = utils_get_keys_path (svFileGetName (ifcfg));
- (void) unlink (keys_path);
- g_free (keys_path);
+ set_secret (ifcfg, secrets, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE);
}
svSetValueStr (ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden (s_wireless) ? "yes" : NULL);
@@ -1886,35 +1929,86 @@ get_route_attributes_string (NMIPRoute *route, int family)
return g_string_free (str, FALSE);
}
-static gboolean
-write_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError **error)
+static shvarFile *
+write_route_file_svformat (const char *filename, NMSettingIPConfig *s_ip4)
{
- nm_auto_free_gstring GString *contents = NULL;
- NMIPRoute *route;
- guint32 i, num;
+ shvarFile *routefile;
+ guint i, num;
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (s_ip4 != NULL, FALSE);
- g_return_val_if_fail (error != NULL, FALSE);
- g_return_val_if_fail (*error == NULL, FALSE);
+ routefile = utils_get_route_ifcfg (filename, TRUE);
+
+ svUnsetAll (routefile, SV_KEY_TYPE_ROUTE_SVFORMAT);
num = nm_setting_ip_config_get_num_routes (s_ip4);
- if (num == 0) {
- unlink (filename);
- return TRUE;
+ for (i = 0; i < num; i++) {
+ char buf[INET_ADDRSTRLEN];
+ NMIPRoute *route;
+ guint32 netmask;
+ gint64 metric;
+ char addr_key[64];
+ char gw_key[64];
+ char netmask_key[64];
+ char metric_key[64];
+ char options_key[64];
+ gs_free char *options = NULL;
+
+ numbered_tag (addr_key, "ADDRESS", i);
+ numbered_tag (netmask_key, "NETMASK", i);
+ numbered_tag (gw_key, "GATEWAY", i);
+
+ route = nm_setting_ip_config_get_route (s_ip4, i);
+
+ svSetValueStr (routefile, addr_key, nm_ip_route_get_dest (route));
+
+ netmask = _nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route));
+ svSetValueStr (routefile, netmask_key,
+ nm_utils_inet4_ntop (netmask, buf));
+
+ svSetValueStr (routefile, gw_key, nm_ip_route_get_next_hop (route));
+
+ metric = nm_ip_route_get_metric (route);
+ if (metric != -1) {
+ svSetValueInt64 (routefile,
+ numbered_tag (metric_key, "METRIC", i),
+ metric);
+ }
+
+ options = get_route_attributes_string (route, AF_INET);
+ if (options) {
+ svSetValueStr (routefile,
+ numbered_tag (options_key, "OPTIONS", i),
+ options);
+ }
}
+ return routefile;
+}
+
+static GString *
+write_route_file (NMSettingIPConfig *s_ip)
+{
+ GString *contents;
+ NMIPRoute *route;
+ guint32 i, num;
+ int addr_family;
+
+ addr_family = nm_setting_ip_config_get_addr_family (s_ip);
+
+ num = nm_setting_ip_config_get_num_routes (s_ip);
+ if (num == 0)
+ return NULL;
+
contents = g_string_new ("");
for (i = 0; i < num; i++) {
- const char *next_hop;
gs_free char *options = NULL;
+ const char *next_hop;
gint64 metric;
- route = nm_setting_ip_config_get_route (s_ip4, i);
+ route = nm_setting_ip_config_get_route (s_ip, i);
next_hop = nm_ip_route_get_next_hop (route);
metric = nm_ip_route_get_metric (route);
- options = get_route_attributes_string (route, AF_INET);
+ options = get_route_attributes_string (route, addr_family);
g_string_append_printf (contents, "%s/%u",
nm_ip_route_get_dest (route),
@@ -1931,13 +2025,7 @@ write_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError
g_string_append_c (contents, '\n');
}
- if (!g_file_set_contents (filename, contents->str, contents->len, NULL)) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Writing route file '%s' failed", filename);
- return FALSE;
- }
-
- return TRUE;
+ return contents;
}
static gboolean
@@ -1988,7 +2076,7 @@ write_user_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
s_user = NM_SETTING_USER (nm_connection_get_setting (connection, NM_TYPE_SETTING_USER));
- svUnsetValuesWithPrefix (ifcfg, "NM_USER_");
+ svUnsetAll (ifcfg, SV_KEY_TYPE_USER);
if (!s_user)
return TRUE;
@@ -2013,13 +2101,16 @@ write_user_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
}
static gboolean
-write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+write_ip4_setting (NMConnection *connection,
+ shvarFile *ifcfg,
+ shvarFile **out_route_content_svformat,
+ GString **out_route_content,
+ GError **error)
{
NMSettingIPConfig *s_ip4;
const char *value;
char *tmp;
char tag[64];
- char *route_path = NULL;
gint j;
guint i, num, n;
gint64 route_metric;
@@ -2030,6 +2121,9 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
const char *method = NULL;
gboolean has_netmask;
+ NM_SET_OUT (out_route_content_svformat, NULL);
+ NM_SET_OUT (out_route_content, NULL);
+
s_ip4 = nm_connection_get_setting_ip4_config (connection);
if (!s_ip4) {
/* slave-type: clear IPv4 settings.
@@ -2037,13 +2131,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
* Some IPv4 setting related options are not cleared,
* for no strong reason. */
svUnsetValue (ifcfg, "BOOTPROTO");
-
- for (j = -1; j < 256; j++) {
- svUnsetValue (ifcfg, numbered_tag (tag, "IPADDR", j));
- svUnsetValue (ifcfg, numbered_tag (tag, "PREFIX", j));
- svUnsetValue (ifcfg, numbered_tag (tag, "NETMASK", j));
- svUnsetValue (ifcfg, numbered_tag (tag, "GATEWAY", j));
- }
+ svUnsetAll (ifcfg, SV_KEY_TYPE_IP4_ADDRESS);
return TRUE;
}
@@ -2054,8 +2142,6 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
- int result;
-
/* IPv4 disabled, clear IPv4 related parameters */
svUnsetValue (ifcfg, "BOOTPROTO");
for (j = -1; j < 256; j++) {
@@ -2064,10 +2150,6 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
svUnsetValue (ifcfg, numbered_tag (tag, "NETMASK", j));
svUnsetValue (ifcfg, numbered_tag (tag, "GATEWAY", j));
}
-
- route_path = utils_get_route_path (svFileGetName (ifcfg));
- result = unlink (route_path);
- g_free (route_path);
return TRUE;
}
@@ -2207,16 +2289,18 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
svSetValueStr (ifcfg, "DHCP_CLIENT_ID", value);
timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip4);
- tmp = timeout ? g_strdup_printf ("%d", timeout) : NULL;
- svSetValueStr (ifcfg, "IPV4_DHCP_TIMEOUT", tmp);
- g_free (tmp);
+ svSetValueInt64_cond (ifcfg,
+ "IPV4_DHCP_TIMEOUT",
+ timeout != 0,
+ timeout);
svSetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", !nm_setting_ip_config_get_may_fail (s_ip4));
route_metric = nm_setting_ip_config_get_route_metric (s_ip4);
- tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL;
- svSetValueStr (ifcfg, "IPV4_ROUTE_METRIC", tmp);
- g_free (tmp);
+ svSetValueInt64_cond (ifcfg,
+ "IPV4_ROUTE_METRIC",
+ route_metric != -1,
+ route_metric);
route_table = nm_setting_ip_config_get_route_table (s_ip4);
svSetValueInt64_cond (ifcfg,
@@ -2224,87 +2308,8 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
route_table != 0,
route_table);
- /* Static routes - route-<name> file */
- route_path = utils_get_route_path (svFileGetName (ifcfg));
- if (!route_path) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Could not get route file path for '%s'", svFileGetName (ifcfg));
- return FALSE;
- }
-
- if (utils_has_route_file_new_syntax (route_path)) {
- shvarFile *routefile;
-
- routefile = utils_get_route_ifcfg (svFileGetName (ifcfg), TRUE);
- if (!routefile) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Could not create route file '%s'", route_path);
- g_free (route_path);
- return FALSE;
- }
- g_free (route_path);
-
- num = nm_setting_ip_config_get_num_routes (s_ip4);
- for (i = 0; i < 256; i++) {
- char buf[INET_ADDRSTRLEN];
- NMIPRoute *route;
- guint32 netmask;
- gint64 metric;
- char addr_key[64];
- char gw_key[64];
- char netmask_key[64];
- char metric_key[64];
- char options_key[64];
-
- numbered_tag (addr_key, "ADDRESS", i);
- numbered_tag (netmask_key, "NETMASK", i);
- numbered_tag (gw_key, "GATEWAY", i);
- numbered_tag (metric_key, "METRIC", i);
- numbered_tag (options_key, "OPTIONS", i);
-
- if (i >= num) {
- svUnsetValue (routefile, addr_key);
- svUnsetValue (routefile, netmask_key);
- svUnsetValue (routefile, gw_key);
- svUnsetValue (routefile, metric_key);
- svUnsetValue (routefile, options_key);
- } else {
- gs_free char *options = NULL;
-
- route = nm_setting_ip_config_get_route (s_ip4, i);
-
- svSetValueStr (routefile, addr_key, nm_ip_route_get_dest (route));
-
- memset (buf, 0, sizeof (buf));
- netmask = _nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route));
- inet_ntop (AF_INET, (const void *) &netmask, &buf[0], sizeof (buf));
- svSetValueStr (routefile, netmask_key, &buf[0]);
-
- svSetValueStr (routefile, gw_key, nm_ip_route_get_next_hop (route));
-
- memset (buf, 0, sizeof (buf));
- metric = nm_ip_route_get_metric (route);
- if (metric == -1)
- svUnsetValue (routefile, metric_key);
- else
- svSetValueInt64 (routefile, metric_key, (guint32) metric);
-
- options = get_route_attributes_string (route, AF_INET);
- if (options)
- svSetValueStr (routefile, options_key, options);
- }
- }
- if (!svWriteFile (routefile, 0644, error)) {
- svCloseFile (routefile);
- return FALSE;
- }
- svCloseFile (routefile);
- } else {
- write_route_file_legacy (route_path, s_ip4, error);
- g_free (route_path);
- if (error && *error)
- return FALSE;
- }
+ NM_SET_OUT (out_route_content_svformat, write_route_file_svformat (svFileGetName (ifcfg), s_ip4));
+ NM_SET_OUT (out_route_content, write_route_file (s_ip4));
timeout = nm_setting_ip_config_get_dad_timeout (s_ip4);
if (timeout < 0)
@@ -2409,59 +2414,6 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
}
}
-static gboolean
-write_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error)
-{
- nm_auto_free_gstring GString *contents = NULL;
- NMIPRoute *route;
- guint32 i, num;
-
- g_return_val_if_fail (filename, FALSE);
- g_return_val_if_fail (s_ip6, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- num = nm_setting_ip_config_get_num_routes (s_ip6);
- if (num == 0) {
- unlink (filename);
- return TRUE;
- }
-
- contents = g_string_new ("");
-
- for (i = 0; i < num; i++) {
- gs_free char *options = NULL;
- const char *next_hop;
- gint64 metric;
-
- route = nm_setting_ip_config_get_route (s_ip6, i);
- next_hop = nm_ip_route_get_next_hop (route);
- metric = nm_ip_route_get_metric (route);
- options = get_route_attributes_string (route, AF_INET6);
-
- g_string_append_printf (contents, "%s/%u",
- nm_ip_route_get_dest (route),
- nm_ip_route_get_prefix (route));
- if (next_hop)
- g_string_append_printf (contents, " via %s", next_hop);
- if (metric >= 0)
- g_string_append_printf (contents, " metric %u", (guint) metric);
- if (options) {
- g_string_append_c (contents, ' ');
- g_string_append (contents, options);
- }
-
- g_string_append_c (contents, '\n');
- }
-
- if (!g_file_set_contents (filename, contents->str, contents->len, NULL)) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Writing route6 file '%s' failed", filename);
- return FALSE;
- }
-
- return TRUE;
-}
-
static void
write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg)
{
@@ -2480,12 +2432,14 @@ write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg)
}
static gboolean
-write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+write_ip6_setting (NMConnection *connection,
+ shvarFile *ifcfg,
+ GString **out_route6_content,
+ GError **error)
{
NMSettingIPConfig *s_ip6;
NMSettingIPConfig *s_ip4;
const char *value;
- char *tmp;
guint i, num, num4;
gint priority;
NMIPAddress *addr;
@@ -2493,9 +2447,10 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
gint64 route_metric;
NMIPRouteTableSyncMode route_table;
GString *ip_str1, *ip_str2, *ip_ptr;
- char *route6_path;
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+ NM_SET_OUT (out_route6_content, NULL);
+
s_ip6 = nm_connection_get_setting_ip6_config (connection);
if (!s_ip6) {
/* slave-type: clear IPv6 settings
@@ -2620,9 +2575,10 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
nm_setting_ip_config_get_may_fail (s_ip6) ? "no" : "yes");
route_metric = nm_setting_ip_config_get_route_metric (s_ip6);
- tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL;
- svSetValueStr (ifcfg, "IPV6_ROUTE_METRIC", tmp);
- g_free (tmp);
+ svSetValueInt64_cond (ifcfg,
+ "IPV6_ROUTE_METRIC",
+ route_metric != -1,
+ route_metric);
route_table = nm_setting_ip_config_get_route_table (s_ip6);
svSetValueInt64_cond (ifcfg,
@@ -2667,17 +2623,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
else
svUnsetValue (ifcfg, "IPV6_DNS_PRIORITY");
- /* Static routes go to route6-<dev> file */
- route6_path = utils_get_route6_path (svFileGetName (ifcfg));
- if (!route6_path) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Could not get route6 file path for '%s'", svFileGetName (ifcfg));
- return FALSE;
- }
- write_route6_file (route6_path, s_ip6, error);
- g_free (route6_path);
- if (error && *error)
- return FALSE;
+ NM_SET_OUT (out_route6_content, write_route_file (s_ip6));
return TRUE;
}
@@ -2759,14 +2705,14 @@ escape_id (const char *id)
return escaped;
}
-static gboolean
-write_connection (NMConnection *connection,
- const char *ifcfg_dir,
- const char *filename,
- char **out_filename,
- NMConnection **out_reread,
- gboolean *out_reread_same,
- GError **error)
+gboolean
+nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ const char *filename,
+ char **out_filename,
+ NMConnection **out_reread,
+ gboolean *out_reread_same,
+ GError **error)
{
NMSettingConnection *s_con;
nm_auto_shvar_file_close shvarFile *ifcfg = NULL;
@@ -2774,12 +2720,23 @@ write_connection (NMConnection *connection,
const char *type;
gboolean no_8021x = FALSE;
gboolean wired = FALSE;
+ gboolean route_path_is_svformat;
+ gs_free char *route_path = NULL;
+ gs_free char *route6_path = NULL;
+ nm_auto_free_gstring GString *route_content = NULL;
+ gboolean route_ignore = FALSE;
+ gboolean has_complex_routes_v4;
+ gboolean has_complex_routes_v6;
+ nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL;
+ nm_auto_free_gstring GString *route6_content = NULL;
+ gs_unref_hashtable GHashTable *secrets = NULL;
+ gs_unref_hashtable GHashTable *blobs = NULL;
nm_assert (NM_IS_CONNECTION (connection));
nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
nm_assert (!out_reread || !*out_reread);
- if (!writer_can_write_connection (connection, error))
+ if (!nms_ifcfg_rh_writer_can_write_connection (connection, error))
return FALSE;
s_con = nm_connection_get_setting_connection (connection);
@@ -2825,6 +2782,20 @@ write_connection (NMConnection *connection,
ifcfg = svCreateFile (ifcfg_name);
}
+ route_path = utils_get_route_path (svFileGetName (ifcfg));
+ if (!route_path) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Could not get route file path for '%s'", svFileGetName (ifcfg));
+ return FALSE;
+ }
+
+ route6_path = utils_get_route6_path (svFileGetName (ifcfg));
+ if (!route6_path) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Could not get route6 file path for '%s'", svFileGetName (ifcfg));
+ return FALSE;
+ }
+
type = nm_setting_connection_get_connection_type (s_con);
if (!type) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
@@ -2832,6 +2803,8 @@ write_connection (NMConnection *connection,
return FALSE;
}
+ secrets = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
+
if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
// FIXME: can't write PPPoE at this time
if (nm_connection_get_setting_pppoe (connection)) {
@@ -2848,7 +2821,7 @@ write_connection (NMConnection *connection,
if (!write_vlan_setting (connection, ifcfg, &wired, error))
return FALSE;
} else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) {
- if (!write_wireless_setting (connection, ifcfg, &no_8021x, error))
+ if (!write_wireless_setting (connection, ifcfg, secrets, &no_8021x, error))
return FALSE;
} else if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
if (!write_infiniband_setting (connection, ifcfg, error))
@@ -2869,7 +2842,8 @@ write_connection (NMConnection *connection,
}
if (!no_8021x) {
- if (!write_8021x_setting (connection, ifcfg, wired, error))
+ blobs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_bytes_unref);
+ if (!write_8021x_setting (connection, ifcfg, secrets, blobs, wired, error))
return FALSE;
}
@@ -2891,11 +2865,48 @@ write_connection (NMConnection *connection,
svUnsetValue (ifcfg, "DHCP_HOSTNAME");
svUnsetValue (ifcfg, "DHCP_FQDN");
- if (!write_ip4_setting (connection, ifcfg, error))
+ route_path_is_svformat = utils_has_route_file_new_syntax (route_path);
+
+ has_complex_routes_v4 = utils_has_complex_routes (ifcfg_name, AF_INET);
+ has_complex_routes_v6 = utils_has_complex_routes (ifcfg_name, AF_INET6);
+
+ if (has_complex_routes_v4 || has_complex_routes_v6) {
+ NMSettingIPConfig *s_ip4, *s_ip6;
+
+ s_ip4 = nm_connection_get_setting_ip4_config (connection);
+ s_ip6 = nm_connection_get_setting_ip6_config (connection);
+ if ( ( s_ip4
+ && nm_setting_ip_config_get_num_routes (s_ip4) > 0)
+ || ( s_ip6
+ && nm_setting_ip_config_get_num_routes (s_ip6) > 0)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Cannot configure static routes on a connection that has an associated 'rule%s-' file",
+ has_complex_routes_v4 ? "" : "6");
+ return FALSE;
+ }
+ if ( ( s_ip4
+ && nm_setting_ip_config_get_route_table (s_ip4) != 0)
+ || ( s_ip6
+ && nm_setting_ip_config_get_route_table (s_ip6) != 0)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Cannot configure a route table for policy routing on a connection that has an associated 'rule%s-' file",
+ has_complex_routes_v4 ? "" : "6");
+ return FALSE;
+ }
+ route_ignore = TRUE;
+ }
+
+ if (!write_ip4_setting (connection,
+ ifcfg,
+ !route_ignore && route_path_is_svformat ? &route_content_svformat : NULL,
+ !route_ignore && route_path_is_svformat ? NULL :&route_content,
+ error))
return FALSE;
- write_ip4_aliases (connection, ifcfg_name);
- if (!write_ip6_setting (connection, ifcfg, error))
+ if (!write_ip6_setting (connection,
+ ifcfg,
+ !route_ignore ? &route6_content : NULL,
+ error))
return FALSE;
if (!write_res_options (connection, ifcfg, error))
@@ -2903,9 +2914,57 @@ write_connection (NMConnection *connection,
write_connection_setting (s_con, ifcfg);
+ /* From here on, we persist data to disk. Before, it was all in-memory
+ * only. But we loaded the ifcfg files from disk, and managled our
+ * new settings (in-momory). */
+
if (!svWriteFile (ifcfg, 0644, error))
return FALSE;
+ write_ip4_aliases (connection, ifcfg_name);
+
+ if (!write_blobs (blobs, error))
+ return FALSE;
+
+ if (!write_secrets (ifcfg, secrets, error))
+ return FALSE;
+
+ if (!route_ignore) {
+ if (!route_content && !route_content_svformat)
+ (void) unlink (route_path);
+ else {
+ if (route_path_is_svformat) {
+ if (!svWriteFile (route_content_svformat, 0644, error))
+ return FALSE;
+ } else {
+ if (!g_file_set_contents (route_path, route_content->str, route_content->len, NULL)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Writing route file '%s' failed", route_path);
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ if (!route_ignore) {
+ if (!route6_content)
+ (void) unlink (route6_path);
+ else {
+ if (!g_file_set_contents (route6_path, route6_content->str, route6_content->len, NULL)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
+ "Writing route6 file '%s' failed", route6_path);
+ return FALSE;
+ }
+ }
+ }
+
+ /* Note that we just wrote the connection to disk, and re-read it from there.
+ * That is racy if somebody else modifies the connection.
+ *
+ * A better solution might be, to re-read the connection only based on the
+ * in-memory representation of what we collected above. But the reader
+ * does not yet allow to inject the configuration. */
+
if (out_reread || out_reread_same) {
gs_unref_object NMConnection *reread = NULL;
gs_free_error GError *local = NULL;
@@ -2948,7 +3007,7 @@ write_connection (NMConnection *connection,
}
gboolean
-writer_can_write_connection (NMConnection *connection, GError **error)
+nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, GError **error)
{
NMSettingConnection *s_con;
@@ -2972,31 +3031,3 @@ writer_can_write_connection (NMConnection *connection, GError **error)
return FALSE;
}
-gboolean
-writer_new_connection (NMConnection *connection,
- const char *ifcfg_dir,
- char **out_filename,
- NMConnection **out_reread,
- gboolean *out_reread_same,
- GError **error)
-{
- return write_connection (connection, ifcfg_dir, NULL, out_filename, out_reread, out_reread_same, error);
-}
-
-gboolean
-writer_update_connection (NMConnection *connection,
- const char *ifcfg_dir,
- const char *filename,
- NMConnection **out_reread,
- gboolean *out_reread_same,
- GError **error)
-{
- if (utils_has_complex_routes (filename)) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
- "Cannot modify a connection that has an associated 'rule-' or 'rule6-' file");
- return FALSE;
- }
-
- return write_connection (connection, ifcfg_dir, filename, NULL, out_reread, out_reread_same, error);
-}
-
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
index 9cd9513ec2..d7a255a9fd 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
@@ -18,26 +18,20 @@
* Copyright (C) 2009 Red Hat, Inc.
*/
-#ifndef _WRITER_H_
-#define _WRITER_H_
+#ifndef __NMS_IFCFG_RH_WRITER_H__
+#define __NMS_IFCFG_RH_WRITER_H__
#include "nm-connection.h"
-gboolean writer_can_write_connection (NMConnection *connection,
- GError **error);
+gboolean nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection,
+ GError **error);
-gboolean writer_new_connection (NMConnection *connection,
- const char *ifcfg_dir,
- char **out_filename,
- NMConnection **out_reread,
- gboolean *out_reread_same,
- GError **error);
+gboolean nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ const char *filename,
+ char **out_filename,
+ NMConnection **out_reread,
+ gboolean *out_reread_same,
+ GError **error);
-gboolean writer_update_connection (NMConnection *connection,
- const char *ifcfg_dir,
- const char *filename,
- NMConnection **out_reread,
- gboolean *out_reread_same,
- GError **error);
-
-#endif /* _WRITER_H_ */
+#endif /* __NMS_IFCFG_RH_WRITER_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index 911da73a05..df03bf654c 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -794,7 +794,7 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
int errsv = 0;
char *arena;
const char *p, *q;
- GError *local = NULL;
+ gs_free_error GError *local = NULL;
nm_auto_close int fd = -1;
if (create)
@@ -824,11 +824,13 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
&arena,
NULL,
&local) < 0) {
+ if (create)
+ return svFile_new (name);
+
g_set_error (error, G_FILE_ERROR,
local->domain == G_FILE_ERROR ? local->code : G_FILE_ERROR_FAILED,
"Could not read file '%s': %s",
name, local->message);
- g_error_free (local);
return NULL;
}
@@ -1118,6 +1120,71 @@ svGetValueEnum (shvarFile *s, const char *key,
/*****************************************************************************/
+static gboolean
+_is_all_digits (const char *str)
+{
+ return str[0]
+ && NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch));
+}
+
+#define IS_NUMBERED_TAG(key, tab_name) \
+ ({ \
+ const char *_key = (key); \
+ \
+ ( (strncmp (_key, tab_name, NM_STRLEN (tab_name)) == 0) \
+ && _is_all_digits (&_key[NM_STRLEN (tab_name)])); \
+ })
+
+gboolean
+svUnsetAll (shvarFile *s, SvKeyType match_key_type)
+{
+ CList *current;
+ shvarLine *line;
+ gboolean changed = FALSE;
+
+ g_return_val_if_fail (s, FALSE);
+
+ c_list_for_each (current, &s->lst_head) {
+ line = c_list_entry (current, shvarLine, lst);
+ ASSERT_shvarLine (line);
+ if (!line->key)
+ continue;
+
+ if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ANY))
+ goto do_clear;
+ if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) {
+ if ( IS_NUMBERED_TAG (line->key, "ADDRESS")
+ || IS_NUMBERED_TAG (line->key, "NETMASK")
+ || IS_NUMBERED_TAG (line->key, "GATEWAY")
+ || IS_NUMBERED_TAG (line->key, "METRIC")
+ || IS_NUMBERED_TAG (line->key, "OPTIONS"))
+ goto do_clear;
+ }
+ if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) {
+ if ( IS_NUMBERED_TAG (line->key, "IPADDR")
+ || IS_NUMBERED_TAG (line->key, "PREFIX")
+ || IS_NUMBERED_TAG (line->key, "NETMASK")
+ || IS_NUMBERED_TAG (line->key, "GATEWAY"))
+ goto do_clear;
+ }
+ if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) {
+ if (g_str_has_prefix (line->key, "NM_USER_"))
+ goto do_clear;
+ }
+
+ continue;
+do_clear:
+ if (nm_clear_g_free (&line->line)) {
+ ASSERT_shvarLine (line);
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ s->modified = TRUE;
+ return changed;
+}
+
/* Same as svSetValueStr() but it preserves empty @value -- contrary to
* svSetValueStr() for which "" effectively means to remove the value. */
gboolean
@@ -1216,27 +1283,6 @@ svUnsetValue (shvarFile *s, const char *key)
return svSetValue (s, key, NULL);
}
-void
-svUnsetValuesWithPrefix (shvarFile *s, const char *prefix)
-{
- CList *current;
-
- g_return_if_fail (s);
- g_return_if_fail (prefix);
-
- c_list_for_each (current, &s->lst_head) {
- shvarLine *line = c_list_entry (current, shvarLine, lst);
-
- ASSERT_shvarLine (line);
- if ( line->key
- && g_str_has_prefix (line->key, prefix)) {
- if (nm_clear_g_free (&line->line))
- s->modified = TRUE;
- }
- ASSERT_shvarLine (line);
- }
-}
-
/*****************************************************************************/
/* Write the current contents iff modified. Returns FALSE on error
diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h
index 8fbc14808e..c48bbfd331 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.h
+++ b/src/settings/plugins/ifcfg-rh/shvar.h
@@ -86,7 +86,14 @@ gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value);
gboolean svUnsetValue (shvarFile *s, const char *key);
-void svUnsetValuesWithPrefix (shvarFile *s, const char *prefix);
+typedef enum {
+ SV_KEY_TYPE_ANY = (1LL << 0),
+ SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1),
+ SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2),
+ SV_KEY_TYPE_USER = (1LL << 3),
+} SvKeyType;
+
+gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type);
/* Write the current contents iff modified. Returns FALSE on error
* and TRUE on success. Do not write if no values have been modified.
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 3d3b672c6a..3c4d76726f 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -232,7 +232,7 @@ _assert_expected_content (NMConnection *connection, const char *filename, const
g_assert (_ifcfg_dir && _ifcfg_dir[0]); \
g_assert (_filename && _filename[0]); \
\
- _success = writer_update_connection (_connection, _ifcfg_dir, _filename, _out_reread, _out_reread_same, &_error); \
+ _success = nms_ifcfg_rh_writer_write_connection (_connection, _ifcfg_dir, _filename, NULL, _out_reread, _out_reread_same, &_error); \
nmtst_assert_success (_success, _error); \
_assert_expected_content (_connection, _filename, _expected); \
} G_STMT_END
@@ -260,8 +260,8 @@ _connection_from_file (const char *filename,
g_assert (!out_unhandled || !*out_unhandled);
- connection = connection_from_file_test (filename, network_file, test_type,
- out_unhandled ?: &unhandled_fallback, &error);
+ connection = nmtst_connection_from_file (filename, network_file, test_type,
+ out_unhandled ?: &unhandled_fallback, &error);
g_assert_no_error (error);
g_assert (!unhandled_fallback);
@@ -282,7 +282,7 @@ _connection_from_file_fail (const char *filename,
GError *local = NULL;
char *unhandled = NULL;
- connection = connection_from_file_test (filename, network_file, test_type, &unhandled, &local);
+ connection = nmtst_connection_from_file (filename, network_file, test_type, &unhandled, &local);
g_assert (!connection);
g_assert (local);
@@ -310,12 +310,13 @@ _writer_new_connection_reread (NMConnection *connection,
con_verified = nmtst_connection_duplicate_and_normalize (connection);
- success = writer_new_connection (con_verified,
- ifcfg_dir,
- &filename,
- reread,
- out_reread_same,
- &error);
+ success = nms_ifcfg_rh_writer_write_connection (con_verified,
+ ifcfg_dir,
+ NULL,
+ &filename,
+ reread,
+ out_reread_same,
+ &error);
nmtst_assert_success (success, error);
g_assert (filename && filename[0]);
@@ -384,12 +385,13 @@ _writer_new_connection_fail (NMConnection *connection,
connection_normalized = nmtst_connection_duplicate_and_normalize (connection);
- success = writer_new_connection (connection_normalized,
- ifcfg_dir,
- &filename,
- &reread,
- NULL,
- &local);
+ success = nms_ifcfg_rh_writer_write_connection (connection_normalized,
+ ifcfg_dir,
+ NULL,
+ &filename,
+ &reread,
+ NULL,
+ &local);
nmtst_assert_no_success (success, local);
g_assert (!filename);
g_assert (!reread);
diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.c b/src/settings/plugins/ifnet/nms-ifnet-connection.c
index ba87d46c4a..5dbb124c30 100644
--- a/src/settings/plugins/ifnet/nms-ifnet-connection.c
+++ b/src/settings/plugins/ifnet/nms-ifnet-connection.c
@@ -74,89 +74,81 @@ nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection)
return NM_IFNET_CONNECTION_GET_PRIVATE (connection)->conn_name;
}
-static void
+static gboolean
commit_changes (NMSettingsConnection *connection,
+ NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+ NMConnection **out_reread_connection,
+ char **out_logmsg_change,
+ GError **error)
{
- GError *error = NULL;
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
- gchar *new_name = NULL;
+ char *new_name = NULL;
gboolean success = FALSE;
+ gboolean added = FALSE;
+
+ nm_assert (out_reread_connection && !*out_reread_connection);
+ nm_assert (!out_logmsg_change || !*out_logmsg_change);
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (priv->conn_name) {
- /* Existing connection; update it */
success = ifnet_update_parsers_by_connection (NM_CONNECTION (connection),
priv->conn_name,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
- &error);
+ error);
} else {
- /* New connection, add it */
+ added = TRUE;
success = ifnet_add_new_connection (NM_CONNECTION (connection),
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
- &error);
- if (success)
- reload_parsers ();
+ error);
}
+ g_assert (!!success == (new_name != NULL));
if (success) {
- /* update connection name */
- g_assert (new_name);
g_free (priv->conn_name);
priv->conn_name = new_name;
-
- NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, commit_reason, callback, user_data);
- nm_log_info (LOGD_SETTINGS, "Successfully updated %s", priv->conn_name);
- } else {
- nm_log_warn (LOGD_SETTINGS, "Failed to update %s",
- priv->conn_name ? priv->conn_name :
- nm_connection_get_id (NM_CONNECTION (connection)));
- reload_parsers ();
- callback (connection, error, user_data);
- g_error_free (error);
}
+ reload_parsers ();
+
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+
+ if (success) {
+ NM_SET_OUT (out_logmsg_change,
+ g_strdup_printf ("ifcfg-rh: %s %s",
+ added ? "persist" : "updated",
+ new_name));
+ }
+ return success;
}
-static void
-do_delete (NMSettingsConnection *connection,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data)
+static gboolean
+delete (NMSettingsConnection *connection,
+ GError **error)
{
- GError *error = NULL;
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
- g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
-
/* Only connections which exist in /etc/conf.d/net will have a conn_name */
if (priv->conn_name) {
+ g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
+
if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL)) {
nm_log_warn (LOGD_SETTINGS, "Failed to delete %s", priv->conn_name);
reload_parsers ();
- callback (connection, error, user_data);
- g_error_free (error);
- g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
- return;
+ /* let's not return an error. */
}
- }
-
- NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data);
- g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+ g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+ }
- nm_log_info (LOGD_SETTINGS, "Successfully deleted %s",
- priv->conn_name ? priv->conn_name :
- nm_connection_get_id (NM_CONNECTION (connection)));
+ return TRUE;
}
/*****************************************************************************/
@@ -222,7 +214,7 @@ nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class)
object_class->finalize = finalize;
- settings_class->delete = do_delete;
+ settings_class->delete = delete;
settings_class->commit_changes = commit_changes;
signals[IFNET_SETUP_MONITORS] =
diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.c b/src/settings/plugins/ifnet/nms-ifnet-plugin.c
index 802988c19a..998b04b47a 100644
--- a/src/settings/plugins/ifnet/nms-ifnet-plugin.c
+++ b/src/settings/plugins/ifnet/nms-ifnet-plugin.c
@@ -138,9 +138,9 @@ monitor_file_changes (const char *filename,
info->callback = callback;
info->user_data = user_data;
g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free,
- info);
+ info);
g_signal_connect (monitor, "changed", G_CALLBACK (file_changed),
- info);
+ info);
} else {
nm_log_warn (LOGD_SETTINGS, "Monitoring %s failed, error: %s", filename,
error == NULL ? "nothing" : (*error)->message);
@@ -150,34 +150,38 @@ monitor_file_changes (const char *filename,
}
static void
-setup_monitors (NMIfnetConnection * connection, gpointer user_data)
+setup_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
- if (nm_config_get_monitor_connection_files (nm_config_get ())) {
- priv->net_monitor =
- monitor_file_changes (CONF_NET_FILE, (FileChangedFn) reload_connections,
- user_data);
- priv->wpa_monitor =
- monitor_file_changes (WPA_SUPPLICANT_CONF, (FileChangedFn) reload_connections,
- user_data);
- }
+ if (!nm_config_get_monitor_connection_files (nm_config_get ()))
+ return;
+
+ if (priv->net_monitor || priv->wpa_monitor)
+ return;
+
+ priv->net_monitor = monitor_file_changes (CONF_NET_FILE,
+ (FileChangedFn) reload_connections,
+ user_data);
+ priv->wpa_monitor = monitor_file_changes (WPA_SUPPLICANT_CONF,
+ (FileChangedFn) reload_connections,
+ user_data);
}
static void
-cancel_monitors (NMIfnetConnection * connection, gpointer user_data)
+cancel_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
if (priv->net_monitor) {
g_file_monitor_cancel (priv->net_monitor);
- g_object_unref (priv->net_monitor);
+ g_clear_object (&priv->net_monitor);
}
if (priv->wpa_monitor) {
g_file_monitor_cancel (priv->wpa_monitor);
- g_object_unref (priv->wpa_monitor);
+ g_clear_object (&priv->wpa_monitor);
}
}
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
index b718a3f831..0928772afa 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
@@ -139,7 +139,10 @@ bind_device_to_connection (SettingsPluginIfupdown *self,
g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, address, NULL);
}
- nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, NULL, NULL);
+ nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported),
+ NULL,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL);
}
static void
@@ -409,7 +412,7 @@ init (NMSettingsPlugin *config)
exported = g_hash_table_lookup (priv->connections, block->name);
if (exported) {
nm_log_info (LOGD_SETTINGS, "deleting %s from connections", block->name);
- nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL, NULL);
+ nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL);
g_hash_table_remove (priv->connections, block->name);
}
diff --git a/src/settings/plugins/keyfile/nms-keyfile-connection.c b/src/settings/plugins/keyfile/nms-keyfile-connection.c
index bd07d263c1..300aa9f7b3 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-connection.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-connection.c
@@ -50,29 +50,30 @@ G_DEFINE_TYPE (NMSKeyfileConnection, nms_keyfile_connection, NM_TYPE_SETTINGS_CO
/*****************************************************************************/
-static void
+static gboolean
commit_changes (NMSettingsConnection *connection,
+ NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
- NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+ NMConnection **out_reread_connection,
+ char **out_logmsg_change,
+ GError **error)
{
- char *path = NULL;
- GError *error = NULL;
+ gs_free char *path = NULL;
gs_unref_object NMConnection *reread = NULL;
gboolean reread_same = FALSE;
- if (!nms_keyfile_writer_connection (NM_CONNECTION (connection),
+ nm_assert (out_reread_connection && !*out_reread_connection);
+ nm_assert (!out_logmsg_change || !*out_logmsg_change);
+
+ if (!nms_keyfile_writer_connection (new_connection ?: NM_CONNECTION (connection),
nm_settings_connection_get_filename (connection),
NM_FLAGS_ALL (commit_reason, NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION
| NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED),
&path,
&reread,
&reread_same,
- &error)) {
- callback (connection, error, user_data);
- g_clear_error (&error);
- return;
- }
+ error))
+ return FALSE;
/* Update the filename if it changed */
if ( path
@@ -81,52 +82,37 @@ commit_changes (NMSettingsConnection *connection,
nm_settings_connection_set_filename (connection, path);
if (old_path) {
- nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and rename from \"%s\"",
- NMS_KEYFILE_CONNECTION_LOG_ARG (connection),
- old_path);
+ NM_SET_OUT (out_logmsg_change,
+ g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and rename from \"%s\"",
+ NMS_KEYFILE_CONNECTION_LOG_ARG (connection),
+ old_path));
} else {
- nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and persist connection",
- NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
+ NM_SET_OUT (out_logmsg_change,
+ g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and persist connection",
+ NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
}
} else {
- nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT,
- NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
- }
-
- if (reread && !reread_same) {
- gs_free_error GError *local = NULL;
-
- if (!nm_settings_connection_replace_settings (connection, reread, FALSE, "update-during-write", &local)) {
- nm_log_warn (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" after persisting connection failed: %s",
- NMS_KEYFILE_CONNECTION_LOG_ARG (connection), local->message);
- } else {
- nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" after persisting connection",
- NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
- }
+ NM_SET_OUT (out_logmsg_change,
+ g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT,
+ NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
}
- g_free (path);
+ if (reread && !reread_same)
+ *out_reread_connection = g_steal_pointer (&reread);
- NM_SETTINGS_CONNECTION_CLASS (nms_keyfile_connection_parent_class)->commit_changes (connection,
- commit_reason,
- callback,
- user_data);
+ return TRUE;
}
-static void
-do_delete (NMSettingsConnection *connection,
- NMSettingsConnectionDeleteFunc callback,
- gpointer user_data)
+static gboolean
+delete (NMSettingsConnection *connection,
+ GError **error)
{
const char *path;
path = nm_settings_connection_get_filename (connection);
if (path)
g_unlink (path);
-
- NM_SETTINGS_CONNECTION_CLASS (nms_keyfile_connection_parent_class)->delete (connection,
- callback,
- user_data);
+ return TRUE;
}
/*****************************************************************************/
@@ -192,5 +178,5 @@ nms_keyfile_connection_class_init (NMSKeyfileConnectionClass *keyfile_connection
NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class);
settings_class->commit_changes = commit_changes;
- settings_class->delete = do_delete;
+ settings_class->delete = delete;
}