summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libnm-core/nm-keyfile.c82
-rw-r--r--libnm-core/tests/test-setting.c124
2 files changed, 204 insertions, 2 deletions
diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c
index bf8d219310..f2edd0661d 100644
--- a/libnm-core/nm-keyfile.c
+++ b/libnm-core/nm-keyfile.c
@@ -994,6 +994,11 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
gboolean is_vpn;
gsize n_keys;
+ nm_assert ( (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_DATA))
+ || (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_SECRETS))
+ || (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
+ || (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
+
keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, &n_keys, NULL);
if (n_keys == 0)
return;
@@ -1041,7 +1046,10 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
value);
}
g_object_set (setting, NM_SETTING_USER_DATA, data, NULL);
+ return;
}
+
+ nm_assert_not_reached ();
}
static gsize
@@ -2019,6 +2027,68 @@ bridge_vlan_writer (KeyfileWriterInfo *info,
g_string_free (string, TRUE);
}
+
+#define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options"
+
+static void
+wired_s390_options_parser_full (KeyfileReaderInfo *info,
+ const NMMetaSettingInfo *setting_info,
+ const NMSettInfoProperty *property_info,
+ const ParseInfoProperty *pip,
+ NMSetting *setting)
+{
+ NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
+ gs_strfreev char **keys = NULL;
+ gsize n_keys;
+ gsize i;
+
+ keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, ETHERNET_S390_OPTIONS_GROUP_NAME, &n_keys, NULL);
+ for (i = 0; i < n_keys; i++) {
+ gs_free char *value = NULL;
+ gs_free char *key_to_free = NULL;
+
+ value = nm_keyfile_plugin_kf_get_string (info->keyfile,
+ ETHERNET_S390_OPTIONS_GROUP_NAME,
+ keys[i],
+ NULL);
+ if (!value)
+ continue;
+
+ nm_setting_wired_add_s390_option (s_wired,
+ nm_keyfile_key_decode (keys[i],
+ &key_to_free),
+ value);
+ }
+}
+
+static void
+wired_s390_options_writer_full (KeyfileWriterInfo *info,
+ const NMMetaSettingInfo *setting_info,
+ const NMSettInfoProperty *property_info,
+ const ParseInfoProperty *pip,
+ NMSetting *setting)
+{
+ NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
+ gs_free NMUtilsNamedValue *arr = NULL;
+ guint i, n;
+
+ n = nm_setting_wired_get_num_s390_options (s_wired);
+ if (n == 0)
+ return;
+ arr = g_new (NMUtilsNamedValue, n);
+ for (i = 0; i < n; i++)
+ nm_setting_wired_get_s390_option (s_wired, i, &arr[i].name, &arr[i].value_str);
+ nm_utils_named_value_list_sort (arr, n, NULL, NULL);
+ for (i = 0; i < n; i++) {
+ gs_free char *key_to_free = NULL;
+
+ nm_keyfile_plugin_kf_set_string (info->keyfile,
+ ETHERNET_S390_OPTIONS_GROUP_NAME,
+ nm_keyfile_key_encode (arr[i].name, &key_to_free),
+ arr[i].value_str);
+ }
+}
+
static void
ip_routing_rule_writer_full (KeyfileWriterInfo *info,
const NMMetaSettingInfo *setting_info,
@@ -2131,6 +2201,11 @@ write_hash_of_string (GKeyFile *file,
gs_free const char **keys = NULL;
guint i, l;
+ nm_assert ( (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_DATA))
+ || (NM_IS_SETTING_VPN (setting) && nm_streq (key, NM_SETTING_VPN_SECRETS))
+ || (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
+ || (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
+
/* Write VPN secrets out to a different group to keep them separate */
if ( NM_IS_SETTING_VPN (setting)
&& nm_streq (key, NM_SETTING_VPN_SECRETS)) {
@@ -2478,6 +2553,13 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
PARSE_INFO_PROPERTY (NM_SETTING_WIRED_MAC_ADDRESS,
.parser = mac_address_parser_ETHER,
),
+ PARSE_INFO_PROPERTY (NM_SETTING_WIRED_S390_OPTIONS,
+ .parser_no_check_key = TRUE,
+ .parser_full = wired_s390_options_parser_full,
+ .writer_full = wired_s390_options_writer_full,
+ .has_parser_full = TRUE,
+ .has_writer_full = TRUE,
+ ),
),
),
PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BLUETOOTH,
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 03100a039b..e1c26328a4 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -2108,6 +2108,116 @@ test_tc_config_dbus (void)
/*****************************************************************************/
+static void
+_rndt_wired_add_s390_options (NMSettingWired *s_wired,
+ char **out_keyfile_entries)
+{
+ gsize n_opts;
+ gsize i, j;
+ const char *const*option_names;
+ gs_free const char **opt_keys = NULL;
+ gs_strfreev char **opt_vals = NULL;
+ gs_free bool *opt_found = NULL;
+ GString *keyfile_entries;
+ nm_auto_free_gstring GString *str_tmp = NULL;
+ gs_free NMUtilsNamedValue *valx = NULL;
+
+ option_names = nm_setting_wired_get_valid_s390_options (nmtst_get_rand_bool () ? NULL : s_wired);
+
+ n_opts = NM_PTRARRAY_LEN (option_names);
+ opt_keys = g_new (const char *, (n_opts + 1));
+ nmtst_rand_perm (NULL, opt_keys, option_names, sizeof (const char *), n_opts);
+ n_opts = nmtst_get_rand_int () % (n_opts + 1);
+ opt_keys[n_opts] = NULL;
+
+ opt_vals = g_new0 (char *, n_opts + 1);
+ opt_found = g_new0 (bool, n_opts + 1);
+ for (i = 0; i < n_opts; i++) {
+ guint p = nmtst_get_rand_int () % 1000;
+
+ if (p < 200)
+ opt_vals[i] = nm_strdup_int (i);
+ else {
+ opt_vals[i] = g_strdup_printf ("%s%s%s%s-%zu",
+ ((p % 5) % 2) ? "\n" : "",
+ ((p % 7) % 2) ? "\t" : "",
+ ((p % 11) % 2) ? "x" : "",
+ ((p % 13) % 2) ? "=" : "",
+ i);
+ }
+ }
+
+ if (nmtst_get_rand_bool ()) {
+ gs_unref_hashtable GHashTable *hash = NULL;
+
+ hash = g_hash_table_new (nm_str_hash, g_str_equal);
+ for (i = 0; i < n_opts; i++)
+ g_hash_table_insert (hash, (char *) opt_keys[i], opt_vals[i]);
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_S390_OPTIONS,
+ hash,
+ NULL);
+ } else {
+ for (i = 0; i < n_opts; i++) {
+ if (!nm_setting_wired_add_s390_option (s_wired, opt_keys[i], opt_vals[i]))
+ g_assert_not_reached ();
+ }
+ }
+
+ g_assert_cmpint (nm_setting_wired_get_num_s390_options (s_wired), ==, n_opts);
+
+ keyfile_entries = g_string_new (NULL);
+ str_tmp = g_string_new (NULL);
+ if (n_opts > 0)
+ g_string_append_printf (keyfile_entries, "[ethernet-s390-options]\n");
+ valx = g_new (NMUtilsNamedValue, n_opts);
+ for (i = 0; i < n_opts; i++) {
+ gssize idx;
+ const char *k, *v;
+
+ nm_setting_wired_get_s390_option (s_wired, i, &k, &v);
+ g_assert (k);
+ g_assert (v);
+
+ idx = nm_utils_strv_find_first ((char **) opt_keys, n_opts, k);
+ g_assert (idx >= 0);
+ g_assert (!opt_found[idx]);
+ opt_found[idx] = TRUE;
+ g_assert_cmpstr (opt_keys[idx], ==, k);
+ g_assert_cmpstr (opt_vals[idx], ==, v);
+
+ valx[i] = (NMUtilsNamedValue) {
+ .name = k,
+ .value_str = v,
+ };
+ }
+ nm_utils_named_value_list_sort (valx, n_opts, NULL, NULL);
+ for (i = 0; i < n_opts; i++) {
+ const char *k = valx[i].name;
+ const char *v = valx[i].value_str;
+
+ g_string_truncate (str_tmp, 0);
+ for (j = 0; v[j] != '\0'; j++) {
+ if (v[j] == '\n')
+ g_string_append (str_tmp, "\\n");
+ else if (v[j] == '\t')
+ g_string_append (str_tmp, "\\t");
+ else
+ g_string_append_c (str_tmp, v[j]);
+ }
+
+ g_string_append_printf (keyfile_entries,
+ "%s=%s\n",
+ k,
+ str_tmp->str);
+ }
+ for (i = 0; i < n_opts; i++)
+ g_assert (opt_found[i]);
+ if (n_opts > 0)
+ g_string_append_printf (keyfile_entries, "\n");
+ *out_keyfile_entries = g_string_free (keyfile_entries, FALSE);
+}
+
static GPtrArray *
_rndt_wg_peers_create (void)
{
@@ -2385,6 +2495,7 @@ test_roundtrip_conversion (gconstpointer test_data)
int is_ipv4;
guint i;
gboolean success;
+ gs_free char *s390_keyfile_entries = NULL;
switch (MODE) {
case 0:
@@ -2403,6 +2514,8 @@ test_roundtrip_conversion (gconstpointer test_data)
ETH_MTU,
NULL);
+ _rndt_wired_add_s390_options (s_eth, &s390_keyfile_entries);
+
g_ptr_array_add (kf_data_arr,
g_strdup_printf ("[connection]\n"
"id=%s\n"
@@ -2415,6 +2528,7 @@ test_roundtrip_conversion (gconstpointer test_data)
"mac-address-blacklist=\n"
"%s" /* mtu */
"\n"
+ "%s" /* [ethernet-s390-options] */
"[ipv4]\n"
"dns-search=\n"
"method=auto\n"
@@ -2429,7 +2543,8 @@ test_roundtrip_conversion (gconstpointer test_data)
INTERFACE_NAME,
(ETH_MTU != 0)
? nm_sprintf_bufa (100, "mtu=%u\n", ETH_MTU)
- : ""));
+ : "",
+ s390_keyfile_entries));
g_ptr_array_add (kf_data_arr,
g_strdup_printf ("[connection]\n"
@@ -2443,6 +2558,7 @@ test_roundtrip_conversion (gconstpointer test_data)
"mac-address-blacklist=\n"
"%s" /* mtu */
"\n"
+ "%s" /* [ethernet-s390-options] */
"[ipv4]\n"
"dns-search=\n"
"method=auto\n"
@@ -2457,7 +2573,8 @@ test_roundtrip_conversion (gconstpointer test_data)
INTERFACE_NAME,
(ETH_MTU != 0)
? nm_sprintf_bufa (100, "mtu=%d\n", (int) ETH_MTU)
- : ""));
+ : "",
+ s390_keyfile_entries));
break;
@@ -2703,6 +2820,9 @@ test_roundtrip_conversion (gconstpointer test_data)
g_assert_cmpint (nm_setting_wired_get_mtu (s_eth), ==, ETH_MTU);
g_assert_cmpint (nm_setting_wired_get_mtu (s_eth2), ==, ETH_MTU);
+
+ g_assert_cmpint (nm_setting_wired_get_num_s390_options (s_eth2), ==, nm_setting_wired_get_num_s390_options (s_eth));
+
break;
case 1: