diff options
Diffstat (limited to 'src/core/settings')
47 files changed, 1427 insertions, 647 deletions
diff --git a/src/core/settings/nm-agent-manager.c b/src/core/settings/nm-agent-manager.c index 7e617909..a1c2eb9c 100644 --- a/src/core/settings/nm-agent-manager.c +++ b/src/core/settings/nm-agent-manager.c @@ -9,7 +9,7 @@ #include <pwd.h> -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-dbus-interface.h" #include "nm-secret-agent.h" #include "nm-auth-utils.h" @@ -19,7 +19,7 @@ #include "nm-session-monitor.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "c-list/src/c-list.h" /*****************************************************************************/ diff --git a/src/core/settings/nm-secret-agent.c b/src/core/settings/nm-secret-agent.c index 7e7c5d7d..45152c27 100644 --- a/src/core/settings/nm-secret-agent.c +++ b/src/core/settings/nm-secret-agent.c @@ -10,11 +10,11 @@ #include <sys/types.h> #include <pwd.h> -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-dbus-aux.h" #include "nm-dbus-interface.h" -#include "nm-core-internal.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" #include "c-list/src/c-list.h" @@ -583,7 +583,7 @@ nm_secret_agent_delete_secrets(NMSecretAgent * self, priv = NM_SECRET_AGENT_GET_PRIVATE(self); /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ - dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_WITH_NON_SECRET); call_id = _call_id_new(self, METHOD_DELETE_SECRETS, path, NULL, callback, callback_data); diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c index 0ff07189..b423bf5b 100644 --- a/src/core/settings/nm-settings-connection.c +++ b/src/core/settings/nm-settings-connection.c @@ -10,8 +10,9 @@ #include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-keyfile-aux.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-config.h" #include "nm-config-data.h" #include "nm-dbus-interface.h" @@ -20,7 +21,7 @@ #include "nm-auth-utils.h" #include "nm-agent-manager.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-audit-manager.h" #include "nm-settings.h" #include "nm-dbus-manager.h" @@ -30,10 +31,13 @@ #define AUTOCONNECT_RETRIES_FOREVER -1 #define AUTOCONNECT_RESET_RETRIES_TIMER 300 -#define _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES \ - ((NMSettingsUpdate2Flags)( \ - NM_SETTINGS_UPDATE2_FLAG_TO_DISK | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY \ - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) +#define SEEN_BSSIDS_MAX 30 + +#define _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES \ + ((NMSettingsUpdate2Flags) (NM_SETTINGS_UPDATE2_FLAG_TO_DISK \ + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY \ + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED \ + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) /*****************************************************************************/ @@ -58,6 +62,56 @@ nm_settings_connections_array_to_connections(NMSettingsConnection *const *connec /*****************************************************************************/ +typedef struct { + char bssid[sizeof(NMEtherAddr) * 3]; + CList seen_bssids_lst; +} SeenBssidEntry; + +static inline SeenBssidEntry * +_seen_bssid_entry_init_stale(SeenBssidEntry *entry, const NMEtherAddr *bssid_bin) +{ + _nm_utils_hwaddr_ntoa(bssid_bin, sizeof(NMEtherAddr), TRUE, entry->bssid, sizeof(entry->bssid)); + return entry; +} + +static inline SeenBssidEntry * +_seen_bssid_entry_new_stale_bin(const NMEtherAddr *bssid_bin) +{ + return _seen_bssid_entry_init_stale(g_slice_new(SeenBssidEntry), bssid_bin); +} + +static inline SeenBssidEntry * +_seen_bssid_entry_new_stale_copy(const SeenBssidEntry *src) +{ + SeenBssidEntry *entry; + + entry = g_slice_new(SeenBssidEntry); + memcpy(entry->bssid, src->bssid, sizeof(entry->bssid)); + return entry; +} + +static void +_seen_bssid_entry_free(gpointer data) +{ + SeenBssidEntry *entry = data; + + c_list_unlink_stale(&entry->seen_bssids_lst); + nm_g_slice_free(entry); +} + +/*****************************************************************************/ + +static GHashTable * +_seen_bssids_hash_new(void) +{ + return g_hash_table_new_full(nm_str_hash, + g_str_equal, + (GDestroyNotify) _seen_bssid_entry_free, + NULL); +} + +/*****************************************************************************/ + NM_GOBJECT_PROPERTIES_DEFINE(NMSettingsConnection, PROP_UNSAVED, PROP_FLAGS, PROP_FILENAME, ); enum { UPDATED_INTERNAL, FLAGS_CHANGED, LAST_SIGNAL }; @@ -79,19 +133,17 @@ typedef struct _NMSettingsConnectionPrivate { NMConnection *connection; + struct { + NMConnectionSerializationOptions options; + GVariant * variant; + } getsettings_cached; + NMSettingsStorage *storage; char *filename; NMDevice *default_wired_device; - /* Caches secrets from on-disk connections; were they not cached any - * call to nm_connection_clear_secrets() wipes them out and we'd have - * to re-read them from disk which defeats the purpose of having the - * connection in-memory at all. - */ - GVariant *system_secrets; - /* Caches secrets from agents during the activation process; if new system * secrets are returned from an agent, they get written out to disk, * triggering a re-read of the connection, which reads only system @@ -100,7 +152,8 @@ typedef struct _NMSettingsConnectionPrivate { */ GVariant *agent_secrets; - GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */ + CList seen_bssids_lst_head; + GHashTable *seen_bssids_hash; guint64 timestamp; /* Up-to-date timestamp of connection use */ @@ -168,8 +221,9 @@ static const GDBusSignalInfo signal_info_updated; static const GDBusSignalInfo signal_info_removed; static const NMDBusInterfaceInfoExtended interface_info_settings_connection; -static void update_system_secrets_cache(NMSettingsConnection *self, NMConnection *new); -static void update_agent_secrets_cache(NMSettingsConnection *self, NMConnection *new); +static void update_agent_secrets_cache(NMSettingsConnection *self, NMConnection *new); +static guint _get_seen_bssids(NMSettingsConnection *self, + const char * strv_buf[static(SEEN_BSSIDS_MAX + 1)]); /*****************************************************************************/ @@ -248,10 +302,53 @@ nm_settings_connection_still_valid(NMSettingsConnection *self) /*****************************************************************************/ -static GHashTable * -_seen_bssids_hash_new(void) +static void +_getsettings_cached_clear(NMSettingsConnectionPrivate *priv) { - return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + if (nm_clear_pointer(&priv->getsettings_cached.variant, g_variant_unref)) { + priv->getsettings_cached.options.timestamp.has = FALSE; + priv->getsettings_cached.options.timestamp.val = 0; + nm_clear_g_free((gpointer *) &priv->getsettings_cached.options.seen_bssids); + } +} + +static GVariant * +_getsettings_cached_get(NMSettingsConnection *self, const NMConnectionSerializationOptions *options) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + GVariant * variant; + + if (priv->getsettings_cached.variant) { + if (nm_connection_serialization_options_equal(&priv->getsettings_cached.options, options)) { +#if NM_MORE_ASSERTS > 10 + gs_unref_variant GVariant *variant2 = NULL; + + variant = nm_connection_to_dbus_full(priv->connection, + NM_CONNECTION_SERIALIZE_WITH_NON_SECRET, + options); + nm_assert(variant); + variant2 = g_variant_new("(@a{sa{sv}})", variant); + nm_assert(g_variant_equal(priv->getsettings_cached.variant, variant2)); +#endif + return priv->getsettings_cached.variant; + } + _getsettings_cached_clear(priv); + } + + nm_assert(!priv->getsettings_cached.options.seen_bssids); + + variant = nm_connection_to_dbus_full(priv->connection, + NM_CONNECTION_SERIALIZE_WITH_NON_SECRET, + options); + nm_assert(variant); + + priv->getsettings_cached.variant = g_variant_ref_sink(g_variant_new("(@a{sa{sv}})", variant)); + + priv->getsettings_cached.options = *options; + priv->getsettings_cached.options.seen_bssids = + nm_utils_strv_dup_packed(priv->getsettings_cached.options.seen_bssids, -1); + + return priv->getsettings_cached.variant; } /*****************************************************************************/ @@ -287,6 +384,9 @@ _nm_settings_connection_set_connection(NMSettingsConnection * self, priv->connection = g_object_ref(new_connection); nmtst_connection_assert_unchanging(priv->connection); + _getsettings_cached_clear(priv); + _nm_settings_notify_sorted_by_autoconnect_priority_maybe_changed(priv->settings); + /* note that we only return @connection_old if the new connection actually differs from * before. * @@ -298,11 +398,6 @@ _nm_settings_connection_set_connection(NMSettingsConnection * self, NM_SET_OUT(out_connection_old, g_steal_pointer(&connection_old)); } - if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS)) - update_system_secrets_cache(self, NULL); - else if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS)) - update_system_secrets_cache(self, priv->connection); - if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS)) update_agent_secrets_cache(self, NULL); else if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS)) @@ -434,63 +529,20 @@ nm_settings_connection_check_permission(NMSettingsConnection *self, const char * /*****************************************************************************/ static void -update_system_secrets_cache(NMSettingsConnection *self, NMConnection *new) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - gs_unref_object NMConnection *connection_cloned = NULL; - gs_unref_variant GVariant *old_secrets = NULL; - - old_secrets = g_steal_pointer(&priv->system_secrets); - - if (!new) - goto out; - - /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, - * in particular if there are no secrets to begin with. */ - - connection_cloned = nm_simple_connection_new_clone(new); - - /* Clear out non-system-owned and not-saved secrets */ - _nm_connection_clear_secrets_by_secret_flags(connection_cloned, NM_SETTING_SECRET_FLAG_NONE); - - priv->system_secrets = nm_g_variant_ref_sink( - nm_connection_to_dbus(connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); - -out: - if (_LOGT_ENABLED()) { - if ((!!old_secrets) != (!!priv->system_secrets)) { - _LOGT("update system secrets: secrets %s", old_secrets ? "cleared" : "set"); - } else if (priv->system_secrets && !g_variant_equal(old_secrets, priv->system_secrets)) - _LOGT("update system secrets: secrets updated"); - } -} - -static void update_agent_secrets_cache(NMSettingsConnection *self, NMConnection *new) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - gs_unref_object NMConnection *connection_cloned = NULL; - gs_unref_variant GVariant *old_secrets = NULL; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_unref_variant GVariant *old_secrets = NULL; old_secrets = g_steal_pointer(&priv->agent_secrets); - if (!new) - goto out; - - /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, - * in particular if there are no secrets to begin with. */ - - connection_cloned = nm_simple_connection_new_clone(new); - - /* Clear out non-system-owned secrets */ - _nm_connection_clear_secrets_by_secret_flags(connection_cloned, - NM_SETTING_SECRET_FLAG_NOT_SAVED - | NM_SETTING_SECRET_FLAG_AGENT_OWNED); - - priv->agent_secrets = nm_g_variant_ref_sink( - nm_connection_to_dbus(connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); + if (new) { + priv->agent_secrets = nm_g_variant_ref_sink( + nm_connection_to_dbus(new, + NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED + | NM_CONNECTION_SERIALIZE_WITH_SECRETS_NOT_SAVED)); + } -out: if (_LOGT_ENABLED()) { if ((!!old_secrets) != (!!priv->agent_secrets)) { _LOGT("update agent secrets: secrets %s", old_secrets ? "cleared" : "set"); @@ -499,39 +551,6 @@ out: } } -void -nm_settings_connection_clear_secrets(NMSettingsConnection *self, - gboolean clear_cached_system_secrets, - gboolean persist) -{ - gs_unref_object NMConnection *connection_cloned = NULL; - - if (!nm_settings_connection_still_valid(self)) - return; - - /* FIXME: add API to NMConnection so that we can clone a profile without secrets. */ - - connection_cloned = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); - - nm_connection_clear_secrets(connection_cloned); - - if (!nm_settings_connection_update( - self, - connection_cloned, - persist ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP - : NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE - | (clear_cached_system_secrets - ? NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS - : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE) - | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS, - "clear-secrets", - NULL)) - nm_assert_not_reached(); -} - static gboolean _secrets_update(NMConnection * connection, const char * setting_name, @@ -829,6 +848,18 @@ nm_settings_connection_new_secrets(NMSettingsConnection *self, return TRUE; } +static gboolean +match_secret_by_setting_name_and_flags_cb(NMSetting * setting, + const char * secret, + NMSettingSecretFlags flags, + gpointer user_data) +{ + const char *get_secrets_setting_name = user_data; + + return nm_streq(nm_setting_get_name(setting), get_secrets_setting_name) + && NM_FLAGS_HAS(flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED); +} + static void get_secrets_done_cb(NMAgentManager * manager, NMAgentManagerCallId call_id_a, @@ -846,7 +877,6 @@ get_secrets_done_cb(NMAgentManager * manager, NMSettingsConnectionPrivate *priv; NMConnection * applied_connection; gs_free_error GError *local = NULL; - gs_unref_variant GVariant *system_secrets = NULL; gs_unref_object NMConnection *new_connection = NULL; gboolean agent_had_system = FALSE; ForEachSecretFlags cmp_flags = {NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE}; @@ -917,18 +947,12 @@ get_secrets_done_cb(NMAgentManager * manager, _LOGD("(%s:%p) secrets request completed", setting_name, call_id); - system_secrets = nm_g_variant_ref(priv->system_secrets); - new_connection = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); - nm_connection_clear_secrets(new_connection); - - if (!_secrets_update(new_connection, setting_name, system_secrets, NULL, &local)) { - _LOGD("(%s:%p) failed to update with existing secrets: %s", - setting_name, - call_id, - local->message); - } + /* Remove old agent-owned secrets in the requested setting */ + nm_connection_clear_secrets_with_flags(new_connection, + match_secret_by_setting_name_and_flags_cb, + (gpointer) setting_name); /* Update the connection with the agent's secrets; by this point if any * system-owned secrets exist in 'secrets' the agent that provided them @@ -962,7 +986,8 @@ get_secrets_done_cb(NMAgentManager * manager, NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | (agent_had_system ? NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE) | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS, "get-new-secrets", NULL)) @@ -970,6 +995,8 @@ get_secrets_done_cb(NMAgentManager * manager, applied_connection = call_id->applied_connection; if (applied_connection) { + gs_unref_variant GVariant *filtered_secrets2 = NULL; + get_cmp_flags(self, call_id, applied_connection, @@ -981,18 +1008,12 @@ get_secrets_done_cb(NMAgentManager * manager, &agent_had_system, &cmp_flags); - nm_connection_clear_secrets(applied_connection); - - if (!system_secrets - || nm_connection_update_secrets(applied_connection, - setting_name, - system_secrets, - NULL)) { - gs_unref_variant GVariant *filtered_secrets2 = NULL; + nm_connection_clear_secrets_with_flags(applied_connection, + match_secret_by_setting_name_and_flags_cb, + (gpointer) setting_name); - filtered_secrets2 = validate_secret_flags(applied_connection, secrets, &cmp_flags); - nm_connection_update_secrets(applied_connection, setting_name, filtered_secrets2, NULL); - } + filtered_secrets2 = validate_secret_flags(applied_connection, secrets, &cmp_flags); + nm_connection_update_secrets(applied_connection, setting_name, filtered_secrets2, NULL); } _get_secrets_info_callback(call_id, agent_username, setting_name, local); @@ -1060,7 +1081,8 @@ nm_settings_connection_get_secrets(NMSettingsConnection * self, NMAgentManagerCallId call_id_a; gs_free char * joined_hints = NULL; NMSettingsConnectionCallId * call_id; - GError * local = NULL; + GError * local = NULL; + gs_unref_variant GVariant *system_secrets = NULL; g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); g_return_val_if_fail( @@ -1111,14 +1133,15 @@ nm_settings_connection_get_secrets(NMSettingsConnection * self, * Then we know that the this request probably did not yet include the latest secret-agent. */ priv->last_secret_agent_version_id = nm_agent_manager_get_agent_version_id(priv->agent_mgr); - /* Use priv->system_secrets to work around the fact that nm_connection_clear_secrets() - * will clear secrets on this object's settings. - */ + system_secrets = nm_g_variant_ref_sink( + nm_connection_to_dbus(nm_settings_connection_get_connection(self), + NM_CONNECTION_SERIALIZE_WITH_SECRETS_SYSTEM_OWNED)); + call_id_a = nm_agent_manager_get_secrets(priv->agent_mgr, nm_dbus_object_get_path(NM_DBUS_OBJECT(self)), nm_settings_connection_get_connection(self), subject, - priv->system_secrets, + system_secrets, setting_name, flags, hints, @@ -1325,9 +1348,8 @@ get_settings_auth_cb(NMSettingsConnection * self, GError * error, gpointer data) { - gs_free const char ** seen_bssids = NULL; - NMConnectionSerializationOptions options = {}; - GVariant * settings; + const char * seen_bssids_strv[SEEN_BSSIDS_MAX + 1]; + NMConnectionSerializationOptions options = {}; if (error) { g_dbus_method_invocation_return_gerror(context, error); @@ -1347,17 +1369,15 @@ get_settings_auth_cb(NMSettingsConnection * self, * from the same reason as timestamp. Thus we put it here to GetSettings() * return settings too. */ - seen_bssids = nm_settings_connection_get_seen_bssids(self); - options.seen_bssids = seen_bssids; + _get_seen_bssids(self, seen_bssids_strv); + options.seen_bssids = seen_bssids_strv; /* Secrets should *never* be returned by the GetSettings method, they * get returned by the GetSecrets method which can be better * protected against leakage of secrets to unprivileged callers. */ - settings = nm_connection_to_dbus_full(nm_settings_connection_get_connection(self), - NM_CONNECTION_SERIALIZE_NO_SECRETS, - &options); - g_dbus_method_invocation_return_value(context, g_variant_new("(@a{sa{sv}})", settings)); + + g_dbus_method_invocation_return_value(context, _getsettings_cached_get(self, &options)); } static void @@ -1488,14 +1508,21 @@ update_auth_cb(NMSettingsConnection * self, if (!_nm_connection_aggregate(info->new_settings, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)) { + gs_unref_variant GVariant *secrets = NULL; + /* 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. */ + secrets = nm_g_variant_ref_sink( + nm_connection_to_dbus(nm_settings_connection_get_connection(self), + NM_CONNECTION_SERIALIZE_WITH_SECRETS)); + + if (secrets) + nm_connection_update_secrets(info->new_settings, NULL, secrets, NULL); + if (priv->agent_secrets) nm_connection_update_secrets(info->new_settings, NULL, priv->agent_secrets, NULL); - if (priv->system_secrets) - nm_connection_update_secrets(info->new_settings, NULL, priv->system_secrets, NULL); } 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 @@ -1558,6 +1585,7 @@ update_auth_cb(NMSettingsConnection * self, : NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL) | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET | (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT) ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE), @@ -1568,7 +1596,7 @@ update_auth_cb(NMSettingsConnection * self, 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. + * as agent-owned secrets are the only ones we send back to be saved. * Only send secrets to agents of the same UID that called update too. */ for_agent = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); @@ -1754,10 +1782,10 @@ impl_settings_connection_update2(NMDBusObject * obj, g_variant_get(parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); if (NM_FLAGS_ANY(flags_u, - ~((guint32)(_NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES - | NM_SETTINGS_UPDATE2_FLAG_VOLATILE - | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT - | NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)))) { + ~((guint32) (_NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES + | NM_SETTINGS_UPDATE2_FLAG_VOLATILE + | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT + | NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)))) { error = g_error_new_literal(NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unknown flags"); @@ -1888,9 +1916,9 @@ dbus_get_agent_secrets_cb(NMSettingsConnection * self, * by the time we get here. */ dict = nm_connection_to_dbus(nm_settings_connection_get_connection(self), - NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + NM_CONNECTION_SERIALIZE_WITH_SECRETS); if (!dict) - dict = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + dict = nm_g_variant_singleton_aLsaLsvII(); g_dbus_method_invocation_return_value(context, g_variant_new("(@a{sa{sv}})", dict)); } } @@ -1959,8 +1987,9 @@ dbus_clear_secrets_auth_cb(NMSettingsConnection * self, GError * error, gpointer user_data) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - gs_free_error GError *local = NULL; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_free_error GError *local = NULL; + gs_unref_object NMConnection *connection_cloned = NULL; if (error) { g_dbus_method_invocation_return_gerror(context, error); @@ -1973,7 +2002,24 @@ dbus_clear_secrets_auth_cb(NMSettingsConnection * self, return; } - nm_settings_connection_clear_secrets(self, TRUE, TRUE); + /* FIXME: add API to NMConnection so that we can clone a profile without secrets. */ + + connection_cloned = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); + + nm_connection_clear_secrets(connection_cloned); + + if (!nm_settings_connection_update( + self, + connection_cloned, + NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS, + "clear-secrets", + NULL)) + nm_assert_not_reached(); /* Tell agents to remove secrets for this connection */ nm_agent_manager_delete_secrets(priv->agent_mgr, @@ -2142,7 +2188,9 @@ _cmp_last_resort(NMSettingsConnection *a, NMSettingsConnection *b) /* hm, same UUID. Use their pointer value to give them a stable * order. */ - return (a > b) ? -1 : 1; + NM_CMP_DIRECT_PTR(a, b); + + return nm_assert_unreachable_val(0); } /* sorting for "best" connections. @@ -2184,6 +2232,15 @@ nm_settings_connection_cmp_autoconnect_priority(NMSettingsConnection *a, NMSetti } int +nm_settings_connection_cmp_autoconnect_priority_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data) +{ + return nm_settings_connection_cmp_autoconnect_priority((NMSettingsConnection *) pa, + (NMSettingsConnection *) pb); +} + +int nm_settings_connection_cmp_autoconnect_priority_p_with_data(gconstpointer pa, gconstpointer pb, gpointer user_data) @@ -2243,6 +2300,8 @@ nm_settings_connection_update_timestamp(NMSettingsConnection *self, guint64 time _LOGT("timestamp: set timestamp %" G_GUINT64_FORMAT, timestamp); + _nm_settings_notify_sorted_by_autoconnect_priority_maybe_changed(priv->settings); + if (!priv->kf_db_timestamps) return; @@ -2293,68 +2352,66 @@ _nm_settings_connection_register_kf_dbs(NMSettingsConnection *self, if (priv->kf_db_seen_bssids != kf_db_seen_bssids) { gs_strfreev char **tmp_strv = NULL; - gsize i, len; + gsize len; + gsize i; + guint result_len; nm_key_file_db_unref(priv->kf_db_seen_bssids); priv->kf_db_seen_bssids = nm_key_file_db_ref(kf_db_seen_bssids); tmp_strv = nm_key_file_db_get_string_list(priv->kf_db_seen_bssids, connection_uuid, &len); - nm_clear_pointer(&priv->seen_bssids, g_hash_table_unref); + if (priv->seen_bssids_hash) + g_hash_table_remove_all(priv->seen_bssids_hash); - if (len > 0) { - _LOGT("read %zu seen-bssids from keyfile database \"%s\"", - len, - nm_key_file_db_get_filename(priv->kf_db_seen_bssids)); - priv->seen_bssids = _seen_bssids_hash_new(); - for (i = len; i > 0;) - g_hash_table_add(priv->seen_bssids, g_steal_pointer(&tmp_strv[--i])); - nm_clear_g_free(&tmp_strv); - } else { - NMSettingWireless *s_wifi; + for (result_len = 0, i = 0; i < len; i++) { + NMEtherAddr addr_bin; + SeenBssidEntry *entry; - _LOGT("no seen-bssids from keyfile database \"%s\"", - nm_key_file_db_get_filename(priv->kf_db_seen_bssids)); + nm_assert(result_len == nm_g_hash_table_size(priv->seen_bssids_hash)); + if (result_len >= SEEN_BSSIDS_MAX) + break; - /* If this connection didn't have an entry in the seen-bssids database, - * maybe this is the first time we've read it in, so populate the - * seen-bssids list from the deprecated seen-bssids property of the - * wifi setting. - */ - s_wifi = - nm_connection_get_setting_wireless(nm_settings_connection_get_connection(self)); - if (s_wifi) { - len = nm_setting_wireless_get_num_seen_bssids(s_wifi); - if (len > 0) { - priv->seen_bssids = _seen_bssids_hash_new(); - for (i = 0; i < len; i++) { - const char *bssid = nm_setting_wireless_get_seen_bssid(s_wifi, i); - - g_hash_table_add(priv->seen_bssids, g_strdup(bssid)); - } - } + if (!_nm_utils_hwaddr_aton_exact(tmp_strv[i], &addr_bin, sizeof(addr_bin))) + continue; + + if (!priv->seen_bssids_hash) + priv->seen_bssids_hash = _seen_bssids_hash_new(); + + entry = _seen_bssid_entry_new_stale_bin(&addr_bin); + c_list_link_tail(&priv->seen_bssids_lst_head, &entry->seen_bssids_lst); + if (!g_hash_table_insert(priv->seen_bssids_hash, entry, entry)) { + /* duplicate detected! The @entry key was freed by g_hash_table_insert(). */ + continue; } + result_len++; } + if (result_len > 0) { + _LOGT("read %u seen-bssids from keyfile database \"%s\"", + result_len, + nm_key_file_db_get_filename(priv->kf_db_seen_bssids)); + } else + nm_clear_pointer(&priv->seen_bssids_hash, g_hash_table_destroy); + + nm_assert(nm_g_hash_table_size(priv->seen_bssids_hash) == result_len); + nm_assert(result_len <= SEEN_BSSIDS_MAX); } } -/** - * nm_settings_connection_get_seen_bssids: - * @self: the #NMSettingsConnection - * - * Returns current list of seen BSSIDs for the connection. - * - * Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation). - * The caller is responsible for freeing the list, but not the content. - **/ -const char ** -nm_settings_connection_get_seen_bssids(NMSettingsConnection *self) +static guint +_get_seen_bssids(NMSettingsConnection *self, const char *strv_buf[static(SEEN_BSSIDS_MAX + 1)]) { - g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + SeenBssidEntry * entry; + guint i; - return nm_utils_strdict_get_keys(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids, - TRUE, - NULL); + i = 0; + c_list_for_each_entry (entry, &priv->seen_bssids_lst_head, seen_bssids_lst) { + nm_assert(i <= SEEN_BSSIDS_MAX); + strv_buf[i++] = entry->bssid; + } + strv_buf[i] = NULL; + return i; } /** @@ -2368,14 +2425,17 @@ gboolean nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const char *bssid) { NMSettingsConnectionPrivate *priv; + NMEtherAddr addr_bin; g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); g_return_val_if_fail(bssid, FALSE); + nm_assert(_nm_utils_hwaddr_aton_exact(bssid, &addr_bin, sizeof(addr_bin))); priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - return priv->seen_bssids - && g_hash_table_contains(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids, bssid); + return priv->seen_bssids_hash + && g_hash_table_contains(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids_hash, + bssid); } /** @@ -2390,15 +2450,47 @@ void nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - gs_free const char ** strv = NULL; + const char * seen_bssids_strv[SEEN_BSSIDS_MAX + 1]; + NMEtherAddr addr_bin; const char * connection_uuid; + SeenBssidEntry entry_stack; + SeenBssidEntry * entry; + guint i; - g_return_if_fail(seen_bssid != NULL); + g_return_if_fail(seen_bssid); - if (!priv->seen_bssids) - priv->seen_bssids = _seen_bssids_hash_new(); + if (!_nm_utils_hwaddr_aton_exact(seen_bssid, &addr_bin, sizeof(addr_bin))) + g_return_if_reached(); - g_hash_table_add(priv->seen_bssids, g_strdup(seen_bssid)); + _seen_bssid_entry_init_stale(&entry_stack, &addr_bin); + + if (!priv->seen_bssids_hash) { + priv->seen_bssids_hash = _seen_bssids_hash_new(); + entry = NULL; + } else + entry = g_hash_table_lookup(priv->seen_bssids_hash, &entry_stack); + + if (entry) { + if (!nm_c_list_move_front(&priv->seen_bssids_lst_head, &entry->seen_bssids_lst)) { + /* no change. */ + return; + } + } else { + entry = _seen_bssid_entry_new_stale_copy(&entry_stack); + c_list_link_front(&priv->seen_bssids_lst_head, &entry->seen_bssids_lst); + if (!g_hash_table_add(priv->seen_bssids_hash, entry)) + nm_assert_not_reached(); + + if (g_hash_table_size(priv->seen_bssids_hash) > SEEN_BSSIDS_MAX) { + g_hash_table_remove( + priv->seen_bssids_hash, + c_list_last_entry(&priv->seen_bssids_lst_head, SeenBssidEntry, seen_bssids_lst)); + } + } + + nm_assert(g_hash_table_size(priv->seen_bssids_hash) <= SEEN_BSSIDS_MAX); + nm_assert(g_hash_table_size(priv->seen_bssids_hash) + == c_list_length(&priv->seen_bssids_lst_head)); if (!priv->kf_db_seen_bssids) return; @@ -2407,12 +2499,8 @@ nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *se if (!connection_uuid) return; - strv = nm_utils_strdict_get_keys(priv->seen_bssids, TRUE, NULL); - - nm_key_file_db_set_string_list(priv->kf_db_seen_bssids, - connection_uuid, - strv ?: NM_PTRARRAY_EMPTY(const char *), - -1); + i = _get_seen_bssids(self, seen_bssids_strv); + nm_key_file_db_set_string_list(priv->kf_db_seen_bssids, connection_uuid, seen_bssids_strv, i); } /*****************************************************************************/ @@ -2623,7 +2711,7 @@ nm_settings_connection_init(NMSettingsConnection *self) self->_priv = priv; c_list_init(&self->_connections_lst); - + c_list_init(&priv->seen_bssids_lst_head); c_list_init(&priv->call_ids_lst_head); c_list_init(&priv->auth_lst_head); @@ -2659,15 +2747,16 @@ dispose(GObject *object) _get_secrets_cancel(self, call_id, TRUE); } - nm_clear_pointer(&priv->system_secrets, g_variant_unref); nm_clear_pointer(&priv->agent_secrets, g_variant_unref); - nm_clear_pointer(&priv->seen_bssids, g_hash_table_destroy); + nm_clear_pointer(&priv->seen_bssids_hash, g_hash_table_destroy); g_clear_object(&priv->agent_mgr); g_clear_object(&priv->connection); + _getsettings_cached_clear(priv); + nm_clear_pointer(&priv->kf_db_timestamps, nm_key_file_db_unref); nm_clear_pointer(&priv->kf_db_seen_bssids, nm_key_file_db_unref); @@ -2732,20 +2821,17 @@ static const NMDBusInterfaceInfoExtended interface_info_settings_connection = { .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("result", "a{sv}"), ), ), .handle = impl_settings_connection_update2, ), ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, - &signal_info_updated, - &signal_info_removed, ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&signal_info_updated, &signal_info_removed, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Unsaved", - "b", - NM_SETTINGS_CONNECTION_UNSAVED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Unsaved", + "b", + NM_SETTINGS_CONNECTION_UNSAVED), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", "u", NM_SETTINGS_CONNECTION_FLAGS), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Filename", "s", NM_SETTINGS_CONNECTION_FILENAME), ), ), - .legacy_property_changed = TRUE, }; static void diff --git a/src/core/settings/nm-settings-connection.h b/src/core/settings/nm-settings-connection.h index 7c61dbeb..fa3dbcfb 100644 --- a/src/core/settings/nm-settings-connection.h +++ b/src/core/settings/nm-settings-connection.h @@ -63,6 +63,9 @@ typedef enum { NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT = (1u << 8), + /* Is anything other than secrets changing */ + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET = (1u << 9), + } NMSettingsConnectionUpdateReason; typedef enum { @@ -274,10 +277,6 @@ nm_settings_connection_get_secrets(NMSettingsConnection * self, void nm_settings_connection_cancel_secrets(NMSettingsConnection * self, NMSettingsConnectionCallId *call_id); -void nm_settings_connection_clear_secrets(NMSettingsConnection *self, - gboolean clear_cached_system_secrets, - gboolean persist); - gboolean nm_settings_connection_check_visibility(NMSettingsConnection *self, NMSessionMonitor * session_monitor); @@ -324,6 +323,9 @@ int nm_settings_connection_cmp_timestamp_p_with_data(gconstpointer pa, gpointer user_data); int nm_settings_connection_cmp_autoconnect_priority(NMSettingsConnection *a, NMSettingsConnection *b); +int nm_settings_connection_cmp_autoconnect_priority_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data); int nm_settings_connection_cmp_autoconnect_priority_p_with_data(gconstpointer pa, gconstpointer pb, gpointer user_data); @@ -338,8 +340,6 @@ gboolean nm_settings_connection_get_timestamp(NMSettingsConnection *self, guint6 void nm_settings_connection_update_timestamp(NMSettingsConnection *self, guint64 timestamp); -const char **nm_settings_connection_get_seen_bssids(NMSettingsConnection *self); - gboolean nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const char *bssid); void nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid); diff --git a/src/core/settings/nm-settings-plugin.c b/src/core/settings/nm-settings-plugin.c index 9e81caab..66cc19b6 100644 --- a/src/core/settings/nm-settings-plugin.c +++ b/src/core/settings/nm-settings-plugin.c @@ -9,7 +9,7 @@ #include "nm-settings-plugin.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-settings-connection.h" diff --git a/src/core/settings/nm-settings-storage.c b/src/core/settings/nm-settings-storage.c index c56ba075..e284b822 100644 --- a/src/core/settings/nm-settings-storage.c +++ b/src/core/settings/nm-settings-storage.c @@ -7,6 +7,7 @@ #include "nm-settings-storage.h" +#include "libnm-glib-aux/nm-uuid.h" #include "nm-utils.h" #include "nm-settings-plugin.h" @@ -72,7 +73,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps case PROP_UUID: /* construct-only */ self->_uuid = g_value_dup_string(value); - nm_assert(!self->_uuid || nm_utils_is_uuid(self->_uuid)); + nm_assert(!self->_uuid || nm_uuid_is_normalized(self->_uuid)); break; case PROP_FILENAME: /* construct-only */ @@ -97,7 +98,7 @@ NMSettingsStorage * nm_settings_storage_new(NMSettingsPlugin *plugin, const char *uuid, const char *filename) { nm_assert(NM_IS_SETTINGS_PLUGIN(plugin)); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); return g_object_new(NM_TYPE_SETTINGS_STORAGE, NM_SETTINGS_STORAGE_PLUGIN, diff --git a/src/core/settings/nm-settings-storage.h b/src/core/settings/nm-settings-storage.h index 970cfd77..2e5e1c55 100644 --- a/src/core/settings/nm-settings-storage.h +++ b/src/core/settings/nm-settings-storage.h @@ -48,36 +48,35 @@ GType nm_settings_storage_get_type(void); NMSettingsStorage * nm_settings_storage_new(struct _NMSettingsPlugin *plugin, const char *uuid, const char *filename); +/* forward declare so we don't have to include "nm-settings-plugin.h" here. */ +GType nm_settings_plugin_get_type(void); + static inline struct _NMSettingsPlugin * nm_settings_storage_get_plugin(const NMSettingsStorage *self) { - GType nm_settings_plugin_get_type(void); - g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(self->_plugin, nm_settings_plugin_get_type())); return self->_plugin; } +gboolean nm_uuid_is_normalized_full(const char *str); + static inline const char * nm_settings_storage_get_uuid(const NMSettingsStorage *self) { - gboolean nm_utils_is_uuid(const char *str); - g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - nm_assert(nm_utils_is_uuid(self->_uuid)); + nm_assert(nm_uuid_is_normalized_full(self->_uuid)); return self->_uuid; } static inline const char * nm_settings_storage_get_uuid_opt(const NMSettingsStorage *self) { - gboolean nm_utils_is_uuid(const char *str); - g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - nm_assert(!self->_uuid || nm_utils_is_uuid(self->_uuid)); + nm_assert(!self->_uuid || nm_uuid_is_normalized_full(self->_uuid)); return self->_uuid; } diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c index 3d31fb8b..f9f98de7 100644 --- a/src/core/settings/nm-settings.c +++ b/src/core/settings/nm-settings.c @@ -20,9 +20,10 @@ #include <selinux/selinux.h> #endif -#include "nm-libnm-core-intern/nm-common-macros.h" -#include "nm-glib-aux/nm-keyfile-aux.h" -#include "nm-keyfile-internal.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nm-dbus-interface.h" #include "nm-connection.h" #include "nm-setting-8021x.h" @@ -44,17 +45,17 @@ #include "nm-setting-proxy.h" #include "nm-setting-bond.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" #include "nm-dbus-manager.h" #include "nm-auth-utils.h" -#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "libnm-core-aux-intern/nm-auth-subject.h" #include "nm-session-monitor.h" #include "plugins/keyfile/nms-keyfile-plugin.h" #include "plugins/keyfile/nms-keyfile-storage.h" @@ -139,7 +140,7 @@ nm_assert_storage_data_lst(CList *head) u = nm_settings_storage_get_uuid(sd->storage); if (!uuid) { uuid = u; - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); } else nm_assert(nm_streq0(uuid, u)); } @@ -182,7 +183,7 @@ _sett_conn_entry_new(const char *uuid) SettConnEntry *sett_conn_entry; gsize l_p_1; - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); l_p_1 = strlen(uuid) + 1; @@ -370,6 +371,7 @@ typedef struct { CList connections_lst_head; NMSettingsConnection **connections_cached_list; + NMSettingsConnection **connections_cached_list_sorted_by_autoconnect_priority; GSList *unmanaged_specs; GSList *unrecognized_specs; @@ -386,8 +388,17 @@ typedef struct { guint kf_db_flush_idle_id_timestamps; guint kf_db_flush_idle_id_seen_bssids; + bool kf_db_pruned_timestamps; + bool kf_db_pruned_seen_bssid; + bool started : 1; + /* Whether NMSettingsConnections changed in a way that affects the comparison + * with nm_settings_connection_cmp_autoconnect_priority_with_data(). In that case, + * we may need to re-sort the connections_cached_list_sorted_by_autoconnect_priority + * list. */ + bool sorted_by_autoconnect_priority_maybe_changed : 1; + } NMSettingsPrivate; struct _NMSettings { @@ -487,6 +498,8 @@ _startup_complete_check_is_ready(NMSettings * self, conn = nm_settings_connection_get_connection(sett_conn); nm_manager_for_each_device (priv->manager, device, tmp_lst) { + gs_free_error GError *error = NULL; + if (!nm_device_is_real(device)) continue; @@ -497,7 +510,13 @@ _startup_complete_check_is_ready(NMSettings * self, continue; } - if (!nm_device_check_connection_compatible(device, conn, NULL)) + /* Check that device is compatible with the device. We are also happy + * with a device compatible but for which the connection is disallowed + * by NM configuration. */ + if (!nm_device_check_connection_compatible(device, conn, &error) + && !g_error_matches(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_DISALLOWED)) continue; return TRUE; @@ -1433,7 +1452,8 @@ _plugin_connections_reload(NMSettings *self) NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, TRUE, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET); for (iter = priv->plugins; iter; iter = iter->next) nm_settings_plugin_load_connections_done(iter->data); @@ -1460,7 +1480,7 @@ _add_connection_to_first_plugin(NMSettings * self, uuid = nm_connection_get_uuid(new_connection); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); for (iter = priv->plugins; iter; iter = iter->next) { NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN(iter->data); @@ -1541,9 +1561,7 @@ _add_connection_to_first_plugin(NMSettings * self, } agent_owned_secrets = - nm_connection_to_dbus(new_connection, - NM_CONNECTION_SERIALIZE_ONLY_SECRETS - | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); + nm_connection_to_dbus(new_connection, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); connection_to_add_real = _connection_changed_normalize_connection(storage, connection_to_add, @@ -1912,7 +1930,8 @@ again_delete_tombstone: _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK, FALSE, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET | (NM_FLAGS_HAS(add_reason, NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT) ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE)); @@ -2218,9 +2237,7 @@ nm_settings_update_connection(NMSettings * self, nm_assert(nm_streq(uuid, nm_settings_storage_get_uuid(new_storage))); agent_owned_secrets = - nm_connection_to_dbus(connection, - NM_CONNECTION_SERIALIZE_ONLY_SECRETS - | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); new_connection_real = _connection_changed_normalize_connection(new_storage, new_connection, agent_owned_secrets, @@ -2297,7 +2314,7 @@ nm_settings_delete_connection(NMSettings * self, nm_assert(NM_IS_SETTINGS_STORAGE(cur_storage)); uuid = nm_settings_storage_get_uuid(cur_storage); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); sett_conn_entry = _sett_conn_entries_get(self, uuid); @@ -2691,9 +2708,9 @@ impl_settings_add_connection2(NMDBusObject * obj, g_variant_get(parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); if (NM_FLAGS_ANY(flags_u, - ~((guint32)(NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK - | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY - | NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)))) { + ~((guint32) (NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY + | NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)))) { g_dbus_method_invocation_take_error(invocation, g_error_new_literal(NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, @@ -2814,7 +2831,8 @@ impl_settings_load_connections(NMDBusObject * obj, NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, TRUE, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET); for (iter = priv->plugins; iter; iter = iter->next) nm_settings_plugin_load_connections_done(iter->data); @@ -2832,7 +2850,7 @@ impl_settings_load_connections(NMDBusObject * obj, g_dbus_method_invocation_return_value(invocation, g_variant_new("(b^as)", - (gboolean)(!failures), + (gboolean) (!failures), failures ? (const char **) failures->pdata : NM_PTRARRAY_EMPTY(const char *))); @@ -2870,25 +2888,48 @@ impl_settings_reload_connections(NMDBusObject * obj, /*****************************************************************************/ +void +_nm_settings_notify_sorted_by_autoconnect_priority_maybe_changed(NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + + priv->sorted_by_autoconnect_priority_maybe_changed = TRUE; +} + static void _clear_connections_cached_list(NMSettingsPrivate *priv) { - if (!priv->connections_cached_list) - return; + if (priv->connections_cached_list) { + nm_assert(priv->connections_len == NM_PTRARRAY_LEN(priv->connections_cached_list)); + +#if NM_MORE_ASSERTS + /* set the pointer to a bogus value. This makes it more apparent + * if somebody has a reference to the cached list and still uses + * it. That is a bug, this code just tries to make it blow up + * more eagerly. */ + memset(priv->connections_cached_list, + 0x43, + sizeof(NMSettingsConnection *) * (priv->connections_len + 1)); +#endif - nm_assert(priv->connections_len == NM_PTRARRAY_LEN(priv->connections_cached_list)); + nm_clear_g_free(&priv->connections_cached_list); + } + if (priv->connections_cached_list_sorted_by_autoconnect_priority) { + nm_assert(priv->connections_len + == NM_PTRARRAY_LEN(priv->connections_cached_list_sorted_by_autoconnect_priority)); #if NM_MORE_ASSERTS - /* set the pointer to a bogus value. This makes it more apparent - * if somebody has a reference to the cached list and still uses - * it. That is a bug, this code just tries to make it blow up - * more eagerly. */ - memset(priv->connections_cached_list, - 0x43, - sizeof(NMSettingsConnection *) * (priv->connections_len + 1)); + /* set the pointer to a bogus value. This makes it more apparent + * if somebody has a reference to the cached list and still uses + * it. That is a bug, this code just tries to make it blow up + * more eagerly. */ + memset(priv->connections_cached_list_sorted_by_autoconnect_priority, + 0x42, + sizeof(NMSettingsConnection *) * (priv->connections_len + 1)); #endif - nm_clear_g_free(&priv->connections_cached_list); + nm_clear_g_free(&priv->connections_cached_list_sorted_by_autoconnect_priority); + } } static void @@ -3027,6 +3068,65 @@ nm_settings_get_connections(NMSettings *self, guint *out_len) return priv->connections_cached_list; } +NMSettingsConnection *const * +nm_settings_get_connections_sorted_by_autoconnect_priority(NMSettings *self, guint *out_len) +{ + NMSettingsPrivate *priv; + gboolean needs_sort = FALSE; + + g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); + + priv = NM_SETTINGS_GET_PRIVATE(self); + + nm_assert(priv->connections_len == c_list_length(&priv->connections_lst_head)); + nm_assert( + !priv->connections_cached_list_sorted_by_autoconnect_priority + || (priv->connections_len + == NM_PTRARRAY_LEN(priv->connections_cached_list_sorted_by_autoconnect_priority))); + + if (!priv->connections_cached_list_sorted_by_autoconnect_priority) { + NMSettingsConnection *const *list_cached; + guint len; + + list_cached = nm_settings_get_connections(self, &len); + priv->connections_cached_list_sorted_by_autoconnect_priority = + nm_memdup(list_cached, sizeof(NMSettingsConnection *) * (len + 1)); + needs_sort = (len > 1); + } else if (priv->sorted_by_autoconnect_priority_maybe_changed) { + if (!nm_utils_ptrarray_is_sorted( + (gconstpointer *) priv->connections_cached_list_sorted_by_autoconnect_priority, + priv->connections_len, + FALSE, + nm_settings_connection_cmp_autoconnect_priority_with_data, + NULL)) { + /* We cache the sorted list, but we don't monitor all entries whether they + * get modified to invalidate the sort order. So every time we have to check + * whether the sort order is still correct. The vast majority of the time it + * is, and this check is faster than sorting anew. */ + needs_sort = TRUE; + } + } else { + nm_assert(nm_utils_ptrarray_is_sorted( + (gconstpointer *) priv->connections_cached_list_sorted_by_autoconnect_priority, + priv->connections_len, + TRUE, + nm_settings_connection_cmp_autoconnect_priority_with_data, + NULL)); + } + + priv->sorted_by_autoconnect_priority_maybe_changed = FALSE; + if (needs_sort) { + g_qsort_with_data(priv->connections_cached_list_sorted_by_autoconnect_priority, + priv->connections_len, + sizeof(NMSettingsConnection *), + nm_settings_connection_cmp_autoconnect_priority_p_with_data, + NULL); + } + + NM_SET_OUT(out_len, priv->connections_len); + return priv->connections_cached_list_sorted_by_autoconnect_priority; +} + /** * nm_settings_get_connections_clone: * @self: the #NMSetting @@ -3058,9 +3158,13 @@ nm_settings_get_connections_clone(NMSettings * self, g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); - list_cached = nm_settings_get_connections(self, &len); + if (sort_compare_func == nm_settings_connection_cmp_autoconnect_priority_p_with_data) { + list_cached = nm_settings_get_connections_sorted_by_autoconnect_priority(self, &len); + sort_compare_func = NULL; + } else + list_cached = nm_settings_get_connections(self, &len); -#if NM_MORE_ASSERTS +#if NM_MORE_ASSERTS > 10 nm_assert(list_cached); for (i = 0; i < len; i++) nm_assert(NM_IS_SETTINGS_CONNECTION(list_cached[i])); @@ -3204,7 +3308,7 @@ add_plugin_load_file(NMSettings *self, const char *pname, GError **error) /* errors after this point are fatal, because we loaded the shared library already. */ - if (!g_module_symbol(module, "nm_settings_plugin_factory", (gpointer)(&factory_func))) { + if (!g_module_symbol(module, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -3591,6 +3695,41 @@ again: /*****************************************************************************/ +static gboolean +_kf_db_prune_predicate(const char *uuid, gpointer user_data) +{ + return !!nm_settings_get_connection_by_uuid(user_data, uuid); +} + +static void +_kf_db_to_file(NMSettings *self, gboolean is_timestamps, gboolean force_write) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + NMKeyFileDB * kf_db; + bool * p_kf_db_pruned; + + if (is_timestamps) { + kf_db = priv->kf_db_timestamps; + p_kf_db_pruned = &priv->kf_db_pruned_timestamps; + } else { + kf_db = priv->kf_db_seen_bssids; + p_kf_db_pruned = &priv->kf_db_pruned_seen_bssid; + } + + if (!*p_kf_db_pruned) { + /* we only prune the DB once, because afterwards every + * add/remove of an connection will lead to a direct update. */ + *p_kf_db_pruned = TRUE; + nm_key_file_db_prune(kf_db, _kf_db_prune_predicate, self); + + /* once we also go over the directory, and see whether we + * have any left over temporary files to delete. */ + nm_key_file_db_prune_tmp_files(kf_db); + } + + nm_key_file_db_to_file(kf_db, force_write); +} + G_GNUC_PRINTF(4, 5) static void _kf_db_log_fcn(NMKeyFileDB *kf_db, int syslog_level, gpointer user_data, const char *fmt, ...) @@ -3639,7 +3778,7 @@ _kf_db_got_dirty_flush(NMSettings *self, gboolean is_timestamps) } if (nm_key_file_db_is_dirty(kf_db)) - nm_key_file_db_to_file(kf_db, FALSE); + _kf_db_to_file(self, is_timestamps, FALSE); else { _LOGT("[%s-keyfile]: skip saving changes to \"%s\"", prefix, @@ -3692,15 +3831,10 @@ _kf_db_got_dirty_fcn(NMKeyFileDB *kf_db, gpointer user_data) void nm_settings_kf_db_write(NMSettings *self) { - NMSettingsPrivate *priv; - g_return_if_fail(NM_IS_SETTINGS(self)); - priv = NM_SETTINGS_GET_PRIVATE(self); - if (priv->kf_db_timestamps) - nm_key_file_db_to_file(priv->kf_db_timestamps, TRUE); - if (priv->kf_db_seen_bssids) - nm_key_file_db_to_file(priv->kf_db_seen_bssids, TRUE); + _kf_db_to_file(self, TRUE, TRUE); + _kf_db_to_file(self, FALSE, TRUE); } /*****************************************************************************/ @@ -3938,8 +4072,8 @@ finalize(GObject *object) nm_clear_g_source(&priv->kf_db_flush_idle_id_timestamps); nm_clear_g_source(&priv->kf_db_flush_idle_id_seen_bssids); - nm_key_file_db_to_file(priv->kf_db_timestamps, FALSE); - nm_key_file_db_to_file(priv->kf_db_seen_bssids, FALSE); + _kf_db_to_file(self, TRUE, FALSE); + _kf_db_to_file(self, FALSE, FALSE); nm_key_file_db_destroy(priv->kf_db_timestamps); nm_key_file_db_destroy(priv->kf_db_seen_bssids); @@ -4027,18 +4161,16 @@ static const NMDBusInterfaceInfoExtended interface_info_settings = { .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("hostname", "s"), ), ), .handle = impl_settings_save_hostname, ), ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, - &signal_info_new_connection, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&signal_info_new_connection, &signal_info_connection_removed, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Connections", - "ao", - NM_SETTINGS_CONNECTIONS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Hostname", "s", NM_SETTINGS_HOSTNAME), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CanModify", - "b", - NM_SETTINGS_CAN_MODIFY), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Connections", + "ao", + NM_SETTINGS_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Hostname", "s", NM_SETTINGS_HOSTNAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("CanModify", + "b", + NM_SETTINGS_CAN_MODIFY), ), ), }; static void diff --git a/src/core/settings/nm-settings.h b/src/core/settings/nm-settings.h index 09a0af57..ce18fecc 100644 --- a/src/core/settings/nm-settings.h +++ b/src/core/settings/nm-settings.h @@ -79,6 +79,9 @@ void nm_settings_add_connection_dbus(NMSettings * self, NMSettingsConnection *const *nm_settings_get_connections(NMSettings *settings, guint *out_len); +NMSettingsConnection *const * +nm_settings_get_connections_sorted_by_autoconnect_priority(NMSettings *self, guint *out_len); + NMSettingsConnection **nm_settings_get_connections_clone(NMSettings * self, guint * out_len, NMSettingsConnectionFilterFunc func, @@ -127,4 +130,6 @@ const char *nm_settings_get_startup_complete_blocked_reason(NMSettings *self, void nm_settings_kf_db_write(NMSettings *settings); +void _nm_settings_notify_sorted_by_autoconnect_priority_maybe_changed(NMSettings *self); + #endif /* __NM_SETTINGS_H__ */ diff --git a/src/core/settings/plugins/ifcfg-rh/meson.build b/src/core/settings/plugins/ifcfg-rh/meson.build index a2f11a92..c62fa89d 100644 --- a/src/core/settings/plugins/ifcfg-rh/meson.build +++ b/src/core/settings/plugins/ifcfg-rh/meson.build @@ -28,7 +28,6 @@ libnms_ifcfg_rh_core = static_library( 'shvar.c', ), dependencies: core_default_dep, - c_args: daemon_c_flags, ) libnm_settings_plugin_ifcfg_rh = shared_module( @@ -38,7 +37,6 @@ libnm_settings_plugin_ifcfg_rh = shared_module( 'nms-ifcfg-rh-plugin.c', ), dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_with: libnms_ifcfg_rh_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/core/settings/plugins/ifcfg-rh/nm-ifdown b/src/core/settings/plugins/ifcfg-rh/nm-ifdown index e7bd73ae..3b05ef1c 100644..100755 --- a/src/core/settings/plugins/ifcfg-rh/nm-ifdown +++ b/src/core/settings/plugins/ifcfg-rh/nm-ifdown @@ -1,3 +1,44 @@ -#!/bin/sh -nmcli connection load "/etc/sysconfig/network-scripts/ifcfg-$1" && -exec nmcli connection down filename "/etc/sysconfig/network-scripts/ifcfg-$1" +#!/bin/bash + +CONFIG="$1" + +if [ -z "${CONFIG}" ] ; then + echo $"Usage: ifdown <device name>" >&2 + exit 1 +fi + +usage_and_fail() { + cat <<EOF >&2 +$1! + +See all profiles with \`nmcli connection\`. +Reload files from disk with \`nmcli connection reload\` +Deactivate the desired profile with \`nmcli connection down \"\$NAME\"\` +EOF + exit 1 +} + +OLD_IFS="$IFS" + +re='^/etc/sysconfig/network-scripts/ifcfg-[^/]+$' +for f in "/etc/sysconfig/network-scripts/ifcfg-$CONFIG" "/etc/sysconfig/network-scripts/$CONFIG" ; do + [[ "$f" =~ $re ]] || continue + [ -f "$f" ] || continue + + nmcli connection load "$f" \ + && nmcli connection down filename "$f" \ + && exit 0 + + usage_and_fail "Failure to deactivate file \"$CONFIG\"" +done + +IFS=$'\n ' +APATHS=( $(nmcli -g GENERAL.DBUS-PATH connection show --active "$CONFIG" 2>/dev/null) ) +IFS="$OLD_IFS" +if [ "${#APATHS[@]}" -eq 1 ] ; then + nmcli connection down apath "${APATHS[0]}" \ + && exit 0 + usage_and_fail "Failure to deactivate profile \"$CONFIG\" (apath ${APATHS[@]})" +fi + +usage_and_fail "No suitable profile \"$CONFIG\" found" diff --git a/src/core/settings/plugins/ifcfg-rh/nm-ifup b/src/core/settings/plugins/ifcfg-rh/nm-ifup index 96637a92..6b32fe1b 100644..100755 --- a/src/core/settings/plugins/ifcfg-rh/nm-ifup +++ b/src/core/settings/plugins/ifcfg-rh/nm-ifup @@ -1,3 +1,44 @@ -#!/bin/sh -nmcli connection load "/etc/sysconfig/network-scripts/ifcfg-$1" && -exec nmcli connection up filename "/etc/sysconfig/network-scripts/ifcfg-$1" +#!/bin/bash + +CONFIG="$1" + +if [ -z "${CONFIG}" ] ; then + echo $"Usage: ifup <device name>" >&2 + exit 1 +fi + +usage_and_fail() { + cat <<EOF >&2 +$1! + +See all profiles with \`nmcli connection\`. +Reload files from disk with \`nmcli connection reload\` +Activate the desired profile with \`nmcli connection up \"\$NAME\"\` +EOF + exit 1 +} + +OLD_IFS="$IFS" + +re='^/etc/sysconfig/network-scripts/ifcfg-[^/]+$' +for f in "/etc/sysconfig/network-scripts/ifcfg-$CONFIG" "/etc/sysconfig/network-scripts/$CONFIG" ; do + [[ "$f" =~ $re ]] || continue + [ -f "$f" ] || continue + + nmcli connection load "$f" \ + && nmcli connection up filename "$f" \ + && exit 0 + + usage_and_fail "Failure to activate file \"$CONFIG\"" +done + +IFS=$'\n ' +UUIDS=( $(nmcli -g connection.uuid connection show "$CONFIG" 2>/dev/null) ) +IFS="$OLD_IFS" +if [ "${#UUIDS[@]}" -eq 1 ] ; then + nmcli connection up uuid "${UUIDS[0]}" \ + && exit 0 + usage_and_fail "Failure to activate profile \"$CONFIG\" (uuid ${UUIDS[0]})" +fi + +usage_and_fail "No suitable profile \"$CONFIG\" found" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index d114db0f..5038ac6a 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -13,12 +13,12 @@ #include <sys/stat.h> #include <unistd.h> -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #include "nm-dbus-manager.h" #include "settings/nm-settings-plugin.h" diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index a42c4188..03b347f9 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -18,7 +18,8 @@ #include <linux/rtnetlink.h> #include <linux/if_ether.h> -#include "nm-glib-aux/nm-secret-utils.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-secret-utils.h" #include "nm-connection.h" #include "nm-dbus-interface.h" #include "nm-setting-connection.h" @@ -38,11 +39,11 @@ #include "nm-setting-user.h" #include "nm-setting-proxy.h" #include "nm-setting-generic.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-utils.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "NetworkManagerUtils.h" #include "nms-ifcfg-rh-common.h" @@ -405,11 +406,9 @@ make_connection_setting(const char *file, /* Try for a UUID key before falling back to hashing the file name */ uuid = svGetValueStr(ifcfg, "UUID", &uuid_free); if (!uuid) { - uuid_free = nm_utils_uuid_generate_from_string(svFileGetName(ifcfg), - -1, - NM_UTILS_UUID_TYPE_LEGACY, - NULL); - uuid = uuid_free; + uuid_free = + nm_uuid_generate_from_string_str(svFileGetName(ifcfg), -1, NM_UUID_TYPE_LEGACY, NULL); + uuid = uuid_free; } g_object_set(s_con, @@ -1896,6 +1895,8 @@ make_ip4_setting(shvarFile *ifcfg, svGetValueBoolean(ifcfg, "DHCP_SEND_HOSTNAME", TRUE), NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64(ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + (int) svGetValueInt64(ifcfg, "IPV4_REQUIRED_TIMEOUT", 10, 0, G_MAXINT32, -1), NULL); nm_clear_g_free(&value); @@ -1986,7 +1987,11 @@ make_ip4_setting(shvarFile *ifcfg, } else if (nm_utils_ipaddr_is_valid(AF_INET6, v)) { /* Ignore IPv6 addresses */ } else { - PARSE_WARNING("invalid DNS server address %s", v); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid DNS server address '%s'", + v); return NULL; } } @@ -2153,6 +2158,8 @@ read_aliases(NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *filen continue; } + svWarnInvalid(parsed, "alias", _NMLOG_DOMAIN); + device = svGetValueStr(parsed, "DEVICE", &device_value); if (!device) { PARSE_WARNING("alias file '%s' has no DEVICE", full_path); @@ -2404,6 +2411,8 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea svGetValueBoolean(ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64(ifcfg, "IPV6_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, + (int) svGetValueInt64(ifcfg, "IPV6_REQUIRED_TIMEOUT", 10, 0, G_MAXINT32, -1), NM_SETTING_IP6_CONFIG_RA_TIMEOUT, (int) svGetValueInt64(ifcfg, "IPV6_RA_TIMEOUT", 10, 0, G_MAXINT32, 0), NULL); @@ -2505,7 +2514,11 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea } else if (nm_utils_ipaddr_is_valid(AF_INET, v)) { /* Ignore IPv4 addresses */ } else { - PARSE_WARNING("invalid DNS server address %s", v); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid DNS server address '%s'", + v); return NULL; } } @@ -4303,7 +4316,7 @@ make_wireless_setting(shvarFile *ifcfg, GError **error) bytes = g_bytes_new(value, value_len); ssid_len = g_bytes_get_size(bytes); - if (ssid_len > 32 || ssid_len == 0) { + if (ssid_len == 0 || ssid_len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -4679,7 +4692,9 @@ static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( {"--coalesce", NM_ETHTOOL_TYPE_COALESCE}, {"--features", NM_ETHTOOL_TYPE_FEATURE}, {"--offload", NM_ETHTOOL_TYPE_FEATURE}, + {"--pause", NM_ETHTOOL_TYPE_PAUSE}, {"--set-ring", NM_ETHTOOL_TYPE_RING}, + {"-A", NM_ETHTOOL_TYPE_PAUSE}, {"-C", NM_ETHTOOL_TYPE_COALESCE}, {"-G", NM_ETHTOOL_TYPE_RING}, {"-K", NM_ETHTOOL_TYPE_FEATURE}, ); @@ -4719,7 +4734,7 @@ parse_ethtool_option(const char * value, w_iter = &words[2]; while (w_iter && *w_iter) { - if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) { + if (NM_IN_SET(ethtool_type, NM_ETHTOOL_TYPE_FEATURE, NM_ETHTOOL_TYPE_PAUSE)) { w_iter = _next_ethtool_options_nmternary(w_iter, ethtool_type, &ifcfg_option); if (ifcfg_option.has_value) { @@ -5022,6 +5037,7 @@ make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x, const char * cvalue; gs_free char * value = NULL; gboolean found = FALSE; + NMTernary accept_all_mac_addresses; s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); @@ -5119,15 +5135,15 @@ make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x, for (i = 0; options && options[i]; i++) { const char *line = options[i]; const char *equals; - gboolean valid = FALSE; equals = strchr(line, '='); - if (equals) { - ((char *) equals)[0] = '\0'; - valid = nm_setting_wired_add_s390_option(s_wired, line, equals + 1); - } - if (!valid) - PARSE_WARNING("invalid s390 OPTION '%s'", line); + if (!equals) + continue; + + /* Here we don't verify the key/value further. If the file contains invalid keys, + * we will later reject the connection as invalid. */ + ((char *) equals)[0] = '\0'; + nm_setting_wired_add_s390_option(s_wired, line, equals + 1); } found = TRUE; } @@ -5180,6 +5196,15 @@ make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x, } nm_clear_g_free(&value); + accept_all_mac_addresses = svGetValueTernary(ifcfg, "ACCEPT_ALL_MAC_ADDRESSES"); + if (accept_all_mac_addresses != NM_TERNARY_DEFAULT) { + g_object_set(s_wired, + NM_SETTING_WIRED_ACCEPT_ALL_MAC_ADDRESSES, + accept_all_mac_addresses, + NULL); + found = TRUE; + } + if (!found) { g_set_error(error, NM_UTILS_ERROR, @@ -6072,15 +6097,14 @@ make_vlan_setting(shvarFile *ifcfg, const char *file, GError **error) v = iface_name + 4; } - if (v) { - int device_vlan_id; - - /* Grab VLAN ID from interface name; this takes precedence over the - * separate VLAN_ID property for backwards compat. + if (vlan_id == -1 && v) { + /* Grab VLAN ID from interface name; The explicit VLAN_ID option takes precedence + * over detecting the ID based on PHYSDEV. + * + * Note that older versions of NetworkManager had a bug and this would overwrite the + * VLAN_ID in this case. */ - device_vlan_id = _nm_utils_ascii_str_to_int64(v, 10, 0, 4095, -1); - if (device_vlan_id != -1) - vlan_id = device_vlan_id; + vlan_id = _nm_utils_ascii_str_to_int64(v, 10, 0, 4095, -1); } } @@ -6288,6 +6312,7 @@ connection_from_file_full(const char *filename, NMSetting * s_ip4; NMSetting * s_ip6; const char * ifcfg_name = NULL; + gs_free char * s_tmp = NULL; gboolean has_ip4_defroute = FALSE; gboolean has_complex_routes_v4; gboolean has_complex_routes_v6; @@ -6315,8 +6340,6 @@ connection_from_file_full(const char *filename, if (!main_ifcfg) return NULL; - network_ifcfg = svOpenFile(network_file, NULL); - if (!svGetValueBoolean(main_ifcfg, "NM_CONTROLLED", TRUE)) { connection = create_unhandled_connection(filename, main_ifcfg, "unmanaged", out_unhandled); if (!connection) { @@ -6330,6 +6353,16 @@ connection_from_file_full(const char *filename, return g_steal_pointer(&connection); } + if (NM_IN_STRSET(svGetValueStr(main_ifcfg, "DEVICE", &s_tmp), "lo")) { + /* "lo" is not handled by NetworkManager and we ignore it. */ + } else + svWarnInvalid(main_ifcfg, "ifcfg", _NMLOG_DOMAIN); + nm_clear_g_free(&s_tmp); + + network_ifcfg = svOpenFile(network_file, NULL); + /* we don't call svWarnInvalid(network_ifcfg), because we will load this file for + * every profile. So we would get a large number of duplicate warnings. */ + /* iBFT is handled by nm-initrd-generator during boot. */ bootproto = svGetValueStr_cp(main_ifcfg, "BOOTPROTO"); if (bootproto && !g_ascii_strcasecmp(bootproto, "ibft")) { diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c index 3f674dea..134bdf68 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c @@ -7,8 +7,9 @@ #include "nms-ifcfg-rh-storage.h" +#include "libnm-glib-aux/nm-uuid.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-connection.h" #include "nms-ifcfg-rh-plugin.h" @@ -88,7 +89,7 @@ static NMSIfcfgRHStorage * _storage_new(NMSIfcfgRHPlugin *plugin, const char *uuid, const char *filename) { nm_assert(NMS_IS_IFCFG_RH_PLUGIN(plugin)); - nm_assert(!uuid || nm_utils_is_uuid(uuid)); + nm_assert(!uuid || nm_uuid_is_normalized(uuid)); nm_assert(filename && filename[0] == '/'); return g_object_new(NMS_TYPE_IFCFG_RH_STORAGE, diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index ada1942a..febfc120 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -9,7 +9,7 @@ #include <stdlib.h> -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nms-ifcfg-rh-common.h" @@ -593,6 +593,9 @@ const char *const _nm_ethtool_ifcfg_names[] = { ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), + ETHT_NAME(NM_ETHTOOL_ID_PAUSE_AUTONEG, "pause-autoneg"), + ETHT_NAME(NM_ETHTOOL_ID_PAUSE_RX, "pause-rx"), + ETHT_NAME(NM_ETHTOOL_ID_PAUSE_TX, "pause-tx"), ETHT_NAME(NM_ETHTOOL_ID_RING_RX, "rx"), ETHT_NAME(NM_ETHTOOL_ID_RING_RX_JUMBO, "rx-jumbo"), ETHT_NAME(NM_ETHTOOL_ID_RING_RX_MINI, "rx-mini"), @@ -722,6 +725,15 @@ static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( {"rx-mini", NM_ETHTOOL_ID_RING_RX_MINI}, {"tx", NM_ETHTOOL_ID_RING_TX}, ); +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _get_ethtoolid_pause_by_name, + NMEthtoolID, + { nm_assert(name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + {"pause-autoneg", NM_ETHTOOL_ID_PAUSE_AUTONEG}, + {"pause-rx", NM_ETHTOOL_ID_PAUSE_RX}, + {"pause-tx", NM_ETHTOOL_ID_PAUSE_TX}, ); + const NMEthtoolData * nms_ifcfg_rh_utils_get_ethtool_by_name(const char *name, NMEthtoolType ethtool_type) { @@ -737,6 +749,9 @@ nms_ifcfg_rh_utils_get_ethtool_by_name(const char *name, NMEthtoolType ethtool_t case NM_ETHTOOL_TYPE_RING: id = _get_ethtoolid_ring_by_name(name); break; + case NM_ETHTOOL_TYPE_PAUSE: + id = _get_ethtoolid_pause_by_name(name); + break; default: nm_assert_not_reached(); return NULL; @@ -800,6 +815,7 @@ nms_ifcfg_rh_utils_is_numbered_tag_impl(const char *key, } const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { + _KEY_TYPE("ACCEPT_ALL_MAC_ADDRESSES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), _KEY_TYPE("AP_ISOLATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN), @@ -942,6 +958,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { _KEY_TYPE("IPV4_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_REQUIRED_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV4_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6ADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), @@ -964,6 +981,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { _KEY_TYPE("IPV6_PRIVACY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_PRIVACY_PREFER_PUBLIC_IP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_RA_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_REQUIRED_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), _KEY_TYPE("IPV6_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 04a1b63d..b7751ec9 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -7,7 +7,7 @@ #define _UTILS_H_ #include "nm-connection.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" #include "shvar.h" @@ -33,7 +33,7 @@ typedef struct { NMSIfcfgKeyTypeFlags key_flags; } NMSIfcfgKeyTypeInfo; -extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[248]; +extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[251]; const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx); diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 45b76456..ef85b6bf 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -15,8 +15,9 @@ #include <unistd.h> #include <stdio.h> -#include "nm-glib-aux/nm-enum-utils.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "nm-manager.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -32,9 +33,9 @@ #include "nm-setting-team.h" #include "nm-setting-team-port.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-base.h" #include "nms-ifcfg-rh-common.h" #include "nms-ifcfg-rh-reader.h" @@ -203,18 +204,18 @@ write_object(NMSetting8021x * s_8021x, g_return_val_if_fail(ifcfg != NULL, FALSE); g_return_val_if_fail(objtype != NULL, FALSE); - scheme = (*(objtype->vtable->scheme_func))(s_8021x); + scheme = (*(objtype->vtable->scheme_func)) (s_8021x); switch (scheme) { case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: break; case NM_SETTING_802_1X_CK_SCHEME_BLOB: - blob = (*(objtype->vtable->blob_func))(s_8021x); + blob = (*(objtype->vtable->blob_func)) (s_8021x); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: - value = (*(objtype->vtable->path_func))(s_8021x); + value = (*(objtype->vtable->path_func)) (s_8021x); break; case NM_SETTING_802_1X_CK_SCHEME_PKCS11: - value = (*(objtype->vtable->uri_func))(s_8021x); + value = (*(objtype->vtable->uri_func)) (s_8021x); break; default: g_set_error(error, @@ -227,8 +228,8 @@ write_object(NMSetting8021x * s_8021x, /* Set the password for certificate/private key. */ nm_sprintf_buf(secret_name, "%s_PASSWORD", objtype->ifcfg_rh_key); nm_sprintf_buf(secret_flags, "%s_PASSWORD_FLAGS", objtype->ifcfg_rh_key); - password = (*(objtype->vtable->passwd_func))(s_8021x); - flags = (*(objtype->vtable->pwflag_func))(s_8021x); + password = (*(objtype->vtable->passwd_func)) (s_8021x); + flags = (*(objtype->vtable->pwflag_func)) (s_8021x); set_secret(ifcfg, secrets, secret_name, password, secret_flags, flags); if (!objtype->vtable->format_func) @@ -299,6 +300,7 @@ write_blobs(GHashTable *blobs, GError **error) g_bytes_get_size(blob), 0600, NULL, + NULL, &write_error)) { g_set_error(error, NM_SETTINGS_ERROR, @@ -862,7 +864,7 @@ write_wireless_setting(NMConnection *connection, return FALSE; } ssid_data = g_bytes_get_data(ssid, &ssid_len); - if (!ssid_len || ssid_len > 32) { + if (ssid_len == 0 || ssid_len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -903,9 +905,9 @@ write_wireless_setting(NMConnection *connection, svSetValueStr(ifcfg, "ESSID", str->str); g_string_free(str, TRUE); } else { - char buf[33]; + char buf[NM_IW_ESSID_MAX_SIZE + 1]; - nm_assert(ssid_len <= 32); + nm_assert(ssid_len <= NM_IW_ESSID_MAX_SIZE); memcpy(buf, ssid_data, ssid_len); buf[ssid_len] = '\0'; svSetValueStr(ifcfg, "ESSID", buf); @@ -1075,25 +1077,18 @@ write_hostname_setting(NMConnection *connection, shvarFile *ifcfg) svSetValueInt64_cond(ifcfg, "HOSTNAME_ONLY_FROM_DEFAULT", t != NM_TERNARY_DEFAULT, t); } -static gboolean -write_wired_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) +static void +write_wired_setting_impl(NMSettingWired *s_wired, shvarFile *ifcfg, gboolean is_virtual) { - NMSettingWired * s_wired; const char *const *s390_subchannels; - guint32 mtu, num_opts, i; + guint32 mtu; + guint32 num_opts; + guint32 i; const char *const *macaddr_blacklist; - s_wired = nm_connection_get_setting_wired(connection); - if (!s_wired) { - g_set_error(error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", - NM_SETTING_WIRED_SETTING_NAME); - return FALSE; - } - - svSetValueStr(ifcfg, "HWADDR", nm_setting_wired_get_mac_address(s_wired)); + svSetValue(ifcfg, + "HWADDR", + nm_setting_wired_get_mac_address(s_wired) ?: (is_virtual ? "" : NULL)); svSetValueStr(ifcfg, "MACADDR", nm_setting_wired_get_cloned_mac_address(s_wired)); @@ -1167,8 +1162,42 @@ write_wired_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValueStr(ifcfg, "OPTIONS", tmp->str); } + svSetValueTernary(ifcfg, + "ACCEPT_ALL_MAC_ADDRESSES", + nm_setting_wired_get_accept_all_mac_addresses(s_wired)); +} + +static gboolean +write_wired_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingWired *s_wired; + + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_WIRED_SETTING_NAME); + return FALSE; + } + svSetValueStr(ifcfg, "TYPE", TYPE_ETHERNET); + write_wired_setting_impl(s_wired, ifcfg, FALSE); + return TRUE; +} + +static gboolean +write_wired_for_virtual(NMConnection *connection, shvarFile *ifcfg) +{ + NMSettingWired *s_wired; + + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired) + return FALSE; + + write_wired_setting_impl(s_wired, ifcfg, TRUE); return TRUE; } @@ -1334,6 +1363,26 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error g_string_append(str, nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); g_string_append_printf(str, " %" G_GUINT32_FORMAT, u32); } + for (ethtool_id = _NM_ETHTOOL_ID_PAUSE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_PAUSE_LAST; + ethtool_id++) { + nm_assert(nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + if (!nm_setting_option_get_boolean(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &b)) + continue; + + _ethtool_gstring_prepare(&str, &is_first, 'A', iface); + g_string_append_c(str, ' '); + g_string_append(str, nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + g_string_append(str, b ? " on" : " off"); + } + + if (!str) { + /* Write an empty dummy "-A" option without arguments. This is to + * ensure that the reader will create an (all default) NMSettingEthtool. + * Also, it seems that `ethtool -A "$IFACE"` is silently accepted. */ + _ethtool_gstring_prepare(&str, &is_first, 'A', iface); + } } if (str) { @@ -1367,35 +1416,6 @@ vlan_priority_maplist_to_stringlist(NMSettingVlan *s_vlan, NMVlanPriorityMap map } static gboolean -write_wired_for_virtual(NMConnection *connection, shvarFile *ifcfg) -{ - NMSettingWired *s_wired; - gboolean has_wired = FALSE; - - s_wired = nm_connection_get_setting_wired(connection); - if (s_wired) { - const char *device_mac, *cloned_mac; - guint32 mtu; - - has_wired = TRUE; - - device_mac = nm_setting_wired_get_mac_address(s_wired); - svSetValue(ifcfg, "HWADDR", device_mac ?: ""); - - cloned_mac = nm_setting_wired_get_cloned_mac_address(s_wired); - svSetValueStr(ifcfg, "MACADDR", cloned_mac); - - svSetValueStr(ifcfg, - "GENERATE_MAC_ADDRESS_MASK", - nm_setting_wired_get_generate_mac_address_mask(s_wired)); - - mtu = nm_setting_wired_get_mtu(s_wired); - svSetValueInt64_cond(ifcfg, "MTU", mtu != 0, mtu); - } - return has_wired; -} - -static gboolean write_vlan_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { NMSettingVlan *s_vlan; @@ -1542,36 +1562,40 @@ write_team_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, static gboolean write_bridge_vlans(NMSetting * setting, - const char *property_name, + gboolean is_port, shvarFile * ifcfg, const char *key, GError ** error) { - gs_unref_ptrarray GPtrArray *vlans = NULL; - NMBridgeVlan * vlan; - GString * string; - guint i; + GPtrArray * vlans; + NMBridgeVlan * vlan; + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(0, FALSE); + guint i; - g_object_get(setting, property_name, &vlans, NULL); + if (is_port) + vlans = _nm_setting_bridge_port_get_vlans(NM_SETTING_BRIDGE_PORT(setting)); + else + vlans = _nm_setting_bridge_get_vlans(NM_SETTING_BRIDGE(setting)); if (!vlans || !vlans->len) return TRUE; - string = g_string_new(""); for (i = 0; i < vlans->len; i++) { gs_free char *vlan_str = NULL; vlan = vlans->pdata[i]; vlan_str = nm_bridge_vlan_to_str(vlan, error); - if (!vlan_str) - return FALSE; - if (string->len > 0) - g_string_append(string, ","); - nm_utils_escaped_tokens_escape_gstr_assert(vlan_str, ",", string); + if (!vlan_str) { + /* nm_bridge_vlan_to_str() cannot fail (for now). */ + nm_assert_not_reached(); + continue; + } + if (strbuf.len > 0) + nm_str_buf_append_c(&strbuf, ','); + nm_str_buf_append(&strbuf, nm_utils_escaped_tokens_escape_unnecessary(vlan_str, ",")); } - svSetValueStr(ifcfg, key, string->str); - g_string_free(string, TRUE); + svSetValueStr(ifcfg, key, nm_str_buf_get_str(&strbuf)); return TRUE; } @@ -1807,11 +1831,7 @@ write_bridge_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired svSetValueStr(ifcfg, "BRIDGING_OPTS", opts->str); g_string_free(opts, TRUE); - if (!write_bridge_vlans((NMSetting *) s_bridge, - NM_SETTING_BRIDGE_VLANS, - ifcfg, - "BRIDGE_VLANS", - error)) + if (!write_bridge_vlans((NMSetting *) s_bridge, FALSE, ifcfg, "BRIDGE_VLANS", error)) return FALSE; svSetValueStr(ifcfg, "TYPE", TYPE_BRIDGE); @@ -1862,11 +1882,7 @@ write_bridge_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **e svSetValueStr(ifcfg, "BRIDGING_OPTS", string->str); g_string_free(string, TRUE); - if (!write_bridge_vlans((NMSetting *) s_port, - NM_SETTING_BRIDGE_PORT_VLANS, - ifcfg, - "BRIDGE_PORT_VLANS", - error)) + if (!write_bridge_vlans((NMSetting *) s_port, TRUE, ifcfg, "BRIDGE_PORT_VLANS", error)) return FALSE; return TRUE; @@ -2824,6 +2840,9 @@ write_ip4_setting(NMConnection *connection, timeout = nm_setting_ip_config_get_dhcp_timeout(s_ip4); svSetValueInt64_cond(ifcfg, "IPV4_DHCP_TIMEOUT", timeout != 0, timeout); + timeout = nm_setting_ip_config_get_required_timeout(s_ip4); + svSetValueInt64_cond(ifcfg, "IPV4_REQUIRED_TIMEOUT", timeout != -1, 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); @@ -3021,6 +3040,9 @@ write_ip6_setting(NMConnection *connection, timeout = nm_setting_ip_config_get_dhcp_timeout(s_ip6); svSetValueInt64_cond(ifcfg, "IPV6_DHCP_TIMEOUT", timeout != 0, timeout); + timeout = nm_setting_ip_config_get_required_timeout(s_ip6); + svSetValueInt64_cond(ifcfg, "IPV6_REQUIRED_TIMEOUT", timeout != -1, timeout); + flags = nm_setting_ip_config_get_dhcp_hostname_flags(s_ip6); svSetValueInt64_cond(ifcfg, "DHCPV6_HOSTNAME_FLAGS", diff --git a/src/core/settings/plugins/ifcfg-rh/shvar.c b/src/core/settings/plugins/ifcfg-rh/shvar.c index 386bcac7..d82efb3c 100644 --- a/src/core/settings/plugins/ifcfg-rh/shvar.c +++ b/src/core/settings/plugins/ifcfg-rh/shvar.c @@ -14,10 +14,11 @@ #include <sys/stat.h> #include <unistd.h> -#include "nm-core-internal.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-core-utils.h" -#include "nm-glib-aux/nm-enum-utils.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-enum-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "c-list/src/c-list.h" #include "nms-ifcfg-rh-utils.h" @@ -152,17 +153,42 @@ _escape_ansic(const char *source) const char *p; char * dest; char * q; + gsize n_alloc; nm_assert(source); - p = (const char *) source; - /* Each source byte needs maximally four destination chars (\777) */ - q = dest = g_malloc(strlen(source) * 4 + 1 + 3); + n_alloc = 4; + for (p = source; p[0]; p++) { + switch (*p) { + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + case '\\': + case '"': + case '\'': + n_alloc += 2; + break; + default: + if (!nm_ascii_is_regular(*p)) + n_alloc += 4; + else + n_alloc += 1; + break; + } + } + + dest = g_malloc(n_alloc); + + q = dest; *q++ = '$'; *q++ = '\''; - while (*p) { + for (p = source; p[0]; p++) { + nm_assert(q < &dest[n_alloc]); switch (*p) { case '\b': *q++ = '\\'; @@ -195,7 +221,7 @@ _escape_ansic(const char *source) *q++ = *p; break; default: - if ((*p < ' ') || (*p >= 0177)) { + if (!nm_ascii_is_regular(*p)) { *q++ = '\\'; *q++ = '0' + (((*p) >> 6) & 07); *q++ = '0' + (((*p) >> 3) & 07); @@ -204,12 +230,11 @@ _escape_ansic(const char *source) *q++ = *p; break; } - p++; } *q++ = '\''; *q++ = '\0'; - nm_assert(q - dest <= strlen(source) * 4 + 1 + 3); + nm_assert(q - dest == n_alloc); return dest; } @@ -217,7 +242,7 @@ _escape_ansic(const char *source) /*****************************************************************************/ #define _char_req_escape(ch) NM_IN_SET(ch, '"', '\\', '$', '`') -#define _char_req_escape_old(ch) NM_IN_SET(ch, '"', '\\', '\'', '$', '`', '~') +#define _char_req_escape_old(ch) NM_IN_SET(ch, '"', '\\', '$', '`', '\'', '~') #define _char_req_quotes(ch) NM_IN_SET(ch, ' ', '\'', '~', '\t', '|', '&', ';', '(', ')', '<', '>') const char * @@ -226,29 +251,48 @@ svEscape(const char *s, char **to_free) char *new; gsize mangle = 0; gboolean requires_quotes = FALSE; - int newlen; - size_t i, j, slen; + gsize n_alloc; + gsize slen; + gsize i; + gsize j; + gboolean all_ascii = TRUE; for (slen = 0; s[slen]; slen++) { if (_char_req_escape(s[slen])) mangle++; else if (_char_req_quotes(s[slen])) requires_quotes = TRUE; - else if (s[slen] < ' ') { - /* if the string contains newline we can only express it using ANSI C quotation - * (as we don't support line continuation). - * Additionally, ANSI control characters look odd with regular quotation, so handle - * them too. */ - return (*to_free = _escape_ansic(s)); + else if (!nm_ascii_is_regular(s[slen])) { + if (nm_ascii_is_ctrl_or_del(s[slen])) { + /* if the string contains newline we can only express it using ANSI C quotation + * (as we don't support line continuation). + * Additionally, ANSI control characters look odd with regular quotation, so handle + * them too. */ + return (*to_free = _escape_ansic(s)); + } + all_ascii = FALSE; + requires_quotes = TRUE; } } + + if (!all_ascii && !g_utf8_validate(s, -1, NULL)) { + /* The string is not valid ASCII/UTF-8. We can escape that via + * _escape_ansic(), however the reader might have a problem to + * do something sensible with the blob later. + * + * This is really a bug of the caller, which should not present us with + * non-text in the first place. But at this place, we cannot handle the + * error better, so just escape it. */ + return (*to_free = _escape_ansic(s)); + } + if (!mangle && !requires_quotes) { *to_free = NULL; return s; } - newlen = slen + mangle + 3; /* 3 is extra ""\0 */ - new = g_malloc(newlen); + n_alloc = slen + mangle + 3; /* 3 is extra ""\0 */ + new = g_malloc(n_alloc); j = 0; new[j++] = '"'; @@ -260,7 +304,7 @@ svEscape(const char *s, char **to_free) new[j++] = '"'; new[j++] = '\0'; - nm_assert(j == slen + mangle + 3); + nm_assert(j == n_alloc); *to_free = new; return new; @@ -318,14 +362,14 @@ _ch_hex_get(char ch) } static void -_gstr_init(GString **str, const char *value, gsize i) +_strbuf_init(NMStrBuf *str, const char *value, gsize i) { nm_assert(str); nm_assert(value); - if (!(*str)) { - /* if @str is not yet initialized, it allocates - * a new GString and copies @i characters from + if (str->allocated == 0) { + /* if @str is not yet initialized, it initializes + * a new NMStrBuf and copies @i characters from * @value over. * * Unescaping usually does not extend the length of a string, @@ -335,20 +379,26 @@ _gstr_init(GString **str, const char *value, gsize i) * (FACTOR*strlen(value) + CONST), which is non trivial to get * right in all cases. Also, we would have to provision for the * very unlikely extreme case. - * Instead, use a GString buffer which can grow as needed. But for an + * Instead, use a NMStrBuf buffer which can grow as needed. But for an * initial guess, strlen(value) is a good start */ - *str = g_string_new_len(NULL, strlen(value) + 3); - if (i) - g_string_append_len(*str, value, i); + nm_str_buf_maybe_expand(str, strlen(value) + 3u, FALSE); + nm_str_buf_append_len(str, value, i); } } const char * svUnescape(const char *value, char **to_free) { - gsize i, j; - GString *str = NULL; + return svUnescape_full(value, to_free, TRUE); +} + +const char * +svUnescape_full(const char *value, char **to_free, gboolean check_utf8) +{ + NMStrBuf str = NM_STR_BUF_INIT(0, FALSE); int looks_like_old_svescaped = -1; + gsize i; + gsize j; /* we handle bash syntax here (note that ifup has #!/bin/bash. * Thus, see https://www.gnu.org/software/bash/manual/html_node/Quoting.html#Quoting */ @@ -395,20 +445,20 @@ svUnescape(const char *value, char **to_free) if (value[i] == '\\') { /* backslash escape */ - _gstr_init(&str, value, i); + _strbuf_init(&str, value, i); i++; if (G_UNLIKELY(value[i] == '\0')) { /* we don't support line continuation */ goto out_error; } - g_string_append_c(str, value[i]); + nm_str_buf_append_c(&str, value[i]); i++; goto loop1_next; } if (value[i] == '\'') { /* single quotes */ - _gstr_init(&str, value, i); + _strbuf_init(&str, value, i); i++; j = i; while (TRUE) { @@ -420,14 +470,14 @@ svUnescape(const char *value, char **to_free) break; j++; } - g_string_append_len(str, &value[i], j - i); + nm_str_buf_append_len(&str, &value[i], j - i); i = j + 1; goto loop1_next; } if (value[i] == '"') { /* double quotes */ - _gstr_init(&str, value, i); + _strbuf_init(&str, value, i); i++; while (TRUE) { if (value[i] == '"') { @@ -466,11 +516,11 @@ svUnescape(const char *value, char **to_free) if (looks_like_old_svescaped < 0) looks_like_old_svescaped = _looks_like_old_svescaped(value); if (!looks_like_old_svescaped) - g_string_append_c(str, '\\'); + nm_str_buf_append_c(&str, '\\'); } else - g_string_append_c(str, '\\'); + nm_str_buf_append_c(&str, '\\'); } - g_string_append_c(str, value[i]); + nm_str_buf_append_c(&str, value[i]); i++; } goto loop1_next; @@ -478,7 +528,7 @@ svUnescape(const char *value, char **to_free) if (value[i] == '$' && value[i + 1] == '\'') { /* ANSI-C Quoting */ - _gstr_init(&str, value, i); + _strbuf_init(&str, value, i); i += 2; while (TRUE) { char ch; @@ -552,7 +602,7 @@ svUnescape(const char *value, char **to_free) } } /* like bash, we cut too large numbers off. E.g. A=$'\772' becomes 0xfa */ - g_string_append_c(str, (guint8) v); + nm_str_buf_append_c(&str, (guint8) v); } else if (NM_IN_SET(value[i], 'x', 'u', 'U')) { const char escape_type = value[i]; int max_digits = escape_type == 'x' ? 2 : escape_type == 'u' ? 4 : 8; @@ -561,8 +611,7 @@ svUnescape(const char *value, char **to_free) i++; if (!_ch_hex_is(value[i])) { /* missing hex value after "\x" escape. This is treated like no escaping. */ - g_string_append_c(str, '\\'); - g_string_append_c(str, escape_type); + nm_str_buf_append_c(&str, '\\', escape_type); } else { v = _ch_hex_get(value[i]); i++; @@ -574,22 +623,21 @@ svUnescape(const char *value, char **to_free) i++; } if (escape_type == 'x') - g_string_append_c(str, v); + nm_str_buf_append_c(&str, v); else { /* we treat the unicode escapes as utf-8 encoded values. */ - g_string_append_unichar(str, v); + nm_str_buf_append_unichar(&str, v); } } } else { - g_string_append_c(str, '\\'); - g_string_append_c(str, value[i]); + nm_str_buf_append_c(&str, '\\', value[i]); i++; } goto loop_ansic_next; } } else ch = value[i]; - g_string_append_c(str, ch); + nm_str_buf_append_c(&str, ch); i++; loop_ansic_next:; } @@ -603,8 +651,8 @@ loop_ansic_next:; } /* an unquoted, regular character. Just consume it directly. */ - if (str) - g_string_append_c(str, value[i]); + if (str.allocated > 0) + nm_str_buf_append_c(&str, value[i]); i++; loop1_next:; @@ -614,22 +662,30 @@ loop1_next:; out_value: if (i == 0) { - nm_assert(!str); + nm_assert(str.allocated == 0); + nm_assert(!str._priv_str); *to_free = NULL; return ""; } - if (str) { - if (str->len == 0 || str->str[0] == '\0') { - g_string_free(str, TRUE); + if (str.allocated > 0) { + if (check_utf8 && !nm_str_buf_utf8_validate(&str)) + goto out_error; + if (str.len == 0 || nm_str_buf_get_str_unsafe(&str)[0] == '\0') { + nm_str_buf_destroy(&str); *to_free = NULL; return ""; } else { - *to_free = g_string_free(str, FALSE); + *to_free = nm_str_buf_finalize(&str, NULL); return *to_free; } } + if (check_utf8 && !g_utf8_validate(value, i, NULL)) { + *to_free = NULL; + return NULL; + } + if (value[i] != '\0') { *to_free = g_strndup(value, i); return *to_free; @@ -639,8 +695,7 @@ out_value: return value; out_error: - if (str) - g_string_free(str, TRUE); + nm_str_buf_destroy(&str); *to_free = NULL; return NULL; } @@ -1095,9 +1150,8 @@ _svGetValue(shvarFile *s, const char *key, char **to_free) if (line && line->line) { v = svUnescape(line->line, to_free); if (!v) { - /* a wrongly quoted value is treated like the empty string. - * See also svWriteFile(), which handles unparsable values - * that way. */ + /* a wrongly quoted value or non-UTF-8 is treated like the empty string. + * See also svWriteFile(), which handles unparsable values that way. */ nm_assert(!*to_free); return ""; } @@ -1470,6 +1524,91 @@ svUnsetValue(shvarFile *s, const char *key) /*****************************************************************************/ +void +svWarnInvalid(shvarFile *s, const char *file_type, NMLogDomain log_domain) +{ + shvarLine *line; + gsize n; + + if (!nm_logging_enabled(LOGL_WARN, log_domain)) + return; + + n = 0; + c_list_for_each_entry (line, &s->lst_head, lst) { + gs_free char *s_tmp = NULL; + + n++; + + if (!line->key) { + const char *str; + + nm_assert(line->line); + str = nm_str_skip_leading_spaces(line->line); + if (!NM_IN_SET(str[0], '\0', '#')) { + nm_log_warn(log_domain, + "ifcfg-rh: %s,%s:%zu: invalid line ignored", + file_type, + s->fileName, + n); + } + continue; + } + + if (g_hash_table_lookup(s->lst_idx, line) != line) { + nm_log_warn( + log_domain, + "ifcfg-rh: %s,%s:%zu: key %s is duplicated and the early occurrence ignored", + file_type, + s->fileName, + n, + line->key); + continue; + } + + if (!line->line) { + /* the line is deleted via svUnsetValue(). Ignore. */ + continue; + } + + if (!svUnescape(line->line, &s_tmp)) { + if (!svUnescape_full(line->line, &s_tmp, FALSE)) { + nm_log_warn(log_domain, + "ifcfg-rh: %s,%s:%zu: key %s is badly quoted and is treated as \"\"", + file_type, + s->fileName, + n, + line->key); + } else { + nm_log_warn(log_domain, + "ifcfg-rh: %s,%s:%zu: key %s does not contain valid UTF-8 and is " + "treated as \"\"", + file_type, + s->fileName, + n, + line->key); + } + continue; + } + + /* TODO: we read different shell scripts, and whether a key is recognized + * depends on the type. For example, alias files only accept a subset of + * known keys. + * + * Basically, depending on the @file_type, different keys are valid. */ + if (!nms_ifcfg_rh_utils_is_well_known_key(line->key)) { + nm_log_dbg(log_domain, + "ifcfg-rh: %s,%s:%zu: key %s is unknown and ignored", + file_type, + s->fileName, + n, + line->key); + continue; + } + } +} + +/*****************************************************************************/ + /* Write the current contents iff modified. Returns FALSE on error * and TRUE on success. Do not write if no values have been modified. * The mode argument is only used if creating the file, not if diff --git a/src/core/settings/plugins/ifcfg-rh/shvar.h b/src/core/settings/plugins/ifcfg-rh/shvar.h index 6965d873..cf91642f 100644 --- a/src/core/settings/plugins/ifcfg-rh/shvar.h +++ b/src/core/settings/plugins/ifcfg-rh/shvar.h @@ -107,6 +107,7 @@ void svCloseFile(shvarFile *s); const char *svEscape(const char *s, char **to_free); const char *svUnescape(const char *s, char **to_free); +const char *svUnescape_full(const char *value, char **to_free, gboolean check_utf8); static inline void _nm_auto_shvar_file_close(shvarFile **p_s) @@ -120,4 +121,6 @@ _nm_auto_shvar_file_close(shvarFile **p_s) } #define nm_auto_shvar_file_close nm_auto(_nm_auto_shvar_file_close) +void svWarnInvalid(shvarFile *s, const char *file_type, NMLogDomain log_domain); + #endif /* _SHVAR_H */ diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-a.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-a.cexpected index d81d9187..aebcd2b8 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-a.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-a.cexpected @@ -1,5 +1,5 @@ -HWADDR=00:22:15:59:62:97 TYPE=Ethernet +HWADDR=00:22:15:59:62:97 BRIDGING_OPTS="priority=28 hairpin_mode=1" NAME="System test-bridge-component" UUID=${UUID} diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-b.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-b.cexpected index 2e69c5e7..71d2cda8 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-b.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-bridge-component-b.cexpected @@ -1,5 +1,5 @@ -HWADDR=00:22:15:59:62:97 TYPE=Ethernet +HWADDR=00:22:15:59:62:97 NAME="System test-bridge-component" UUID=${UUID} DEVICE=eth0 diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected index 59a6f79b..240cd5c1 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected @@ -1,5 +1,5 @@ -HWADDR=00:11:22:33:44:EE TYPE=Ethernet +HWADDR=00:11:22:33:44:EE KEY_MGMT=IEEE8021X IEEE_8021X_EAP_METHODS=PEAP IEEE_8021X_IDENTITY="Jara Cimrman" diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected index a8ff8df3..d31d8ff5 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected @@ -1,6 +1,6 @@ +TYPE=Ethernet HWADDR=31:33:33:37:BE:CD MTU=1492 -TYPE=Ethernet BRIDGING_OPTS="priority=50 path_cost=33" BRIDGE_PORT_VLANS="1 untagged,2 pvid,4-4094 untagged" NAME="Test Write Bridge Component" diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected index cd8fc96f..cc29a2cc 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected @@ -1,6 +1,6 @@ +TYPE=Ethernet HWADDR=31:33:33:37:BE:CD MTU=1492 -TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy.cexpected index a28c5c1c..8197f320 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy.cexpected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy.cexpected @@ -1,5 +1,5 @@ -HWADDR=00:16:41:11:22:33 TYPE=Ethernet +HWADDR=00:16:41:11:22:33 PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=dhcp diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use new file mode 100644 index 00000000..fc9c8a45 --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use @@ -0,0 +1,4 @@ +VLAN=yes +TYPE=Vlan +DEVICE=eth0.9 +VLAN_ID=10 diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use.cexpected new file mode 100644 index 00000000..a7be14ce --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-vlanid-use.cexpected @@ -0,0 +1,15 @@ +VLAN=yes +TYPE=Vlan +PHYSDEV=eth0 +VLAN_ID=10 +REORDER_HDR=yes +GVRP=no +MVRP=no +HWADDR= +PROXY_METHOD=none +BROWSER_ONLY=no +IPV6INIT=no +NAME="Vlan test-vlan-vlanid-use" +UUID=${UUID} +DEVICE=eth0.9 +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-suite-b-192-tls b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-suite-b-192-tls index 9a74bb4d..a21c301c 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-suite-b-192-tls +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-suite-b-192-tls @@ -3,7 +3,6 @@ DEVICE=eth2 HWADDR=00:16:41:11:22:33 BOOTPROTO=dhcp ONBOOT=yes -ONBOOT=yes USERCTL=yes IPV6INIT=no NM_CONTROLLED=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls index 42ed1d68..bb63d5e8 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls @@ -4,7 +4,6 @@ DEVICE=eth2 HWADDR=00:16:41:11:22:33 BOOTPROTO=dhcp ONBOOT=yes -ONBOOT=yes USERCTL=yes IPV6INIT=no NM_CONTROLLED=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected index 040ddc9d..92c03b12 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected @@ -13,8 +13,10 @@ #L2 METRIC1='' -METRIC2=$'\U0x' -METRIC3=$'x\U0' +METRIC2= +#NM: METRIC2=$'\U0x' +METRIC3= +#NM: METRIC3=$'x\U0' #L4 IPADDR=set-by-test1 diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-1.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-1.cexpected new file mode 100644 index 00000000..5186f90c --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-1.cexpected @@ -0,0 +1,14 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=test_roundtrip_ethtool +UUID=${UUID} +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-2.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-2.cexpected new file mode 100644 index 00000000..5632ebec --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-2.cexpected @@ -0,0 +1,15 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +ETHTOOL_OPTS="-A net0" +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=test_roundtrip_ethtool +UUID=${UUID} +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-3.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-3.cexpected new file mode 100644 index 00000000..96eec43b --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-3.cexpected @@ -0,0 +1,15 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +ETHTOOL_OPTS="autoneg on" +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=test_roundtrip_ethtool +UUID=${UUID} +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-4.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-4.cexpected new file mode 100644 index 00000000..90250a30 --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-4.cexpected @@ -0,0 +1,15 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +ETHTOOL_OPTS="-K net0 rx on" +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=test_roundtrip_ethtool +UUID=${UUID} +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-5.cexpected b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-5.cexpected new file mode 100644 index 00000000..721eacb2 --- /dev/null +++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_roundtrip_ethtool-5.cexpected @@ -0,0 +1,15 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +ETHTOOL_OPTS="autoneg on ; -K net0 rx on" +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME=test_roundtrip_ethtool +UUID=${UUID} +ONBOOT=yes diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 9d9ed626..d9829f84 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -17,7 +17,8 @@ #include <linux/if_ether.h> #include <linux/if_infiniband.h> -#include "nm-glib-aux/nm-json-aux.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-json-aux.h" #include "nm-utils.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -36,9 +37,9 @@ #include "nm-setting-serial.h" #include "nm-setting-vlan.h" #include "nm-setting-dcb.h" -#include "nm-core-internal.h" -#include "nm-base/nm-ethtool-base.h" -#include "nm-base/nm-ethtool-utils-base.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-base/nm-ethtool-utils-base.h" #include "NetworkManagerUtils.h" @@ -180,8 +181,20 @@ _assert_expected_content(NMConnection *connection, const char *filename, const c } if (len_expectd != len_written || memcmp(content_expectd, content_written, len_expectd) != 0) { - if (g_getenv("NMTST_IFCFG_RH_UPDATE_EXPECTED") - || nm_streq0(g_getenv("NM_TEST_REGENERATE"), "1")) { + static int rewrite_static = 0; + int rewrite; + + rewrite = g_atomic_int_get(&rewrite_static); + if (G_UNLIKELY(rewrite == 0)) { + rewrite = (g_getenv("NMTST_IFCFG_RH_UPDATE_EXPECTED") + || nm_streq0(g_getenv("NM_TEST_REGENERATE"), "1")) + ? 1 + : -1; + if (!g_atomic_int_compare_and_exchange(&rewrite_static, 0, rewrite)) + g_assert_not_reached(); + } + + if (rewrite > 0) { if (uuid) { gs_free char *search = g_strdup_printf("UUID=%s\n", uuid); const char * s; @@ -209,15 +222,16 @@ _assert_expected_content(NMConnection *connection, const char *filename, const c success = g_file_set_contents(expected, content_written, len_written, &error); nmtst_assert_success(success, error); } else { - g_error("The content of \"%s\" (%zu) differs from \"%s\" (%zu). Set " - "NMTST_IFCFG_RH_UPDATE_EXPECTED=yes to update the files " - "inplace\n\n>>>%s<<<\n\n>>>%s<<<\n", - filename, - len_written, - expected, - len_expectd, - content_written, - content_expectd); + g_error( + "The content of \"%s\" (%zu) differs from \"%s\" (%zu). Set " + "NMTST_IFCFG_RH_UPDATE_EXPECTED=yes (or NM_TEST_REGENERATE=1) to update the files " + "inplace\n\n>>>%s<<<\n\n>>>%s<<<\n", + filename, + len_written, + expected, + len_expectd, + content_written, + content_expectd); } } } @@ -359,8 +373,10 @@ _writer_new_connection_reread(NMConnection * connection, if (out_filename) *out_filename = filename; - else + else { + nmtst_file_unlink(filename); g_free(filename); + } } static void @@ -722,10 +738,13 @@ test_read_variables_corner_cases(void) const char * mac; char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + NMTST_EXPECT_NM_WARN("*key NAME is badly quoted and is treated as \"\"*"); + NMTST_EXPECT_NM_WARN("*key ZONE is badly quoted and is treated as \"\"*"); connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-variables-corner-cases-1", NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages(); /* ===== CONNECTION SETTING ===== */ s_con = nm_connection_get_setting_connection(connection); @@ -814,10 +833,12 @@ test_read_unrecognized(void) gs_free char * unhandled_spec = NULL; guint64 expected_timestamp = 0; + NMTST_EXPECT_NM_WARN("*key NAME is badly quoted and is treated as \"\"*"); connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-unrecognized", NULL, NULL, &unhandled_spec); + g_test_assert_expected_messages(); g_assert_cmpstr(unhandled_spec, ==, "unrecognized:mac:00:11:22:33"); /* ===== CONNECTION SETTING ===== */ @@ -988,10 +1009,12 @@ test_read_wired_dhcp(void) char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xee}; const char * mac; + NMTST_EXPECT_NM_WARN("*key IPV6INIT is duplicated and the early occurrence ignored*"); connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp", NULL, TYPE_ETHERNET, &unmanaged); + g_test_assert_expected_messages(); g_assert(unmanaged == NULL); /* ===== CONNECTION SETTING ===== */ @@ -2519,7 +2542,7 @@ test_write_dns_options(void) NM_SETTING_CONNECTION_ID, "Test DNS options", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -3567,10 +3590,12 @@ test_read_wifi_wpa_eap_tls(void) char * unmanaged = NULL; const char * expected_privkey_password = "test1"; + NMTST_EXPECT_NM_WARN("*key ONBOOT is duplicated and the early occurrence ignored*"); connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-eap-tls", NULL, TYPE_ETHERNET, &unmanaged); + g_test_assert_expected_messages(); g_assert(!unmanaged); /* ===== WIRELESS SETTING ===== */ @@ -3775,10 +3800,12 @@ test_read_wifi_wep_eap_ttls_chap(void) NMSetting8021x * s_8021x; char * unmanaged = NULL; + NMTST_EXPECT_NM_WARN("*key ONBOOT is duplicated and the early occurrence ignored*"); connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-eap-ttls-chap", NULL, TYPE_WIRELESS, &unmanaged); + g_test_assert_expected_messages(); g_assert(!unmanaged); /* ===== WIRELESS SETTING ===== */ @@ -3933,6 +3960,76 @@ test_read_wired_unknown_ethtool_opt(void) } static void +test_roundtrip_ethtool(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSetting * s_ethtool; + NMSetting * s_wired; + + connection = nmtst_create_minimal_connection("test_roundtrip_ethtool", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_roundtrip_ethtool-1.cexpected", + NULL); + g_clear_object(&connection); + + connection = nmtst_create_minimal_connection("test_roundtrip_ethtool", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_ethtool = nm_setting_ethtool_new(); + nm_connection_add_setting(connection, s_ethtool); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_roundtrip_ethtool-2.cexpected", + NULL); + g_clear_object(&connection); + + connection = nmtst_create_minimal_connection("test_roundtrip_ethtool", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_wired = nm_connection_get_setting(connection, NM_TYPE_SETTING_WIRED); + g_object_set(s_wired, NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_roundtrip_ethtool-3.cexpected", + NULL); + g_clear_object(&connection); + + connection = nmtst_create_minimal_connection("test_roundtrip_ethtool", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_ethtool = nm_setting_ethtool_new(); + nm_connection_add_setting(connection, s_ethtool); + nm_setting_option_set_boolean(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX, TRUE); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_roundtrip_ethtool-4.cexpected", + NULL); + g_clear_object(&connection); + + connection = nmtst_create_minimal_connection("test_roundtrip_ethtool", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_wired = nm_connection_get_setting(connection, NM_TYPE_SETTING_WIRED); + g_object_set(s_wired, NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, NULL); + s_ethtool = nm_setting_ethtool_new(); + nm_connection_add_setting(connection, s_ethtool); + nm_setting_option_set_boolean(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX, TRUE); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_roundtrip_ethtool-5.cexpected", + NULL); + g_clear_object(&connection); +} + +static void test_read_wifi_hidden(void) { NMConnection * connection; @@ -3977,7 +4074,7 @@ test_write_wifi_hidden(void) NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Hidden", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -4062,7 +4159,7 @@ test_write_wifi_mac_random(gconstpointer user_data) NM_SETTING_CONNECTION_ID, val, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -4122,7 +4219,7 @@ test_write_wired_wake_on_lan(void) NM_SETTING_CONNECTION_ID, "Test Write Wired Wake-on-LAN", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -4305,7 +4402,7 @@ test_write_wifi_band_a(void) NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Band A", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -4363,7 +4460,7 @@ test_write_wifi_ap_mode(void) NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi AP Mode", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -4676,7 +4773,7 @@ test_write_wired_static(void) NM_SETTING_CONNECTION_ID, "Test Write Wired Static", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, @@ -4831,7 +4928,7 @@ test_write_wired_static_with_generic(void) NM_SETTING_CONNECTION_ID, "Test Write Wired Static", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, @@ -4999,7 +5096,7 @@ test_write_wired_dhcp(void) NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5111,7 +5208,7 @@ test_write_routing_rules(void) NM_SETTING_CONNECTION_ID, "Test Write Routing Rules", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5169,7 +5266,7 @@ test_write_wired_match(void) NM_SETTING_CONNECTION_ID, "Test Write Wired with Match setting", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5315,7 +5412,7 @@ test_write_wired_static_ip6_only(void) NM_SETTING_CONNECTION_ID, "Test Write Wired Static IP6 Only", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5432,7 +5529,7 @@ test_write_wired_static_ip6_only_gw(gconstpointer user_data) NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5587,7 +5684,7 @@ test_write_wired_static_routes(void) NM_SETTING_CONNECTION_ID, "Test Write Wired Static Routes", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5711,7 +5808,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2(void) NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP 802.1x PEAP MSCHAPv2", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5813,7 +5910,7 @@ test_write_wired_8021x_tls(gconstpointer test_data) NM_SETTING_CONNECTION_ID, "Test Write Wired 802.1x TLS Blobs", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -5983,7 +6080,7 @@ test_write_wired_aliases(void) NM_SETTING_CONNECTION_ID, "alias0", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -6110,7 +6207,7 @@ test_write_gateway(void) NM_SETTING_CONNECTION_ID, "Test Write Static Addresses Gateway", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -6187,7 +6284,7 @@ test_write_wifi_open(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi Open", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6273,7 +6370,7 @@ test_write_wifi_open_hex_ssid(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi Open Hex SSID", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6347,7 +6444,7 @@ test_write_wifi_wep(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6445,7 +6542,7 @@ test_write_wifi_wep_adhoc(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP AdHoc", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6539,7 +6636,7 @@ test_write_wifi_wep_passphrase(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Passphrase", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6634,7 +6731,7 @@ test_write_wifi_wep_40_ascii(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 40 ASCII", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6732,7 +6829,7 @@ test_write_wifi_wep_104_ascii(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 104 ASCII", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6833,7 +6930,7 @@ test_write_wifi_leap(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -6931,7 +7028,7 @@ test_write_wifi_leap_secret_flags(gconstpointer data) NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP Secret Flags", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -7037,7 +7134,7 @@ test_write_wifi_wpa_psk(gconstpointer test_data) NM_SETTING_CONNECTION_ID, args.name, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7142,7 +7239,7 @@ test_write_wifi_wpa_psk_adhoc(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA PSK", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7252,7 +7349,7 @@ test_write_wifi_wpa_eap_tls(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TLS", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7295,8 +7392,8 @@ test_write_wifi_wpa_eap_tls(void) g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, - (guint)(NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE - | NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE), + (guint) (NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE + | NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE), NULL); nm_setting_802_1x_add_eap_method(s_8021x, "tls"); @@ -7379,7 +7476,7 @@ test_write_wifi_wpa_eap_ttls_tls(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (TLS)", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7515,7 +7612,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (MSCHAPv2)", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7630,7 +7727,7 @@ test_write_wifi_wpa_then_open(void) NM_SETTING_CONNECTION_ID, "random wifi connection", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -7747,7 +7844,7 @@ test_write_wifi_wpa_then_wep_with_perms(void) NM_SETTING_CONNECTION_ID, "random wifi connection 2", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_PERMISSIONS, @@ -7872,7 +7969,7 @@ test_write_wifi_dynamic_wep_leap(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -7969,7 +8066,7 @@ test_write_wired_qeth_dhcp(void) NM_SETTING_CONNECTION_ID, "Test Write Wired qeth Static", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8043,7 +8140,7 @@ test_write_wired_ctc_dhcp(void) NM_SETTING_CONNECTION_ID, "Test Write Wired ctc Static", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -8118,7 +8215,7 @@ test_write_permissions(void) NM_SETTING_CONNECTION_ID, "Test Write Permissions", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8187,7 +8284,7 @@ test_write_wifi_wep_agent_keys(void) NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Agent Owned", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); @@ -8273,7 +8370,7 @@ test_write_wired_pppoe(void) NM_SETTING_CONNECTION_ID, "Test Write Wired PPPoE", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8334,7 +8431,7 @@ test_write_vpn(void) NM_SETTING_CONNECTION_ID, "Test Write VPN", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8392,7 +8489,7 @@ test_write_mobile_broadband(gconstpointer data) NM_SETTING_CONNECTION_ID, gsm ? "Test Write GSM" : "Test Write CDMA", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8510,7 +8607,7 @@ test_write_bridge_main(void) NM_SETTING_CONNECTION_ID, "Test Write Bridge Main", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -8639,7 +8736,7 @@ test_write_bridge_component(void) NM_SETTING_CONNECTION_ID, "Test Write Bridge Component", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -8787,6 +8884,38 @@ test_read_vlan_only_vlan_id(void) } static void +test_read_vlan_vlanid_use(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingVlan * s_vlan; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-vlanid-use", + NULL, + TYPE_ETHERNET, + NULL); + + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "eth0.9"); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 10); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test-vlan-vlanid-use.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void test_read_vlan_only_device(void) { NMConnection * connection; @@ -8991,7 +9120,7 @@ test_write_vlan_reorder_hdr(void) NM_SETTING_CONNECTION_ID, "Test Write VLAN reorder_hdr", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NM_SETTING_CONNECTION_TYPE, @@ -9046,7 +9175,7 @@ test_write_ethernet_missing_ipv6(void) NM_SETTING_CONNECTION_ID, "Test Write Ethernet Without IPv6 Setting", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -9170,7 +9299,7 @@ test_write_bond_main(void) NM_SETTING_CONNECTION_ID, "Test Write Bond Main", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -9270,7 +9399,7 @@ test_write_bond_slave(void) NM_SETTING_CONNECTION_ID, "Test Write Bond Slave", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -9357,7 +9486,7 @@ test_write_infiniband(void) NM_SETTING_CONNECTION_ID, "Test Write InfiniBand", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -9446,7 +9575,7 @@ test_write_bond_slave_ib(void) NM_SETTING_CONNECTION_ID, "Test Write Bond Slave InfiniBand", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, @@ -9604,7 +9733,7 @@ test_write_dcb_basic(void) NM_SETTING_CONNECTION_ID, "dcb-test", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -9850,7 +9979,7 @@ test_write_fcoe_mode(gconstpointer user_data) NM_SETTING_CONNECTION_ID, "fcoe-test", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -9968,7 +10097,7 @@ test_write_team_master(void) NM_SETTING_CONNECTION_ID, "Test Write Team Master", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_INTERFACE_NAME, "team0", NM_SETTING_CONNECTION_TYPE, @@ -10060,7 +10189,7 @@ test_write_team_port(void) NM_SETTING_CONNECTION_ID, "Test Write Team Port", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_CONNECTION_MASTER, @@ -10119,7 +10248,7 @@ test_write_team_infiniband_port(void) NM_SETTING_CONNECTION_ID, "Test Write Team Infiniband Port", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_CONNECTION_MASTER, @@ -10309,7 +10438,7 @@ test_write_proxy_basic(void) NM_SETTING_CONNECTION_ID, "Test Write Proxy Basic", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -10358,7 +10487,7 @@ _svUnescape(const char *str, char **to_free) str = (str_free = g_strdup(str)); } - s = svUnescape(str, to_free); + s = svUnescape_full(str, to_free, FALSE); if (*to_free) { g_assert(s == *to_free); g_assert(s[0]); @@ -10366,6 +10495,37 @@ _svUnescape(const char *str, char **to_free) g_assert(s == NULL || (!s[0] && (s < str || s > strchr(str, '\0'))) || (s[0] && s >= str && s <= strchr(str, '\0'))); } + + { + const char * s2; + gs_free char *to_free2 = NULL; + + gboolean is_utf8 = s && g_utf8_validate(s, -1, NULL); + + s2 = svUnescape_full(str, &to_free2, TRUE); + if (NM_IN_STRSET(str, "$'\\U0x'", "$'\\x0'", "$'\\008'", "$'\\08'")) { + g_assert_cmpstr(s2, ==, NULL); + g_assert(!to_free2); + g_assert_cmpstr(s, ==, ""); + g_assert(!*to_free); + } else if (NM_IN_STRSET(str, "$'x\\U0'")) { + g_assert_cmpstr(s2, ==, NULL); + g_assert(!to_free2); + g_assert_cmpstr(s, ==, "x"); + g_assert(*to_free == s); + } else if (!is_utf8) { + g_assert(!s2); + g_assert(!to_free2); + } else if (!to_free2) { + g_assert_cmpstr(s, ==, s2); + g_assert(s == s2); + } else { + g_assert_cmpstr(s, ==, s2); + g_assert(s != s2); + g_assert(s2 == to_free2); + } + } + return s; } @@ -10547,6 +10707,9 @@ test_svUnescape(void) V1("\"\\'\"''", "\\'"), V0("\"b\\~b\" ", "b\\~b"), V1("\"b\\~b\"x", "b\\~bx"), + + V0("$'x\\U0'", "x"), + V0("$'\\U0x'", ""), }; const UnescapeTestData data_ansi[] = { /* strings inside $''. They cannot be compared directly, but must @@ -10733,7 +10896,7 @@ test_write_unknown(gconstpointer test_data) _svGetValue_check(sv, "METRIC", NULL); _svGetValue_check(sv, "METRIC1", ""); _svGetValue_check(sv, "METRIC2", ""); - _svGetValue_check(sv, "METRIC3", "x"); + _svGetValue_check(sv, "METRIC3", ""); _svGetValue_check(sv, "IPADDR", "set-by-test1"); _svGetValue_check(sv, "IPADDR2", "set-by-test2"); @@ -10999,7 +11162,7 @@ test_sriov_write(void) NM_SETTING_CONNECTION_ID, "Test Write SR-IOV config", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -11132,7 +11295,7 @@ test_tc_write_empty(void) NM_SETTING_CONNECTION_ID, "Test Write TC config", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -11213,7 +11376,7 @@ test_tc_write(void) NM_SETTING_CONNECTION_ID, "Test Write TC config", NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_a(), + nm_uuid_generate_random_str_a(), NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_INTERFACE_NAME, @@ -11405,6 +11568,7 @@ test_ethtool_names(void) } s_idxs[] = { {_NM_ETHTOOL_ID_FEATURE_FIRST, _NM_ETHTOOL_ID_FEATURE_LAST}, {_NM_ETHTOOL_ID_COALESCE_FIRST, _NM_ETHTOOL_ID_COALESCE_LAST}, + {_NM_ETHTOOL_ID_PAUSE_FIRST, _NM_ETHTOOL_ID_PAUSE_LAST}, {_NM_ETHTOOL_ID_RING_FIRST, _NM_ETHTOOL_ID_RING_LAST}, }; const NMEthtoolData *data; @@ -11599,6 +11763,8 @@ main(int argc, char **argv) g_test_add_func(TPATH "802-1x/password_raw", test_read_write_802_1x_password_raw); g_test_add_func(TPATH "802-1x/tls-p12-no-client-cert", test_read_802_1x_tls_p12_no_client_cert); + g_test_add_func(TPATH "wired/roundtrip/ethtool", test_roundtrip_ethtool); + g_test_add_data_func(TPATH "wired/read/aliases/good/0", GINT_TO_POINTER(0), test_read_wired_aliases_good); @@ -11705,6 +11871,7 @@ main(int argc, char **argv) g_test_add_func(TPATH "vlan/read/physdev", test_read_vlan_physdev); g_test_add_func(TPATH "vlan/read/reorder-hdr-1", test_read_vlan_reorder_hdr_1); g_test_add_func(TPATH "vlan/read/reorder-hdr-2", test_read_vlan_reorder_hdr_2); + g_test_add_func(TPATH "vlan/read/vlanid-use", test_read_vlan_vlanid_use); g_test_add_func(TPATH "wired/read/read-wake-on-lan", test_read_wired_wake_on_lan); g_test_add_func(TPATH "wired/read/read-auto-negotiate-off", test_read_wired_auto_negotiate_off); g_test_add_func(TPATH "wired/read/read-auto-negotiate-on", test_read_wired_auto_negotiate_on); diff --git a/src/core/settings/plugins/ifupdown/meson.build b/src/core/settings/plugins/ifupdown/meson.build index dd252783..1bff8155 100644 --- a/src/core/settings/plugins/ifupdown/meson.build +++ b/src/core/settings/plugins/ifupdown/meson.build @@ -7,14 +7,12 @@ libnms_ifupdown_core = static_library( 'nms-ifupdown-parser.c', ), dependencies: core_default_dep, - c_args: daemon_c_flags, ) libnm_settings_plugin_ifupdown = shared_module( 'nm-settings-plugin-ifupdown', sources: 'nms-ifupdown-plugin.c', dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_with: libnms_ifupdown_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c index a4974a96..db6b1aef 100644 --- a/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c +++ b/src/core/settings/plugins/ifupdown/nms-ifupdown-parser.c @@ -12,7 +12,8 @@ #include <stdlib.h> #include <ctype.h> -#include "nm-core-internal.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings-plugin.h" #include "nms-ifupdown-plugin.h" @@ -32,14 +33,6 @@ /*****************************************************************************/ -#define _str_has_prefix(val, prefix, require_suffix) \ - ({ \ - const char *_val = (val); \ - \ - (strncmp(_val, "" prefix "", NM_STRLEN(prefix)) == 0) \ - && (!(require_suffix) || _val[NM_STRLEN(prefix)] != '\0'); \ - }) - static const char * _ifupdownplugin_guess_connection_type(if_block *block) { @@ -51,8 +44,7 @@ _ifupdownplugin_guess_connection_type(if_block *block) if_data *ifb; c_list_for_each_entry (ifb, &block->data_lst_head, data_lst) { - if (_str_has_prefix(ifb->key, "wireless-", FALSE) - || _str_has_prefix(ifb->key, "wpa-", FALSE)) { + if (NM_STR_HAS_PREFIX(ifb->key, "wireless-") || NM_STR_HAS_PREFIX(ifb->key, "wpa-")) { ret_type = NM_SETTING_WIRELESS_SETTING_NAME; break; } @@ -102,7 +94,7 @@ update_wireless_setting_from_if_block(NMConnection *connection, if_block *block) wireless_setting = NM_SETTING_WIRELESS(nm_setting_wireless_new()); c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix(curr->key, "wireless-", TRUE)) { + if (NM_STR_HAS_PREFIX_WITH_MORE(curr->key, "wireless-")) { const char *newkey = map_by_mapping(mapping, curr->key + NM_STRLEN("wireless-")); _LOGI("wireless setting key: %s='%s'", newkey, curr->data); @@ -137,7 +129,7 @@ update_wireless_setting_from_if_block(NMConnection *connection, if_block *block) } else { g_object_set(wireless_setting, newkey, curr->data, NULL); } - } else if (_str_has_prefix(curr->key, "wpa-", TRUE)) { + } else if (NM_STR_HAS_PREFIX_WITH_MORE(curr->key, "wpa-")) { const char *newkey = map_by_mapping(mapping, curr->key + NM_STRLEN("wpa-")); if (nm_streq0(newkey, "ssid")) { @@ -304,7 +296,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection, if_bloc wireless_security_setting = NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix(curr->key, "wireless-", TRUE)) { + if (NM_STR_HAS_PREFIX_WITH_MORE(curr->key, "wireless-")) { const char * key = curr->key + NM_STRLEN("wireless-"); char * property_value = NULL; gpointer typed_property_value = NULL; @@ -336,7 +328,7 @@ wireless_next: if (typed_property_value && free_func) (*free_func)(typed_property_value); - } else if (_str_has_prefix(curr->key, "wpa-", TRUE)) { + } else if (NM_STR_HAS_PREFIX_WITH_MORE(curr->key, "wpa-")) { const char * key = curr->key + NM_STRLEN("wpa-"); char * property_value = NULL; gpointer typed_property_value = NULL; @@ -644,7 +636,7 @@ ifupdown_new_connection_from_if_block(if_block *block, gboolean autoconnect, GEr type = _ifupdownplugin_guess_connection_type(block); idstr = g_strconcat("Ifupdown (", block->name, ")", NULL); - uuid = nm_utils_uuid_generate_from_string(idstr, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); + uuid = nm_uuid_generate_from_string_str(idstr, -1, NM_UUID_TYPE_LEGACY, NULL); g_object_set(s_con, NM_SETTING_CONNECTION_TYPE, type, @@ -655,7 +647,7 @@ ifupdown_new_connection_from_if_block(if_block *block, gboolean autoconnect, GEr NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_AUTOCONNECT, - (gboolean)(!!autoconnect), + (gboolean) (!!autoconnect), NULL); _LOGD("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", diff --git a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 34523f8d..80a5638a 100644 --- a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -9,7 +9,7 @@ #include "nms-ifupdown-plugin.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-core-utils.h" #include "nm-config.h" #include "settings/nm-settings-plugin.h" diff --git a/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c index 6e3eb0e7..0e8db733 100644 --- a/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/core/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -5,7 +5,7 @@ #include "src/core/nm-default-daemon.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/plugins/ifupdown/nms-ifupdown-interface-parser.h" #include "settings/plugins/ifupdown/nms-ifupdown-parser.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c index 789bfc1a..e8ae1814 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -13,19 +13,20 @@ #include <sys/types.h> #include <sys/time.h> -#include "nm-std-aux/c-list-util.h" -#include "nm-glib-aux/nm-c-list.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-std-aux/c-list-util.h" +#include "libnm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "nm-connection.h" #include "nm-setting.h" #include "nm-setting-connection.h" #include "nm-utils.h" #include "nm-config.h" -#include "nm-core-internal.h" -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "settings/nm-settings-plugin.h" #include "settings/nm-settings-storage.h" @@ -233,7 +234,7 @@ _read_from_file(const char * full_filename, nm_assert(!connection || (_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS)); - nm_assert(!connection || nm_utils_is_uuid(nm_connection_get_uuid(connection))); + nm_assert(!connection || nm_uuid_is_normalized(nm_connection_get_uuid(connection))); return connection; } @@ -260,7 +261,7 @@ _nm_assert_storage(gpointer plugin /* NMSKeyfilePlugin */, uuid = nms_keyfile_storage_get_uuid(storage); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); nm_assert(((NMSKeyfileStorage *) storage)->is_meta_data || !(((NMSKeyfileStorage *) storage)->u.conn_data.connection) @@ -1106,7 +1107,7 @@ nms_keyfile_plugin_set_nmmeta_tombstone(NMSKeyfilePlugin * self, const char * dirname; nm_assert(NMS_IS_KEYFILE_PLUGIN(self)); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); nm_assert(!out_storage || !*out_storage); nm_assert(!shadowed_storage || (set && in_memory)); @@ -1246,9 +1247,9 @@ nms_keyfile_plugin_init(NMSKeyfilePlugin *plugin) /* dirname_libs are a set of read-only directories with lower priority than /etc or /run. * There is nothing complicated about having multiple of such directories, so dirname_libs * is a list (which currently only has at most one directory). */ - priv->dirname_libs[0] = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_LIB), FALSE); + priv->dirname_libs[0] = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_LIB)); priv->dirname_libs[1] = NULL; - priv->dirname_run = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_RUN), FALSE); + priv->dirname_run = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_RUN)); priv->dirname_etc = nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH, @@ -1261,10 +1262,9 @@ nms_keyfile_plugin_init(NMSKeyfilePlugin *plugin) } else if (!priv->dirname_etc || priv->dirname_etc[0] != '/') { /* either invalid path or unspecified. Use the default. */ g_free(priv->dirname_etc); - priv->dirname_etc = - nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_ETC_DEFAULT), FALSE); + priv->dirname_etc = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_ETC_DEFAULT)); } else - nm_sd_utils_path_simplify(priv->dirname_etc, FALSE); + nm_sd_utils_path_simplify(priv->dirname_etc); /* no duplicates */ if (NM_IN_STRSET(priv->dirname_libs[0], priv->dirname_etc, priv->dirname_run)) diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-reader.c b/src/core/settings/plugins/keyfile/nms-keyfile-reader.c index 70b047f3..8b9d982f 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-reader.c @@ -9,7 +9,7 @@ #include <sys/stat.h> -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "NetworkManagerUtils.h" #include "nms-keyfile-utils.h" diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-storage.c b/src/core/settings/plugins/keyfile/nms-keyfile-storage.c index 89be817a..8c526c81 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-storage.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-storage.c @@ -7,8 +7,9 @@ #include "nms-keyfile-storage.h" +#include "libnm-glib-aux/nm-uuid.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nms-keyfile-plugin.h" /*****************************************************************************/ @@ -108,7 +109,7 @@ _storage_new(NMSKeyfilePlugin * plugin, NMSKeyfileStorage *self; nm_assert(NMS_IS_KEYFILE_PLUGIN(plugin)); - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); nm_assert(filename && filename[0] == '/'); self = g_object_new(NMS_TYPE_KEYFILE_STORAGE, @@ -135,7 +136,7 @@ nms_keyfile_storage_new_tombstone(NMSKeyfilePlugin * plugin, { NMSKeyfileStorage *self; - nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(nm_uuid_is_normalized(uuid)); nm_assert(filename && filename[0] == '/'); nm_assert(nms_keyfile_nmmeta_check_filename(filename, NULL)); nm_assert(NM_IN_SET(storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, NMS_KEYFILE_STORAGE_TYPE_RUN)); diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c index ca1233f5..e2c68bbe 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c @@ -10,8 +10,9 @@ #include <stdlib.h> #include <sys/stat.h> -#include "nm-glib-aux/nm-io-utils.h" -#include "nm-keyfile-internal.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nm-utils.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" @@ -30,9 +31,9 @@ const char * nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len) { - const char *uuid; const char *s; gsize len; + char uuid[37]; s = strrchr(filename, '/'); if (s) @@ -50,17 +51,18 @@ nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len) len -= NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA); - if (!NM_IN_SET(len, 36, 40)) { + if (len != 36) { /* the remaining part of the filename has not the right length to - * contain a UUID (according to nm_utils_is_uuid()). */ + * contain a UUID (according to nm_uuid_is_normalized()). */ return NULL; } - uuid = nm_strndup_a(100, filename, len, NULL); - if (!nm_utils_is_uuid(uuid)) + memcpy(uuid, filename, 36); + uuid[36] = '\0'; + if (!nm_uuid_is_normalized(uuid)) return NULL; - NM_SET_OUT(out_uuid_len, len); + NM_SET_OUT(out_uuid_len, 36); return filename; } @@ -71,7 +73,7 @@ nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temp char *s; nm_assert(dirname && dirname[0] == '/'); - nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/')); + nm_assert(nm_uuid_is_normalized(uuid) && !strchr(uuid, '/')); if (g_snprintf(filename, sizeof(filename), @@ -80,7 +82,7 @@ nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temp NM_KEYFILE_PATH_SUFFIX_NMMETA, temporary ? "~" : "") >= sizeof(filename)) { - /* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always + /* valid uuids are limited in length (nm_uuid_is_normalized). The buffer should always * be large enough. */ nm_assert_not_reached(); } @@ -215,7 +217,7 @@ nms_keyfile_nmmeta_write(const char *dirname, int errsv; nm_assert(dirname && dirname[0] == '/'); - nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/')); + nm_assert(nm_uuid_is_normalized(uuid) && !strchr(uuid, '/')); nm_assert(!loaded_path || loaded_path[0] == '/'); nm_assert(!shadowed_storage || loaded_path); @@ -273,7 +275,13 @@ nms_keyfile_nmmeta_write(const char *dirname, contents = g_key_file_to_data(kf, &length, NULL); - if (!nm_utils_file_set_contents(full_filename, contents, length, 0600, &errsv, NULL)) { + if (!nm_utils_file_set_contents(full_filename, + contents, + length, + 0600, + NULL, + &errsv, + NULL)) { NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp)); return -NM_ERRNO_NATIVE(errsv); } diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c index 0e2c94b5..70afdc23 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c @@ -12,12 +12,12 @@ #include <sys/stat.h> #include <unistd.h> -#include "nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" #include "nms-keyfile-utils.h" #include "nms-keyfile-reader.h" -#include "nm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" /*****************************************************************************/ @@ -125,13 +125,14 @@ cert_writer(NMConnection * connection, /* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before * being sure that the entire profile can be written and all circumstances are good to - * proceed. That means, while writing we must only collect the blogs in-memory, and write + * proceed. That means, while writing we must only collect the blobs in-memory, and write * them all in the end together (or not at all). */ success = nm_utils_file_set_contents(new_path, (const char *) blob_data, blob_len, 0600, NULL, + NULL, &local); if (success) { /* Write the path value to the keyfile. @@ -378,7 +379,7 @@ _internal_write_connection(NMConnection * connection, } } - nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, &local_err); + nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, NULL, &local_err); if (local_err) { g_set_error(error, NM_SETTINGS_ERROR, diff --git a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c index 348b0ed6..a13c2586 100644 --- a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +++ b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c @@ -15,7 +15,8 @@ #include <linux/if_ether.h> #include <linux/if_infiniband.h> -#include "nm-core-internal.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/plugins/keyfile/nms-keyfile-reader.h" #include "settings/plugins/keyfile/nms-keyfile-writer.h" @@ -2289,7 +2290,7 @@ test_read_missing_id_uuid(void) gs_free char * expected_uuid = NULL; const char * FILENAME = TEST_KEYFILES_DIR "/Test_Missing_ID_UUID"; - expected_uuid = _nm_utils_uuid_generate_from_strings("keyfile", FILENAME, NULL); + expected_uuid = nm_uuid_generate_from_strings("keyfile", FILENAME, NULL); connection = keyfile_read_connection_from_file(FILENAME); |