diff options
| author | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
| commit | a54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch) | |
| tree | 6a32883bd916c4096357b35298beff6db8bcd0b5 /src/settings | |
| parent | 45e8e1149027529194982212c804c0468aa01d98 (diff) | |
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'src/settings')
19 files changed, 808 insertions, 325 deletions
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 48e3dce2..ca46de68 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1409,6 +1409,54 @@ update_complete (NMSettingsConnection *self, g_slice_free (UpdateInfo, info); } +static int +_autoconnect_retries_initial (NMSettingsConnection *self) +{ + NMSettingConnection *s_con; + int retries = -1; + + s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + if (s_con) + retries = nm_setting_connection_get_autoconnect_retries (s_con); + + /* -1 means 'default' */ + if (retries == -1) + retries = nm_config_data_get_autoconnect_retries_default (NM_CONFIG_GET_DATA); + + /* 0 means 'forever', which is translated to a retry count of -1 */ + if (retries == 0) + retries = AUTOCONNECT_RETRIES_FOREVER; + + nm_assert (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); + return retries; +} + +static void +_autoconnect_retries_set (NMSettingsConnection *self, + int retries, + gboolean is_reset) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); + + if (priv->autoconnect_retries != retries) { + _LOGT ("autoconnect: retries set %d%s", retries, + is_reset ? " (reset)" : ""); + priv->autoconnect_retries = retries; + } + + if (retries) + priv->autoconnect_retries_blocked_until = 0; + else { + /* NOTE: the blocked time must be identical for all connections, otherwise + * the tracking of resetting the retry count in NMPolicy needs adjustment + * in _connection_autoconnect_retries_set() (as it would need to re-evaluate + * the next-timeout every time a connection gets blocked). */ + priv->autoconnect_retries_blocked_until = nm_utils_get_monotonic_timestamp_sec () + AUTOCONNECT_RESET_RETRIES_TIMER; + } +} + static void update_auth_cb (NMSettingsConnection *self, GDBusMethodInvocation *context, @@ -1444,6 +1492,11 @@ update_auth_cb (NMSettingsConnection *self, * they're in the main connection. */ update_agent_secrets_cache (self, info->new_settings); + + /* New secrets, allow autoconnection again */ + if ( nm_settings_connection_autoconnect_blocked_reason_set (self, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, FALSE) + && !nm_settings_connection_autoconnect_blocked_reason_get (self)) + nm_settings_connection_autoconnect_retries_reset (self); } } @@ -1482,7 +1535,8 @@ update_auth_cb (NMSettingsConnection *self, ? NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME | ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY) ? NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE @@ -1975,6 +2029,7 @@ NM_UTILS_FLAGS2STR_DEFINE (_settings_connection_flags_to_string, NMSettingsConne NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, "nm-generated"), NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, "volatile"), NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, "visible"), + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, "external"), ); NMSettingsConnectionIntFlags @@ -2136,15 +2191,24 @@ void nm_settings_connection_update_timestamp (NMSettingsConnection *self, guint64 timestamp) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv; const char *connection_uuid; char sbuf[60]; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if ( priv->timestamp == timestamp + && priv->timestamp_set) + return; + priv->timestamp = timestamp; priv->timestamp_set = TRUE; + _LOGT ("timestamp: set timestamp %"G_GUINT64_FORMAT, + timestamp); + if (!priv->kf_db_timestamps) return; @@ -2185,10 +2249,10 @@ _nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, if (timestamp != G_MAXUINT64) { priv->timestamp = timestamp; priv->timestamp_set = TRUE; - _LOGT ("read timestamp %"G_GUINT64_FORMAT" from keyfile database \"%s\"", + _LOGT ("timestamp: read timestamp %"G_GUINT64_FORMAT" from keyfile database \"%s\"", timestamp, nm_key_file_db_get_filename (priv->kf_db_timestamps)); } else - _LOGT ("no timestamp from keyfile database \"%s\"", + _LOGT ("timestamp: no timestamp from keyfile database \"%s\"", nm_key_file_db_get_filename (priv->kf_db_timestamps)); } @@ -2319,54 +2383,6 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *self, /*****************************************************************************/ -static int -_autoconnect_retries_initial (NMSettingsConnection *self) -{ - NMSettingConnection *s_con; - int retries = -1; - - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); - if (s_con) - retries = nm_setting_connection_get_autoconnect_retries (s_con); - - /* -1 means 'default' */ - if (retries == -1) - retries = nm_config_data_get_autoconnect_retries_default (NM_CONFIG_GET_DATA); - - /* 0 means 'forever', which is translated to a retry count of -1 */ - if (retries == 0) - retries = AUTOCONNECT_RETRIES_FOREVER; - - nm_assert (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); - return retries; -} - -static void -_autoconnect_retries_set (NMSettingsConnection *self, - int retries, - gboolean is_reset) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - g_return_if_fail (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); - - if (priv->autoconnect_retries != retries) { - _LOGT ("autoconnect: retries set %d%s", retries, - is_reset ? " (reset)" : ""); - priv->autoconnect_retries = retries; - } - - if (retries) - priv->autoconnect_retries_blocked_until = 0; - else { - /* NOTE: the blocked time must be identical for all connections, otherwise - * the tracking of resetting the retry count in NMPolicy needs adjustment - * in _connection_autoconnect_retries_set() (as it would need to re-evaluate - * the next-timeout every time a connection gets blocked). */ - priv->autoconnect_retries_blocked_until = nm_utils_get_monotonic_timestamp_sec () + AUTOCONNECT_RESET_RETRIES_TIMER; - } -} - /** * nm_settings_connection_autoconnect_retries_get: * @self: the settings connection @@ -2423,9 +2439,9 @@ NM_UTILS_FLAGS2STR_DEFINE (_autoconnect_blocked_reason_to_string, NMSettingsAuto ); NMSettingsAutoconnectBlockedReason -nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self, NMSettingsAutoconnectBlockedReason mask) +nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason & (mask ?: NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL); + return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason; } gboolean @@ -2467,7 +2483,8 @@ nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) return TRUE; flags = priv->flags; - if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) + if (NM_FLAGS_ANY (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) return TRUE; if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) return TRUE; diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index dfc3786c..17573bbe 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -147,6 +147,8 @@ typedef enum { * when it disconnects. That is for in-memory connections (unsaved), which are * currently active but cleanup on disconnect. * See also #NM_SETTINGS_CONNECTION_FLAG_VOLATILE. + * @NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL: the profile was generated to + * represent the external activation of a device. See also #NM_SETTINGS_CONNECTION_FLAG_EXTERNAL. * @NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE: The connection is visible * @_NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK: the entire enum is * internal, however, parts of it is public API as #NMSettingsConnectionFlags. @@ -161,8 +163,9 @@ typedef enum _NMSettingsConnectionIntFlags { NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED = NM_SETTINGS_CONNECTION_FLAG_UNSAVED, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED = NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE = NM_SETTINGS_CONNECTION_FLAG_VOLATILE, + NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL = NM_SETTINGS_CONNECTION_FLAG_EXTERNAL, - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = 0x08, + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = 0x10, _NM_SETTINGS_CONNECTION_INT_FLAGS_LAST, @@ -170,11 +173,13 @@ typedef enum _NMSettingsConnectionIntFlags { | NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL | 0, _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK = 0 | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL | 0, _NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1, @@ -337,8 +342,7 @@ void nm_settings_connection_autoconnect_retries_reset (NMSettingsConnection *sel gint32 nm_settings_connection_autoconnect_retries_blocked_until (NMSettingsConnection *self); -NMSettingsAutoconnectBlockedReason nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self, - NMSettingsAutoconnectBlockedReason mask); +NMSettingsAutoconnectBlockedReason nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self); gboolean nm_settings_connection_autoconnect_blocked_reason_set_full (NMSettingsConnection *self, NMSettingsAutoconnectBlockedReason mask, NMSettingsAutoconnectBlockedReason value); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 874efbfc..5899b079 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1091,12 +1091,14 @@ _connection_changed_update (NMSettings *self, else { nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED)); - /* Profiles that don't reside in /run, are never nm-generated - * and never volatile. */ + /* Profiles that don't reside in /run, are never nm-generated, + * volatile, and external. */ sett_mask |= ( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE); + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); sett_flags &= ~( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE); + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); } nm_settings_connection_set_flags_full (sett_conn, @@ -1200,7 +1202,8 @@ _connection_changed_delete (NMSettings *self, nm_settings_connection_set_flags (sett_conn, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, FALSE); _emit_connection_removed (self, sett_conn); @@ -1491,6 +1494,7 @@ _add_connection_to_first_plugin (NMSettings *self, in_memory, NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), + NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), shadowed_storage, shadowed_owned, &storage, @@ -1501,6 +1505,7 @@ _add_connection_to_first_plugin (NMSettings *self, continue; nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)); nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)); + nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); success = nm_settings_plugin_add_connection (plugin, new_connection, &storage, @@ -1578,6 +1583,7 @@ _update_connection_to_plugin (NMSettings *self, connection, NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), + NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), shadowed_storage, shadowed_owned, force_rename, @@ -1693,8 +1699,9 @@ nm_settings_add_connection (NMSettings *self, nm_assert (!NM_FLAGS_ANY (sett_flags, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); - if (NM_FLAGS_ANY (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) { + if (NM_FLAGS_ANY (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { nm_assert (new_in_memory); new_in_memory = TRUE; } @@ -1992,7 +1999,8 @@ nm_settings_update_connection (NMSettings *self, nm_assert (cur_in_memory); nm_assert (!NM_FLAGS_ANY (nm_settings_connection_get_flags (sett_conn), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)); + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); default_wired_clear_tag (self, device, sett_conn, FALSE); @@ -2011,11 +2019,13 @@ nm_settings_update_connection (NMSettings *self, if ( persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST && NM_FLAGS_ANY (sett_mask, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE) + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL) && NM_FLAGS_ANY ((sett_flags ^ nm_settings_connection_get_flags (sett_conn)) & sett_mask, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) { - /* we update the nm-generated/volatile setting of a profile (which is inherrently + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { + /* we update the nm-generated/volatile setting of a profile (which is inherently * in-memory. The caller did not request to persist this to disk, however we need * to store the flags in run. */ nm_assert (cur_in_memory); @@ -2043,11 +2053,14 @@ nm_settings_update_connection (NMSettings *self, * the nm-generated flag after restart/reload, and that cannot be right. If a profile * ends up on disk, the information who created it gets lost. */ nm_assert (!NM_FLAGS_ANY (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)); + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL; sett_flags &= ~( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE); + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); } if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST) { @@ -3374,7 +3387,8 @@ have_connection_for_device (NMSettings *self, NMDevice *device) continue; if (NM_FLAGS_ANY (nm_settings_connection_get_flags (sett_conn), - NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) + NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) continue; return TRUE; diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf index cc6ccb5c..c7a1730a 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf @@ -2,11 +2,10 @@ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> - <policy context="default"> - <allow send_destination="com.redhat.ifcfgrh1"/> - </policy> - <policy user="root"> - <allow own="com.redhat.ifcfgrh1"/> - </policy> + <policy context="default"> + <allow send_destination="com.redhat.ifcfgrh1"/> + </policy> + <policy user="root"> + <allow own="com.redhat.ifcfgrh1"/> + </policy> </busconfig> - diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 338c22ed..d65ae555 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -582,6 +582,11 @@ make_connection_setting (const char *file, g_object_set (s_con, NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, (int) vint64, NULL); } + nm_clear_g_free (&value); + v = svGetValue (ifcfg, "MUD_URL", &value); + if (v) + g_object_set (s_con, NM_SETTING_CONNECTION_MUD_URL, v, NULL); + i_val = NM_SETTING_CONNECTION_MDNS_DEFAULT; if (!svGetValueEnum (ifcfg, "MDNS", nm_setting_connection_mdns_get_type (), @@ -1532,29 +1537,45 @@ make_user_setting (shvarFile *ifcfg) : NULL; } -static NMSetting * -make_match_setting (shvarFile *ifcfg) + +static void +make_match_setting_prop (const char *v, + NMSettingMatch **s_match, + void (*add_fcn) (NMSettingMatch *s_match, const char *value)) { - NMSettingMatch *s_match = NULL; gs_free const char **strv = NULL; - gs_free char *value = NULL; - const char *v; gsize i; - v = svGetValueStr (ifcfg, "MATCH_INTERFACE_NAME", &value); - if (!v) - return NULL; - strv = nm_utils_escaped_tokens_split (v, NM_ASCII_SPACES); if (strv) { for (i = 0; strv[i]; i++) { - if (!s_match) - s_match = (NMSettingMatch *) nm_setting_match_new (); - nm_setting_match_add_interface_name (s_match, strv[i]); + if (!(*s_match)) + *s_match = NM_SETTING_MATCH (nm_setting_match_new ()); + add_fcn (*s_match, strv[i]); } } +} + +static NMSetting * +make_match_setting (shvarFile *ifcfg) +{ + NMSettingMatch *s_match = NULL; + gs_free char *value_ifn = NULL; + gs_free char *value_kcl = NULL; + gs_free char *value_d = NULL; + gs_free char *value_p = NULL; + const char *v; - return (NMSetting *) s_match; + v = svGetValueStr (ifcfg, "MATCH_INTERFACE_NAME", &value_ifn); + make_match_setting_prop (v, &s_match, nm_setting_match_add_interface_name); + v = svGetValueStr (ifcfg, "MATCH_KERNEL_COMMAND_LINE", &value_kcl); + make_match_setting_prop (v, &s_match, nm_setting_match_add_kernel_command_line); + v = svGetValueStr (ifcfg, "MATCH_DRIVER", &value_d); + make_match_setting_prop (v, &s_match, nm_setting_match_add_driver); + v = svGetValueStr (ifcfg, "MATCH_PATH", &value_p); + make_match_setting_prop (v, &s_match, nm_setting_match_add_path); + + return NM_SETTING (s_match); } static NMSetting * @@ -4244,6 +4265,130 @@ wireless_connection_from_ifcfg (const char *file, return connection; } +typedef struct { + const char *optname; + union { + guint32 u32; + NMTernary nmternary; + } v; + gboolean has_value; +} NMEthtoolIfcfgOption; + +/* returns an 'iterator' to words + * pointing to the next unprocessed option or NULL + * in case of failure */ +static const char ** +_next_ethtool_options_nmternary (const char **words, + NMEthtoolType ethtool_type, + NMEthtoolIfcfgOption *out_value) +{ + const char *opt; + const char *opt_val; + const NMEthtoolData *d = NULL; + NMTernary onoff = NM_TERNARY_DEFAULT; + + nm_assert (out_value); + + out_value->has_value = FALSE; + out_value->optname = NULL; + + if ( !words + || !words[0] + || !words[1]) + return NULL; + + opt = *words; + opt_val = *(++words); + + if (nm_streq0 (opt_val, "on")) + onoff = NM_TERNARY_TRUE; + else if (nm_streq0 (opt_val, "off")) + onoff = NM_TERNARY_FALSE; + + d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt, ethtool_type); + if (!d) { + if (onoff != NM_TERNARY_DEFAULT) { + /* the next value is just the on/off argument. Skip it too. */ + ++words; + } + + /* silently ignore unsupported offloading features. */ + return words; + } + + if (onoff == NM_TERNARY_DEFAULT) { + PARSE_WARNING ("Expects on/off argument for feature '%s'", opt); + return words; + } + + out_value->has_value = TRUE; + out_value->optname = d->optname; + out_value->v.nmternary = onoff; + + return ++words; +} + +/* returns an 'iterator' to words + * pointing to the next unprocessed option or NULL + * in case of failure */ +static const char ** +_next_ethtool_options_uint32 (const char **words, + NMEthtoolType ethtool_type, + NMEthtoolIfcfgOption *out_value) +{ + gint64 i64; + const char *opt; + const char *opt_val; + const NMEthtoolData *d = NULL; + + nm_assert (out_value); + + out_value->has_value = FALSE; + out_value->optname = NULL; + + if ( !words + || !words[0] + || !words[1]) + return NULL; + + opt = *words; + opt_val = *(++words); + + i64 = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, -1); + + d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt, ethtool_type); + if (!d) { + if (i64 != -1) { + /* the next value is just the on/off argument. Skip it too. */ + ++words; + } + + /* silently ignore unsupported offloading features. */ + return words; + } + + out_value->has_value = TRUE; + out_value->optname = d->optname; + out_value->v.u32 = (guint32) i64; + + return ++words; +} + +static +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( + _get_ethtool_type_by_name, + NMEthtoolType, + { nm_assert (name); }, + { return NM_ETHTOOL_TYPE_UNKNOWN; }, + { "--coalesce", NM_ETHTOOL_TYPE_COALESCE }, + { "--features", NM_ETHTOOL_TYPE_FEATURE }, + { "--offload", NM_ETHTOOL_TYPE_FEATURE }, + { "--set-ring", NM_ETHTOOL_TYPE_RING }, + { "-C", NM_ETHTOOL_TYPE_COALESCE }, + { "-G", NM_ETHTOOL_TYPE_RING }, + { "-K", NM_ETHTOOL_TYPE_FEATURE }, +); + static void parse_ethtool_option (const char *value, NMSettingWiredWakeOnLan *out_flags, @@ -4253,59 +4398,58 @@ parse_ethtool_option (const char *value, const char **out_duplex, NMSettingEthtool **out_s_ethtool) { - gs_free const char **words = NULL; guint i; + const char **w_iter; + NMEthtoolIfcfgOption ifcfg_option; + gs_free const char **words = NULL; + NMEthtoolType ethtool_type = NM_ETHTOOL_TYPE_UNKNOWN; words = nm_utils_strsplit_set (value, " \t\n"); if (!words) return; - if (words[0] && words[0][0] == '-') { - /* /sbin/ethtool $opts */ - if (NM_IN_STRSET (words[0], "-K", "--features", "--offload")) { - if (!words[1]) { - /* first argument must be the interface name. This is invalid. */ - return; - } - - if (!*out_s_ethtool) - *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); + if (words[0]) + ethtool_type = _get_ethtool_type_by_name (words[0]); - for (i = 2; words[i]; ) { - const char *opt = words[i]; - const char *opt_val = words[++i]; - const NMEthtoolData *d = NULL; - NMTernary onoff = NM_TERNARY_DEFAULT; + if (ethtool_type != NM_ETHTOOL_TYPE_UNKNOWN) { + if (!words[1]) { + /* first argument must be the interface name. This is invalid. */ + return; + } - if (nm_streq0 (opt_val, "on")) - onoff = NM_TERNARY_TRUE; - else if (nm_streq0 (opt_val, "off")) - onoff = NM_TERNARY_FALSE; + if (!*out_s_ethtool) + *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt); + /* skip ethtool type && interface name */ + w_iter = &words[2]; - if (!d) { - if (onoff != NM_TERNARY_DEFAULT) { - /* the next value is just the on/off argument. Skip it too. */ - i++; - } + while (w_iter && *w_iter) { + if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) { + w_iter = _next_ethtool_options_nmternary (w_iter, + ethtool_type, + &ifcfg_option); - /* silently ignore unsupported offloading features. */ - continue; + if (ifcfg_option.has_value) { + nm_setting_option_set_boolean (NM_SETTING (*out_s_ethtool), + ifcfg_option.optname, + ifcfg_option.v.nmternary != NM_TERNARY_FALSE); } - - i++; - - if (onoff == NM_TERNARY_DEFAULT) { - PARSE_WARNING ("Expects on/off argument for feature '%s'", opt); - continue; + } + if (NM_IN_SET (ethtool_type, + NM_ETHTOOL_TYPE_COALESCE, + NM_ETHTOOL_TYPE_RING)) { + w_iter = _next_ethtool_options_uint32 (w_iter, + ethtool_type, + &ifcfg_option); + + if (ifcfg_option.has_value) { + nm_setting_option_set_uint32 (NM_SETTING (*out_s_ethtool), + ifcfg_option.optname, + ifcfg_option.v.u32); } - - nm_setting_ethtool_set_feature (*out_s_ethtool, - d->optname, - onoff); } } + return; } @@ -5166,24 +5310,33 @@ handle_bridge_option (NMSetting *setting, gboolean only_with_stp; gboolean extended_bool; } m/*etadata*/[] = { - { "DELAY", NM_SETTING_BRIDGE_FORWARD_DELAY, BRIDGE_OPT_TYPE_MAIN, .only_with_stp = TRUE }, - { "priority", NM_SETTING_BRIDGE_PRIORITY, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_querier", NM_SETTING_BRIDGE_MULTICAST_QUERIER, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_query_use_ifaddr", NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_router", NM_SETTING_BRIDGE_MULTICAST_ROUTER, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION }, - { "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION }, - { "group_address", NM_SETTING_BRIDGE_GROUP_ADDRESS, BRIDGE_OPT_TYPE_OPTION }, - { "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_protocol", NM_SETTING_BRIDGE_VLAN_PROTOCOL, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_stats_enabled", NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, BRIDGE_OPT_TYPE_OPTION }, - { "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION }, - { "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION }, - { "hairpin_mode", NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, BRIDGE_OPT_TYPE_PORT_OPTION, .extended_bool = TRUE, }, + { "DELAY", NM_SETTING_BRIDGE_FORWARD_DELAY, BRIDGE_OPT_TYPE_MAIN, .only_with_stp = TRUE }, + { "priority", NM_SETTING_BRIDGE_PRIORITY, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, + { "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, + { "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, + { "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_last_member_count", NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_last_member_interval", NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_membership_interval", NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_hash_max", NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_querier", NM_SETTING_BRIDGE_MULTICAST_QUERIER, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_querier_interval", NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_query_interval", NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_query_response_interval", NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_query_use_ifaddr", NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_router", NM_SETTING_BRIDGE_MULTICAST_ROUTER, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_startup_query_count", NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, BRIDGE_OPT_TYPE_OPTION }, + { "multicast_startup_query_interval", NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, + { "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION }, + { "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION }, + { "group_address", NM_SETTING_BRIDGE_GROUP_ADDRESS, BRIDGE_OPT_TYPE_OPTION }, + { "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION }, + { "vlan_protocol", NM_SETTING_BRIDGE_VLAN_PROTOCOL, BRIDGE_OPT_TYPE_OPTION }, + { "vlan_stats_enabled", NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, BRIDGE_OPT_TYPE_OPTION }, + { "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION }, + { "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION }, + { "hairpin_mode", NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, BRIDGE_OPT_TYPE_PORT_OPTION, .extended_bool = TRUE, }, }; const char *error_message = NULL; int i; @@ -5236,6 +5389,16 @@ handle_bridge_option (NMSetting *setting, goto warn; } return; + case G_TYPE_UINT64: { + guint64 vu64; + + vu64 = _nm_utils_ascii_str_to_uint64 (value, 10, 0, G_MAXUINT64, 0); + if (!nm_g_object_set_property_uint64 (G_OBJECT (setting), m[i].property_name, vu64, NULL)) { + error_message = "number is out of range"; + goto warn; + } + } + return; case G_TYPE_STRING: nm_g_object_set_property_string (G_OBJECT (setting), m[i].property_name, value, NULL); return; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 15a772bc..d1500dbd 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -522,9 +522,30 @@ nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer) /*****************************************************************************/ const char *const _nm_ethtool_ifcfg_names[] = { -#define ETHT_NAME(eid, ename) \ -[eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename"" - /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ +#define ETHT_NAME(eid, ename) [eid] = ""ename"" + /* indexed by NMEthtoolID */ + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, "adaptive-rx"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, "adaptive-tx"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES, "rx-frames"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH, "rx-frames-high"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ, "rx-frames-irq"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW, "rx-frames-low"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, "pkt-rate-high"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW, "pkt-rate-low"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS, "rx-usecs"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH, "rx-usecs-high"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ, "rx-usecs-irq"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW, "rx-usecs-low"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL, "sample-interval"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS, "stats-block-usecs"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES, "tx-frames"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH, "tx-frames-high"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ, "tx-frames-irq"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW, "tx-frames-low"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS, "tx-usecs"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH, "tx-usecs-high"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ, "tx-usecs-irq"), + ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, "tx-usecs-low"), ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), ETHT_NAME (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), @@ -577,11 +598,45 @@ 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_RING_RX, "rx"), + ETHT_NAME (NM_ETHTOOL_ID_RING_RX_JUMBO, "rx-jumbo"), + ETHT_NAME (NM_ETHTOOL_ID_RING_RX_MINI, "rx-mini"), + ETHT_NAME (NM_ETHTOOL_ID_RING_TX, "tx"), }; static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( - _get_ethtoolid_by_name, + _get_ethtoolid_coalesce_by_name, + NMEthtoolID, + { nm_assert (name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + { "adaptive-rx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX }, + { "adaptive-tx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX }, + { "pkt-rate-high", NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH }, + { "pkt-rate-low", NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW }, + { "rx-frames", NM_ETHTOOL_ID_COALESCE_RX_FRAMES }, + { "rx-frames-high", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH }, + { "rx-frames-irq", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ }, + { "rx-frames-low", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW }, + { "rx-usecs", NM_ETHTOOL_ID_COALESCE_RX_USECS }, + { "rx-usecs-high", NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH }, + { "rx-usecs-irq", NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ }, + { "rx-usecs-low", NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW }, + { "sample-interval", NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL }, + { "stats-block-usecs", NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS }, + { "tx-frames", NM_ETHTOOL_ID_COALESCE_TX_FRAMES }, + { "tx-frames-high", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH }, + { "tx-frames-irq", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ }, + { "tx-frames-low", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW }, + { "tx-usecs", NM_ETHTOOL_ID_COALESCE_TX_USECS }, + { "tx-usecs-high", NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH }, + { "tx-usecs-irq", NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ }, + { "tx-usecs-low", NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW }, +); + +static +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( + _get_ethtoolid_feature_by_name, NMEthtoolID, { nm_assert (name); }, { return NM_ETHTOOL_ID_UNKNOWN; }, @@ -660,12 +715,39 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( { "txvlan", NM_ETHTOOL_ID_FEATURE_TXVLAN }, ); +static +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( + _get_ethtoolid_ring_by_name, + NMEthtoolID, + { nm_assert (name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + { "rx", NM_ETHTOOL_ID_RING_RX }, + { "rx-jumbo", NM_ETHTOOL_ID_RING_RX_JUMBO }, + { "rx-mini", NM_ETHTOOL_ID_RING_RX_MINI }, + { "tx", NM_ETHTOOL_ID_RING_TX }, +); + const NMEthtoolData * -nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) +nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name, + NMEthtoolType ethtool_type) { NMEthtoolID id; - id = _get_ethtoolid_by_name (name); + switch (ethtool_type) { + case NM_ETHTOOL_TYPE_COALESCE: + id = _get_ethtoolid_coalesce_by_name (name); + break; + case NM_ETHTOOL_TYPE_FEATURE: + id = _get_ethtoolid_feature_by_name (name); + break; + case NM_ETHTOOL_TYPE_RING: + id = _get_ethtoolid_ring_by_name (name); + break; + default: + nm_assert_not_reached(); + return NULL; + } + if (id == NM_ETHTOOL_ID_UNKNOWN) return NULL; @@ -892,11 +974,15 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { _KEY_TYPE ("MAC_ADDRESS_RANDOMIZATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), + _KEY_TYPE ("MATCH_DRIVER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MATCH_INTERFACE_NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), + _KEY_TYPE ("MATCH_KERNEL_COMMAND_LINE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), + _KEY_TYPE ("MATCH_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("METRIC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), _KEY_TYPE ("MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MTU", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), + _KEY_TYPE ("MUD_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MULTI_CONNECT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("MVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), _KEY_TYPE ("NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 6c31b269..459c5ae9 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -33,7 +33,7 @@ typedef struct { NMSIfcfgKeyTypeFlags key_flags; } NMSIfcfgKeyTypeInfo; -extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[236]; +extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[240]; const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx); @@ -141,18 +141,19 @@ const NMSIfcfgKeyTypeInfo *nms_ifcfg_rh_utils_is_well_known_key (const char *key /*****************************************************************************/ -extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_FEATURE_NUM]; +extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_NUM]; static inline const char * nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id) { - nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST && ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); - nm_assert ((ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST) < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); - nm_assert (_nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); + nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FIRST && ethtool_id <= _NM_ETHTOOL_ID_LAST); + nm_assert (ethtool_id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); + nm_assert (_nm_ethtool_ifcfg_names[ethtool_id]); - return _nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]; + return _nm_ethtool_ifcfg_names[ethtool_id]; } -const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name); +const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name, + NMEthtoolType ethtool_type); #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index e126c77f..199e8e4e 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1091,6 +1091,27 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } +static void +_ethtool_gstring_prepare (GString **str, + gboolean *is_first, + char cmdline_flag, + const char *iface) +{ + if (!*is_first) { + nm_assert (*str && (*str)->len > 0); + return; + } + + if (!*str) + *str = g_string_sized_new (30); + else { + nm_assert ((*str)->len > 0); + g_string_append (*str, " ; "); + } + g_string_append_printf (*str, "-%c %s", cmdline_flag, iface); + *is_first = FALSE; +} + static gboolean write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { @@ -1172,7 +1193,10 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro if (s_ethtool) { NMEthtoolID ethtool_id; NMSettingConnection *s_con; - const char *iface = NULL; + const char *iface; + gboolean is_first; + guint32 u32; + gboolean b; s_con = nm_connection_get_setting_connection (connection); if (s_con) { @@ -1184,28 +1208,45 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro || (ch >= '0' && ch <= '9') || NM_IN_SET (ch, '_')))) iface = NULL; - } - - if (!str) - str = g_string_sized_new (30); - else - g_string_append (str, " ; "); - g_string_append (str, "-K "); - g_string_append (str, iface ?: "net0"); + } else + iface = NULL; + if (!iface) + iface = "net0"; + is_first = TRUE; for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; ethtool_id++) { - const NMEthtoolData *ed = nm_ethtool_data[ethtool_id]; - NMTernary val; + 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, 'K', 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"); + } + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_COALESCE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_COALESCE_LAST; ethtool_id++) { nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); + if (!nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), nm_ethtool_data[ethtool_id]->optname, &u32)) + continue; + + _ethtool_gstring_prepare (&str, &is_first, 'C', iface); + g_string_append_c (str, ' '); + g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); + g_string_append_printf (str, " %"G_GUINT32_FORMAT, u32); + } - val = nm_setting_ethtool_get_feature (s_ethtool, ed->optname); - if (val == NM_TERNARY_DEFAULT) + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_RING_FIRST; ethtool_id <= _NM_ETHTOOL_ID_RING_LAST; ethtool_id++) { + nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); + if (!nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), nm_ethtool_data[ethtool_id]->optname, &u32)) continue; + _ethtool_gstring_prepare (&str, &is_first, 'G', iface); g_string_append_c (str, ' '); g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - g_string_append (str, val == NM_TERNARY_TRUE ? " on" : " off"); + g_string_append_printf (str, " %"G_GUINT32_FORMAT, u32); } } @@ -1374,38 +1415,22 @@ write_team_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, return TRUE; } -static guint32 -get_setting_default_uint (NMSetting *setting, const char *prop) +static gboolean +get_setting_default_boolean (gpointer setting, const char *prop) { - GParamSpec *pspec; - GValue val = G_VALUE_INIT; - guint32 ret = 0; - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop); - g_assert (pspec); - g_value_init (&val, pspec->value_type); - g_param_value_set_default (pspec, &val); - g_assert (G_VALUE_HOLDS_UINT (&val)); - ret = g_value_get_uint (&val); - g_value_unset (&val); - return ret; + return NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); } -static gboolean -get_setting_default_boolean (NMSetting *setting, const char *prop) +static guint +get_setting_default_uint (gpointer setting, const char *prop) { - GParamSpec *pspec; - GValue val = G_VALUE_INIT; - gboolean ret = 0; - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop); - g_assert (pspec); - g_value_init (&val, pspec->value_type); - g_param_value_set_default (pspec, &val); - g_assert (G_VALUE_HOLDS_BOOLEAN (&val)); - ret = g_value_get_boolean (&val); - g_value_unset (&val); - return ret; + return NM_G_PARAM_SPEC_GET_DEFAULT_UINT (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); +} + +static guint64 +get_setting_default_uint64 (gpointer setting, const char *prop) +{ + return NM_G_PARAM_SPEC_GET_DEFAULT_UINT64 (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); } static gboolean @@ -1448,7 +1473,8 @@ static gboolean write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { NMSettingBridge *s_bridge; - guint32 i; + guint32 u32; + guint64 u64; gboolean b; const char *s; GString *opts; @@ -1471,32 +1497,32 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire if (nm_setting_bridge_get_stp (s_bridge)) { svSetValueStr (ifcfg, "STP", "yes"); - i = nm_setting_bridge_get_forward_delay (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_FORWARD_DELAY)) - svSetValueInt64 (ifcfg, "DELAY", i); + u32 = nm_setting_bridge_get_forward_delay (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY)) + svSetValueInt64 (ifcfg, "DELAY", u32); g_string_append_printf (opts, "priority=%u", nm_setting_bridge_get_priority (s_bridge)); - i = nm_setting_bridge_get_hello_time (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_HELLO_TIME)) { + u32 = nm_setting_bridge_get_hello_time (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_HELLO_TIME)) { if (opts->len) g_string_append_c (opts, ' '); - g_string_append_printf (opts, "hello_time=%u", i); + g_string_append_printf (opts, "hello_time=%u", u32); } - i = nm_setting_bridge_get_max_age (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MAX_AGE)) { + u32 = nm_setting_bridge_get_max_age (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MAX_AGE)) { if (opts->len) g_string_append_c (opts, ' '); - g_string_append_printf (opts, "max_age=%u", i); + g_string_append_printf (opts, "max_age=%u", u32); } } - i = nm_setting_bridge_get_ageing_time (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_AGEING_TIME)) { + u32 = nm_setting_bridge_get_ageing_time (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME)) { if (opts->len) g_string_append_c (opts, ' '); - g_string_append_printf (opts, "ageing_time=%u", i); + g_string_append_printf (opts, "ageing_time=%u", u32); } s = nm_setting_bridge_get_group_address (s_bridge); @@ -1506,34 +1532,98 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire g_string_append_printf (opts, "group_address=%s", s); } - i = nm_setting_bridge_get_group_forward_mask (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_GROUP_FORWARD_MASK)) { + u32 = nm_setting_bridge_get_group_forward_mask (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK)) { if (opts->len) g_string_append_c (opts, ' '); - g_string_append_printf (opts, "group_fwd_mask=%u", i); + g_string_append_printf (opts, "group_fwd_mask=%u", u32); + } + + + u32 = nm_setting_bridge_get_multicast_hash_max (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_HASH_MAX)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_hash_max=%u", u32); + } + + u32 = nm_setting_bridge_get_multicast_last_member_count (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_last_member_count=%u", u32); + } + + u64 = nm_setting_bridge_get_multicast_last_member_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_last_member_interval=%"G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_membership_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_membership_interval=%"G_GUINT64_FORMAT, u64); } b = nm_setting_bridge_get_multicast_querier (s_bridge); - if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MULTICAST_QUERIER)) { + if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERIER)) { if (opts->len) g_string_append_c (opts, ' '); g_string_append_printf (opts, "multicast_querier=%u", (guint) b); } + u64 = nm_setting_bridge_get_multicast_querier_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_querier_interval=%"G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_query_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_query_interval=%"G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_query_response_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_query_response_interval=%"G_GUINT64_FORMAT, u64); + } + b = nm_setting_bridge_get_multicast_query_use_ifaddr (s_bridge); - if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR)) { + if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR)) { if (opts->len) g_string_append_c (opts, ' '); g_string_append_printf (opts, "multicast_query_use_ifaddr=%u", (guint) b); } b = nm_setting_bridge_get_multicast_snooping (s_bridge); - if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MULTICAST_SNOOPING)) { + if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_SNOOPING)) { if (opts->len) g_string_append_c (opts, ' '); g_string_append_printf (opts, "multicast_snooping=%u", (guint32) b); } + u32 = nm_setting_bridge_get_multicast_startup_query_count (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_startup_query_count=%u", u32); + } + + u64 = nm_setting_bridge_get_multicast_startup_query_interval (s_bridge); + if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_startup_query_interval=%"G_GUINT64_FORMAT, u64); + } + s = nm_setting_bridge_get_multicast_router (s_bridge); if (s) { if (opts->len) @@ -1542,17 +1632,17 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire } b = nm_setting_bridge_get_vlan_filtering (s_bridge); - if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_FILTERING)) { + if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_VLAN_FILTERING)) { if (opts->len) g_string_append_c (opts, ' '); g_string_append_printf (opts, "vlan_filtering=%u", (guint32) b); } - i = nm_setting_bridge_get_vlan_default_pvid (s_bridge); - if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) { + u32 = nm_setting_bridge_get_vlan_default_pvid (s_bridge); + if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) { if (opts->len) g_string_append_c (opts, ' '); - g_string_append_printf (opts, "default_pvid=%u", i); + g_string_append_printf (opts, "default_pvid=%u", u32); } s = nm_setting_bridge_get_vlan_protocol (s_bridge); @@ -1563,7 +1653,7 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire } b = nm_setting_bridge_get_vlan_stats_enabled (s_bridge); - if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_STATS_ENABLED)) { + if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_VLAN_STATS_ENABLED)) { if (opts->len) g_string_append_c (opts, ' '); g_string_append_printf (opts, "vlan_stats_enabled=%u", (guint) b); @@ -1591,7 +1681,7 @@ static gboolean write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingBridgePort *s_port; - guint32 i; + guint32 u32; GString *string; s_port = nm_connection_get_setting_bridge_port (connection); @@ -1601,15 +1691,15 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError ** /* Bridge options */ string = g_string_sized_new (32); - i = nm_setting_bridge_port_get_priority (s_port); - if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PRIORITY)) - g_string_append_printf (string, "priority=%u", i); + u32 = nm_setting_bridge_port_get_priority (s_port); + if (u32 != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PRIORITY)) + g_string_append_printf (string, "priority=%u", u32); - i = nm_setting_bridge_port_get_path_cost (s_port); - if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PATH_COST)) { + u32 = nm_setting_bridge_port_get_path_cost (s_port); + if (u32 != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PATH_COST)) { if (string->len) g_string_append_c (string, ' '); - g_string_append_printf (string, "path_cost=%u", i); + g_string_append_printf (string, "path_cost=%u", u32); } if (nm_setting_bridge_port_get_hairpin_mode (s_port)) { @@ -1804,7 +1894,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) NMSettingConnectionMdns mdns; NMSettingConnectionLlmnr llmnr; guint32 vuint32; - const char *tmp; + const char *tmp, *mud_url; svSetValueStr (ifcfg, "NAME", nm_setting_connection_get_id (s_con)); svSetValueStr (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con)); @@ -1879,6 +1969,9 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) svSetValueStr (ifcfg, "TEAM_MASTER_UUID", NULL); svSetValueStr (ifcfg, "TEAM_MASTER", NULL); + mud_url = nm_setting_connection_get_mud_url (s_con); + svSetValue (ifcfg, "MUD_URL", mud_url); + master = nm_setting_connection_get_master (s_con); if (master) { /* The reader prefers the *_UUID variants, however we still try to resolve @@ -2301,36 +2394,61 @@ write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } -static gboolean -write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +static void +write_match_setting (NMConnection *connection, shvarFile *ifcfg) { - NMSettingMatch *s_match; nm_auto_free_gstring GString *str = NULL; + NMSettingMatch *s_match; guint i, num; + const char *name; s_match = (NMSettingMatch *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MATCH); if (!s_match) - return TRUE; - - num = nm_setting_match_get_num_interface_names (s_match); - for (i = 0; i < num; i++) { - const char *name; - - name = nm_setting_match_get_interface_name (s_match, i); - if (!name || !name[0]) - continue; + return; - if (!str) - str = g_string_new (""); - else - g_string_append_c (str, ' '); - nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); + num = nm_setting_match_get_num_drivers (s_match); + if (num > 0) { + nm_gstring_prepare (&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_driver (s_match, i); + nm_gstring_add_space_delimiter (str); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); + } + svSetValueStr (ifcfg, "MATCH_DRIVER", str->str); } - if (str) + num = nm_setting_match_get_num_interface_names (s_match); + if (num > 0) { + nm_gstring_prepare (&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_interface_name (s_match, i); + nm_gstring_add_space_delimiter (str); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); + } svSetValueStr (ifcfg, "MATCH_INTERFACE_NAME", str->str); + } - return TRUE; + num = nm_setting_match_get_num_kernel_command_lines (s_match); + if (num > 0) { + nm_gstring_prepare (&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_kernel_command_line (s_match, i); + nm_gstring_add_space_delimiter (str); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); + } + svSetValueStr (ifcfg, "MATCH_KERNEL_COMMAND_LINE", str->str); + } + + num = nm_setting_match_get_num_paths (s_match); + if (num > 0) { + nm_gstring_prepare (&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_path (s_match, i); + nm_gstring_add_space_delimiter (str); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); + } + svSetValueStr (ifcfg, "MATCH_PATH", str->str); + } } static void @@ -3090,8 +3208,7 @@ do_write_construct (NMConnection *connection, if (!write_user_setting (connection, ifcfg, error)) return FALSE; - if (!write_match_setting (connection, ifcfg, error)) - return FALSE; + write_match_setting (connection, ifcfg); write_sriov_setting (connection, ifcfg); diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected index f0cd36cb..9499278e 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected @@ -1,7 +1,9 @@ TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no +MATCH_DRIVER="!virtio e1000e" MATCH_INTERFACE_NAME="ens* eth\\ 1? !veth*" +MATCH_KERNEL_COMMAND_LINE=!ip= BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index ffedff01..a5025f3b 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -4690,6 +4690,9 @@ test_write_wired_match (void) nm_setting_match_add_interface_name (s_match, "ens*"); nm_setting_match_add_interface_name (s_match, "eth 1?"); nm_setting_match_add_interface_name (s_match, "!veth*"); + nm_setting_match_add_driver (s_match, "!virtio"); + nm_setting_match_add_driver (s_match, "e1000e"); + nm_setting_match_add_kernel_command_line (s_match, "!ip="); nm_connection_add_setting (connection, NM_SETTING (s_match)); nmtst_assert_connection_verifies (connection); @@ -10364,37 +10367,48 @@ test_ethtool_names (void) { NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" }, { NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" }, }; + const struct { + guint nm_ethtool_id_first; + guint nm_ethtool_id_last; + } 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_RING_FIRST, _NM_ETHTOOL_ID_RING_LAST }, + }; const NMEthtoolData *data; NMEthtoolID id; - int i; + guint i, k; - for (id = _NM_ETHTOOL_ID_FEATURE_FIRST; id <= _NM_ETHTOOL_ID_FEATURE_LAST; id++) { - const char *ifcfg_rh_name; - int idx; + for (k = 0; k < sizeof(s_idxs) / sizeof(*s_idxs); ++k) { + for (id = s_idxs[k].nm_ethtool_id_first; id <= s_idxs[k].nm_ethtool_id_last; id++) { + const char *ifcfg_rh_name; - idx = id - _NM_ETHTOOL_ID_FEATURE_FIRST; - g_assert (idx >= 0); - g_assert (idx < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); - ifcfg_rh_name = _nm_ethtool_ifcfg_names[idx]; - g_assert (ifcfg_rh_name && ifcfg_rh_name[0]); + g_assert (id >= 0); + g_assert (id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); + ifcfg_rh_name = _nm_ethtool_ifcfg_names[id]; + g_assert (ifcfg_rh_name && ifcfg_rh_name[0]); - for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) { - if (i != idx) - g_assert_cmpstr (ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]); - } + for (i = s_idxs[k].nm_ethtool_id_first; i < s_idxs[k].nm_ethtool_id_last; i++) { + if (i != id) + g_assert_cmpstr (ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]); + } - g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), ==, ifcfg_rh_name); + g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), ==, ifcfg_rh_name); - data = nms_ifcfg_rh_utils_get_ethtool_by_name (ifcfg_rh_name); - g_assert (data); - g_assert (data->id == id); + data = nms_ifcfg_rh_utils_get_ethtool_by_name (ifcfg_rh_name, nm_ethtool_id_to_type (id)); + + g_assert (data); + g_assert (data->id == id); + } } for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) { const char *name = kernel_names[i].kernel_name; id = kernel_names[i].ethtool_id; - data = nms_ifcfg_rh_utils_get_ethtool_by_name (name); + + data = nms_ifcfg_rh_utils_get_ethtool_by_name (name, nm_ethtool_id_to_type (id)); + g_assert (data); g_assert (data->id == id); g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), !=, name); diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c index 2906b399..c84bd78d 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -89,22 +89,33 @@ G_DEFINE_TYPE (NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN) /*****************************************************************************/ static const char * -_extra_flags_to_string (char *str, gsize str_len, gboolean is_nm_generated, gboolean is_volatile) +_extra_flags_to_string (char *str, gsize str_len, gboolean is_nm_generated, gboolean is_volatile, gboolean is_external) { const char *str0 = str; if ( !is_nm_generated - && !is_volatile) + && !is_volatile + && !is_external) nm_utils_strbuf_append_str (&str, &str_len, ""); else { - nm_utils_strbuf_append_str (&str, &str_len, " ("); + char ch = '('; + + nm_utils_strbuf_append_c (&str, &str_len, ' '); if (is_nm_generated) { + nm_utils_strbuf_append_c (&str, &str_len, ch); nm_utils_strbuf_append_str (&str, &str_len, "nm-generated"); - if (is_volatile) - nm_utils_strbuf_append_c (&str, &str_len, ','); + ch = ','; } - if (is_volatile) + if (is_volatile) { + nm_utils_strbuf_append_c (&str, &str_len, ch); nm_utils_strbuf_append_str (&str, &str_len, "volatile"); + ch = ','; + } + if (is_external) { + nm_utils_strbuf_append_c (&str, &str_len, ch); + nm_utils_strbuf_append_str (&str, &str_len, "external"); + ch = ','; + } nm_utils_strbuf_append_c (&str, &str_len, ')'); } @@ -202,6 +213,7 @@ _read_from_file (const char *full_filename, struct stat *out_stat, NMTernary *out_is_nm_generated, NMTernary *out_is_volatile, + NMTernary *out_is_external, char **out_shadowed_storage, NMTernary *out_shadowed_owned, GError **error) @@ -215,6 +227,7 @@ _read_from_file (const char *full_filename, out_stat, out_is_nm_generated, out_is_volatile, + out_is_external, out_shadowed_storage, out_shadowed_owned, error); @@ -284,8 +297,9 @@ _load_file (NMSKeyfilePlugin *self, { NMSKeyfilePluginPrivate *priv; gs_unref_object NMConnection *connection = NULL; - NMTernary is_volatile_opt; NMTernary is_nm_generated_opt; + NMTernary is_volatile_opt; + NMTernary is_external_opt; NMTernary shadowed_owned_opt; gs_free char *shadowed_storage = NULL; gs_free_error GError *local = NULL; @@ -350,6 +364,7 @@ _load_file (NMSKeyfilePlugin *self, &st, &is_nm_generated_opt, &is_volatile_opt, + &is_external_opt, &shadowed_storage, &shadowed_owned_opt, &local); @@ -367,6 +382,7 @@ _load_file (NMSKeyfilePlugin *self, storage_type, is_nm_generated_opt, is_volatile_opt, + is_external_opt, shadowed_storage, shadowed_owned_opt, &st.st_mtim); @@ -732,6 +748,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, gboolean in_memory, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, NMSettingsStorage **out_storage, @@ -756,6 +773,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, nm_assert ( in_memory || ( !is_nm_generated && !is_volatile + && !is_external && !shadowed_storage && !shadowed_owned)); @@ -770,6 +788,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, if (!nms_keyfile_writer_connection (connection, is_nm_generated, is_volatile, + is_external, shadowed_storage, shadowed_owned, storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC @@ -807,7 +826,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, uuid, nm_connection_get_id (connection), full_filename, - _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile), + _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile, is_external), NM_PRINT_FMT_QUOTED (shadowed_storage, " (shadows \"", shadowed_storage, shadowed_owned ? "\", owned)" : "\")", "")); storage = nms_keyfile_storage_new_connection (self, @@ -816,6 +835,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, storage_type, is_nm_generated ? NM_TERNARY_TRUE : NM_TERNARY_FALSE, is_volatile ? NM_TERNARY_TRUE : NM_TERNARY_FALSE, + is_external ? NM_TERNARY_TRUE : NM_TERNARY_FALSE, shadowed_storage, shadowed_owned ? NM_TERNARY_TRUE : NM_TERNARY_FALSE, nm_sett_util_stat_mtime (full_filename, FALSE, &mtime)); @@ -840,6 +860,7 @@ add_connection (NMSettingsPlugin *plugin, FALSE, FALSE, FALSE, + FALSE, NULL, FALSE, out_storage, @@ -853,6 +874,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, NMConnection *connection, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, gboolean force_rename, @@ -883,6 +905,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, nm_assert ( storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN || ( !is_nm_generated && !is_volatile + && !is_external && !shadowed_storage && !shadowed_owned)); nm_assert (!shadowed_owned || shadowed_storage); @@ -895,6 +918,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, if (!nms_keyfile_writer_connection (connection, is_nm_generated, is_volatile, + is_external, shadowed_storage, shadowed_owned, storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC @@ -933,11 +957,12 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, full_filename, uuid, nm_connection_get_id (connection), - _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile), + _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile, is_external), NM_PRINT_FMT_QUOTED (shadowed_storage, shadowed_owned ? " (owns \"" : " (shadows \"", shadowed_storage, "\")", "")); storage->u.conn_data.is_nm_generated = is_nm_generated; storage->u.conn_data.is_volatile = is_volatile; + storage->u.conn_data.is_external = is_external; storage->u.conn_data.stat_mtime = *nm_sett_util_stat_mtime (full_filename, FALSE, &mtime); storage->u.conn_data.shadowed_owned = shadowed_owned; @@ -959,6 +984,7 @@ update_connection (NMSettingsPlugin *plugin, connection, FALSE, FALSE, + FALSE, NULL, FALSE, FALSE, diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.h b/src/settings/plugins/keyfile/nms-keyfile-plugin.h index e885f16c..603f0c26 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.h +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.h @@ -31,6 +31,7 @@ gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, gboolean in_memory, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, NMSettingsStorage **out_storage, @@ -42,6 +43,7 @@ gboolean nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, NMConnection *connection, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, gboolean force_rename, diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c index e8c9f9fe..577709d8 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c @@ -17,11 +17,15 @@ /*****************************************************************************/ static const char * -_fmt_warn (const char *group, NMSetting *setting, const char *property_name, const char *message, char **out_message) +_fmt_warn (const NMKeyfileHandlerData *handler_data, char **out_message) { - const char *setting_name = setting ? nm_setting_get_name (setting) : NULL; + const char *group = handler_data->kf_group_name; + const char *message = _nm_keyfile_handler_data_warn_get_message (handler_data); if (group) { + NMSetting *setting = handler_data->cur_setting; + const char *property_name = handler_data->cur_property; + const char *setting_name = setting ? nm_setting_get_name (setting) : NULL; char *res; if (setting_name) { @@ -37,30 +41,30 @@ _fmt_warn (const char *group, NMSetting *setting, const char *property_name, con res = g_strdup_printf ("%s: %s", group, message); *out_message = res; return res; - } else - return message; + } + + return message; } typedef struct { bool verbose; -} HandlerReadData; +} ReadInfo; static gboolean _handler_read (GKeyFile *keyfile, NMConnection *connection, - NMKeyfileReadType type, - void *type_data, - void *user_data, - GError **error) + NMKeyfileHandlerType handler_type, + NMKeyfileHandlerData *handler_data, + void *user_data) { - const HandlerReadData *handler_data = user_data; + const ReadInfo *read_info = user_data; - if (type == NM_KEYFILE_READ_TYPE_WARN) { - NMKeyfileReadTypeDataWarn *warn_data = type_data; + if (handler_type == NM_KEYFILE_HANDLER_TYPE_WARN) { + const NMKeyfileHandlerDataWarn *warn_data = &handler_data->warn; NMLogLevel level; char *message_free = NULL; - if (!handler_data->verbose) + if (!read_info->verbose) return TRUE; if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN) @@ -72,15 +76,17 @@ _handler_read (GKeyFile *keyfile, else level = LOGL_INFO; - nm_log (level, LOGD_SETTINGS, NULL, + nm_log (level, + LOGD_SETTINGS, + NULL, nm_connection_get_uuid (connection), "keyfile: %s", - _fmt_warn (warn_data->group, warn_data->setting, - warn_data->property_name, warn_data->message, + _fmt_warn (handler_data, &message_free)); g_free (message_free); return TRUE; } + return FALSE; } @@ -93,7 +99,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file, GError **error) { NMConnection *connection; - HandlerReadData data = { + ReadInfo read_info = { .verbose = verbose, }; gs_free char *base_dir_free = NULL; @@ -122,7 +128,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file, filename = &s[1]; } - connection = nm_keyfile_read (key_file, base_dir, _handler_read, &data, error); + connection = nm_keyfile_read (key_file, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_read, &read_info, error); if (!connection) return NULL; @@ -150,6 +156,7 @@ nms_keyfile_reader_from_file (const char *full_filename, struct stat *out_stat, NMTernary *out_is_nm_generated, NMTernary *out_is_volatile, + NMTernary *out_is_external, char **out_shadowed_storage, NMTernary *out_shadowed_owned, GError **error) @@ -163,6 +170,7 @@ nms_keyfile_reader_from_file (const char *full_filename, NM_SET_OUT (out_is_nm_generated, NM_TERNARY_DEFAULT); NM_SET_OUT (out_is_volatile, NM_TERNARY_DEFAULT); + NM_SET_OUT (out_is_external, NM_TERNARY_DEFAULT); if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_KEYFILE, full_filename, @@ -198,6 +206,11 @@ nms_keyfile_reader_from_file (const char *full_filename, NM_KEYFILE_KEY_NMMETA_VOLATILE, NM_TERNARY_DEFAULT)); + NM_SET_OUT (out_is_external, nm_key_file_get_boolean (key_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_EXTERNAL, + NM_TERNARY_DEFAULT)); + NM_SET_OUT (out_shadowed_storage, g_key_file_get_string (key_file, NM_KEYFILE_GROUP_NMMETA, NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE, diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.h b/src/settings/plugins/keyfile/nms-keyfile-reader.h index 307d6ffe..828715fa 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.h +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.h @@ -23,6 +23,7 @@ NMConnection *nms_keyfile_reader_from_file (const char *full_filename, struct stat *out_stat, NMTernary *out_is_nm_generated, NMTernary *out_is_volatile, + NMTernary *out_is_external, char **out_shadowed_storage, NMTernary *out_shadowed_owned, GError **error); diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.c b/src/settings/plugins/keyfile/nms-keyfile-storage.c index bcc06795..15f20295 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-storage.c +++ b/src/settings/plugins/keyfile/nms-keyfile-storage.c @@ -155,6 +155,7 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin, NMSKeyfileStorageType storage_type, NMTernary is_nm_generated_opt, NMTernary is_volatile_opt, + NMTernary is_external_opt, const char *shadowed_storage, NMTernary shadowed_owned_opt, const struct timespec *stat_mtime) @@ -181,6 +182,7 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin, if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) { self->u.conn_data.is_nm_generated = (is_nm_generated_opt == NM_TERNARY_TRUE); self->u.conn_data.is_volatile = (is_volatile_opt == NM_TERNARY_TRUE); + self->u.conn_data.is_external = (is_external_opt == NM_TERNARY_TRUE); self->u.conn_data.shadowed_owned = shadowed_storage && (shadowed_owned_opt == NM_TERNARY_TRUE); } @@ -243,7 +245,8 @@ nm_settings_storage_load_sett_flags (NMSettingsStorage *self, *sett_flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; *sett_mask = NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL; if (!NMS_IS_KEYFILE_STORAGE (self)) return; @@ -260,4 +263,7 @@ nm_settings_storage_load_sett_flags (NMSettingsStorage *self, if (s->u.conn_data.is_volatile) *sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + + if (s->u.conn_data.is_external) + *sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL; } diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.h b/src/settings/plugins/keyfile/nms-keyfile-storage.h index 00a034d4..bd8a4367 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-storage.h +++ b/src/settings/plugins/keyfile/nms-keyfile-storage.h @@ -65,6 +65,7 @@ typedef struct { * That is, it must be tied to the actual keyfile, and not to the UUID. */ bool is_nm_generated:1; bool is_volatile:1; + bool is_external:1; /* if shadowed_storage is set, then this flag indicates whether the file * is owned. The difference comes into play when deleting the in-memory, @@ -112,6 +113,7 @@ NMSKeyfileStorage *nms_keyfile_storage_new_connection (struct _NMSKeyfilePlugin NMSKeyfileStorageType storage_type, NMTernary is_nm_generated_opt, NMTernary is_volatile_opt, + NMTernary is_external_opt, const char *shadowed_storage, NMTernary shadowed_owned_opt, const struct timespec *stat_mtime); diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c index 7554becc..feea6065 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/settings/plugins/keyfile/nms-keyfile-writer.c @@ -28,21 +28,22 @@ typedef struct { static void cert_writer (NMConnection *connection, GKeyFile *file, - NMKeyfileWriteTypeDataCert *cert_data, + NMSetting8021x *setting, + const NMSetting8021xSchemeVtable *vtable, WriteInfo *info, GError **error) { - const char *setting_name = nm_setting_get_name (NM_SETTING (cert_data->setting)); + const char *setting_name = nm_setting_get_name (NM_SETTING (setting)); NMSetting8021xCKScheme scheme; NMSetting8021xCKFormat format; const char *path = NULL, *ext = "pem"; - scheme = cert_data->vtable->scheme_func (cert_data->setting); + scheme = vtable->scheme_func (setting); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { char *tmp = NULL; const char *accepted_path = NULL; - path = cert_data->vtable->path_func (cert_data->setting); + path = vtable->path_func (setting); g_assert (path); if (g_str_has_prefix (path, info->keyfile_dir)) { @@ -78,11 +79,11 @@ cert_writer (NMConnection *connection, if (!accepted_path) accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL); - nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, accepted_path); + nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, accepted_path); g_free (tmp); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { - nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, - cert_data->vtable->uri_func (cert_data->setting)); + nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, + vtable->uri_func (setting)); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { GBytes *blob; const guint8 *blob_data; @@ -91,13 +92,13 @@ cert_writer (NMConnection *connection, GError *local = NULL; char *new_path; - blob = cert_data->vtable->blob_func (cert_data->setting); + blob = vtable->blob_func (setting); g_assert (blob); blob_data = g_bytes_get_data (blob, &blob_len); - if (cert_data->vtable->format_func) { + if (vtable->format_func) { /* Get the extension for a private key */ - format = cert_data->vtable->format_func (cert_data->setting); + format = vtable->format_func (setting); if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) ext = "p12"; } else { @@ -110,7 +111,7 @@ cert_writer (NMConnection *connection, * from now on instead of pushing around the certificate data. */ new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection), - cert_data->vtable->file_suffix, ext); + vtable->file_suffix, ext); /* 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 @@ -125,10 +126,10 @@ cert_writer (NMConnection *connection, if (success) { /* Write the path value to the keyfile. * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64," */ - nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, strrchr (new_path, '/') + 1); + nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, strrchr (new_path, '/') + 1); } else { nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s", - setting_name, cert_data->vtable->setting_key, new_path, local->message); + setting_name, vtable->setting_key, new_path, local->message); g_error_free (local); } g_free (new_path); @@ -146,15 +147,17 @@ cert_writer (NMConnection *connection, static gboolean _handler_write (NMConnection *connection, GKeyFile *keyfile, - NMKeyfileWriteType type, - void *type_data, - void *user_data, - GError **error) + NMKeyfileHandlerType type, + NMKeyfileHandlerData *type_data, + void *user_data) { - if (type == NM_KEYFILE_WRITE_TYPE_CERT) { - cert_writer (connection, keyfile, - (NMKeyfileWriteTypeDataCert *) type_data, - (WriteInfo *) user_data, error); + if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) { + cert_writer (connection, + keyfile, + NM_SETTING_802_1X (type_data->cur_setting), + type_data->write_cert.vtable, + user_data, + type_data->p_error); return TRUE; } return FALSE; @@ -164,6 +167,7 @@ static gboolean _internal_write_connection (NMConnection *connection, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, const char *keyfile_dir, @@ -211,7 +215,7 @@ _internal_write_connection (NMConnection *connection, info.keyfile_dir = keyfile_dir; - kf_file = nm_keyfile_write (connection, _handler_write, &info, error); + kf_file = nm_keyfile_write (connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error); if (!kf_file) return FALSE; @@ -229,6 +233,13 @@ _internal_write_connection (NMConnection *connection, TRUE); } + if (is_external) { + g_key_file_set_boolean (kf_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_EXTERNAL, + TRUE); + } + if (shadowed_storage) { g_key_file_set_string (kf_file, NM_KEYFILE_GROUP_NMMETA, @@ -375,6 +386,7 @@ gboolean nms_keyfile_writer_connection (NMConnection *connection, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, const char *keyfile_dir, @@ -392,6 +404,7 @@ nms_keyfile_writer_connection (NMConnection *connection, return _internal_write_connection (connection, is_nm_generated, is_volatile, + is_external, shadowed_storage, shadowed_owned, keyfile_dir, @@ -423,6 +436,7 @@ nms_keyfile_writer_test_connection (NMConnection *connection, return _internal_write_connection (connection, FALSE, FALSE, + FALSE, NULL, FALSE, keyfile_dir, diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.h b/src/settings/plugins/keyfile/nms-keyfile-writer.h index 98ec8a6b..73a2e333 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-writer.h +++ b/src/settings/plugins/keyfile/nms-keyfile-writer.h @@ -15,6 +15,7 @@ typedef gboolean (*NMSKeyfileWriterAllowFilenameCb) (const char *check_filename, gboolean nms_keyfile_writer_connection (NMConnection *connection, gboolean is_nm_generated, gboolean is_volatile, + gboolean is_external, const char *shadowed_storage, gboolean shadowed_owned, const char *keyfile_dir, diff --git a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c index d2da09da..1a9482e5 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c @@ -63,6 +63,7 @@ check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int NULL, \ NULL, \ NULL, \ + NULL, \ (nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \ nmtst_assert_success (_connection, _error); \ nmtst_assert_connection_verifies_without_normalization (_connection); \ |