libnm/s390: Merge branch 'th/s390-option-bridge-role'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/782
This commit is contained in:
Thomas Haller 2021-03-16 13:17:56 +01:00
commit e91acb2806
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
15 changed files with 251 additions and 136 deletions

View file

@ -1786,7 +1786,8 @@ update_connection(NMDevice *device, NMConnection *connection)
const char * mac = nm_device_get_hw_address(device);
const char * mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
GHashTableIter iter;
gpointer key, value;
const char * key;
const char * value;
if (!s_wired) {
s_wired = (NMSettingWired *) nm_setting_wired_new();
@ -1824,8 +1825,8 @@ update_connection(NMDevice *device, NMConnection *connection)
_nm_setting_wired_clear_s390_options(s_wired);
g_hash_table_iter_init(&iter, priv->s390_options);
while (g_hash_table_iter_next(&iter, &key, &value))
nm_setting_wired_add_s390_option(s_wired, (const char *) key, (const char *) value);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value))
nm_setting_wired_add_s390_option(s_wired, key, value);
}
static void

View file

@ -433,13 +433,7 @@ nm_config_set_no_auto_default_for_device(NMConfig *self, NMDevice *device)
len = NM_PTRARRAY_LEN(no_auto_default_current);
idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) no_auto_default_current,
len,
spec,
nm_strcmp_with_data,
NULL,
NULL,
NULL);
idx = nm_utils_strv_find_binary_search(no_auto_default_current, len, spec);
if (idx >= 0) {
/* @spec is already blocked. We don't have to update our in-memory representation.
* Maybe we should write to no_auto_default_file anew, but let's save that too. */

View file

@ -5118,15 +5118,15 @@ make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x,
for (i = 0; options && options[i]; i++) {
const char *line = options[i];
const char *equals;
gboolean valid = FALSE;
equals = strchr(line, '=');
if (equals) {
((char *) equals)[0] = '\0';
valid = nm_setting_wired_add_s390_option(s_wired, line, equals + 1);
}
if (!valid)
PARSE_WARNING("invalid s390 OPTION '%s'", line);
if (!equals)
continue;
/* Here we don't verify the key/value further. If the file contains invalid keys,
* we will later reject the connection as invalid. */
((char *) equals)[0] = '\0';
nm_setting_wired_add_s390_option(s_wired, line, equals + 1);
}
found = TRUE;
}

View file

@ -751,8 +751,6 @@ nml_dbus_meta_iface_get(const char *dbus_iface_name)
G_N_ELEMENTS(_nml_dbus_meta_ifaces),
&dbus_iface_name[NM_STRLEN(COMMON_PREFIX)],
_strcmp_common_prefix,
NULL,
NULL,
NULL);
} else
return NULL;

View file

@ -2286,6 +2286,8 @@ wired_s390_options_parser_full(KeyfileReaderInfo * info,
if (!value)
continue;
/* Here we don't verify the key/value further. If the file contains invalid keys,
* we will later reject the connection as invalid. */
nm_setting_wired_add_s390_option(s_wired,
nm_keyfile_key_decode(keys[i], &key_to_free),
value);
@ -3085,8 +3087,6 @@ _parse_info_find(NMSetting * setting,
NM_PTRARRAY_LEN(pis->properties),
&property_name,
nm_strcmp_p_with_data,
NULL,
NULL,
NULL);
if (idx >= 0)
pip = pis->properties[idx];

View file

@ -74,7 +74,8 @@ G_DEFINE_TYPE(NMSettingWired, nm_setting_wired, NM_TYPE_SETTING)
/*****************************************************************************/
static const char *valid_s390_opts[] = {
static const char *const valid_s390_opts[] = {
"bridge_role",
"broadcast_mode",
"buffer_count",
"canonical_macaddr",
@ -107,37 +108,58 @@ static const char *valid_s390_opts[] = {
NULL,
};
static gboolean
valid_s390_opts_check(const char *option)
gboolean
_nm_setting_wired_is_valid_s390_option(const char *option)
{
#if NM_MORE_ASSERTS > 5
nm_assert(NM_PTRARRAY_LEN(valid_s390_opts) + 1 == G_N_ELEMENTS(valid_s390_opts));
{
if (NM_MORE_ASSERT_ONCE(10)) {
gsize i;
nm_assert(NM_PTRARRAY_LEN(valid_s390_opts) + 1u == G_N_ELEMENTS(valid_s390_opts));
for (i = 0; i < G_N_ELEMENTS(valid_s390_opts); i++) {
if (i == G_N_ELEMENTS(valid_s390_opts) - 1)
if (i == G_N_ELEMENTS(valid_s390_opts) - 1u)
nm_assert(!valid_s390_opts[i]);
else {
nm_assert(valid_s390_opts[i]);
nm_assert(valid_s390_opts[i][0] != '\0');
if (i > 0)
g_assert(strcmp(valid_s390_opts[i - 1], valid_s390_opts[i]) < 0);
nm_assert(strcmp(valid_s390_opts[i - 1], valid_s390_opts[i]) < 0);
}
}
}
#endif
return option
&& (nm_utils_array_find_binary_search(valid_s390_opts,
sizeof(const char *),
G_N_ELEMENTS(valid_s390_opts) - 1,
&option,
nm_strcmp_p_with_data,
NULL)
&& (nm_utils_strv_find_binary_search(valid_s390_opts,
G_N_ELEMENTS(valid_s390_opts) - 1,
option)
>= 0);
}
gboolean
_nm_setting_wired_is_valid_s390_option_value(const char *name, const char *option)
{
nm_assert(name);
if (!option)
return FALSE;
/* For historic reasons, the s390-options values were not validated beyond
* simple length check (below).
*
* Here, for certain (recently added) options we add strict validation.
* As this is only done for a few hand picked options, do it right here.
*
* Maybe we should find a backward compatible way to validate all options.
* In that case, the validation should become more elaborate, like we do
* for bond options. */
if (nm_streq(name, "bridge_role")) {
return NM_IN_STRSET(option, "primary", "secondary", "none");
}
return option[0] != '\0' && strlen(option) <= NM_SETTING_WIRED_S390_OPTION_MAX_LEN;
}
/**
* nm_setting_wired_get_port:
* @setting: the #NMSettingWired
@ -467,9 +489,9 @@ nm_setting_wired_get_num_s390_options(NMSettingWired *setting)
* @setting: the #NMSettingWired
* @idx: index of the desired option, from 0 to
* nm_setting_wired_get_num_s390_options() - 1
* @out_key: (out) (transfer none): on return, the key name of the s390 specific
* @out_key: (allow-none) (out) (transfer none): on return, the key name of the s390 specific
* option; this value is owned by the setting and should not be modified
* @out_value: (out) (transfer none): on return, the value of the key of the
* @out_value: (allow-none) (out) (transfer none): on return, the value of the key of the
* s390 specific option; this value is owned by the setting and should not be
* modified
*
@ -527,7 +549,7 @@ nm_setting_wired_get_s390_option_by_key(NMSettingWired *setting, const char *key
gssize idx;
g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL);
g_return_val_if_fail(key && key[0], NULL);
g_return_val_if_fail(key, NULL);
priv = NM_SETTING_WIRED_GET_PRIVATE(setting);
@ -543,43 +565,40 @@ nm_setting_wired_get_s390_option_by_key(NMSettingWired *setting, const char *key
* @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.
* Add an option to the table. If the key already exists, the value gets
* replaced.
*
* Returns: %TRUE if the option was valid and was added to the internal option
* list, %FALSE if it was not.
* Before 1.32, the function would assert that the key is valid. Since then,
* an invalid key gets silently added but renders the profile as invalid.
*
* Returns: since 1.32 this always returns %TRUE.
**/
gboolean
nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const char *value)
{
NMSettingWiredPrivate *priv;
gssize idx;
NMUtilsNamedValue * v;
g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE);
g_return_val_if_fail(key, FALSE);
g_return_val_if_fail(value, FALSE);
if (!valid_s390_opts_check(key)) {
g_return_val_if_fail(key, FALSE);
return FALSE;
}
priv = NM_SETTING_WIRED_GET_PRIVATE(setting);
idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE);
if (idx < 0) {
gsize dst_idx = ~idx;
if (priv->s390_options.n_alloc < priv->s390_options.len + 1) {
priv->s390_options.n_alloc = NM_MAX(4, (priv->s390_options.len + 1) * 2);
g_return_val_if_fail(priv->s390_options.len < G_MAXUINT32 - 1u, FALSE);
if (priv->s390_options.n_alloc < ((gsize) priv->s390_options.len) + 1u) {
priv->s390_options.n_alloc = NM_MAX(4u, (((gsize) priv->s390_options.len) + 1u) * 2u);
priv->s390_options.arr =
g_realloc(priv->s390_options.arr,
priv->s390_options.n_alloc * sizeof(NMUtilsNamedValue));
}
if (dst_idx < priv->s390_options.len) {
memmove(&priv->s390_options.arr[dst_idx + 1],
memmove(&priv->s390_options.arr[dst_idx + 1u],
&priv->s390_options.arr[dst_idx],
(priv->s390_options.len - dst_idx) * sizeof(NMUtilsNamedValue));
}
@ -589,11 +608,8 @@ nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const
};
priv->s390_options.len++;
} else {
v = &priv->s390_options.arr[idx];
if (nm_streq(value, v->value_str))
if (!nm_utils_strdup_reset(&priv->s390_options.arr[idx].value_str_mutable, value))
return TRUE;
g_free((char *) v->value_str);
v->value_str = g_strdup(value);
}
_notify(setting, PROP_S390_OPTIONS);
@ -631,10 +647,10 @@ nm_setting_wired_remove_s390_option(NMSettingWired *setting, const char *key)
g_free((char *) priv->s390_options.arr[dst_idx].name);
g_free((char *) priv->s390_options.arr[dst_idx].value_str);
if (dst_idx + 1 != priv->s390_options.len) {
if (dst_idx + 1u != priv->s390_options.len) {
memmove(&priv->s390_options.arr[dst_idx],
&priv->s390_options.arr[dst_idx + 1],
(priv->s390_options.len - dst_idx - 1) * sizeof(NMUtilsNamedValue));
&priv->s390_options.arr[dst_idx + 1u],
(priv->s390_options.len - dst_idx - 1u) * sizeof(NMUtilsNamedValue));
}
priv->s390_options.len--;
@ -679,7 +695,7 @@ _nm_setting_wired_clear_s390_options(NMSettingWired *setting)
const char **
nm_setting_wired_get_valid_s390_options(NMSettingWired *setting)
{
return valid_s390_opts;
return (const char **) valid_s390_opts;
}
/**
@ -809,14 +825,24 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
nm_assert(v->name);
if (!valid_s390_opts_check(v->name) || v->value_str[0] == '\0'
|| strlen(v->value_str) > 200) {
if (!_nm_setting_wired_is_valid_s390_option(v->name)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("invalid '%s' or its value '%s'"),
v->name,
v->value_str);
_("invalid key '%s'"),
v->name);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_S390_OPTIONS);
return FALSE;
}
if (!_nm_setting_wired_is_valid_s390_option_value(v->name, v->value_str)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("invalid value for key '%s'"),
v->name);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_WIRED_SETTING_NAME,
@ -1087,23 +1113,27 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
hash = g_value_get_boxed(value);
priv->s390_options.n_alloc = hash ? g_hash_table_size(hash) : 0u;
priv->s390_options.n_alloc = nm_g_hash_table_size(hash);
if (priv->s390_options.n_alloc > 0) {
if (priv->s390_options.n_alloc > 0u) {
gboolean invalid_content = FALSE;
GHashTableIter iter;
const char * key;
const char * val;
guint i, j;
guint j;
guint i;
priv->s390_options.arr = g_new(NMUtilsNamedValue, priv->s390_options.n_alloc);
g_hash_table_iter_init(&iter, hash);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) {
if (!key || !val) {
invalid_content = TRUE;
continue;
}
nm_assert(priv->s390_options.len < priv->s390_options.n_alloc);
priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue){
.name = g_strdup(key),
.value_str = g_strdup(val),
@ -1116,10 +1146,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
NULL,
NULL);
/* prune duplicate keys. This is only possible if @hash does not use
* g_str_equal() as compare function (which would be a bug).
* Still, handle this, because we use later binary sort and rely
* on unique names. One bug here, should not bork the remainder
* of the program. */
* g_str_equal() as compare function (which would be a bug).
* Still, handle this, because we use later binary sort and rely
* on unique names. One bug here, should not bork the remainder
* of the program. */
j = 1;
for (i = 1; i < priv->s390_options.len; i++) {
if (nm_streq(priv->s390_options.arr[j - 1].name,

View file

@ -5325,8 +5325,6 @@ _nm_variant_attribute_spec_find_binary_search(const NMVariantAttributeSpec *cons
len,
&name,
nm_strcmp_p_with_data,
NULL,
NULL,
NULL);
if (idx < 0)
return NULL;

View file

@ -8609,7 +8609,7 @@ static void
_test_find_binary_search_do(const int *array, gsize len)
{
gsize i;
gssize idx, idx_first, idx_last;
gssize idx, idx2, idx_first, idx_last;
gs_free gconstpointer *parray = g_new(gconstpointer, len);
const int NEEDLE = 0;
gconstpointer pneedle = GINT_TO_POINTER(NEEDLE);
@ -8620,17 +8620,26 @@ _test_find_binary_search_do(const int *array, gsize len)
expected_result = nm_utils_ptrarray_find_first(parray, len, pneedle);
idx = nm_utils_ptrarray_find_binary_search(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL,
&idx_first,
&idx_last);
idx = nm_utils_ptrarray_find_binary_search_range(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL,
&idx_first,
&idx_last);
idx2 = nm_utils_ptrarray_find_binary_search(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL);
g_assert_cmpint(idx, ==, idx2);
if (expected_result >= 0) {
g_assert_cmpint(expected_result, ==, idx);
} else {
gssize idx2 = ~idx;
idx2 = ~idx;
g_assert_cmpint(idx, <, 0);
g_assert(idx2 >= 0);
@ -8787,13 +8796,13 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates(void)
for (i = 0; i < i_len + BIN_SEARCH_W_DUPS_JITTER; i++) {
gconstpointer p = GINT_TO_POINTER(i);
idx = nm_utils_ptrarray_find_binary_search(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL,
&idx_first,
&idx_last);
idx = nm_utils_ptrarray_find_binary_search_range(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL,
&idx_first,
&idx_last);
idx_first2 = nm_utils_ptrarray_find_first(arr, i_len, p);
@ -8805,6 +8814,13 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates(void)
NULL);
g_assert_cmpint(idx, ==, idx2);
idx2 = nm_utils_ptrarray_find_binary_search(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL);
g_assert_cmpint(idx, ==, idx2);
if (idx_first2 < 0) {
g_assert_cmpint(idx, <, 0);
g_assert_cmpint(idx, ==, idx_first);
@ -10813,7 +10829,7 @@ main(int argc, char **argv)
g_test_add_func("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
g_test_add_func("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two);
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search",
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_range",
test_nm_utils_ptrarray_find_binary_search);
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_with_duplicates",
test_nm_utils_ptrarray_find_binary_search_with_duplicates);

View file

@ -2904,17 +2904,20 @@ _rndt_wired_add_s390_options(NMSettingWired *s_wired, char **out_keyfile_entries
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_uint32() % 1000;
if (p < 200)
opt_vals[i] = nm_strdup_int(i);
if (nm_streq(opt_keys[i], "bridge_role"))
opt_vals[i] = g_strdup(nmtst_rand_select_str("primary", "secondary", "none"));
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);
guint p = nmtst_get_rand_uint32() % 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);
}
}
}

View file

@ -309,7 +309,11 @@ typedef gpointer (*NMUtilsCopyFunc)(gpointer);
const char **
_nm_ip_address_get_attribute_names(const NMIPAddress *addr, gboolean sorted, guint *out_length);
void _nm_setting_wired_clear_s390_options(NMSettingWired *setting);
#define NM_SETTING_WIRED_S390_OPTION_MAX_LEN 200u
void _nm_setting_wired_clear_s390_options(NMSettingWired *setting);
gboolean _nm_setting_wired_is_valid_s390_option(const char *option);
gboolean _nm_setting_wired_is_valid_s390_option_value(const char *name, const char *option);
gboolean _nm_ip_route_attribute_validate_all(const NMIPRoute *route, GError **error);
const char **

View file

@ -520,9 +520,9 @@ NM_G_ERROR_MSG(GError *error)
#ifndef _NM_CC_SUPPORT_GENERIC
/* In the meantime, NetworkManager requires C11 and _Generic() should always be available.
* However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet
* bump the C standard requirement. Leave this for the moment, but eventually we can
* drop it. */
* However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet
* bump the C standard requirement. Leave this for the moment, but eventually we can
* drop it. */
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) \
|| (defined(__clang__))
#define _NM_CC_SUPPORT_GENERIC 1
@ -682,21 +682,21 @@ NM_G_ERROR_MSG(GError *error)
#if _NM_CC_SUPPORT_GENERIC
/* these macros cast (value) to
* - "const char **" (for "MC", mutable-const)
* - "const char *const*" (for "CC", const-const)
* The point is to do this cast, but only accepting pointers
* that are compatible already.
*
* The problem is, if you add a function like g_strdupv(), the input
* argument is not modified (CC), but you want to make it work also
* for "char **". C doesn't allow this form of casting (for good reasons),
* so the function makes a choice like g_strdupv(char**). That means,
* every time you want to call it with a const argument, you need to
* explicitly cast it.
*
* These macros do the cast, but they only accept a compatible input
* type, otherwise they will fail compilation.
*/
* - "const char **" (for "MC", mutable-const)
* - "const char *const*" (for "CC", const-const)
* The point is to do this cast, but only accepting pointers
* that are compatible already.
*
* The problem is, if you add a function like g_strdupv(), the input
* argument is not modified (CC), but you want to make it work also
* for "char **". C doesn't allow this form of casting (for good reasons),
* so the function makes a choice like g_strdupv(char**). That means,
* every time you want to call it with a const argument, you need to
* explicitly cast it.
*
* These macros do the cast, but they only accept a compatible input
* type, otherwise they will fail compilation.
*/
#define NM_CAST_STRV_MC(value) \
(_Generic ((value), \
const char * *: (const char * *) (value), \

View file

@ -3833,9 +3833,46 @@ nm_utils_ptrarray_find_binary_search(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last)
gpointer user_data)
{
gssize imin, imax, imid;
int cmp;
g_return_val_if_fail(list || !len, ~((gssize) 0));
g_return_val_if_fail(cmpfcn, ~((gssize) 0));
imin = 0;
if (len > 0) {
imax = len - 1;
while (imin <= imax) {
imid = imin + (imax - imin) / 2;
cmp = cmpfcn(list[imid], needle, user_data);
if (cmp == 0)
return imid;
if (cmp < 0)
imin = imid + 1;
else
imax = imid - 1;
}
}
/* return the inverse of @imin. This is a negative number, but
* also is ~imin the position where the value should be inserted. */
imin = ~imin;
return imin;
}
gssize
nm_utils_ptrarray_find_binary_search_range(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last)
{
gssize imin, imax, imid, i2min, i2max, i2mid;
int cmp;

View file

@ -1727,9 +1727,11 @@ typedef struct {
union {
NMUtilsNamedEntry named_entry;
const char * name;
char * name_mutable;
};
union {
const char *value_str;
char * value_str_mutable;
gpointer value_ptr;
};
} NMUtilsNamedValue;
@ -2016,9 +2018,31 @@ gssize nm_utils_ptrarray_find_binary_search(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last);
gpointer user_data);
gssize nm_utils_ptrarray_find_binary_search_range(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last);
#define nm_utils_strv_find_binary_search(strv, len, needle) \
({ \
const char *const *const _strv = NM_CAST_STRV_CC(strv); \
const gsize _len = (len); \
const char *const _needle = (needle); \
\
nm_assert(_len == 0 || _strv); \
nm_assert(_needle); \
\
nm_utils_ptrarray_find_binary_search((gconstpointer *) _strv, \
_len, \
_needle, \
nm_strcmp_with_data, \
NULL); \
})
gssize nm_utils_array_find_binary_search(gconstpointer list,
gsize elem_size,

View file

@ -977,6 +977,8 @@ nmtst_rand_buf(GRand *rand, gpointer buffer, gsize buffer_length)
#define nmtst_rand_select(...) _nmtst_rand_select(NM_UNIQ, __VA_ARGS__)
#define nmtst_rand_select_str(x, ...) nmtst_rand_select((const char *) (x), ##__VA_ARGS__)
static inline void *
nmtst_rand_perm(GRand *rand, void *dst, const void *src, gsize elmt_size, gsize n_elmt)
{

View file

@ -969,17 +969,25 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
NULL);
while ((tmp = get_word(&argument, ',')) != NULL) {
char *val;
const char *key;
char * val;
val = strchr(tmp, '=');
if (val) {
gs_free char *key = NULL;
key = g_strndup(tmp, val - tmp);
val[0] = '\0';
val++;
nm_setting_wired_add_s390_option(s_wired, key, val);
if (!val) {
/* an invalid (or empty) entry. Ignore. */
continue;
}
key = tmp;
val[0] = '\0';
val++;
if (!_nm_setting_wired_is_valid_s390_option(key)
|| !_nm_setting_wired_is_valid_s390_option_value(key, val)) {
/* Invalid setting. Silently ignore, but also ensure we
* didn't already set it. */
nm_setting_wired_remove_s390_option(s_wired, key);
} else
nm_setting_wired_add_s390_option(s_wired, key, val);
}
}