diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 7afab54dd..6c2b9fc71 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -290,11 +290,13 @@ global: nm_setting_wired_get_mac_address; nm_setting_wired_get_cloned_mac_address; nm_setting_wired_get_mtu; - nm_setting_wired_get_s390_subchannels; - nm_setting_wired_get_s390_port_name; - nm_setting_wired_get_s390_port_number; - nm_setting_wired_get_s390_qeth_layer; + nm_setting_wired_get_num_s390_options; nm_setting_wired_get_s390_nettype; + nm_setting_wired_get_s390_option; + nm_setting_wired_get_s390_option_by_key; + nm_setting_wired_add_s390_option; + nm_setting_wired_get_s390_subchannels; + nm_setting_wired_remove_s390_option; nm_setting_wireless_ap_security_compatible; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 90f0a1ad1..b18f691f2 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -24,8 +24,10 @@ */ #include +#include #include #include + #include "nm-setting-wired.h" #include "nm-param-spec-specialized.h" #include "nm-utils.h" @@ -79,10 +81,8 @@ typedef struct { GByteArray *cloned_mac_address; guint32 mtu; GPtrArray *s390_subchannels; - char *s390_port_name; - guint32 s390_port_number; - guint32 s390_qeth_layer; char *s390_nettype; + GHashTable *s390_options; } NMSettingWiredPrivate; enum { @@ -95,14 +95,22 @@ enum { PROP_CLONED_MAC_ADDRESS, PROP_MTU, PROP_S390_SUBCHANNELS, - PROP_S390_PORT_NAME, - PROP_S390_PORT_NUMBER, - PROP_S390_QETH_LAYER, PROP_S390_NETTYPE, + PROP_S390_OPTIONS, LAST_PROP }; +static const char *valid_s390_opts[] = { + "portno", "layer2", "portname", "protocol", "priority_queueing", + "buffer_count", "isolation", "total", "inter", "inter_jumbo", "route4", + "route6", "fake_broadcast", "broadcast_mode", "canonical_macaddr", + "checksumming", "sniffer", "large_send", "ipato_enable", "ipato_invert4", + "ipato_add4", "ipato_invert6", "ipato_add6", "vipa_add4", "vipa_add6", + "rxip_add4", "rxip_add6", "lancmd_timeout", + NULL +}; + NMSetting * nm_setting_wired_new (void) { @@ -165,6 +173,17 @@ nm_setting_wired_get_mtu (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->mtu; } +/** + * nm_setting_wired_get_s390_subchannels: + * @setting: the #NMSettingWired + * + * Return the list of s390 subchannels that identify the device that this + * connection is applicable to. The connection should only be used in + * conjunction with that device. + * + * Returns: a #GPtrArray of strings, each specifying one subchannel the + * s390 device uses to communicate to the host. + **/ const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) { @@ -173,30 +192,15 @@ nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_subchannels; } -const char * -nm_setting_wired_get_s390_port_name (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_name; -} - -guint32 -nm_setting_wired_get_s390_port_number (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_number; -} - -guint32 -nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 2); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_qeth_layer; -} - +/** + * nm_setting_wired_get_s390_nettype: + * @setting: the #NMSettingWired + * + * Returns the s390 device type this connection should apply to. Will be one + * of 'qeth', 'lcs', or 'ctcm'. + * + * Returns: the s390 device type + **/ const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting) { @@ -205,12 +209,161 @@ nm_setting_wired_get_s390_nettype (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_nettype; } +/** + * nm_setting_wired_get_num_s390_options: + * @setting: the #NMSettingWired + * + * Returns the number of s390-specific options that should be set for this + * device when it is activated. This can be used to retrieve each s390 + * option individually using nm_setting_wired_get_s390_option(). + * + * Returns: the number of s390-specific device options + **/ +guint32 +nm_setting_wired_get_num_s390_options (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return g_hash_table_size (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options); +} + +/** + * nm_setting_wired_get_s390_option: + * @setting: the #NMSettingWired + * @idx: index of the desired option, from 0 to + * nm_setting_wired_get_num_s390_options() - 1 + * @out_key: on return, the key name of the s390 specific option; this value is + * owned by the setting and should not be modified + * @out_value: on return, the value of the key of the s390 specific option; this + * value is owned by the setting and should not be modified + * + * Given an index, return the value of the s390 option at that index. indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_wired_add_s390_option() and nm_setting_wired_remove_s390_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value) +{ + NMSettingWiredPrivate *priv; + guint32 num_keys; + GList *keys; + const char *_key = NULL, *_value = NULL; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + + num_keys = nm_setting_wired_get_num_s390_options (setting); + g_return_val_if_fail (idx < num_keys, FALSE); + + keys = g_hash_table_get_keys (priv->s390_options); + _key = g_list_nth_data (keys, idx); + _value = g_hash_table_lookup (priv->s390_options, _key); + + if (out_key) + *out_key = _key; + if (out_value) + *out_value = _value; + return TRUE; +} + +/** + * nm_setting_wired_get_s390_option_by_key: + * @setting: the #NMSettingWired + * @key: the key for which to retrieve the value + * + * Returns the value associated with the s390-specific option specified by + * @key, if it exists. + * + * Returns: the value, or NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + g_return_val_if_fail (key != NULL, NULL); + g_return_val_if_fail (strlen (key), NULL); + + return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); +} + +/** + * nm_setting_wired_add_s390_options: + * @setting: the #NMSettingWired + * @key: key name for the option + * @value: value for the option + * + * Add an option to the table. The option is compared to an internal list + * of allowed options. Key names may contain only alphanumeric characters + * (ie [a-zA-Z0-9]). Adding a new key replaces any existing key/value pair that + * may already exist. + * + * Returns: %TRUE if the option was valid and was added to the internal option + * list, %FALSE if it was not. + **/ +gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *value) +{ + size_t value_len; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + g_return_val_if_fail (_nm_utils_string_in_list (key, valid_s390_opts), FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + value_len = strlen (value); + g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE); + + g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, + g_strdup (key), + g_strdup (value)); + return TRUE; +} + +/** + * nm_setting_wired_remove_s390_options: + * @setting: the #NMSettingWired + * @key: key name for the option to remove + * + * Remove the s390-specific option referenced by @key from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + + return g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; const char *valid_duplex[] = { "half", "full", NULL }; + const char *valid_nettype[] = { "qeth", "lcs", "ctcm", NULL }; + GHashTableIter iter; + const char *key, *value; if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) { g_set_error (error, @@ -236,7 +389,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->s390_subchannels && priv->s390_subchannels->len != 3) { + if ( priv->s390_subchannels + && !(priv->s390_subchannels->len == 3 || priv->s390_subchannels->len == 2)) { g_set_error (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, @@ -244,26 +398,27 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->s390_nettype) { - if ( strcmp (priv->s390_nettype, "qeth") - && strcmp (priv->s390_nettype, "lcs") - && strcmp (priv->s390_nettype, "ctc")) { - g_set_error (error, - NM_SETTING_WIRED_ERROR, - NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_S390_NETTYPE); - return FALSE; - } - } - - if (priv->s390_port_name && strlen (priv->s390_port_name) > 8) { + if (priv->s390_nettype && !_nm_utils_string_in_list (priv->s390_nettype, valid_nettype)) { g_set_error (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_S390_NETTYPE); return FALSE; } + g_hash_table_iter_init (&iter, priv->s390_options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if ( !_nm_utils_string_in_list (key, valid_s390_opts) + || !strlen (value) + || (strlen (value) > 200)) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_S390_OPTIONS); + return FALSE; + } + } + if (priv->cloned_mac_address && priv->cloned_mac_address->len != ETH_ALEN) { g_set_error (error, NM_SETTING_WIRED_ERROR, @@ -278,7 +433,10 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) static void nm_setting_wired_init (NMSettingWired *setting) { + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + g_object_set (setting, NM_SETTING_NAME, NM_SETTING_WIRED_SETTING_NAME, NULL); + priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static void @@ -288,9 +446,10 @@ finalize (GObject *object) g_free (priv->port); g_free (priv->duplex); - g_free (priv->s390_port_name); g_free (priv->s390_nettype); + g_hash_table_destroy (priv->s390_options); + if (priv->device_mac_address) g_byte_array_free (priv->device_mac_address, TRUE); @@ -300,11 +459,18 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object); } +static void +copy_hash (gpointer key, gpointer value, gpointer user_data) +{ + g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value)); +} + static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (object); + GHashTable *new_hash; switch (prop_id) { case PROP_PORT: @@ -341,20 +507,17 @@ set_property (GObject *object, guint prop_id, } priv->s390_subchannels = g_value_dup_boxed (value); break; - case PROP_S390_PORT_NAME: - g_free (priv->s390_port_name); - priv->s390_port_name = g_value_dup_string (value); - break; - case PROP_S390_PORT_NUMBER: - priv->s390_port_number = g_value_get_uint (value); - break; - case PROP_S390_QETH_LAYER: - priv->s390_qeth_layer = g_value_get_uint (value); - break; case PROP_S390_NETTYPE: g_free (priv->s390_nettype); priv->s390_nettype = g_value_dup_string (value); break; + case PROP_S390_OPTIONS: + /* Must make a deep copy of the hash table here... */ + g_hash_table_remove_all (priv->s390_options); + new_hash = g_value_get_boxed (value); + if (new_hash) + g_hash_table_foreach (new_hash, copy_hash, priv->s390_options); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -363,9 +526,10 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingWired *setting = NM_SETTING_WIRED (object); + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); switch (prop_id) { case PROP_PORT: @@ -392,18 +556,12 @@ get_property (GObject *object, guint prop_id, case PROP_S390_SUBCHANNELS: g_value_set_boxed (value, nm_setting_wired_get_s390_subchannels (setting)); break; - case PROP_S390_PORT_NAME: - g_value_set_string (value, nm_setting_wired_get_s390_port_name (setting)); - break; - case PROP_S390_PORT_NUMBER: - g_value_set_uint (value, nm_setting_wired_get_s390_port_number (setting)); - break; - case PROP_S390_QETH_LAYER: - g_value_set_uint (value, nm_setting_wired_get_s390_qeth_layer (setting)); - break; case PROP_S390_NETTYPE: g_value_set_string (value, nm_setting_wired_get_s390_nettype (setting)); break; + case PROP_S390_OPTIONS: + g_value_set_boxed (value, priv->s390_options); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -570,48 +728,6 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - /** - * NMSettingWired:s390-port-name: - * - * s390 device port name, if required by your configuration. - **/ - g_object_class_install_property - (object_class, PROP_S390_PORT_NAME, - g_param_spec_string (NM_SETTING_WIRED_S390_PORT_NAME, - "s390 Port Name", - "s390 device port name, if required by your configuration.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - - /** - * NMSettingWired:s390-port-number: - * - * s390 device port number, if required by your configuration. For 'qeth' - * devices, this is the "relative port number". - **/ - g_object_class_install_property - (object_class, PROP_S390_PORT_NUMBER, - g_param_spec_uint (NM_SETTING_WIRED_S390_PORT_NUMBER, - "s390 Port Number", - "s390 device port number, if required by your " - "configuration. For 'qeth' devices, this is the " - "'relative port number'.", - 0, 100, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); - - /** - * NMSettingWired:s390-qeth-layer: - * - * s390 'qeth' device layer, either '2' or '3'. - **/ - g_object_class_install_property - (object_class, PROP_S390_QETH_LAYER, - g_param_spec_uint (NM_SETTING_WIRED_S390_QETH_LAYER, - "s390 'qeth' layer", - "s390 'qeth' device layer, either '2' or '3'.", - 2, 3, 2, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); - /** * NMSettingWired:s390-nettype: * @@ -627,5 +743,24 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "network devices available on s390 systems.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-options: + * + * Dictionary of key/value pairs of s390-specific device options. Both keys + * and values must be strings. Allowed keys include 'portno', 'layer2', + * 'portname', 'protocol', among others. Key names must contain only + * alphanumeric characters (ie, [a-zA-Z0-9]). + **/ + g_object_class_install_property + (object_class, PROP_S390_OPTIONS, + _nm_param_spec_specialized (NM_SETTING_WIRED_S390_OPTIONS, + "s390 Options", + "Dictionary of key/value pairs of s390-specific " + "device options. Both keys and values must be " + "strings. Allowed keys include 'portno', " + "'layer2', 'portname', 'protocol', among others.", + DBUS_TYPE_G_MAP_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index ad89b3b22..32361b4bc 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -60,10 +60,8 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address" #define NM_SETTING_WIRED_MTU "mtu" #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" -#define NM_SETTING_WIRED_S390_PORT_NAME "s390-port-name" -#define NM_SETTING_WIRED_S390_PORT_NUMBER "s390-port-number" -#define NM_SETTING_WIRED_S390_QETH_LAYER "s390-qeth-layer" #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" +#define NM_SETTING_WIRED_S390_OPTIONS "s390-options" typedef struct { NMSetting parent; @@ -89,12 +87,23 @@ gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); const GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting); guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); + const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); -const char * nm_setting_wired_get_s390_port_name (NMSettingWired *setting); -guint32 nm_setting_wired_get_s390_port_number (NMSettingWired *setting); -guint32 nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting); const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting); +guint32 nm_setting_wired_get_num_s390_options (NMSettingWired *setting); +gboolean nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value); +const char * nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key); +gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *item); +gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key); + G_END_DECLS #endif /* NM_SETTING_WIRED_H */ diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 57eaae920..e1b2b98bd 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -2926,35 +2926,6 @@ wireless_connection_from_ifcfg (const char *file, return connection; } -#define LAYER2_TAG "layer2=" -#define PORTNO_TAG "portno=" - -static gboolean -get_s390_option (const char *tag, - guint32 min, - guint32 max, - const char *value, - int *out_int_val) -{ - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - if (strncmp (value, tag, strlen (tag))) - return FALSE; - - if (get_int (value + strlen (tag), out_int_val)) { - if (*out_int_val < min || *out_int_val > max) { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s value '%d'", tag, *out_int_val); - return FALSE; - } - } else { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s '%s'", tag, value); - return FALSE; - } - - return TRUE; -} - static NMSetting * make_wired_setting (shvarFile *ifcfg, const char *file, @@ -2965,7 +2936,7 @@ make_wired_setting (shvarFile *ifcfg, { NMSettingWired *s_wired; char *value = NULL; - int mtu, portno, layer2; + int mtu; GByteArray *mac = NULL; char *nettype; @@ -3046,8 +3017,9 @@ make_wired_setting (shvarFile *ifcfg, } value = svGetValue (ifcfg, "PORTNAME", FALSE); - if (value && strlen (value)) - g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NAME, value, NULL); + if (value && strlen (value)) { + nm_setting_wired_add_s390_option (s_wired, "portname", value); + } g_free (value); nettype = svGetValue (ifcfg, "NETTYPE", FALSE); @@ -3064,17 +3036,15 @@ make_wired_setting (shvarFile *ifcfg, iter = options = g_strsplit_set (value, " ", 0); while (iter && *iter) { - if (get_s390_option (LAYER2_TAG, 0, 1, *iter, &layer2)) { - if (!nettype || strcmp (nettype, "qeth")) { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: s390 layer2 set but NETTYPE not 'qeth'"); - } else { - if (layer2 == 0) - g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); - else if (layer2 == 1) - g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 2, NULL); - } - } else if (get_s390_option (PORTNO_TAG, 0, 100, *iter, &portno)) - g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NUMBER, portno, NULL); + char *equals = strchr (*iter, '='); + gboolean valid = FALSE; + + if (equals) { + *equals = '\0'; + valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1); + } + if (!valid) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 OPTION '%s'", *iter); iter++; } g_strfreev (options); diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 829727d82..0aafcf9d6 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5368,7 +5368,6 @@ test_read_wired_qeth_static (void) const char *expected_channel1 = "0.0.0601"; const char *expected_channel2 = "0.0.0602"; const GPtrArray *subchannels; - guint32 num; connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, NULL, @@ -5468,33 +5467,37 @@ test_read_wired_qeth_static (void) NM_SETTING_WIRED_S390_NETTYPE); /* port name */ - tmp = nm_setting_wired_get_s390_port_name (s_wired); + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); ASSERT (tmp != NULL, - "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portname'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_SETTING_NAME); ASSERT (strcmp (tmp, "OSAPORT") == 0, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portname' value", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_SETTING_NAME); /* port number */ - num = nm_setting_wired_get_s390_port_number (s_wired); - ASSERT (num == 0, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portno"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portno'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NUMBER); + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "0") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portno' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); /* layer */ - num = nm_setting_wired_get_s390_qeth_layer (s_wired); - ASSERT (num == 2, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "layer2"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'layer2'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_QETH_LAYER); + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "1") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'layer2' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); /* ===== IPv4 SETTING ===== */ @@ -8937,12 +8940,14 @@ test_write_wired_qeth_dhcp (void) g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, NM_SETTING_WIRED_S390_NETTYPE, "qeth", - NM_SETTING_WIRED_S390_PORT_NAME, "OSAPORT", - NM_SETTING_WIRED_S390_PORT_NUMBER, 5, - NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); g_ptr_array_free (subchans, TRUE); + nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR"); + nm_setting_wired_add_s390_option (s_wired, "portno", "1"); + nm_setting_wired_add_s390_option (s_wired, "layer2", "0"); + nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh"); + /* IP4 setting */ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); ASSERT (s_ip4 != NULL, diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index 7a64700ab..cc7577860 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -842,8 +842,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) NMSettingWired *s_wired; const GByteArray *device_mac, *cloned_mac; char *tmp; - const char *nettype, *portname; - guint32 mtu, layer, portno; + const char *nettype, *portname, *s390_key, *s390_val; + guint32 mtu, num_opts, i; const GPtrArray *s390_subchannels; GString *str; @@ -904,21 +904,27 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "NETTYPE", nettype, FALSE); svSetValue (ifcfg, "PORTNAME", NULL, FALSE); - portname = nm_setting_wired_get_s390_port_name (s_wired); + portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); if (portname) svSetValue (ifcfg, "PORTNAME", portname, FALSE); svSetValue (ifcfg, "OPTIONS", NULL, FALSE); - if (s390_subchannels && nettype) { - str = g_string_sized_new (20); - if (!strcmp (nettype, "qeth")) { - layer = nm_setting_wired_get_s390_qeth_layer (s_wired); - g_string_append_printf (str, "layer2=%d ", layer == 2 ? 1 : 0); - } - portno = nm_setting_wired_get_s390_port_number (s_wired); - g_string_append_printf (str, "portno=%d", portno); + num_opts = nm_setting_wired_get_num_s390_options (s_wired); + if (s390_subchannels && num_opts) { + str = g_string_sized_new (30); + for (i = 0; i < num_opts; i++) { + nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); - svSetValue (ifcfg, "OPTIONS", str->str, FALSE); + /* portname is handled separately */ + if (!strcmp (s390_key, "portname")) + continue; + + if (str->len) + g_string_append_c (str, ' '); + g_string_append_printf (str, "%s=%s", s390_key, s390_val); + } + if (str->len) + svSetValue (ifcfg, "OPTIONS", str->str, FALSE); g_string_free (str, TRUE); }