/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
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 ',' */
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,
include $(GLIB_MAKEFILE)
+@GNOME_CODE_COVERAGE_RULES@
+
SUBDIRS = . tests
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
$(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
/***********************************************************/
+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
#include "nm-utils-private.h"
#include "nm-connection-private.h"
#include "nm-setting-infiniband.h"
+#include "nm-core-internal.h"
/**
* SECTION:nm-setting-bond
LAST_PROP
};
-enum {
- TYPE_INT,
- TYPE_STR,
- TYPE_BOTH,
- TYPE_IP,
- TYPE_IFNAME,
-};
-
typedef struct {
const char *opt;
const char *val;
} 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 },
};
/**
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;
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)
{
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;
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) {
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,
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,
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,
}
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;
}
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,
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;
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)
{
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 */
/**
#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;
test-keyfile \
test-secrets \
test-setting-8021x \
+ test-setting-bond \
test-setting-dcb \
test-settings-defaults
--- /dev/null
+/* -*- 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 ();
+}
include $(GLIB_MAKEFILE)
+@GNOME_CODE_COVERAGE_RULES@
+
SUBDIRS = . tests
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
$(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) \
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++;
}
}
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) {
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 */
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)
{