mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-03 05:28:01 +02:00
merge: branch 'bg/bond-options-rh1299103'
Add missing bond options and improve connection matching for bond connections.
This commit is contained in:
commit
6e738c83f1
10 changed files with 473 additions and 77 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -153,6 +153,7 @@ test-*.trs
|
|||
/libnm-core/tests/test-need-secrets
|
||||
/libnm-core/tests/test-secrets
|
||||
/libnm-core/tests/test-setting-8021x
|
||||
/libnm-core/tests/test-setting-bond
|
||||
/libnm-core/tests/test-setting-dcb
|
||||
|
||||
/libnm-glib/nm-secret-agent-glue.h
|
||||
|
|
|
|||
|
|
@ -1150,8 +1150,19 @@ nmc_property_bond_get_options (NMSetting *setting, NmcPropertyGetType get_type)
|
|||
bond_options_s = g_string_new (NULL);
|
||||
for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) {
|
||||
const char *key, *value;
|
||||
gs_free char *tmp_value = NULL;
|
||||
char *p;
|
||||
|
||||
nm_setting_bond_get_option (s_bond, i, &key, &value);
|
||||
|
||||
if (nm_streq0 (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
|
||||
value = tmp_value = g_strdup (value);
|
||||
for (p = tmp_value; p && *p; p++) {
|
||||
if (*p == ',')
|
||||
*p = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
g_string_append_printf (bond_options_s, "%s=%s,", key, value);
|
||||
}
|
||||
g_string_truncate (bond_options_s, bond_options_s->len-1); /* chop off trailing ',' */
|
||||
|
|
@ -3651,10 +3662,28 @@ _validate_bond_option_value (const char *option, const char *value, GError **err
|
|||
return value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_bond_add_option (NMSettingBond *setting,
|
||||
const char *name,
|
||||
const char *value)
|
||||
{
|
||||
gs_free char *tmp_value = NULL;
|
||||
char *p;
|
||||
|
||||
if (nm_streq0 (name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
|
||||
value = tmp_value = g_strdup (value);
|
||||
for (p = tmp_value; p && *p; p++)
|
||||
if (*p == ' ')
|
||||
*p = ',';
|
||||
}
|
||||
|
||||
return nm_setting_bond_add_option (setting, name, value);
|
||||
}
|
||||
|
||||
DEFINE_SETTER_OPTIONS (nmc_property_bond_set_options,
|
||||
NM_SETTING_BOND,
|
||||
NMSettingBond,
|
||||
nm_setting_bond_add_option,
|
||||
_bond_add_option,
|
||||
nm_setting_bond_get_valid_options,
|
||||
_validate_bond_option_value)
|
||||
DEFINE_REMOVER_OPTION (nmc_property_bond_remove_option_options,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
include $(GLIB_MAKEFILE)
|
||||
|
||||
@GNOME_CODE_COVERAGE_RULES@
|
||||
|
||||
SUBDIRS = . tests
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
|
@ -11,7 +13,8 @@ AM_CPPFLAGS = \
|
|||
-DNMLIBDIR=\"$(nmlibdir)\" \
|
||||
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \
|
||||
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
|
||||
$(GLIB_CFLAGS)
|
||||
$(GLIB_CFLAGS) \
|
||||
$(CODE_COVERAGE_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libnm-core.la
|
||||
|
||||
|
|
@ -35,6 +38,9 @@ libnm_core_la_LIBADD = \
|
|||
$(GLIB_LIBS) \
|
||||
$(UUID_LIBS)
|
||||
|
||||
libnm_core_la_LDFLAGS = \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
if WITH_GNUTLS
|
||||
AM_CPPFLAGS += $(GNUTLS_CFLAGS)
|
||||
libnm_core_la_SOURCES += crypto_gnutls.c
|
||||
|
|
|
|||
|
|
@ -283,4 +283,16 @@ void _nm_setting_vlan_get_priorities (NMSettingVlan *setting,
|
|||
|
||||
/***********************************************************/
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_OPTION_TYPE_INT,
|
||||
NM_BOND_OPTION_TYPE_STRING,
|
||||
NM_BOND_OPTION_TYPE_BOTH,
|
||||
NM_BOND_OPTION_TYPE_IP,
|
||||
NM_BOND_OPTION_TYPE_MAC,
|
||||
NM_BOND_OPTION_TYPE_IFNAME,
|
||||
} NMBondOptionType;
|
||||
|
||||
NMBondOptionType
|
||||
_nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "nm-utils-private.h"
|
||||
#include "nm-connection-private.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
/**
|
||||
* SECTION:nm-setting-bond
|
||||
|
|
@ -57,14 +58,6 @@ enum {
|
|||
LAST_PROP
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_INT,
|
||||
TYPE_STR,
|
||||
TYPE_BOTH,
|
||||
TYPE_IP,
|
||||
TYPE_IFNAME,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *opt;
|
||||
const char *val;
|
||||
|
|
@ -75,28 +68,40 @@ typedef struct {
|
|||
} BondDefault;
|
||||
|
||||
static const BondDefault defaults[] = {
|
||||
{ NM_SETTING_BOND_OPTION_MODE, "balance-rr", TYPE_BOTH, 0, 6,
|
||||
{ NM_SETTING_BOND_OPTION_MODE, "balance-rr", NM_BOND_OPTION_TYPE_BOTH, 0, 6,
|
||||
{ "balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_MIIMON, "100", TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_DOWNDELAY, "0", TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_UPDELAY, "0", TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_INTERVAL, "0", TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "", TYPE_IP },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_VALIDATE, "0", TYPE_BOTH, 0, 3,
|
||||
{ NM_SETTING_BOND_OPTION_MIIMON, "100", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_DOWNDELAY, "0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_UPDELAY, "0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_INTERVAL, "0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "", NM_BOND_OPTION_TYPE_IP },
|
||||
{ NM_SETTING_BOND_OPTION_ARP_VALIDATE, "none", NM_BOND_OPTION_TYPE_BOTH, 0, 3,
|
||||
{ "none", "active", "backup", "all", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_PRIMARY, "", TYPE_IFNAME },
|
||||
{ NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, "0", TYPE_BOTH, 0, 2,
|
||||
{ NM_SETTING_BOND_OPTION_PRIMARY, "", NM_BOND_OPTION_TYPE_IFNAME },
|
||||
{ NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, "always", NM_BOND_OPTION_TYPE_BOTH, 0, 2,
|
||||
{ "always", "better", "failure", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, "0", TYPE_BOTH, 0, 2,
|
||||
{ NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, "none", NM_BOND_OPTION_TYPE_BOTH, 0, 2,
|
||||
{ "none", "active", "follow", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_USE_CARRIER, "1", TYPE_INT, 0, 1 },
|
||||
{ NM_SETTING_BOND_OPTION_AD_SELECT, "0", TYPE_BOTH, 0, 2,
|
||||
{ NM_SETTING_BOND_OPTION_USE_CARRIER, "1", NM_BOND_OPTION_TYPE_INT, 0, 1 },
|
||||
{ NM_SETTING_BOND_OPTION_AD_SELECT, "stable", NM_BOND_OPTION_TYPE_BOTH, 0, 2,
|
||||
{ "stable", "bandwidth", "count", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "0", TYPE_BOTH, 0, 2,
|
||||
{ NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "layer2", NM_BOND_OPTION_TYPE_BOTH, 0, 2,
|
||||
{ "layer2", "layer3+4", "layer2+3", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", TYPE_INT, 0, 255 },
|
||||
{ NM_SETTING_BOND_OPTION_LACP_RATE, "0", TYPE_BOTH, 0, 1,
|
||||
{ NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", NM_BOND_OPTION_TYPE_INT, 0, 255 },
|
||||
{ NM_SETTING_BOND_OPTION_LACP_RATE, "slow", NM_BOND_OPTION_TYPE_BOTH, 0, 1,
|
||||
{ "slow", "fast", NULL } },
|
||||
{ NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, "", NM_BOND_OPTION_TYPE_IFNAME },
|
||||
{ NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,"65535", NM_BOND_OPTION_TYPE_INT, 1, 65535 },
|
||||
{ NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, "", NM_BOND_OPTION_TYPE_MAC },
|
||||
{ NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, "0", NM_BOND_OPTION_TYPE_INT, 0, 1023},
|
||||
{ NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,"0", NM_BOND_OPTION_TYPE_INT, 0, 1},
|
||||
{ NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, "any", NM_BOND_OPTION_TYPE_BOTH, 0, 1, {"any", "all"}},
|
||||
{ NM_SETTING_BOND_OPTION_MIN_LINKS, "0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT },
|
||||
{ NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, "1", NM_BOND_OPTION_TYPE_INT, 0, 255 },
|
||||
{ NM_SETTING_BOND_OPTION_NUM_UNSOL_NA, "1", NM_BOND_OPTION_TYPE_INT, 0, 255 },
|
||||
{ NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,"1", NM_BOND_OPTION_TYPE_INT, 0, 65535 },
|
||||
{ NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, "1", NM_BOND_OPTION_TYPE_INT, 0, 1 },
|
||||
{ NM_SETTING_BOND_OPTION_LP_INTERVAL, "1", NM_BOND_OPTION_TYPE_INT, 1, G_MAXINT },
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -268,16 +273,18 @@ nm_setting_bond_validate_option (const char *name,
|
|||
if (value == NULL)
|
||||
return TRUE;
|
||||
switch (defaults[i].opt_type) {
|
||||
case TYPE_INT:
|
||||
case NM_BOND_OPTION_TYPE_INT:
|
||||
return validate_int (name, value, &defaults[i]);
|
||||
case TYPE_STR:
|
||||
case NM_BOND_OPTION_TYPE_STRING:
|
||||
return validate_list (name, value, &defaults[i]);
|
||||
case TYPE_BOTH:
|
||||
case NM_BOND_OPTION_TYPE_BOTH:
|
||||
return ( validate_int (name, value, &defaults[i])
|
||||
|| validate_list (name, value, &defaults[i]));
|
||||
case TYPE_IP:
|
||||
case NM_BOND_OPTION_TYPE_IP:
|
||||
return validate_ip (name, value);
|
||||
case TYPE_IFNAME:
|
||||
case NM_BOND_OPTION_TYPE_MAC:
|
||||
return nm_utils_hwaddr_valid (value, ETH_ALEN);
|
||||
case NM_BOND_OPTION_TYPE_IFNAME:
|
||||
return validate_ifname (name, value);
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -433,6 +440,29 @@ nm_setting_bond_get_option_default (NMSettingBond *setting, const char *name)
|
|||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bond_get_option_type:
|
||||
* @setting: the #NMSettingBond
|
||||
* @name: the name of the option
|
||||
*
|
||||
* Returns: the type of the bond option.
|
||||
**/
|
||||
NMBondOptionType
|
||||
_nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NM_BOND_OPTION_TYPE_INT);
|
||||
g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NM_BOND_OPTION_TYPE_INT);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (defaults); i++) {
|
||||
if (nm_streq0 (defaults[i].opt, name))
|
||||
return defaults[i].opt_type;
|
||||
}
|
||||
/* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
|
|
@ -440,6 +470,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
GHashTableIter iter;
|
||||
const char *key, *value;
|
||||
int mode, miimon = 0, arp_interval = 0;
|
||||
int num_grat_arp = -1, num_unsol_na = -1;
|
||||
const char *mode_orig, *mode_new;
|
||||
const char *arp_ip_target = NULL;
|
||||
const char *lacp_rate;
|
||||
|
|
@ -464,6 +495,12 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
if (value)
|
||||
arp_interval = atoi (value);
|
||||
value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP);
|
||||
if (value)
|
||||
num_grat_arp = atoi (value);
|
||||
value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
|
||||
if (value)
|
||||
num_unsol_na = atoi (value);
|
||||
|
||||
/* Can only set one of miimon and arp_interval */
|
||||
if (miimon > 0 && arp_interval > 0) {
|
||||
|
|
@ -474,11 +511,12 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
NM_SETTING_BOND_OPTION_MIIMON,
|
||||
NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Verify bond mode */
|
||||
mode_orig = value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
|
||||
if (!value) {
|
||||
mode_orig = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
|
||||
if (!mode_orig) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -487,7 +525,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 = nm_utils_bond_mode_string_to_int (value);
|
||||
mode = nm_utils_bond_mode_string_to_int (mode_orig);
|
||||
if (mode == -1) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
@ -497,24 +535,24 @@ 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);
|
||||
mode_new = nm_utils_bond_mode_int_to_string (mode);
|
||||
|
||||
/* Make sure mode is compatible with other settings */
|
||||
if ( strcmp (value, "balance-alb") == 0
|
||||
|| strcmp (value, "balance-tlb") == 0) {
|
||||
if ( strcmp (mode_new, "balance-alb") == 0
|
||||
|| strcmp (mode_new, "balance-tlb") == 0) {
|
||||
if (arp_interval > 0) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s=%s' is incompatible with '%s > 0'"),
|
||||
NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
NM_SETTING_BOND_OPTION_MODE, mode_new, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
primary = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||
if (strcmp (value, "active-backup") == 0) {
|
||||
if (strcmp (mode_new, "active-backup") == 0) {
|
||||
if (primary && !nm_utils_iface_valid_name (primary)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
@ -538,12 +576,12 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
}
|
||||
|
||||
if (nm_connection_get_setting_infiniband (connection)) {
|
||||
if (strcmp (value, "active-backup") != 0) {
|
||||
if (strcmp (mode_new, "active-backup") != 0) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s=%s' is not a valid configuration for '%s'"),
|
||||
NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_INFINIBAND_SETTING_NAME);
|
||||
NM_SETTING_BOND_OPTION_MODE, mode_new, NM_SETTING_INFINIBAND_SETTING_NAME);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -629,8 +667,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
lacp_rate = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_LACP_RATE);
|
||||
if ( lacp_rate
|
||||
&& (g_strcmp0 (value, "802.3ad") != 0 && g_strcmp0 (value, "4") != 0)
|
||||
&& (strcmp (lacp_rate, "slow") != 0 && strcmp (lacp_rate, "0") != 0)) {
|
||||
&& g_strcmp0 (mode_new, "802.3ad")
|
||||
&& strcmp (lacp_rate, "slow") != 0
|
||||
&& strcmp (lacp_rate, "0") != 0) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -640,6 +679,18 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if ( (num_grat_arp != -1 && num_unsol_na != -1)
|
||||
&& (num_grat_arp != num_unsol_na)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s' and '%s' cannot have different values"),
|
||||
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP,
|
||||
NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_nm_connection_verify_required_interface_name (connection, error))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -658,6 +709,63 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
options_hash_match (NMSettingBond *s_bond, GHashTable *options1, GHashTable *options2)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
const char *key, *value, *value2;
|
||||
|
||||
g_hash_table_iter_init (&iter, options1);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
|
||||
value2 = g_hash_table_lookup (options2, key);
|
||||
|
||||
if (!value2) {
|
||||
if (nm_streq (key, "num_grat_arp"))
|
||||
value2 = g_hash_table_lookup (options2, "num_unsol_na");
|
||||
else if (nm_streq (key, "num_unsol_na"))
|
||||
value2 = g_hash_table_lookup (options2, "num_grat_arp");
|
||||
}
|
||||
|
||||
if (value2) {
|
||||
if (nm_streq (value, value2))
|
||||
continue;
|
||||
} else {
|
||||
if (nm_streq (value, nm_setting_bond_get_option_default (s_bond, key)))
|
||||
continue;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
options_equal (NMSettingBond *s_bond, GHashTable *options1, GHashTable *options2)
|
||||
{
|
||||
return options_hash_match (s_bond, options1, options2)
|
||||
&& options_hash_match (s_bond, options2, options1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compare_property (NMSetting *setting,
|
||||
NMSetting *other,
|
||||
const GParamSpec *prop_spec,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingClass *parent_class;
|
||||
|
||||
if (nm_streq0 (prop_spec->name, NM_SETTING_BOND_OPTIONS)) {
|
||||
return options_equal (NM_SETTING_BOND (setting),
|
||||
NM_SETTING_BOND_GET_PRIVATE (setting)->options,
|
||||
NM_SETTING_BOND_GET_PRIVATE (other)->options);
|
||||
}
|
||||
|
||||
/* Otherwise chain up to parent to handle generic compare */
|
||||
parent_class = NM_SETTING_CLASS (nm_setting_bond_parent_class);
|
||||
return parent_class->compare_property (setting, other, prop_spec, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_bond_init (NMSettingBond *setting)
|
||||
{
|
||||
|
|
@ -721,10 +829,11 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class)
|
|||
g_type_class_add_private (setting_class, sizeof (NMSettingBondPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
parent_class->compare_property = compare_property;
|
||||
|
||||
/* Properties */
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -42,21 +42,33 @@ G_BEGIN_DECLS
|
|||
#define NM_SETTING_BOND_OPTIONS "options"
|
||||
|
||||
/* Valid options for the 'options' property */
|
||||
#define NM_SETTING_BOND_OPTION_MODE "mode"
|
||||
#define NM_SETTING_BOND_OPTION_MIIMON "miimon"
|
||||
#define NM_SETTING_BOND_OPTION_DOWNDELAY "downdelay"
|
||||
#define NM_SETTING_BOND_OPTION_UPDELAY "updelay"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_INTERVAL "arp_interval"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate"
|
||||
#define NM_SETTING_BOND_OPTION_PRIMARY "primary"
|
||||
#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect"
|
||||
#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac"
|
||||
#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier"
|
||||
#define NM_SETTING_BOND_OPTION_AD_SELECT "ad_select"
|
||||
#define NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY "xmit_hash_policy"
|
||||
#define NM_SETTING_BOND_OPTION_RESEND_IGMP "resend_igmp"
|
||||
#define NM_SETTING_BOND_OPTION_LACP_RATE "lacp_rate"
|
||||
#define NM_SETTING_BOND_OPTION_MODE "mode"
|
||||
#define NM_SETTING_BOND_OPTION_MIIMON "miimon"
|
||||
#define NM_SETTING_BOND_OPTION_DOWNDELAY "downdelay"
|
||||
#define NM_SETTING_BOND_OPTION_UPDELAY "updelay"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_INTERVAL "arp_interval"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate"
|
||||
#define NM_SETTING_BOND_OPTION_PRIMARY "primary"
|
||||
#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect"
|
||||
#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac"
|
||||
#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier"
|
||||
#define NM_SETTING_BOND_OPTION_AD_SELECT "ad_select"
|
||||
#define NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY "xmit_hash_policy"
|
||||
#define NM_SETTING_BOND_OPTION_RESEND_IGMP "resend_igmp"
|
||||
#define NM_SETTING_BOND_OPTION_LACP_RATE "lacp_rate"
|
||||
#define NM_SETTING_BOND_OPTION_ACTIVE_SLAVE "active_slave"
|
||||
#define NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO "ad_actor_sys_prio"
|
||||
#define NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM "ad_actor_system"
|
||||
#define NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY "ad_user_port_key"
|
||||
#define NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE "all_slaves_active"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS "arp_all_targets"
|
||||
#define NM_SETTING_BOND_OPTION_MIN_LINKS "min_links"
|
||||
#define NM_SETTING_BOND_OPTION_NUM_GRAT_ARP "num_grat_arp"
|
||||
#define NM_SETTING_BOND_OPTION_NUM_UNSOL_NA "num_unsol_na"
|
||||
#define NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE "packets_per_slave"
|
||||
#define NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB "tlb_dynamic_lb"
|
||||
#define NM_SETTING_BOND_OPTION_LP_INTERVAL "lp_interval"
|
||||
|
||||
struct _NMSettingBond {
|
||||
NMSetting parent;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ noinst_PROGRAMS = \
|
|||
test-keyfile \
|
||||
test-secrets \
|
||||
test-setting-8021x \
|
||||
test-setting-bond \
|
||||
test-setting-dcb \
|
||||
test-settings-defaults
|
||||
|
||||
|
|
|
|||
198
libnm-core/tests/test-setting-bond.c
Normal file
198
libnm-core/tests/test-setting-bond.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2016 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-connection.h"
|
||||
#include "nm-simple-connection.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-errors.h"
|
||||
|
||||
#include "nm-test-utils.h"
|
||||
|
||||
static void
|
||||
create_bond_connection (NMConnection **con, NMSettingBond **s_bond)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
g_assert (con);
|
||||
g_assert (s_bond);
|
||||
|
||||
*con = nmtst_create_minimal_connection ("bond",
|
||||
NULL,
|
||||
NM_SETTING_BOND_SETTING_NAME,
|
||||
&s_con);
|
||||
g_assert (*con);
|
||||
g_assert (s_con);
|
||||
|
||||
g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "bond0", NULL);
|
||||
|
||||
*s_bond = (NMSettingBond *) nm_setting_bond_new ();
|
||||
g_assert (*s_bond);
|
||||
|
||||
nm_connection_add_setting (*con, NM_SETTING (*s_bond));
|
||||
}
|
||||
|
||||
#define test_verify_options(exp, ...) \
|
||||
G_STMT_START { \
|
||||
const char *__opts[] = { __VA_ARGS__ , NULL }; \
|
||||
\
|
||||
_test_verify_options (__opts, exp); \
|
||||
} G_STMT_END
|
||||
|
||||
static void
|
||||
_test_verify_options (const char **options, gboolean expected_result)
|
||||
{
|
||||
gs_unref_object NMConnection *con = NULL;
|
||||
NMSettingBond *s_bond;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
const char **option;
|
||||
|
||||
create_bond_connection (&con, &s_bond);
|
||||
|
||||
for (option = options; option[0] && option[1]; option += 2)
|
||||
g_assert (nm_setting_bond_add_option (s_bond, option[0], option[1]));
|
||||
|
||||
if (expected_result) {
|
||||
nmtst_assert_connection_verifies_and_normalizable (con);
|
||||
nmtst_connection_normalize (con);
|
||||
success = nm_setting_verify ((NMSetting *) s_bond, con, &error);
|
||||
nmtst_assert_success (success, error);
|
||||
} else {
|
||||
nmtst_assert_connection_unnormalizable (con,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_verify (void)
|
||||
{
|
||||
test_verify_options (TRUE,
|
||||
"mode", "3",
|
||||
"arp_interval", "0");
|
||||
test_verify_options (FALSE,
|
||||
/* arp_interval not supported in balance-alb mode */
|
||||
"mode", "balance-alb",
|
||||
"arp_interval", "1",
|
||||
"arp_ip_target", "1.2.3.4");
|
||||
test_verify_options (FALSE,
|
||||
/* arp_ip_target requires arp_interval */
|
||||
"mode", "balance-rr",
|
||||
"arp_ip_target", "1.2.3.4");
|
||||
test_verify_options (TRUE,
|
||||
"mode", "balance-rr",
|
||||
"arp_interval", "1",
|
||||
"arp_ip_target", "1.2.3.4");
|
||||
test_verify_options (FALSE,
|
||||
/* num_grat_arp, num_unsol_na cannot be different */
|
||||
"mode", "balance-rr",
|
||||
"num_grat_arp", "3",
|
||||
"num_unsol_na", "4");
|
||||
test_verify_options (TRUE,
|
||||
"mode", "balance-rr",
|
||||
"num_grat_arp", "5",
|
||||
"num_unsol_na", "5");
|
||||
test_verify_options (TRUE,
|
||||
"mode", "active-backup",
|
||||
"primary", "eth0");
|
||||
test_verify_options (FALSE,
|
||||
/* primary requires mode=active-backup */
|
||||
"mode", "802.3ad",
|
||||
"primary", "eth0");
|
||||
test_verify_options (TRUE,
|
||||
"mode", "802.3ad",
|
||||
"lacp_rate", "fast");
|
||||
test_verify_options (FALSE,
|
||||
/* lacp_rate=fast requires mode=802.3ad */
|
||||
"mode", "balance-rr",
|
||||
"lacp_rate", "fast");
|
||||
test_verify_options (TRUE,
|
||||
"mode", "802.3ad",
|
||||
"ad_actor_system", "ae:00:11:33:44:55");
|
||||
}
|
||||
|
||||
static void
|
||||
test_compare_options (gboolean exp_res, const char **opts1, const char **opts2)
|
||||
{
|
||||
gs_unref_object NMSettingBond *s_bond1 = NULL, *s_bond2 = NULL;
|
||||
const char **p;
|
||||
|
||||
s_bond1 = (NMSettingBond *) nm_setting_bond_new ();
|
||||
g_assert (s_bond1);
|
||||
s_bond2 = (NMSettingBond *) nm_setting_bond_new ();
|
||||
g_assert (s_bond2);
|
||||
|
||||
for (p = opts1; p[0] && p[1]; p += 2)
|
||||
g_assert (nm_setting_bond_add_option (s_bond1, p[0], p[1]));
|
||||
|
||||
for (p = opts2; p[0] && p[1]; p += 2)
|
||||
g_assert (nm_setting_bond_add_option (s_bond2, p[0], p[1]));
|
||||
|
||||
g_assert_cmpint (nm_setting_compare ((NMSetting *) s_bond1,
|
||||
(NMSetting *) s_bond2,
|
||||
NM_SETTING_COMPARE_FLAG_EXACT),
|
||||
==,
|
||||
exp_res);
|
||||
}
|
||||
|
||||
static void
|
||||
test_compare (void)
|
||||
{
|
||||
test_compare_options (TRUE,
|
||||
((const char *[]){ "mode", "balance-rr", "miimon", "1", NULL }),
|
||||
((const char *[]){ "mode", "balance-rr", "miimon", "1", NULL }));
|
||||
test_compare_options (FALSE,
|
||||
((const char *[]){ "mode", "balance-rr", "miimon", "1", NULL }),
|
||||
((const char *[]){ "mode", "balance-rr", "miimon", "2", NULL }));
|
||||
|
||||
/* ignore default values */
|
||||
test_compare_options (TRUE,
|
||||
((const char *[]){ "miimon", "1", NULL }),
|
||||
((const char *[]){ "miimon", "1", "updelay", "0", NULL }));
|
||||
|
||||
/* special handling of num_grat_arp, num_unsol_na */
|
||||
test_compare_options (FALSE,
|
||||
((const char *[]){ "num_grat_arp", "2", NULL }),
|
||||
((const char *[]){ "num_grat_arp", "1", NULL }));
|
||||
test_compare_options (TRUE,
|
||||
((const char *[]){ "num_grat_arp", "3", NULL }),
|
||||
((const char *[]){ "num_unsol_na", "3", NULL }));
|
||||
test_compare_options (TRUE,
|
||||
((const char *[]){ "num_grat_arp", "4", NULL }),
|
||||
((const char *[]){ "num_unsol_na", "4", "num_grat_arp", "4", NULL }));
|
||||
}
|
||||
|
||||
#define TPATH "/libnm/settings/bond/"
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
nmtst_init (&argc, &argv, TRUE);
|
||||
|
||||
g_test_add_func (TPATH "verify", test_verify);
|
||||
g_test_add_func (TPATH "compare", test_compare);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
include $(GLIB_MAKEFILE)
|
||||
|
||||
@GNOME_CODE_COVERAGE_RULES@
|
||||
|
||||
SUBDIRS = . tests
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
|
@ -15,7 +17,8 @@ AM_CPPFLAGS = \
|
|||
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(GUDEV_CFLAGS) \
|
||||
-DNMRUNDIR=\"$(nmrundir)\"
|
||||
-DNMRUNDIR=\"$(nmrundir)\" \
|
||||
$(CODE_COVERAGE_CFLAGS)
|
||||
|
||||
include $(top_srcdir)/libnm-core/Makefile.libnm-core
|
||||
|
||||
|
|
@ -139,6 +142,9 @@ libnm_la_LIBADD = \
|
|||
$(UUID_LIBS) \
|
||||
$(GUDEV_LIBS)
|
||||
|
||||
libnm_la_LDFLAGS = \
|
||||
$(CODE_COVERAGE_LDFLAGS)
|
||||
|
||||
SYMBOL_VIS_FILE=$(srcdir)/libnm.ver
|
||||
|
||||
libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
|
||||
|
|
|
|||
|
|
@ -160,16 +160,23 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
while (options && *options) {
|
||||
gs_free char *value = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, *options);
|
||||
const char *defvalue = nm_setting_bond_get_option_default (s_bond, *options);
|
||||
char *p;
|
||||
|
||||
if (value && !ignore_if_zero (*options, value) && (g_strcmp0 (value, defvalue) != 0)) {
|
||||
if (_nm_setting_bond_get_option_type (s_bond, *options) == NM_BOND_OPTION_TYPE_BOTH) {
|
||||
p = strchr (value, ' ');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if ( value
|
||||
&& value[0]
|
||||
&& !ignore_if_zero (*options, value)
|
||||
&& !nm_streq0 (value, defvalue)) {
|
||||
/* Replace " " with "," for arp_ip_targets from the kernel */
|
||||
if (strcmp (*options, "arp_ip_target") == 0) {
|
||||
char *p = value;
|
||||
|
||||
while (p && *p) {
|
||||
for (p = value; *p; p++) {
|
||||
if (*p == ' ')
|
||||
*p = ',';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +292,7 @@ apply_bonding_config (NMDevice *device)
|
|||
set_bond_attr (device, "mode", mode);
|
||||
|
||||
/* arp_interval not compatible with ALB, TLB */
|
||||
if (g_strcmp0 (mode, "balance-alb") == 0 || g_strcmp0 (mode, "balance-tlb") == 0)
|
||||
if (NM_IN_STRSET (mode, "balance-alb", "balance-tlb"))
|
||||
set_arp_interval = FALSE;
|
||||
|
||||
if (set_arp_interval) {
|
||||
|
|
@ -299,18 +306,17 @@ apply_bonding_config (NMDevice *device)
|
|||
value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_VALIDATE);
|
||||
/* arp_validate > 0 only valid in active-backup mode */
|
||||
if ( value
|
||||
&& g_strcmp0 (value, "0") != 0
|
||||
&& g_strcmp0 (value, "none") != 0
|
||||
&& g_strcmp0 (mode, "active-backup") == 0)
|
||||
&& !nm_streq (value, "0")
|
||||
&& !nm_streq (value, "none")
|
||||
&& nm_streq (mode, "active-backup"))
|
||||
set_bond_attr (device, "arp_validate", value);
|
||||
else
|
||||
set_bond_attr (device, "arp_validate", "0");
|
||||
|
||||
if ( g_strcmp0 (mode, "active-backup") == 0
|
||||
|| g_strcmp0 (mode, "balance-alb") == 0
|
||||
|| g_strcmp0 (mode, "balance-tlb") == 0) {
|
||||
if (NM_IN_STRSET (mode, "active-backup", "balance-alb", "balance-tlb")) {
|
||||
value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||
set_bond_attr (device, "primary", value ? value : "");
|
||||
set_simple_option (device, "lp_internal", s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL);
|
||||
}
|
||||
|
||||
/* Clear ARP targets */
|
||||
|
|
@ -328,15 +334,31 @@ apply_bonding_config (NMDevice *device)
|
|||
set_simple_option (device, "ad_select", s_bond, NM_SETTING_BOND_OPTION_AD_SELECT);
|
||||
set_simple_option (device, "xmit_hash_policy", s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY);
|
||||
set_simple_option (device, "resend_igmp", s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP);
|
||||
set_simple_option (device, "active_slave", s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
|
||||
set_simple_option (device, "all_slaves_active", s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE);
|
||||
set_simple_option (device, "num_grat_arp", s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP);
|
||||
set_simple_option (device, "num_unsol_na", s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
|
||||
|
||||
if ( g_strcmp0 (mode, "4") == 0
|
||||
|| g_strcmp0 (mode, "802.3ad") == 0)
|
||||
if (nm_streq (mode, "802.3ad")) {
|
||||
set_simple_option (device, "lacp_rate", s_bond, NM_SETTING_BOND_OPTION_LACP_RATE);
|
||||
set_simple_option (device, "ad_actor_sys_prio", s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO);
|
||||
set_simple_option (device, "ad_actor_system", s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM);
|
||||
set_simple_option (device, "ad_user_port_key", s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY);
|
||||
set_simple_option (device, "min_links", s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS);
|
||||
}
|
||||
|
||||
if (nm_streq (mode, "active-backup"))
|
||||
set_simple_option (device, "arp_all_targets", s_bond, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS);
|
||||
|
||||
if (nm_streq (mode, "balance-rr"))
|
||||
set_simple_option (device, "packets_per_slave", s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE);
|
||||
|
||||
if (nm_streq (mode, "balance-tlb"))
|
||||
set_simple_option (device, "tlb_dynamic_lb", s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB);
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue