Commit 5cf985e1 authored by Jiří Klimeš's avatar Jiří Klimeš

merge: accept numeric bonding modes (bgo #704666) (rh #1133544) (rh #1171009)

Bonding mode can be provided either as descriptive name of a numeric value
(on D-Bus and ifcfg-rh too).

https://bugzilla.gnome.org/show_bug.cgi?id=704666
https://bugzilla.redhat.com/show_bug.cgi?id=1133544
https://bugzilla.redhat.com/show_bug.cgi?id=1171009
parents d9f143df c7436702
......@@ -723,6 +723,27 @@ _normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters)
return FALSE;
}
static gboolean
_normalize_bond_mode (NMConnection *self, GHashTable *parameters)
{
NMSettingBond *s_bond = nm_connection_get_setting_bond (self);
/* Convert mode from numeric to string notation */
if (s_bond) {
const char *mode = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
int mode_int = nm_utils_bond_mode_string_to_int (mode);
if (mode_int != -1) {
const char *mode_new = nm_utils_bond_mode_int_to_string (mode_int);
if (g_strcmp0 (mode_new, mode) != 0) {
nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MODE, mode_new);
return TRUE;
}
}
}
return FALSE;
}
/**
* nm_connection_verify:
* @connection: the #NMConnection to verify
......@@ -936,6 +957,7 @@ nm_connection_normalize (NMConnection *connection,
was_modified |= _normalize_connection_slave_type (connection);
was_modified |= _normalize_ip_config (connection, parameters);
was_modified |= _normalize_infiniband_mtu (connection, parameters);
was_modified |= _normalize_bond_mode (connection, parameters);
/* Verify anew. */
success = _nm_connection_verify (connection, error);
......
......@@ -440,15 +440,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting);
GHashTableIter iter;
const char *key, *value;
const char *valid_modes[] = { "balance-rr",
"active-backup",
"balance-xor",
"broadcast",
"802.3ad",
"balance-tlb",
"balance-alb",
NULL };
int miimon = 0, arp_interval = 0;
int mode, miimon = 0, arp_interval = 0;
const char *mode_orig, *mode_new;
const char *arp_ip_target = NULL;
const char *lacp_rate;
const char *primary;
......@@ -484,7 +477,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
}
value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
/* Verify bond mode */
mode_orig = value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
if (!value) {
g_set_error (error,
NM_CONNECTION_ERROR,
......@@ -494,7 +488,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
return FALSE;
}
if (!_nm_utils_string_in_list (value, valid_modes)) {
mode = nm_utils_bond_mode_string_to_int (value);
if (mode == -1) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
......@@ -503,6 +498,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
return FALSE;
}
mode_new = value = nm_utils_bond_mode_int_to_string (mode);
/* Make sure mode is compatible with other settings */
if ( strcmp (value, "balance-alb") == 0
......@@ -645,7 +641,22 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
return _nm_connection_verify_required_interface_name (connection, error);
if (!_nm_connection_verify_required_interface_name (connection, error))
return FALSE;
/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
if (g_strcmp0 (mode_orig, mode_new) != 0) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' option should be string"),
NM_SETTING_BOND_OPTION_MODE);
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
return NM_SETTING_VERIFY_NORMALIZABLE;
}
return TRUE;
}
static void
......
......@@ -3213,3 +3213,64 @@ nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_typ
return FALSE;
}
}
typedef struct {
const char *str;
const char *num;
} BondMode;
static BondMode bond_mode_table[] = {
[0] = { "balance-rr", "0" },
[1] = { "active-backup", "1" },
[2] = { "balance-xor", "2" },
[3] = { "broadcast", "3" },
[4] = { "802.3ad", "4" },
[5] = { "balance-tlb", "5" },
[6] = { "balance-alb", "6" },
};
/**
* nm_utils_bond_mode_int_to_string:
* @mode: bonding mode as a numeric value
*
* Convert bonding mode from integer value to descriptive name.
* See https://www.kernel.org/doc/Documentation/networking/bonding.txt for
* available modes.
*
* Returns: bonding mode string, or NULL on error
*/
const char *
nm_utils_bond_mode_int_to_string (int mode)
{
if (mode >= 0 && mode < G_N_ELEMENTS (bond_mode_table))
return bond_mode_table[mode].str;
return NULL;
}
/**
* nm_utils_bond_mode_string_to_int:
* @mode: bonding mode as string
*
* Convert bonding mode from string representation to numeric value.
* See https://www.kernel.org/doc/Documentation/networking/bonding.txt for
* available modes.
* The @mode string can be either a descriptive name or a number (as string).
*
* Returns: numeric bond mode, or -1 on error
*/
int
nm_utils_bond_mode_string_to_int (const char *mode)
{
int i;
if (!mode || !*mode)
return -1;
for (i = 0; i < G_N_ELEMENTS (bond_mode_table); i++) {
if ( strcmp (mode, bond_mode_table[i].str) == 0
|| strcmp (mode, bond_mode_table[i].num) == 0)
return i;
}
return -1;
}
......@@ -15,7 +15,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2005 - 2013 Red Hat, Inc.
* Copyright 2005 - 2014 Red Hat, Inc.
*/
#ifndef __NM_UTILS_H__
......@@ -185,6 +185,9 @@ gboolean nm_utils_ipaddr_valid (int family, const char *ip);
gboolean nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type);
int nm_utils_bond_mode_string_to_int (const char *mode);
const char *nm_utils_bond_mode_int_to_string (int mode);
G_END_DECLS
#endif /* __NM_UTILS_H__ */
......@@ -754,6 +754,8 @@ global:
nm_state_get_type;
nm_utils_ap_mode_security_valid;
nm_utils_bin2hexstr;
nm_utils_bond_mode_int_to_string;
nm_utils_bond_mode_string_to_int;
nm_utils_check_virtual_device_compatibility;
nm_utils_escape_ssid;
nm_utils_file_is_certificate;
......
......@@ -3832,7 +3832,8 @@ handle_bond_option (NMSettingBond *s_bond,
}
if (!nm_setting_bond_add_option (s_bond, key, sanitized ? sanitized : value))
PARSE_WARNING ("invalid bonding option '%s'", key);
PARSE_WARNING ("invalid bonding option '%s' = %s",
key, sanitized ? sanitized : value);
g_free (sanitized);
}
......
......@@ -106,6 +106,7 @@ EXTRA_DIST = \
ifcfg-test-bond-main \
ifcfg-test-bond-slave \
ifcfg-test-bond-slave-ib \
ifcfg-test-bond-mode-numeric \
ifcfg-test-dcb \
ifcfg-test-dcb-default-app-priorities \
ifcfg-test-dcb-bad-booleans \
......
DEVICE=bond0
ONBOOT=no
TYPE=Bond
BOOTPROTO=dhcp
BONDING_OPTS="mode=4 miimon=100"
......@@ -11443,6 +11443,37 @@ test_write_bond_slave_ib (void)
g_object_unref (reread);
}
static void
test_read_bond_opts_mode_numeric (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingBond *s_bond;
gboolean success;
GError *error = NULL;
connection = connection_from_file_test (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-mode-numeric",
NULL, TYPE_ETHERNET, NULL, &error);
g_assert_no_error (error);
g_assert (connection);
success = nm_connection_verify (connection, &error);
g_assert_no_error (error);
g_assert (success);
g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "bond0");
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME);
s_bond = nm_connection_get_setting_bond (connection);
g_assert (s_bond);
g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE), ==, "802.3ad");
g_object_unref (connection);
}
#define DCB_ALL_FLAGS (NM_SETTING_DCB_FLAG_ENABLE | \
NM_SETTING_DCB_FLAG_ADVERTISE | \
NM_SETTING_DCB_FLAG_WILLING)
......@@ -12525,6 +12556,7 @@ int main (int argc, char **argv)
test_write_bond_main ();
test_write_bond_slave ();
test_write_bond_slave_ib ();
g_test_add_func (TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric);
/* bridging */
test_read_bridge_main ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment