summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/src/connections.c2
-rw-r--r--libnm-util/libnm-util.ver15
-rw-r--r--libnm-util/nm-setting-bond.c1370
-rw-r--r--libnm-util/nm-setting-bond.h77
-rw-r--r--libnm-util/tests/test-general.c2
-rw-r--r--src/devices/nm-device-bond.c115
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c156
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c6
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c70
9 files changed, 1339 insertions, 474 deletions
diff --git a/cli/src/connections.c b/cli/src/connections.c
index 8ae9ce3337..e5b5182309 100644
--- a/cli/src/connections.c
+++ b/cli/src/connections.c
@@ -3725,7 +3725,7 @@ cleanup_vlan:
bond_primary);
goto cleanup_bond;
}
- nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_PRIMARY, bond_primary);
+ g_object_set (s_bond, NM_SETTING_BOND_PRIMARY, bond_primary, NULL);
}
if (bond_miimon)
nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON, bond_miimon);
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index bcaa4260ae..6a1b2c810e 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -199,16 +199,29 @@ global:
nm_setting_bond_add_option;
nm_setting_bond_error_get_type;
nm_setting_bond_error_quark;
+ nm_setting_bond_get_ad_select;
+ nm_setting_bond_get_arp_interval;
+ nm_setting_bond_get_arp_ip_target;
+ nm_setting_bond_get_arp_validate;
+ nm_setting_bond_get_downdelay;
+ nm_setting_bond_get_fail_over_mac;
nm_setting_bond_get_interface_name;
+ nm_setting_bond_get_miimon;
+ nm_setting_bond_get_mode;
nm_setting_bond_get_num_options;
nm_setting_bond_get_option;
nm_setting_bond_get_option_by_name;
nm_setting_bond_get_option_default;
+ nm_setting_bond_get_primary;
+ nm_setting_bond_get_primary_reselect;
+ nm_setting_bond_get_resend_igmp;
nm_setting_bond_get_type;
+ nm_setting_bond_get_updelay;
+ nm_setting_bond_get_use_carrier;
nm_setting_bond_get_valid_options;
+ nm_setting_bond_get_xmit_hash_policy;
nm_setting_bond_new;
nm_setting_bond_remove_option;
- nm_setting_bond_validate_option;
nm_setting_bridge_error_get_type;
nm_setting_bridge_error_quark;
nm_setting_bridge_get_ageing_time;
diff --git a/libnm-util/nm-setting-bond.c b/libnm-util/nm-setting-bond.c
index 3fe5f51903..1177451a9f 100644
--- a/libnm-util/nm-setting-bond.c
+++ b/libnm-util/nm-setting-bond.c
@@ -34,6 +34,7 @@
#include "nm-utils.h"
#include "nm-utils-private.h"
#include "nm-dbus-glib-types.h"
+#include "nm-glib-compat.h"
#include "nm-setting-private.h"
/**
@@ -74,15 +75,48 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BOND)
typedef struct {
char *interface_name;
+ char *mode;
+ guint miimon;
+ guint downdelay;
+ guint updelay;
+ guint arp_interval;
+ char **arp_ip_target;
+ char *arp_validate;
+ char *primary;
+ char *primary_reselect;
+ char *fail_over_mac;
+ char *ad_select;
+ char *xmit_hash_policy;
+ gboolean use_carrier;
+ guint resend_igmp;
+
GHashTable *options;
} NMSettingBondPrivate;
enum {
PROP_0,
PROP_INTERFACE_NAME,
+
+ PROP_MODE,
+ PROP_MIIMON,
+ PROP_DOWNDELAY,
+ PROP_UPDELAY,
+ PROP_ARP_INTERVAL,
+ PROP_ARP_IP_TARGET,
+ PROP_ARP_VALIDATE,
+ PROP_PRIMARY,
+ PROP_PRIMARY_RESELECT,
+ PROP_FAIL_OVER_MAC,
+ PROP_USE_CARRIER,
+ PROP_AD_SELECT,
+ PROP_XMIT_HASH_POLICY,
+ PROP_RESEND_IGMP,
+
PROP_OPTIONS,
LAST_PROP
};
+#define _FIRST_LEGACY_PROP PROP_MODE
+#define _LAST_LEGACY_PROP PROP_RESEND_IGMP
enum {
TYPE_INT,
@@ -93,35 +127,34 @@ enum {
};
typedef struct {
- const char *opt;
- const char *val;
guint opt_type;
- guint min;
- guint max;
- char *list[10];
-} BondDefault;
-
-static const BondDefault defaults[] = {
- { NM_SETTING_BOND_OPTION_MODE, "balance-rr", 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,
- { "none", "active", "backup", "all", NULL } },
- { NM_SETTING_BOND_OPTION_PRIMARY, "", TYPE_IFNAME },
- { NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, "0", TYPE_BOTH, 0, 2,
- { "always", "better", "failure", NULL } },
- { NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, "0", 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,
- { "stable", "bandwidth", "count", NULL } },
- { NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "0", TYPE_BOTH, 0, 2,
- { "layer2", "layer3+4", "layer2+3", NULL } },
- { NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", TYPE_INT, 0, 255 },
+ const char *legacy_name;
+ const char *list[10];
+ GParamSpec *pspec;
+ char *defval;
+} BondProperty;
+
+static BondProperty props[ LAST_PROP + 1 ] = {
+ [PROP_MODE] = { TYPE_BOTH, NM_SETTING_BOND_OPTION_MODE,
+ { "balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb" } },
+ [PROP_MIIMON] = { TYPE_INT, NM_SETTING_BOND_OPTION_MIIMON },
+ [PROP_DOWNDELAY] = { TYPE_INT, NM_SETTING_BOND_OPTION_DOWNDELAY },
+ [PROP_UPDELAY] = { TYPE_INT, NM_SETTING_BOND_OPTION_UPDELAY },
+ [PROP_ARP_INTERVAL] = { TYPE_INT, NM_SETTING_BOND_OPTION_ARP_INTERVAL },
+ [PROP_ARP_IP_TARGET] = { TYPE_IP, NM_SETTING_BOND_OPTION_ARP_IP_TARGET },
+ [PROP_ARP_VALIDATE] = { TYPE_BOTH, NULL,
+ { "none", "active", "backup", "all" } },
+ [PROP_PRIMARY] = { TYPE_IFNAME, NULL },
+ [PROP_PRIMARY_RESELECT] = { TYPE_BOTH, NULL,
+ { "always", "better", "failure" } },
+ [PROP_FAIL_OVER_MAC] = { TYPE_BOTH, NULL,
+ { "none", "active", "follow" } },
+ [PROP_USE_CARRIER] = { TYPE_INT },
+ [PROP_AD_SELECT] = { TYPE_BOTH, NULL,
+ { "stable", "bandwidth", "count" } },
+ [PROP_XMIT_HASH_POLICY] = { TYPE_STR, NULL,
+ { "layer2", "layer2+3", "layer3+4", "encap2+3", "encap3+4" } },
+ [PROP_RESEND_IGMP] = { TYPE_INT },
};
/**
@@ -137,6 +170,8 @@ nm_setting_bond_new (void)
return (NMSetting *) g_object_new (NM_TYPE_SETTING_BOND, NULL);
}
+/*****************************************************************************/
+
/**
* nm_setting_bond_get_interface_name:
* @setting: the #NMSettingBond
@@ -152,21 +187,295 @@ nm_setting_bond_get_interface_name (NMSettingBond *setting)
}
/**
+ * nm_setting_bond_get_mode:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:mode property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_mode (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->mode;
+}
+
+/**
+ * nm_setting_bond_get_miimon:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:miimon property of the setting
+ *
+ * Since: 0.9.10
+ **/
+guint
+nm_setting_bond_get_miimon (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->miimon;
+}
+
+/**
+ * nm_setting_bond_get_downdelay:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:downdelay property of the setting
+ *
+ * Since: 0.9.10
+ **/
+guint
+nm_setting_bond_get_downdelay (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->downdelay;
+}
+
+/**
+ * nm_setting_bond_get_updelay:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:updelay property of the setting
+ *
+ * Since: 0.9.10
+ **/
+guint
+nm_setting_bond_get_updelay (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->updelay;
+}
+
+/**
+ * nm_setting_bond_get_arp_interval:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:arp-interval property of the setting
+ *
+ * Since: 0.9.10
+ **/
+guint
+nm_setting_bond_get_arp_interval (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->arp_interval;
+}
+
+/**
+ * nm_setting_bond_get_arp_ip_target:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: (transfer none): the #NMSettingBond:arp-ip-target property
+ * of the setting (which belongs to the setting and must not be freed).
+ *
+ * Since: 0.9.10
+ **/
+const char *const*
+nm_setting_bond_get_arp_ip_target (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return (const char *const*) NM_SETTING_BOND_GET_PRIVATE (setting)->arp_ip_target;
+}
+
+/**
+ * nm_setting_bond_get_arp_validate:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:arp-validate property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_arp_validate (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->arp_validate;
+}
+
+/**
+ * nm_setting_bond_get_primary:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:primary property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_primary (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->primary;
+}
+
+/**
+ * nm_setting_bond_get_primary_reselect:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:primary-reselect property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_primary_reselect (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->primary_reselect;
+}
+
+/**
+ * nm_setting_bond_get_fail_over_mac:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:fail-over-mac property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_fail_over_mac (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->fail_over_mac;
+}
+
+/**
+ * nm_setting_bond_get_use_carrier:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:use-carrier property of the setting
+ *
+ * Since: 0.9.10
+ **/
+gboolean
+nm_setting_bond_get_use_carrier (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->use_carrier;
+}
+
+/**
+ * nm_setting_bond_get_ad_select:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:ad-select property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_ad_select (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->ad_select;
+}
+
+/**
+ * nm_setting_bond_get_xmit_hash_policy:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:xmit-hash-policy property of the setting
+ *
+ * Since: 0.9.10
+ **/
+const char *
+nm_setting_bond_get_xmit_hash_policy (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->xmit_hash_policy;
+}
+
+/**
+ * nm_setting_bond_get_resend_igmp:
+ * @setting: the #NMSettingBond
+ *
+ * Returns: the #NMSettingBond:resend-igmp property of the setting
+ *
+ * Since: 0.9.10
+ **/
+guint
+nm_setting_bond_get_resend_igmp (NMSettingBond *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
+
+ return NM_SETTING_BOND_GET_PRIVATE (setting)->resend_igmp;
+}
+
+/*****************************************************************************/
+
+static BondProperty *
+find_property (const char *name, const char **out_new_name, guint *out_idx)
+{
+ guint i;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ for (i = _FIRST_LEGACY_PROP; i <= _LAST_LEGACY_PROP; i++) {
+ const char *new_name = g_param_spec_get_name (props[i].pspec);
+
+ if (strcmp (name, new_name) == 0 || g_strcmp0 (name, props[i].legacy_name) == 0) {
+ if (out_new_name)
+ *out_new_name = new_name;
+ if (out_idx)
+ *out_idx = i;
+ return &props[i];
+ }
+ }
+ return NULL;
+}
+
+/* For a new property or legacy option name, returns the new property name */
+static const char *
+get_property_name (const char *name, const BondProperty **out_prop)
+{
+ const char *new_name = NULL;
+
+ *out_prop = find_property (name, &new_name, NULL);
+ return *out_prop ? new_name : NULL;
+}
+
+/* For a new property or legacy option name, returns the legacy option name */
+static const char *
+get_legacy_name (GParamSpec *pspec)
+{
+ const BondProperty *prop;
+ const char *new_name = NULL;
+
+ prop = find_property (g_param_spec_get_name (pspec), &new_name, NULL);
+ if (prop)
+ return prop->legacy_name ? prop->legacy_name : new_name;
+
+ return NULL;
+}
+
+/**
* nm_setting_bond_get_num_options:
* @setting: the #NMSettingBond
*
- * Returns the number of options that should be set for this bond when it
- * is activated. This can be used to retrieve each option individually
- * using nm_setting_bond_get_option().
+ * Returns the number of options that are set in the legacy
+ * #NMSettingBond:options property. This does not include other bond
+ * properties which are not included in #NMSettingBond:options.
+ *
+ * Returns: the number of legacy bonding options
*
- * Returns: the number of bonding options
+ * Deprecated: use the option-specific getters instead.
**/
guint32
nm_setting_bond_get_num_options (NMSettingBond *setting)
{
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0);
- return g_hash_table_size (NM_SETTING_BOND_GET_PRIVATE (setting)->options);
+ return _LAST_LEGACY_PROP - _FIRST_LEGACY_PROP;
}
/**
@@ -188,6 +497,8 @@ nm_setting_bond_get_num_options (NMSettingBond *setting)
* Returns: %TRUE on success if the index was valid and an option was found,
* %FALSE if the index was invalid (ie, greater than the number of options
* currently held by the setting)
+ *
+ * Deprecated: use the option-specific getters instead.
**/
gboolean
nm_setting_bond_get_option (NMSettingBond *setting,
@@ -196,132 +507,173 @@ nm_setting_bond_get_option (NMSettingBond *setting,
const char **out_value)
{
NMSettingBondPrivate *priv;
- GList *keys;
- const char *_key = NULL, *_value = NULL;
+ const char *legacy_name, *value;
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE);
-
priv = NM_SETTING_BOND_GET_PRIVATE (setting);
- if (idx >= nm_setting_bond_get_num_options (setting))
- return FALSE;
+ idx += _FIRST_LEGACY_PROP;
+ g_return_val_if_fail (idx <= _LAST_LEGACY_PROP, FALSE);
- keys = g_hash_table_get_keys (priv->options);
- _key = g_list_nth_data (keys, idx);
- _value = g_hash_table_lookup (priv->options, _key);
+ legacy_name = get_legacy_name (props[idx].pspec);
+ g_assert (legacy_name);
+ value = g_hash_table_lookup (priv->options, legacy_name);
+ if (!value)
+ return FALSE;
if (out_name)
- *out_name = _key;
+ *out_name = legacy_name;
if (out_value)
- *out_value = _value;
-
- g_list_free (keys);
+ *out_value = value;
return TRUE;
}
static gboolean
-validate_int (const char *name, const char *value, const BondDefault *def)
+int_from_string (const char *s, glong *out_num)
{
- glong num;
guint i;
- for (i = 0; i < strlen (value); i++) {
- if (!g_ascii_isdigit (value[i]) && value[i] != '-')
+ for (i = 0; i < strlen (s); i++) {
+ if (!g_ascii_isdigit (s[i]) && s[i] != '-')
return FALSE;
}
errno = 0;
- num = strtol (value, NULL, 10);
- if (errno)
+ *out_num = strtol (s, NULL, 10);
+ return errno ? FALSE : TRUE;
+}
+
+static gboolean
+validate_int (const BondProperty *prop, const char *value)
+{
+ GParamSpecInt *ispec;
+ glong num = 0;
+
+ if (!G_IS_PARAM_SPEC_INT (prop->pspec))
+ return FALSE;
+ if (!value)
return FALSE;
- if (num < def->min || num > def->max)
+ if (!int_from_string (value, &num))
return FALSE;
- return TRUE;
+ ispec = G_PARAM_SPEC_INT (prop->pspec);
+ return (num >= ispec->minimum && num <= ispec->maximum);
}
static gboolean
-validate_list (const char *name, const char *value, const BondDefault *def)
+validate_list (const BondProperty *prop, const char *value)
{
guint i;
- for (i = 0; i < G_N_ELEMENTS (def->list) && def->list[i]; i++) {
- if (g_strcmp0 (def->list[i], value) == 0)
+ if (!value)
+ return FALSE;
+
+ for (i = 0; i < G_N_ELEMENTS (prop->list) && prop->list[i]; i++) {
+ if (g_strcmp0 (prop->list[i], value) == 0)
return TRUE;
}
/* empty validation list means all values pass */
- return def->list[0] == NULL ? TRUE : FALSE;
+ return prop->list[0] == NULL ? TRUE : FALSE;
}
static gboolean
-validate_ip (const char *name, const char *value)
+validate_both (const BondProperty *prop, const char *value)
+{
+ glong num = -1;
+
+ g_assert (prop->list);
+
+ if (!value)
+ return FALSE;
+
+ if (validate_list (prop, value))
+ return TRUE;
+
+ if (!int_from_string (value, &num))
+ return FALSE;
+
+ /* Ensure number is within bounds of string list */
+ return num >= 0 && num < G_N_ELEMENTS (prop->list);
+}
+
+static char **
+parse_ip (const char *value, gboolean warn_on_error)
{
char **ips, **iter;
- gboolean success = TRUE;
struct in_addr addr;
- if (!value || !value[0])
- return FALSE;
+ if (!value || !value[0]) {
+ /* missing value is valid, we just NULL instead of an empty array. */
+ return NULL;
+ }
ips = g_strsplit_set (value, ",", 0);
- for (iter = ips; iter && *iter && success; iter++)
- success = !!inet_aton (*iter, &addr);
- g_strfreev (ips);
-
- return success;
+ for (iter = ips; *iter; iter++) {
+ if (!inet_aton (*iter, &addr)) {
+ g_strfreev (ips);
+ g_return_val_if_fail (!warn_on_error, NULL);
+ return NULL;
+ }
+ }
+ return ips;
}
static gboolean
-validate_ifname (const char *name, const char *value)
+validate_ip (const char *value)
{
- if (!value || !value[0])
+ char **ips;
+
+ if (!value || !value[0]) {
+ /* there is only one TYPE_IP, and that property is not mandatory.
+ * Accept empty as valid.
+ **/
+ return TRUE;
+ }
+
+ /* make reuse of parse_ip, as it should validate the input anyway. */
+ ips = parse_ip (value, FALSE);
+ if (!ips)
return FALSE;
+ g_strfreev (ips);
+ return TRUE;
+}
+
+static gboolean
+validate_ifname (const char *value)
+{
+ if (!value || !value[0]) {
+ /* there is only one TYPE_IFNAME, and that property is not mandatory.
+ * Accept empty as valid.
+ **/
+ return TRUE;
+ }
+
return nm_utils_iface_valid_name (value);
}
-/**
- * nm_setting_bond_validate_option:
- * @name: the name of the option to validate
- * @value: the value of the option to validate
- *
- * Checks whether @name is a valid bond option and @value is a valid value for
- * the @name. If @value is NULL, the function only validates the option name.
+/* Checks whether @value is is a valid value for @prop.
*
* Returns: TRUE, if the @value is valid for the given name.
- * If the @name is not a valid option, FALSE will be returned.
- *
- * Since: 0.9.10
+ * If @value is NULL, false will be returned.
**/
-gboolean
-nm_setting_bond_validate_option (const char *name,
- const char *value)
+static gboolean
+validate_property (const BondProperty *prop, const char *value)
{
- guint i;
-
- if (!name || !name[0])
- return FALSE;
-
- for (i = 0; i < G_N_ELEMENTS (defaults); i++) {
- if (g_strcmp0 (defaults[i].opt, name) == 0) {
- if (value == NULL)
- return TRUE;
- switch (defaults[i].opt_type) {
- case TYPE_INT:
- return validate_int (name, value, &defaults[i]);
- case TYPE_STR:
- return validate_list (name, value, &defaults[i]);
- case TYPE_BOTH:
- return validate_int (name, value, &defaults[i])
- || validate_list (name, value, &defaults[i]);
- case TYPE_IP:
- return validate_ip (name, value);
- case TYPE_IFNAME:
- return validate_ifname (name, value);
- }
- return FALSE;
- }
+ switch (prop->opt_type) {
+ case TYPE_INT:
+ return validate_int (prop, value);
+ case TYPE_STR:
+ return validate_list (prop, value);
+ case TYPE_BOTH:
+ return validate_both (prop, value);
+ case TYPE_IP:
+ return validate_ip (value);
+ case TYPE_IFNAME:
+ return validate_ifname (value);
+ default:
+ g_assert_not_reached();
}
return FALSE;
}
@@ -336,6 +688,8 @@ nm_setting_bond_validate_option (const char *name,
*
* Returns: the value, or %NULL if the key/value pair was never added to the
* setting; the value is owned by the setting and must not be modified
+ *
+ * Deprecated: use the option-specific getters instead.
**/
const char *
nm_setting_bond_get_option_by_name (NMSettingBond *setting,
@@ -343,9 +697,6 @@ nm_setting_bond_get_option_by_name (NMSettingBond *setting,
{
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
- if (!nm_setting_bond_validate_option (name, NULL))
- return NULL;
-
return g_hash_table_lookup (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name);
}
@@ -365,6 +716,8 @@ nm_setting_bond_get_option_by_name (NMSettingBond *setting,
*
* Returns: %TRUE if the option was valid and was added to the internal option
* list, %FALSE if it was not.
+ *
+ * Deprecated: use the option-specific properties instead.
**/
gboolean
nm_setting_bond_add_option (NMSettingBond *setting,
@@ -372,28 +725,60 @@ nm_setting_bond_add_option (NMSettingBond *setting,
const char *value)
{
NMSettingBondPrivate *priv;
+ GObject *object = G_OBJECT (setting);
+ const BondProperty *prop = NULL;
+ const char *prop_name;
+ glong num = 0;
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE);
- if (!value || !nm_setting_bond_validate_option (name, value))
+ priv = NM_SETTING_BOND_GET_PRIVATE (setting);
+
+ prop_name = get_property_name (name, &prop);
+ if (!prop_name)
+ return FALSE;
+ if (!validate_property (prop, value))
return FALSE;
- priv = NM_SETTING_BOND_GET_PRIVATE (setting);
+ g_object_freeze_notify (object);
- g_hash_table_insert (priv->options, g_strdup (name), g_strdup (value));
+ switch (prop->opt_type) {
+ case TYPE_INT:
+ if (!int_from_string (value, &num))
+ return FALSE;
+ g_object_set (object, prop_name, (gint) num, NULL);
+ break;
+ case TYPE_BOTH: {
+ const char *str_value = value;
- if ( !strcmp (name, NM_SETTING_BOND_OPTION_MIIMON)
- && strcmp (value, "0") != 0) {
- g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
- g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
- } else if ( !strcmp (name, NM_SETTING_BOND_OPTION_ARP_INTERVAL)
- && strcmp (value, "0") != 0) {
- g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_MIIMON);
- g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY);
- g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_UPDELAY);
+ /* Might be an integer-as-string; find the string */
+ if (!validate_list (prop, value)) {
+ if (!int_from_string (value, &num))
+ return FALSE;
+ /* Be paranoid although it's already been checked by validate_property() */
+ g_assert (num >= 0 && num < G_N_ELEMENTS (prop->list));
+ str_value = prop->list[num];
+ }
+ g_object_set (object, prop_name, str_value, NULL);
+ break;
}
+ case TYPE_IFNAME:
+ case TYPE_STR:
+ g_object_set (object, prop_name, value, NULL);
+ break;
+ case TYPE_IP: {
+ char **ip = parse_ip (value, TRUE);
- g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS);
+ g_object_set (object, prop_name, ip, NULL);
+ g_strfreev (ip);
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ g_object_thaw_notify (object);
return TRUE;
}
@@ -408,22 +793,36 @@ nm_setting_bond_add_option (NMSettingBond *setting,
*
* Returns: %TRUE if the option was found and removed from the internal option
* list, %FALSE if it was not.
+ *
+ * Deprecated: use the option-specific properties instead.
**/
gboolean
nm_setting_bond_remove_option (NMSettingBond *setting,
const char *name)
{
- gboolean found;
+ GObject *object = G_OBJECT (setting);
+ NMSettingBondPrivate *priv;
+ const BondProperty *prop;
+ const char *prop_name;
+ GValue defval = G_VALUE_INIT;
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE);
+ priv = NM_SETTING_BOND_GET_PRIVATE (setting);
- if (!nm_setting_bond_validate_option (name, NULL))
+ prop_name = get_property_name (name, &prop);
+ if (!prop_name)
return FALSE;
- found = g_hash_table_remove (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name);
- if (found)
- g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS);
- return found;
+ g_object_freeze_notify (object);
+
+ /* we don't really remove the property, instead we reset the default value. */
+ g_value_init (&defval, prop->pspec->value_type);
+ g_param_value_set_default (prop->pspec, &defval);
+ g_object_set_property (object, prop_name, &defval);
+ g_value_unset (&defval);
+
+ g_object_thaw_notify (object);
+ return TRUE;
}
/**
@@ -433,19 +832,25 @@ nm_setting_bond_remove_option (NMSettingBond *setting,
* Returns a list of valid bond options.
*
* Returns: (transfer none): a %NULL-terminated array of strings of valid bond options.
+ *
+ * Deprecated: the valid options are defined by the #NMSettingBond
+ * properties.
**/
const char **
nm_setting_bond_get_valid_options (NMSettingBond *setting)
{
- static const char *array[G_N_ELEMENTS (defaults) + 1] = { NULL };
- int i;
+ static const char *array[LAST_PROP + 1] = { NULL };
/* initialize the array once */
if (G_UNLIKELY (array[0] == NULL)) {
- for (i = 0; i < G_N_ELEMENTS (defaults); i++)
- array[i] = defaults[i].opt;
- array[i] = NULL;
+ guint prop, i;
+
+ for (prop = _FIRST_LEGACY_PROP, i = 0; prop <= _LAST_LEGACY_PROP; prop++, i++) {
+ array[i] = props[prop].legacy_name ?
+ props[prop].legacy_name : g_param_spec_get_name (props[prop].pspec);
+ }
}
+
return array;
}
@@ -456,42 +861,77 @@ nm_setting_bond_get_valid_options (NMSettingBond *setting)
*
* Returns: the value of the bond option if not overridden by an entry in
* the #NMSettingBond:options property.
+ *
+ * Deprecated: Use the default values of the option-specific properties.
**/
const char *
nm_setting_bond_get_option_default (NMSettingBond *setting, const char *name)
{
- guint i;
+ BondProperty *prop;
+ GValue defval = G_VALUE_INIT;
+ guint idx = 0;
g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL);
- g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NULL);
- for (i = 0; i < G_N_ELEMENTS (defaults); i++) {
- if (g_strcmp0 (defaults[i].opt, name) == 0)
- return defaults[i].val;
+ prop = find_property (name, NULL, &idx);
+ if (!prop)
+ return NULL;
+
+ if (G_UNLIKELY (prop->defval == NULL)) {
+ if (idx == PROP_ARP_IP_TARGET)
+ prop->defval = "";
+ else {
+ g_value_init (&defval, prop->pspec->value_type);
+ g_param_value_set_default (prop->pspec, &defval);
+ prop->defval = g_strdup_value_contents (&defval);
+ g_value_unset (&defval);
+ }
+ }
+ return prop->defval;
+}
+
+/*****************************************************************/
+
+static void
+set_properties_from_hash (NMSettingBond *self, GHashTable *options)
+{
+ const char *value;
+ guint i;
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ /* Set each property to the value given by @options, or if not present
+ * in @options, to the default value.
+ */
+ for (i = _FIRST_LEGACY_PROP; i <= _LAST_LEGACY_PROP; i++) {
+ const char *new_name = g_param_spec_get_name (props[i].pspec);
+ const char *legacy_name = new_name;
+ GValue defval = G_VALUE_INIT;
+
+ value = g_hash_table_lookup (options, legacy_name);
+ if (!value)
+ legacy_name = props[i].legacy_name;
+ value = g_hash_table_lookup (options, legacy_name);
+
+ if (value)
+ nm_setting_bond_add_option (self, legacy_name, value);
+ else {
+ g_value_init (&defval, props[i].pspec->value_type);
+ g_param_value_set_default (props[i].pspec, &defval);
+ g_object_set_property (G_OBJECT (self), new_name, &defval);
+ g_value_unset (&defval);
+ }
}
- /* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */
- g_assert_not_reached ();
+
+ g_object_thaw_notify (G_OBJECT (self));
}
static gboolean
verify (NMSetting *setting, GSList *all_settings, 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;
- const char *arp_ip_target = NULL;
- const char *primary;
-
- if (!priv->interface_name || !strlen(priv->interface_name)) {
+
+ if (!priv->interface_name || !strlen (priv->interface_name)) {
g_set_error_literal (error,
NM_SETTING_BOND_ERROR,
NM_SETTING_BOND_ERROR_MISSING_PROPERTY,
@@ -499,7 +939,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME);
return FALSE;
}
-
if (!nm_utils_iface_valid_name (priv->interface_name)) {
g_set_error_literal (error,
NM_SETTING_BOND_ERROR,
@@ -509,185 +948,215 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
return FALSE;
}
- g_hash_table_iter_init (&iter, priv->options);
- while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
- if (!value[0] || !nm_setting_bond_validate_option (key, value)) {
- g_set_error (error,
- NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("invalid option '%s' or its value '%s'"),
- key, value);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
- return FALSE;
- }
- }
-
- value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MIIMON);
- if (value)
- miimon = atoi (value);
- value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
- if (value)
- arp_interval = atoi (value);
-
/* Can only set one of miimon and arp_interval */
- if (miimon > 0 && arp_interval > 0) {
+ if (priv->miimon > 0 && priv->arp_interval > 0) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
_("only one of '%s' and '%s' can be set"),
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);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME,
+ priv->arp_ip_target == NULL && priv->arp_ip_target[0] ? NM_SETTING_BOND_ARP_INTERVAL : NM_SETTING_BOND_MIIMON);
}
- value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
- if (!value) {
+ if (!priv->mode) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_MISSING_OPTION,
- _("mandatory option '%s' is missing"),
- NM_SETTING_BOND_OPTION_MODE);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_MISSING_PROPERTY,
+ _("mandatory property '%s' is missing"),
+ NM_SETTING_BOND_MODE);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_MODE);
return FALSE;
}
- if (!_nm_utils_string_in_list (value, valid_modes)) {
+ if (!validate_property (&props[PROP_MODE], priv->mode)) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid value for '%s'"),
- value, NM_SETTING_BOND_OPTION_MODE);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ priv->mode, NM_SETTING_BOND_MODE);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_MODE);
return FALSE;
}
/* Make sure mode is compatible with other settings */
- if ( strcmp (value, "balance-alb") == 0
- || strcmp (value, "balance-tlb") == 0) {
- if (arp_interval > 0) {
+ if ( strcmp (priv->mode, "balance-alb") == 0
+ || strcmp (priv->mode, "balance-tlb") == 0) {
+ if (priv->arp_interval > 0) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
_("'%s=%s' is incompatible with '%s > 0'"),
- NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_OPTION_MODE, priv->mode,
+ NM_SETTING_BOND_OPTION_ARP_INTERVAL);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_INTERVAL);
return FALSE;
}
}
- primary = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_PRIMARY);
- if (strcmp (value, "active-backup") == 0) {
- if (primary && !nm_utils_iface_valid_name (primary)) {
+ if (strcmp (priv->mode, "active-backup") == 0) {
+ if (priv->primary && !nm_utils_iface_valid_name (priv->primary)) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' is not a valid interface name for '%s' option"),
- primary, NM_SETTING_BOND_OPTION_PRIMARY);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid interface name"),
+ priv->primary);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_PRIMARY);
return FALSE;
}
} else {
- if (primary) {
+ if (priv->primary) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' option is only valid for '%s=%s'"),
- NM_SETTING_BOND_OPTION_PRIMARY,
- NM_SETTING_BOND_OPTION_MODE, "active-backup");
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is only valid for '%s=%s'"),
+ NM_SETTING_BOND_PRIMARY,
+ NM_SETTING_BOND_MODE, "active-backup");
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_PRIMARY);
return FALSE;
}
}
if (nm_setting_find_in_list (all_settings, NM_SETTING_INFINIBAND_SETTING_NAME)) {
- if (strcmp (value, "active-backup") != 0) {
+ if (strcmp (priv->mode, "active-backup") != 0) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
_("'%s=%s' is not a valid configuration for '%s'"),
- NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_INFINIBAND_SETTING_NAME);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_OPTION_MODE, priv->mode,
+ NM_SETTING_INFINIBAND_SETTING_NAME);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_MODE);
return FALSE;
}
}
- if (miimon == 0) {
+ if (priv->miimon == 0) {
/* updelay and downdelay can only be used with miimon */
- if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_UPDELAY)) {
+ if (priv->updelay > 0) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' option requires '%s' option to be set"),
- NM_SETTING_BOND_OPTION_UPDELAY, NM_SETTING_BOND_OPTION_MIIMON);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' property requires '%s' property to be set"),
+ NM_SETTING_BOND_UPDELAY, NM_SETTING_BOND_MIIMON);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_UPDELAY);
return FALSE;
}
- if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY)) {
+ if (priv->downdelay > 0) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' option requires '%s' option to be set"),
- NM_SETTING_BOND_OPTION_DOWNDELAY, NM_SETTING_BOND_OPTION_MIIMON);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' property requires '%s' property to be set"),
+ NM_SETTING_BOND_DOWNDELAY, NM_SETTING_BOND_MIIMON);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_DOWNDELAY);
return FALSE;
}
}
/* arp_ip_target can only be used with arp_interval, and must
- * contain a comma-separated list of IPv4 addresses.
+ * contain IPv4 addresses.
*/
- arp_ip_target = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
- if (arp_interval > 0) {
- char **addrs;
+ if (priv->arp_interval > 0) {
guint32 addr;
int i;
- if (!arp_ip_target) {
+ if (!priv->arp_ip_target) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_MISSING_OPTION,
- _("'%s' option requires '%s' option to be set"),
- NM_SETTING_BOND_OPTION_ARP_INTERVAL, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_MISSING_PROPERTY,
+ _("'%s' property requires '%s' property to be set"),
+ NM_SETTING_BOND_ARP_INTERVAL, NM_SETTING_BOND_ARP_IP_TARGET);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_IP_TARGET);
return FALSE;
}
- addrs = g_strsplit (arp_ip_target, ",", -1);
- if (!addrs[0]) {
+ if (!priv->arp_ip_target[0]) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' option is empty"),
- NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
- g_strfreev (addrs);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' property is empty"),
+ NM_SETTING_BOND_ARP_IP_TARGET);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_IP_TARGET);
return FALSE;
}
- for (i = 0; addrs[i]; i++) {
- if (!inet_pton (AF_INET, addrs[i], &addr)) {
+ for (i = 0; priv->arp_ip_target[i]; i++) {
+ if (!inet_pton (AF_INET, priv->arp_ip_target[i], &addr)) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' is not a valid IPv4 address for '%s' option"),
- NM_SETTING_BOND_OPTION_ARP_IP_TARGET, addrs[i]);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
- g_strfreev (addrs);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid IPv4 address for '%s' property"),
+ priv->arp_ip_target[i], NM_SETTING_BOND_ARP_IP_TARGET);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_IP_TARGET);
return FALSE;
}
}
- g_strfreev (addrs);
} else {
- if (arp_ip_target) {
+ if (priv->arp_ip_target && priv->arp_ip_target[0]) {
g_set_error (error,
NM_SETTING_BOND_ERROR,
- NM_SETTING_BOND_ERROR_INVALID_OPTION,
- _("'%s' option requires '%s' option to be set"),
- NM_SETTING_BOND_OPTION_ARP_IP_TARGET, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
- g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' property requires '%s' property to be set"),
+ NM_SETTING_BOND_ARP_IP_TARGET, NM_SETTING_BOND_ARP_INTERVAL);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_IP_TARGET);
return FALSE;
}
}
+ /* FIXME: maybe we should not be too excessively about validating the strings,
+ * because the kernel might add new values (which we would then not support).
+ * OTOH, the checking above already requires some deep knowledge about the exact
+ * meaning of the flags, so, why check there, but not here?
+ **/
+ if (priv->arp_validate && !validate_property (&props[PROP_ARP_VALIDATE], priv->arp_validate)) {
+ g_set_error (error,
+ NM_SETTING_BOND_ERROR,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid value for '%s'"),
+ priv->arp_validate, NM_SETTING_BOND_ARP_VALIDATE);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_ARP_VALIDATE);
+ return FALSE;
+ }
+
+ if (priv->primary_reselect && !validate_property (&props[PROP_PRIMARY_RESELECT], priv->primary_reselect)) {
+ g_set_error (error,
+ NM_SETTING_BOND_ERROR,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid value for '%s'"),
+ priv->primary_reselect, NM_SETTING_BOND_PRIMARY_RESELECT);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_PRIMARY_RESELECT);
+ return FALSE;
+ }
+
+ if (priv->fail_over_mac && !validate_property (&props[PROP_FAIL_OVER_MAC], priv->fail_over_mac)) {
+ g_set_error (error,
+ NM_SETTING_BOND_ERROR,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid value for '%s'"),
+ priv->fail_over_mac, NM_SETTING_BOND_FAIL_OVER_MAC);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_FAIL_OVER_MAC);
+ return FALSE;
+ }
+
+ if (priv->ad_select && !validate_property (&props[PROP_FAIL_OVER_MAC], priv->ad_select)) {
+ g_set_error (error,
+ NM_SETTING_BOND_ERROR,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid value for '%s'"),
+ priv->ad_select, NM_SETTING_BOND_AD_SELECT);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_AD_SELECT);
+ return FALSE;
+ }
+
+ if (priv->xmit_hash_policy && !validate_property (&props[PROP_FAIL_OVER_MAC], priv->xmit_hash_policy)) {
+ g_set_error (error,
+ NM_SETTING_BOND_ERROR,
+ NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
+ _("'%s' is not a valid value for '%s'"),
+ priv->xmit_hash_policy, NM_SETTING_BOND_XMIT_HASH_POLICY);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_XMIT_HASH_POLICY);
+ return FALSE;
+ }
+
return TRUE;
}
@@ -704,13 +1173,9 @@ nm_setting_bond_init (NMSettingBond *setting)
{
NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting);
- g_object_set (setting, NM_SETTING_NAME, NM_SETTING_BOND_SETTING_NAME,
- NULL);
+ g_object_set (setting, NM_SETTING_NAME, NM_SETTING_BOND_SETTING_NAME, NULL);
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- /* Default values: */
- nm_setting_bond_add_option (setting, NM_SETTING_BOND_OPTION_MODE, "balance-rr");
}
static void
@@ -719,52 +1184,159 @@ finalize (GObject *object)
NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object);
g_free (priv->interface_name);
+ g_free (priv->mode);
+ g_free (priv->primary);
+ g_strfreev (priv->arp_ip_target);
g_hash_table_destroy (priv->options);
G_OBJECT_CLASS (nm_setting_bond_parent_class)->finalize (object);
}
static void
-copy_hash (gpointer key, gpointer value, gpointer user_data)
-{
- g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value));
-}
-
-static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
+ NMSettingBond *setting = NM_SETTING_BOND (object);
NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object);
- GHashTable *new_hash;
+ const char *legacy_name = get_legacy_name (pspec);
+ char *legacy_value = NULL;
switch (prop_id) {
case PROP_INTERFACE_NAME:
+ g_free (priv->interface_name);
priv->interface_name = g_value_dup_string (value);
break;
+ case PROP_MODE:
+ g_free (priv->mode);
+ priv->mode = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_MIIMON:
+ priv->miimon = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
+ case PROP_DOWNDELAY:
+ priv->downdelay = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
+ case PROP_UPDELAY:
+ priv->updelay = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
+ case PROP_ARP_INTERVAL:
+ priv->arp_interval = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
+ case PROP_ARP_IP_TARGET:
+ g_strfreev (priv->arp_ip_target);
+ priv->arp_ip_target = g_value_dup_boxed (value);
+ legacy_value = priv->arp_ip_target ? g_strjoinv (",", priv->arp_ip_target) : g_strdup ("");
+ break;
+ case PROP_ARP_VALIDATE:
+ g_free (priv->arp_validate);
+ priv->arp_validate = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_PRIMARY:
+ g_free (priv->primary);
+ priv->primary = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_PRIMARY_RESELECT:
+ g_free (priv->primary_reselect);
+ priv->primary_reselect = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_FAIL_OVER_MAC:
+ g_free (priv->fail_over_mac);
+ priv->fail_over_mac = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_USE_CARRIER:
+ priv->use_carrier = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
+ case PROP_AD_SELECT:
+ g_free (priv->ad_select);
+ priv->ad_select = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_XMIT_HASH_POLICY:
+ g_free (priv->xmit_hash_policy);
+ priv->xmit_hash_policy = g_value_dup_string (value);
+ legacy_value = g_value_dup_string (value);
+ break;
+ case PROP_RESEND_IGMP:
+ priv->resend_igmp = g_value_get_int (value);
+ legacy_value = g_strdup_printf ("%u", g_value_get_int (value));
+ break;
case PROP_OPTIONS:
- /* Must make a deep copy of the hash table here... */
- g_hash_table_remove_all (priv->options);
- new_hash = g_value_get_boxed (value);
- if (new_hash)
- g_hash_table_foreach (new_hash, copy_hash, priv->options);
+ set_properties_from_hash (setting, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+
+ if (legacy_value) {
+ g_hash_table_insert (priv->options, g_strdup (legacy_name), legacy_value);
+ g_object_notify (object, NM_SETTING_BOND_OPTIONS);
+ }
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
- NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object);
NMSettingBond *setting = NM_SETTING_BOND (object);
+ NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object);
switch (prop_id) {
case PROP_INTERFACE_NAME:
g_value_set_string (value, nm_setting_bond_get_interface_name (setting));
break;
+ case PROP_MODE:
+ g_value_set_string (value, nm_setting_bond_get_mode (setting));
+ break;
+ case PROP_MIIMON:
+ g_value_set_int (value, nm_setting_bond_get_miimon (setting));
+ break;
+ case PROP_DOWNDELAY:
+ g_value_set_int (value, nm_setting_bond_get_downdelay (setting));
+ break;
+ case PROP_UPDELAY:
+ g_value_set_int (value, nm_setting_bond_get_updelay (setting));
+ break;
+ case PROP_ARP_INTERVAL:
+ g_value_set_int (value, nm_setting_bond_get_arp_interval (setting));
+ break;
+ case PROP_ARP_IP_TARGET:
+ g_value_set_boxed (value, nm_setting_bond_get_arp_ip_target (setting));
+ break;
+ case PROP_ARP_VALIDATE:
+ g_value_set_string (value, nm_setting_bond_get_arp_validate (setting));
+ break;
+ case PROP_PRIMARY:
+ g_value_set_string (value, nm_setting_bond_get_primary (setting));
+ break;
+ case PROP_PRIMARY_RESELECT:
+ g_value_set_string (value, nm_setting_bond_get_primary_reselect (setting));
+ break;
+ case PROP_FAIL_OVER_MAC:
+ g_value_set_string (value, nm_setting_bond_get_fail_over_mac (setting));
+ break;
+ case PROP_USE_CARRIER:
+ g_value_set_int (value, nm_setting_bond_get_use_carrier (setting));
+ break;
+ case PROP_AD_SELECT:
+ g_value_set_string (value, nm_setting_bond_get_ad_select (setting));
+ break;
+ case PROP_XMIT_HASH_POLICY:
+ g_value_set_string (value, nm_setting_bond_get_xmit_hash_policy (setting));
+ break;
+ case PROP_RESEND_IGMP:
+ g_value_set_int (value, nm_setting_bond_get_resend_igmp (setting));
+ break;
case PROP_OPTIONS:
g_value_set_boxed (value, priv->options);
break;
@@ -779,6 +1351,7 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
+ guint i;
g_type_class_add_private (setting_class, sizeof (NMSettingBondPrivate));
@@ -795,29 +1368,252 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class)
*
* The name of the virtual in-kernel bonding network interface
**/
- g_object_class_install_property
- (object_class, PROP_INTERFACE_NAME,
- g_param_spec_string (NM_SETTING_BOND_INTERFACE_NAME,
- "InterfaceName",
- "The name of the virtual in-kernel bonding network interface",
- NULL,
- G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+ props[PROP_INTERFACE_NAME].pspec =
+ g_param_spec_string (NM_SETTING_BOND_INTERFACE_NAME,
+ "InterfaceName",
+ "The name of the virtual in-kernel bonding network interface",
+ NULL,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:mode:
+ *
+ * The bonding mode. One of 'balance-rr', 'active-backup',
+ * 'balance-xor', 'broadcast', '802.3ad', 'balance-tlb', or
+ * 'balance-alb'.
+ **/
+ props[PROP_MODE].pspec =
+ g_param_spec_string (NM_SETTING_BOND_MODE,
+ "Mode",
+ "The bonding mode",
+ "balance-rr",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:miimon:
+ *
+ * The MII link monitoring frequency, in milliseconds. Either this
+ * or #NMSettingBond:arp-interval should be set, and they can't
+ * both be set.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_MIIMON].pspec =
+ g_param_spec_int (NM_SETTING_BOND_MIIMON,
+ "miimon",
+ "The MII link monitoring frequence",
+ 0, G_MAXINT, 100,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:downdelay:
+ *
+ * The time, in milliseconds, to wait before disabling a slave
+ * after it goes down. Only valid if #NMSettingBond:miimon is
+ * non-0.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_DOWNDELAY].pspec =
+ g_param_spec_int (NM_SETTING_BOND_DOWNDELAY,
+ "downdelay",
+ "downdelay",
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:updelay:
+ *
+ * The time, in milliseconds, to wait before enabling a slave
+ * after it comes up. Only valid if #NMSettingBond:miimon is
+ * non-0.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_UPDELAY].pspec =
+ g_param_spec_int (NM_SETTING_BOND_UPDELAY,
+ "updelay",
+ "updelay",
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:arp-interval:
+ *
+ * The ARP-based link monitoring frequency, in milliseconds.
+ * Either this or #NMSettingBond:miimon should be set, and they
+ * can't both be set.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_ARP_INTERVAL].pspec =
+ g_param_spec_int (NM_SETTING_BOND_ARP_INTERVAL,
+ "ARP interval",
+ "The ARP-based link monitoring frequence",
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:arp-ip-target:
+ *
+ * An array of IPv4 addresses to ping when using ARP-based link monitoring.
+ * This only has an effect when #NMSettingBond:arp-interval is also set.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_ARP_IP_TARGET].pspec =
+ g_param_spec_boxed (NM_SETTING_BOND_ARP_IP_TARGET,
+ "ARP IP target",
+ "ARP monitoring target IP addresses",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:arp-validate:
+ *
+ * Specifies whether or not ARP probes and replies should be
+ * validated in the active-backup mode. One of
+ * 'none', 'active', 'backup', 'all'.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_ARP_VALIDATE].pspec =
+ g_param_spec_string (NM_SETTING_BOND_ARP_VALIDATE,
+ "arp-validate",
+ "Specifies whether or not ARP probes and replies should "
+ "be validate in the active-backup mode",
+ "none",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:primary:
+ *
+ * The primary interface to use in 'active-backup' mode.
+ **/
+ props[PROP_PRIMARY].pspec =
+ g_param_spec_string (NM_SETTING_BOND_PRIMARY,
+ "Primary",
+ "The primary interface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:primary-reselect:
+ *
+ * Specifies the reselection policy for the primary slave.
+ * One of 'always', 'better', 'failure'.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_PRIMARY_RESELECT].pspec =
+ g_param_spec_string (NM_SETTING_BOND_PRIMARY_RESELECT,
+ "primary-reselect",
+ "Specifies the reselection policy for the primary slave",
+ "always",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:fail-over-mac:
+ *
+ * Specifies whether active-backup mode should set all slaves to
+ * the same MAC address at enslavement (the traditional
+ * behavior), or, when enabled, perform special handling of the
+ * bond's MAC address in accordance with the selected policy.
+ * One of 'none', 'active', 'follow'.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_FAIL_OVER_MAC].pspec =
+ g_param_spec_string (NM_SETTING_BOND_FAIL_OVER_MAC,
+ "fail-over-mac",
+ "fail_over_mac",
+ "none",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:use-carrier:
+ *
+ * Specifies whether or not miimon should use MII or ETHTOOL
+ * ioctls vs. netif_carrier_ok() to determine the link
+ * status.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_USE_CARRIER].pspec =
+ g_param_spec_int (NM_SETTING_BOND_USE_CARRIER,
+ "use-carrier",
+ "use_carrier",
+ 0, 1, 1,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:ad-select:
+ *
+ * Specifies the 802.3ad aggregation selection logic to use.
+ * One of 'stable', 'bandwidth', or 'count'.
+ **/
+ props[PROP_AD_SELECT].pspec =
+ g_param_spec_string (NM_SETTING_BOND_AD_SELECT,
+ "ad-select",
+ "ad_select",
+ "stable",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:xmit-hash-policy:
+ *
+ * Selects the transmit hash policy to use for slave selection in
+ * balance-xor and 802.3ad modes. One of 'layer2', 'layer2+3',
+ * 'layer3+4', 'encap2+3', or 'encap3+4'.
+ *
+ **/
+ props[PROP_XMIT_HASH_POLICY].pspec =
+ g_param_spec_string (NM_SETTING_BOND_XMIT_HASH_POLICY,
+ "xmit-hash-policy",
+ "xmit_hash_policy",
+ "layer2",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
+
+ /**
+ * NMSettingBond:resend-igmp:
+ *
+ * Specifies the number of IGMP membership reports to be issued after
+ * a failover event. One membership report is issued immediately after
+ * the failover, subsequent packets are sent in each 200ms interval.
+ *
+ * The valid range is 0 - 255; the default value is 1. A value of 0
+ * prevents the IGMP membership report from being issued in response
+ * to the failover event.
+ *
+ * Since: 0.9.10
+ **/
+ props[PROP_RESEND_IGMP].pspec =
+ g_param_spec_int (NM_SETTING_BOND_RESEND_IGMP,
+ "resend-igmp",
+ "resend_igmp",
+ 0, 255, 1,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE);
/**
* NMSettingBond:options:
*
* Dictionary of key/value pairs of bonding options. Both keys
* and values must be strings. Option names must contain only
- * alphanumeric characters (ie, [a-zA-Z0-9]).
+ * alphanumeric characters (ie, [a-zA-Z0-9_).
+ *
+ * Deprecated: use the specific properties
**/
- g_object_class_install_property
- (object_class, PROP_OPTIONS,
- _nm_param_spec_specialized (NM_SETTING_BOND_OPTIONS,
- "Options",
- "Dictionary of key/value pairs of bonding "
- "options. Both keys and values must be "
- "strings. Option names must contain only "
- "alphanumeric characters (ie, [a-zA-Z0-9]).",
- DBUS_TYPE_G_MAP_OF_STRING,
- G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+ props[PROP_OPTIONS].pspec =
+ _nm_param_spec_specialized (NM_SETTING_BOND_OPTIONS,
+ "Options",
+ "Dictionary of key/value pairs of bonding "
+ "options. Both keys and values must be "
+ "strings. Option names must contain only "
+ "alphanumeric characters (ie, [a-zA-Z0-9_]).",
+ DBUS_TYPE_G_MAP_OF_STRING,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE);
+
+ /* Skip PROP_0 */
+ for (i = 1; i < LAST_PROP; i++)
+ g_object_class_install_property (object_class, i, props[i].pspec);
}
diff --git a/libnm-util/nm-setting-bond.h b/libnm-util/nm-setting-bond.h
index 383e0eadb3..5a5676a053 100644
--- a/libnm-util/nm-setting-bond.h
+++ b/libnm-util/nm-setting-bond.h
@@ -55,24 +55,41 @@ typedef enum {
#define NM_SETTING_BOND_ERROR nm_setting_bond_error_quark ()
GQuark nm_setting_bond_error_quark (void);
-#define NM_SETTING_BOND_INTERFACE_NAME "interface-name"
-#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_INTERFACE_NAME "interface-name"
+#define NM_SETTING_BOND_MODE "mode"
+#define NM_SETTING_BOND_PRIMARY "primary"
+#define NM_SETTING_BOND_MIIMON "miimon"
+#define NM_SETTING_BOND_DOWNDELAY "downdelay"
+#define NM_SETTING_BOND_UPDELAY "updelay"
+#define NM_SETTING_BOND_ARP_INTERVAL "arp-interval"
+#define NM_SETTING_BOND_ARP_IP_TARGET "arp-ip-target"
+#define NM_SETTING_BOND_ARP_VALIDATE "arp-validate"
+#define NM_SETTING_BOND_PRIMARY "primary"
+#define NM_SETTING_BOND_PRIMARY_RESELECT "primary_reselect"
+#define NM_SETTING_BOND_FAIL_OVER_MAC "fail-over-mac"
+#define NM_SETTING_BOND_USE_CARRIER "use-carrier"
+#define NM_SETTING_BOND_AD_SELECT "ad-select"
+#define NM_SETTING_BOND_XMIT_HASH_POLICY "xmit-hash-policy"
+#define NM_SETTING_BOND_RESEND_IGMP "resend-igmp"
+
+/* Deprecated */
+#define NM_SETTING_BOND_OPTIONS "options"
+
+/* Valid options for the 'options' property (deprecated) */
+#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_MODE_IS_balance_rr(mode) ((mode) && (!strcmp ((mode), "0") || !strcmp ((mode), "balance-rr")))
+#define __NM_SETTING_BOND_MODE_IS_active_backup(mode) ((mode) && (!strcmp ((mode), "1") || !strcmp ((mode), "active-backup")))
+#define __NM_SETTING_BOND_MODE_IS_balance_xor(mode) ((mode) && (!strcmp ((mode), "2") || !strcmp ((mode), "balance-xor")))
+#define __NM_SETTING_BOND_MODE_IS_broadcast(mode) ((mode) && (!strcmp ((mode), "3") || !strcmp ((mode), "broadcast")))
+#define __NM_SETTING_BOND_MODE_IS_802_3ad(mode) ((mode) && (!strcmp ((mode), "4") || !strcmp ((mode), "802.3ad")))
+#define __NM_SETTING_BOND_MODE_IS_balance_tlb(mode) ((mode) && (!strcmp ((mode), "5") || !strcmp ((mode), "balance-tlb")))
+#define __NM_SETTING_BOND_MODE_IS_balance_alb(mode) ((mode) && (!strcmp ((mode), "6") || !strcmp ((mode), "balance-alb")))
typedef struct {
NMSetting parent;
@@ -90,8 +107,25 @@ typedef struct {
GType nm_setting_bond_get_type (void);
-NMSetting * nm_setting_bond_new (void);
-const char * nm_setting_bond_get_interface_name (NMSettingBond *setting);
+NMSetting * nm_setting_bond_new (void);
+const char * nm_setting_bond_get_interface_name (NMSettingBond *setting);
+
+const char * nm_setting_bond_get_mode (NMSettingBond *setting);
+const char * nm_setting_bond_get_primary (NMSettingBond *setting);
+guint nm_setting_bond_get_miimon (NMSettingBond *setting);
+guint nm_setting_bond_get_downdelay (NMSettingBond *setting);
+guint nm_setting_bond_get_updelay (NMSettingBond *setting);
+guint nm_setting_bond_get_arp_interval (NMSettingBond *setting);
+const char *const* nm_setting_bond_get_arp_ip_target (NMSettingBond *setting);
+const char * nm_setting_bond_get_arp_validate (NMSettingBond *setting);
+const char * nm_setting_bond_get_primary_reselect (NMSettingBond *setting);
+const char * nm_setting_bond_get_fail_over_mac (NMSettingBond *setting);
+gboolean nm_setting_bond_get_use_carrier (NMSettingBond *setting);
+const char * nm_setting_bond_get_ad_select (NMSettingBond *setting);
+const char * nm_setting_bond_get_xmit_hash_policy (NMSettingBond *setting);
+guint nm_setting_bond_get_resend_igmp (NMSettingBond *setting);
+
+/* Deprecated */
guint32 nm_setting_bond_get_num_options (NMSettingBond *setting);
gboolean nm_setting_bond_get_option (NMSettingBond *setting,
guint32 idx,
@@ -105,9 +139,6 @@ gboolean nm_setting_bond_add_option (NMSettingBond *setting,
gboolean nm_setting_bond_remove_option (NMSettingBond *setting,
const char *name);
-gboolean nm_setting_bond_validate_option (const char *name,
- const char *value);
-
const char **nm_setting_bond_get_valid_options (NMSettingBond *setting);
const char * nm_setting_bond_get_option_default (NMSettingBond *setting,
diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c
index 56d6e679e2..54d8f23dce 100644
--- a/libnm-util/tests/test-general.c
+++ b/libnm-util/tests/test-general.c
@@ -1758,7 +1758,7 @@ test_setting_bond_changed_signal (void)
ASSERT_CHANGED (nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "10"));
ASSERT_CHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY));
- ASSERT_UNCHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY));
+ ASSERT_CHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY));
g_object_unref (connection);
}
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
index 8d9939b096..4e191632aa 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -200,6 +200,16 @@ set_bond_attr (NMDevice *device, const char *attr, const char *value)
return ret;
}
+static gboolean
+set_bond_attr_int (NMDevice *device, const char *attr, int value)
+{
+ char buf[20];
+
+ snprintf (buf, sizeof (buf), "%d", value);
+ buf[sizeof (buf) -1] = 0;
+ return set_bond_attr (device, attr, buf);
+}
+
/* Ignore certain bond options if they are zero (off/disabled) */
static gboolean
ignore_if_zero (const char *option, const char *value)
@@ -253,38 +263,21 @@ update_connection (NMDevice *device, NMConnection *connection)
static void
set_arp_targets (NMDevice *device,
- const char *value,
- const char *delim,
+ const char *const *values,
const char *prefix)
{
- char **items, **iter, *tmp;
+ char *tmp;
- if (!value || !*value)
+ if (!values)
return;
- items = g_strsplit_set (value, delim, 0);
- for (iter = items; iter && *iter; iter++) {
- if (*iter[0]) {
- tmp = g_strdup_printf ("%s%s", prefix, *iter);
+ for (; *values; values++) {
+ if (*values[0]) {
+ tmp = g_strconcat (prefix, *values, NULL);
set_bond_attr (device, "arp_ip_target", tmp);
g_free (tmp);
}
}
- g_strfreev (items);
-}
-
-static void
-set_simple_option (NMDevice *device,
- const char *attr,
- NMSettingBond *s_bond,
- const char *opt)
-{
- const char *value;
-
- value = nm_setting_bond_get_option_by_name (s_bond, opt);
- if (!value)
- value = nm_setting_bond_get_option_default (s_bond, opt);
- set_bond_attr (device, attr, value);
}
static NMActStageReturn
@@ -294,6 +287,7 @@ apply_bonding_config (NMDevice *device)
NMSettingBond *s_bond;
int ifindex = nm_device_get_ifindex (device);
const char *mode, *value;
+ int ivalue;
char *contents;
gboolean set_arp_interval = TRUE;
@@ -315,78 +309,65 @@ apply_bonding_config (NMDevice *device)
s_bond = nm_connection_get_setting_bond (connection);
g_assert (s_bond);
- mode = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
- if (mode == NULL)
- mode = "balance-rr";
+ mode = nm_setting_bond_get_mode (s_bond);
+ g_assert (mode && !mode[0]);
- value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON);
- if (value && atoi (value)) {
+ ivalue = nm_setting_bond_get_miimon (s_bond);
+ if (ivalue > 0) {
/* clear arp interval */
set_bond_attr (device, "arp_interval", "0");
set_arp_interval = FALSE;
- set_bond_attr (device, "miimon", value);
- set_simple_option (device, "updelay", s_bond, NM_SETTING_BOND_OPTION_UPDELAY);
- set_simple_option (device, "downdelay", s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY);
- } else if (!value) {
- /* If not given, and arp_interval is not given, default to 100 */
- long int val_int;
- char *end;
-
- value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
- errno = 0;
- val_int = strtol (value ? value : "0", &end, 10);
- if (!value || (val_int == 0 && errno == 0 && *end == '\0'))
- set_bond_attr (device, "miimon", "100");
+ set_bond_attr_int (device, "miimon", ivalue);
+ set_bond_attr_int (device, "updelay", nm_setting_bond_get_updelay (s_bond));
+ set_bond_attr_int (device, "downdelay", nm_setting_bond_get_downdelay (s_bond));
}
/* The stuff after 'mode' requires the given mode or doesn't care */
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_SETTING_BOND_MODE_IS_balance_alb (mode) || __NM_SETTING_BOND_MODE_IS_balance_tlb (mode))
set_arp_interval = FALSE;
if (set_arp_interval) {
- set_simple_option (device, "arp_interval", s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
+ set_bond_attr_int (device, "arp_interval", nm_setting_bond_get_arp_interval (s_bond));
/* Just let miimon get cleared automatically; even setting miimon to
* 0 (disabled) clears 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)
- 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) {
- value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
+ value = nm_setting_bond_get_arp_validate (s_bond);
+ set_bond_attr (device, "arp_validate", value);
+
+ if ( __NM_SETTING_BOND_MODE_IS_active_backup (mode)
+ || __NM_SETTING_BOND_MODE_IS_balance_alb (mode)
+ || __NM_SETTING_BOND_MODE_IS_balance_tlb (mode)) {
+ value = nm_setting_bond_get_primary (s_bond);
set_bond_attr (device, "primary", value ? value : "");
}
/* Clear ARP targets */
contents = nm_platform_master_get_option (ifindex, "arp_ip_target");
- set_arp_targets (device, contents, " \n", "-");
+ if (contents && contents[0]) {
+ char **items;
+
+ items = g_strsplit_set (contents, " \n", 0);
+ set_arp_targets (device, (const char *const*) items, "-");
+ g_strfreev (items);
+ }
g_free (contents);
/* Add new ARP targets */
- value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
- set_arp_targets (device, value, ",", "+");
-
- set_simple_option (device, "primary_reselect", s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT);
- set_simple_option (device, "fail_over_mac", s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC);
- set_simple_option (device, "use_carrier", s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER);
- 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_arp_targets (device, nm_setting_bond_get_arp_ip_target (s_bond), "+");
+
+ set_bond_attr (device, "primary_reselect", nm_setting_bond_get_primary_reselect (s_bond));
+ set_bond_attr (device, "fail_over_mac", nm_setting_bond_get_fail_over_mac (s_bond));
+ set_bond_attr_int (device, "use_carrier", nm_setting_bond_get_use_carrier (s_bond));
+ set_bond_attr (device, "ad_select", nm_setting_bond_get_ad_select (s_bond));
+ set_bond_attr (device, "xmit_hash_policy", nm_setting_bond_get_xmit_hash_policy (s_bond));
+ set_bond_attr_int (device, "resend_igmp", nm_setting_bond_get_resend_igmp (s_bond));
return NM_ACT_STAGE_RETURN_SUCCESS;
}
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index e2cff0b2cf..e11e75eb05 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -4059,29 +4059,87 @@ infiniband_connection_from_ifcfg (const char *file,
return connection;
}
+typedef void (*IfcfgRhOptFunc) (NMSetting *setting,
+ const char *key,
+ const char *value,
+ gpointer data);
+
static void
-handle_bond_option (NMSettingBond *s_bond,
- const char *key,
- const char *value)
+handle_ifcfg_rh_opts (NMSetting *setting,
+ const char *value,
+ IfcfgRhOptFunc func,
+ gpointer data)
{
- char *sanitized = NULL, *j;
- const char *p = value;
+ char **items, **iter;
- /* Remove any quotes or +/- from arp_ip_target */
- if (!g_strcmp0 (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) && value && value[0]) {
- if (*p == '\'' || *p == '"')
- p++;
- j = sanitized = g_malloc0 (strlen (p) + 1);
- while (*p) {
- if (*p != '+' && *p != '-' && *p != '\'' && *p != '"')
- *j++ = *p;
- p++;
+ items = g_strsplit_set (value, " ", -1);
+ for (iter = items; iter && *iter; iter++) {
+ if (strlen (*iter)) {
+ char **keys, *key, *val;
+
+ keys = g_strsplit_set (*iter, "=", 2);
+ if (keys && *keys) {
+ key = *keys;
+ val = *(keys + 1);
+ if (val && strlen(key) && strlen(val))
+ func (setting, key, val, data);
+ }
+
+ g_strfreev (keys);
}
}
+ g_strfreev (items);
+}
+
+static void
+handle_bond_option (NMSetting *setting,
+ const char *key,
+ const char *value,
+ gpointer data)
+{
+ NMSettingBond *s_bond = NM_SETTING_BOND (setting);
+
+ if (!strcmp (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
+ char **arp_ip_target;
+ char *sanitized = NULL, *j;
+ const char *p = value;
+
+ /* Remove any quotes or +/- from arp_ip_target */
+ if (value[0]) {
+ if (*p == '\'' || *p == '"')
+ p++;
+ j = sanitized = g_malloc0 (strlen (p) + 1);
+ while (*p) {
+ if (*p != '+' && *p != '-' && *p != '\'' && *p != '"')
+ *j++ = *p;
+ p++;
+ }
+ value = sanitized;
+ }
+
+ arp_ip_target = g_strsplit (",", value, -1);
+ g_object_set (s_bond, NM_SETTING_BOND_ARP_IP_TARGET, arp_ip_target, NULL);
+ g_strfreev (arp_ip_target);
+ g_free (sanitized);
+ } else {
+ GValue gval = G_VALUE_INIT;
+
+ /* We take advantage of the fact that ifcfg files and NMSettingBond use
+ * the same property names (which are also the ones the kernel uses).
+ * GObject will transform our string values to guints or gboolean as
+ * needed.
+ */
- if (!nm_setting_bond_add_option (s_bond, key, sanitized ? sanitized : value))
- PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid bonding option '%s'", key);
- g_free (sanitized);
+ if (!g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key)) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unrecognized bond property '%s'", key);
+ return;
+ }
+
+ g_value_init (&gval, G_TYPE_STRING);
+ g_value_set_string (&gval, value);
+ g_object_set_property (G_OBJECT (setting), key, &gval);
+ g_value_unset (&gval);
+ }
}
static NMSetting *
@@ -4105,26 +4163,8 @@ make_bond_setting (shvarFile *ifcfg,
value = svGetValue (ifcfg, "BONDING_OPTS", FALSE);
if (value) {
- char **items, **iter;
-
- items = g_strsplit_set (value, " ", -1);
- for (iter = items; iter && *iter; iter++) {
- if (strlen (*iter)) {
- char **keys, *key, *val;
-
- keys = g_strsplit_set (*iter, "=", 2);
- if (keys && *keys) {
- key = *keys;
- val = *(keys + 1);
- if (val && strlen(key) && strlen(val))
- handle_bond_option (s_bond, key, val);
- }
-
- g_strfreev (keys);
- }
- }
+ handle_ifcfg_rh_opts (NM_SETTING (s_bond), value, handle_bond_option, NULL);
g_free (value);
- g_strfreev (items);
}
return (NMSetting *) s_bond;
@@ -4266,17 +4306,13 @@ team_connection_from_ifcfg (const char *file,
return connection;
}
-typedef void (*BridgeOptFunc) (NMSetting *setting,
- gboolean stp,
- const char *key,
- const char *value);
-
static void
handle_bridge_option (NMSetting *setting,
- gboolean stp,
const char *key,
- const char *value)
+ const char *value,
+ gpointer data)
{
+ gboolean stp = GPOINTER_TO_INT (data);
guint32 u = 0;
if (!strcmp (key, "priority")) {
@@ -4309,33 +4345,6 @@ handle_bridge_option (NMSetting *setting,
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unhandled bridge option '%s'", key);
}
-static void
-handle_bridging_opts (NMSetting *setting,
- gboolean stp,
- const char *value,
- BridgeOptFunc func)
-{
- char **items, **iter;
-
- items = g_strsplit_set (value, " ", -1);
- for (iter = items; iter && *iter; iter++) {
- if (strlen (*iter)) {
- char **keys, *key, *val;
-
- keys = g_strsplit_set (*iter, "=", 2);
- if (keys && *keys) {
- key = *keys;
- val = *(keys + 1);
- if (val && strlen(key) && strlen(val))
- func (setting, stp, key, val);
- }
-
- g_strfreev (keys);
- }
- }
- g_strfreev (items);
-}
-
static NMSetting *
make_bridge_setting (shvarFile *ifcfg,
const char *file,
@@ -4391,7 +4400,8 @@ make_bridge_setting (shvarFile *ifcfg,
value = svGetValue (ifcfg, "BRIDGING_OPTS", FALSE);
if (value) {
- handle_bridging_opts (NM_SETTING (s_bridge), stp, value, handle_bridge_option);
+ handle_ifcfg_rh_opts (NM_SETTING (s_bridge), value, handle_bridge_option,
+ GINT_TO_POINTER (stp));
g_free (value);
}
@@ -4442,9 +4452,9 @@ bridge_connection_from_ifcfg (const char *file,
static void
handle_bridge_port_option (NMSetting *setting,
- gboolean stp,
const char *key,
- const char *value)
+ const char *value,
+ gpointer data)
{
guint32 u = 0;
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 14c4fb9f72..bc8c9740b9 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -12101,9 +12101,9 @@ test_read_bond_main (void)
"bond-main", "failed to verify %s: DEVICE=%s does not match bond0",
TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_interface_name (s_bond));
- ASSERT (g_strcmp0 (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), "100") == 0,
- "bond-main", "failed to verify %s: miimon=%s does not match 100",
- TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON));
+ ASSERT (nm_setting_bond_get_miimon (s_bond) == 100,
+ "bond-main", "failed to verify %s: miimon=%u does not match 100",
+ TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_miimon (s_bond));
g_free (unmanaged);
g_free (keyfile);
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index 6abbe2a568..091a87ce6f 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -1245,12 +1245,30 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired,
return TRUE;
}
+static const char *bonding_props[] = {
+ /* NM_SETTING_BOND_OPTION_MODE, */
+ NM_SETTING_BOND_OPTION_MIIMON,
+ NM_SETTING_BOND_OPTION_DOWNDELAY,
+ NM_SETTING_BOND_OPTION_UPDELAY,
+ NM_SETTING_BOND_OPTION_ARP_INTERVAL,
+ NM_SETTING_BOND_OPTION_ARP_IP_TARGET,
+ NM_SETTING_BOND_OPTION_ARP_VALIDATE,
+ NM_SETTING_BOND_OPTION_PRIMARY,
+ NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
+ NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
+ NM_SETTING_BOND_OPTION_USE_CARRIER,
+ NM_SETTING_BOND_OPTION_AD_SELECT,
+ NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
+ NM_SETTING_BOND_OPTION_RESEND_IGMP,
+ NULL
+};
+
static gboolean
write_bonding_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
{
NMSettingBond *s_bond;
const char *iface;
- guint32 i, num_opts;
+ GString *str;
s_bond = nm_connection_get_setting_bond (connection);
if (!s_bond) {
@@ -1268,28 +1286,44 @@ write_bonding_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
svSetValue (ifcfg, "DEVICE", iface, FALSE);
svSetValue (ifcfg, "BONDING_OPTS", NULL, FALSE);
- num_opts = nm_setting_bond_get_num_options (s_bond);
- if (num_opts > 0) {
- GString *str = g_string_sized_new (64);
-
- for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) {
- const char *key, *value;
+ str = g_string_sized_new (64);
+ g_string_append_printf (str, "mode=%s", nm_setting_bond_get_mode (s_bond));
+
+ for (i = 0; bonding_props[i]; i++) {
+ if (!strcmp (bonding_props[i], NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
+ char **arp_ip_target;
+ int j;
+
+ arp_ip_target = nm_setting_bond_get_arp_ip_target (s_bond);
+ if (arp_ip_target) {
+ g_string_append (str, " arp_ip_target=");
+ for (j = 0; arp_ip_target[j]; j++) {
+ if (j > 0)
+ g_string_append_c (str, ',');
+ g_string_append (str, arp_ip_target[j]);
+ }
+ g_strfreev (arp_ip_target);
+ }
+ } else if (!strcmp (bonding_props[i], NM_SETTING_BOND_OPTION_USE_CARRIER)) {
+ if (!nm_setting_bond_get_use_carrier (s_bond))
+ g_string_append (str, " use_carrier=0");
+ } else {
+ GValue val = G_VALUE_INIT;
+ const char *strval;
- if (!nm_setting_bond_get_option (s_bond, i, &key, &value))
- continue;
+ g_value_init (&val, G_TYPE_STRING);
+ g_object_get_property (G_OBJECT (s_bond), bonding_props[i], &val);
+ strval = g_value_get_string (&val);
- if (str->len)
- g_string_append_c (str, ' ');
-
- g_string_append_printf (str, "%s=%s", key, value);
+ if (strval && *strval && *strval != '0')
+ g_string_append_printf (str, " %s=%s", bonding_props[i], strval);
+ g_value_unset (&val);
}
-
- if (str->len)
- svSetValue (ifcfg, "BONDING_OPTS", str->str, FALSE);
-
- g_string_free (str, TRUE);
}
+ svSetValue (ifcfg, "BONDING_OPTS", str->str, FALSE);
+ g_string_free (str, TRUE);
+
svSetValue (ifcfg, "TYPE", TYPE_BOND, FALSE);
svSetValue (ifcfg, "BONDING_MASTER", "yes", FALSE);