Thomas Haller
2020-09-10 22:10:45 +02:00
5 changed files with 178 additions and 176 deletions

View File

@@ -2376,12 +2376,14 @@ _nm_meta_setting_bond_add_option (NMSetting *setting,
const char *value, const char *value,
GError **error) GError **error)
{ {
NMSettingBond *s_bond = NM_SETTING_BOND (setting);
gs_free char *tmp_value = NULL; gs_free char *tmp_value = NULL;
const char *val2;
char *p; char *p;
if ( !value if ( !value
|| !value[0]) { || !value[0]) {
if (!nm_setting_bond_remove_option (NM_SETTING_BOND (setting), name)) { if (!nm_setting_bond_remove_option (s_bond, name)) {
nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT, nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
_("failed to unset bond option \"%s\""), _("failed to unset bond option \"%s\""),
name); name);
@@ -2401,7 +2403,7 @@ _nm_meta_setting_bond_add_option (NMSetting *setting,
*p = ','; *p = ',';
} }
if (!nm_setting_bond_add_option (NM_SETTING_BOND (setting), name, value)) { if (!nm_setting_bond_add_option (s_bond, name, value)) {
nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT, nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
_("failed to set bond option \"%s\""), _("failed to set bond option \"%s\""),
name); name);
@@ -2410,10 +2412,35 @@ _nm_meta_setting_bond_add_option (NMSetting *setting,
if (nm_streq (name, NM_SETTING_BOND_OPTION_ARP_INTERVAL)) { if (nm_streq (name, NM_SETTING_BOND_OPTION_ARP_INTERVAL)) {
if (_nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT, 0) > 0) if (_nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT, 0) > 0)
_nm_setting_bond_remove_options_miimon (NM_SETTING_BOND (setting)); _nm_setting_bond_remove_options_miimon (s_bond);
} else if (nm_streq (name, NM_SETTING_BOND_OPTION_MIIMON)) { } else if (nm_streq (name, NM_SETTING_BOND_OPTION_MIIMON)) {
if (_nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT, 0) > 0) if (_nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT, 0) > 0)
_nm_setting_bond_remove_options_arp_interval (NM_SETTING_BOND (setting)); _nm_setting_bond_remove_options_arp_interval (s_bond);
} else if (nm_streq (name, NM_SETTING_BOND_OPTION_PRIMARY)) {
if ( (val2 = nm_setting_bond_get_option_by_name (s_bond,
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE))
&& !nm_streq (val2, value)) {
/* "active_slave" option is deprecated and an alias for "primary". When
* setting "primary" to a different value, remove the deprecated "active_slave"
* setting.
*
* If we wouldn't do this, then the profile would work as requested, but ignoring
* the (redundant, differing) "active_slave" option. That is confusing, thus clean
* it up. */
nm_setting_bond_remove_option (s_bond,
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
}
} else if (nm_streq (name, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE)) {
if ( (val2 = nm_setting_bond_get_option_by_name (s_bond,
NM_SETTING_BOND_OPTION_PRIMARY))
&& !nm_streq (val2, value)) {
/* "active_slave" is a deprecated alias for "primary". NetworkManager will ignore
* "active_slave" if "primary" is set, we thus need to coerce the primary option
* too. */
nm_setting_bond_add_option (s_bond,
NM_SETTING_BOND_OPTION_PRIMARY,
value);
}
} }
return TRUE; return TRUE;

View File

@@ -211,6 +211,7 @@ _bond_add_option (NMSettingBond *s_bond,
_nm_setting_bond_remove_options_miimon (s_bond); _nm_setting_bond_remove_options_miimon (s_bond);
else if (nm_streq (option, NM_SETTING_BOND_OPTION_MIIMON)) else if (nm_streq (option, NM_SETTING_BOND_OPTION_MIIMON))
_nm_setting_bond_remove_options_arp_interval (s_bond); _nm_setting_bond_remove_options_arp_interval (s_bond);
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
} }
#define WIDGET_CHANGED_FUNC(widget, func, option, dflt) \ #define WIDGET_CHANGED_FUNC(widget, func, option, dflt) \
@@ -255,13 +256,16 @@ mode_widget_changed (GObject *object,
_bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_MODE, mode); _bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_MODE, mode);
priv->updating = FALSE; priv->updating = FALSE;
if (!strcmp (mode, "balance-tlb") || !strcmp (mode, "balance-alb")) { if (NM_IN_STRSET (mode, "balance-tlb",
"balance-alb")) {
nmt_newt_popup_set_active (priv->monitoring, NMT_PAGE_BOND_MONITORING_MII); nmt_newt_popup_set_active (priv->monitoring, NMT_PAGE_BOND_MONITORING_MII);
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), FALSE); nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), FALSE);
} else } else
nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), TRUE); nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->monitoring), TRUE);
if (!strcmp (mode, "active-backup")) { if (NM_IN_STRSET (mode, "active-backup",
"balance-alb",
"balance-tlb")) {
nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), TRUE); nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->primary), TRUE);
_bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_PRIMARY, _bond_add_option (priv->s_bond, NM_SETTING_BOND_OPTION_PRIMARY,
nmt_newt_entry_get_text (priv->primary)); nmt_newt_entry_get_text (priv->primary));

View File

@@ -111,9 +111,9 @@ _nm_assert_bond_meta (const OptionMeta *option_meta)
})); }));
return TRUE; return TRUE;
case NM_BOND_OPTION_TYPE_IP: case NM_BOND_OPTION_TYPE_IP:
case NM_BOND_OPTION_TYPE_IFNAME:
nm_assert (option_meta->val); nm_assert (option_meta->val);
/* fall-through */ /* fall-through */
case NM_BOND_OPTION_TYPE_IFNAME:
case NM_BOND_OPTION_TYPE_MAC: case NM_BOND_OPTION_TYPE_MAC:
nm_assert (!option_meta->list); nm_assert (!option_meta->list);
nm_assert (option_meta->min == 0); nm_assert (option_meta->min == 0);
@@ -151,7 +151,7 @@ NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE (
} }
}, },
{ return NULL; }, { return NULL; },
{ NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, { "", NM_BOND_OPTION_TYPE_IFNAME } }, { NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, { NULL, 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_SYS_PRIO, { "65535", NM_BOND_OPTION_TYPE_INT, 1, 65535 } },
{ NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, { NULL, NM_BOND_OPTION_TYPE_MAC } }, { NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, { NULL, NM_BOND_OPTION_TYPE_MAC } },
{ NM_SETTING_BOND_OPTION_AD_SELECT, { "stable", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_ad_select } }, { NM_SETTING_BOND_OPTION_AD_SELECT, { "stable", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_ad_select } },
@@ -295,6 +295,17 @@ _bond_get_option_normalized (NMSettingBond* self,
value = _bond_get_option (self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); value = _bond_get_option (self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP);
if (!value) if (!value)
value = _bond_get_option (self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); value = _bond_get_option (self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
} else if (NM_IN_STRSET (option,
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE)) {
/* "active_slave" is deprecated, and an alias for "primary". The property
* itself always normalizes to %NULL. */
value = NULL;
} else if (NM_IN_STRSET (option,
NM_SETTING_BOND_OPTION_PRIMARY)) {
/* "active_slave" is deprecated, and an alias for "primary". */
value = _bond_get_option (self, NM_SETTING_BOND_OPTION_PRIMARY);
if (!value)
value = _bond_get_option (self, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
} else } else
value = _bond_get_option (self, option); value = _bond_get_option (self, option);
@@ -835,7 +846,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
} }
primary = _bond_get_option (self, NM_SETTING_BOND_OPTION_PRIMARY); primary = _bond_get_option (self, NM_SETTING_BOND_OPTION_PRIMARY);
if (bond_mode == NM_BOND_MODE_ACTIVEBACKUP) { if (NM_IN_SET (bond_mode, NM_BOND_MODE_ACTIVEBACKUP,
NM_BOND_MODE_TLB,
NM_BOND_MODE_ALB)) {
GError *tmp_error = NULL; GError *tmp_error = NULL;
if (primary && !nm_utils_ifname_valid_kernel (primary, &tmp_error)) { if (primary && !nm_utils_ifname_valid_kernel (primary, &tmp_error)) {

View File

@@ -357,6 +357,16 @@ nm_streq0 (const char *s1, const char *s2)
#define _NM_IN_SET_EVAL_18(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_17 (op, _x, __VA_ARGS__) #define _NM_IN_SET_EVAL_18(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_17 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_19(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_18 (op, _x, __VA_ARGS__) #define _NM_IN_SET_EVAL_19(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_18 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_20(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_19 (op, _x, __VA_ARGS__) #define _NM_IN_SET_EVAL_20(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_19 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_21(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_20 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_22(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_21 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_23(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_22 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_24(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_23 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_25(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_24 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_26(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_25 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_27(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_26 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_28(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_27 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_29(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_28 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_30(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_29 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)) #define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \ #define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \
@@ -410,6 +420,16 @@ nm_streq0 (const char *s1, const char *s2)
#define _NM_IN_SETOP_EVAL_18(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_17 (op, op_eq, _x, __VA_ARGS__) #define _NM_IN_SETOP_EVAL_18(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_17 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_19(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_18 (op, op_eq, _x, __VA_ARGS__) #define _NM_IN_SETOP_EVAL_19(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_18 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_20(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_19 (op, op_eq, _x, __VA_ARGS__) #define _NM_IN_SETOP_EVAL_20(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_19 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_21(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_20 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_22(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_21 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_23(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_22 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_24(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_23 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_25(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_24 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_26(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_25 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_27(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_26 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_28(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_27 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_29(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_28 (op, op_eq, _x, __VA_ARGS__)
#define _NM_IN_SETOP_EVAL_30(op, op_eq, _x, y, ...) (op_eq (_x, y)) op _NM_IN_SETOP_EVAL_29 (op, op_eq, _x, __VA_ARGS__)
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -22,6 +22,59 @@ _LOG_DECLARE_SELF(NMDeviceBond);
/*****************************************************************************/ /*****************************************************************************/
#define OPTIONS_APPLY_SUBSET \
NM_SETTING_BOND_OPTION_MIIMON, \
NM_SETTING_BOND_OPTION_UPDELAY, \
NM_SETTING_BOND_OPTION_DOWNDELAY, \
NM_SETTING_BOND_OPTION_ARP_INTERVAL, \
NM_SETTING_BOND_OPTION_ARP_VALIDATE, \
NM_SETTING_BOND_OPTION_PRIMARY, \
NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, \
NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, \
NM_SETTING_BOND_OPTION_AD_SELECT, \
NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, \
NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, \
NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, \
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, \
NM_SETTING_BOND_OPTION_LACP_RATE, \
NM_SETTING_BOND_OPTION_LP_INTERVAL, \
NM_SETTING_BOND_OPTION_MIN_LINKS, \
NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, \
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, \
NM_SETTING_BOND_OPTION_RESEND_IGMP, \
NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, \
NM_SETTING_BOND_OPTION_USE_CARRIER, \
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP
#define OPTIONS_REAPPLY_SUBSET \
NM_SETTING_BOND_OPTION_MIIMON, \
NM_SETTING_BOND_OPTION_UPDELAY, \
NM_SETTING_BOND_OPTION_DOWNDELAY, \
NM_SETTING_BOND_OPTION_ARP_INTERVAL, \
NM_SETTING_BOND_OPTION_ARP_VALIDATE, \
NM_SETTING_BOND_OPTION_PRIMARY, \
NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, \
NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, \
NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, \
NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, \
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, \
NM_SETTING_BOND_OPTION_LP_INTERVAL, \
NM_SETTING_BOND_OPTION_MIN_LINKS, \
NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, \
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, \
NM_SETTING_BOND_OPTION_RESEND_IGMP, \
NM_SETTING_BOND_OPTION_USE_CARRIER, \
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP
#define OPTIONS_REAPPLY_FULL \
OPTIONS_REAPPLY_SUBSET, \
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, \
NM_SETTING_BOND_OPTION_ARP_IP_TARGET
/*****************************************************************************/
struct _NMDeviceBond { struct _NMDeviceBond {
NMDevice parent; NMDevice parent;
}; };
@@ -128,42 +181,48 @@ update_connection (NMDevice *device, NMConnection *connection)
} }
/* Read bond options from sysfs and update the Bond setting to match */ /* Read bond options from sysfs and update the Bond setting to match */
options = nm_setting_bond_get_valid_options (s_bond); options = nm_setting_bond_get_valid_options (NULL);
for (; *options; options++) { for (; options[0]; options++) {
const char *option = options[0];
gs_free char *value = NULL;
char *p; char *p;
gs_free char *value = nm_platform_sysctl_master_get_option (nm_device_get_platform (device),
ifindex, if (NM_IN_STRSET (option, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE))
*options); continue;
value = nm_platform_sysctl_master_get_option (nm_device_get_platform (device),
ifindex,
option);
if ( value if ( value
&& _nm_setting_bond_get_option_type (s_bond, *options) == NM_BOND_OPTION_TYPE_BOTH) { && _nm_setting_bond_get_option_type (s_bond, option) == NM_BOND_OPTION_TYPE_BOTH) {
p = strchr (value, ' '); p = strchr (value, ' ');
if (p) if (p)
*p = '\0'; *p = '\0';
} }
if (mode == NM_BOND_MODE_UNKNOWN) { if (mode == NM_BOND_MODE_UNKNOWN) {
if (value && nm_streq (*options, NM_SETTING_BOND_OPTION_MODE)) if (value && nm_streq (option, NM_SETTING_BOND_OPTION_MODE))
mode = _nm_setting_bond_mode_from_string (value); mode = _nm_setting_bond_mode_from_string (value);
if (mode == NM_BOND_MODE_UNKNOWN) if (mode == NM_BOND_MODE_UNKNOWN)
continue; continue;
} }
if (!_nm_setting_bond_option_supported (*options, mode)) if (!_nm_setting_bond_option_supported (option, mode))
continue; continue;
if ( value if ( value
&& value[0] && value[0]
&& !ignore_option (s_bond, *options, value)) { && !ignore_option (s_bond, option, value)) {
/* Replace " " with "," for arp_ip_targets from the kernel */ /* Replace " " with "," for arp_ip_targets from the kernel */
if (strcmp (*options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) == 0) { if (nm_streq (option, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
for (p = value; *p; p++) { for (p = value; *p; p++) {
if (*p == ' ') if (*p == ' ')
*p = ','; *p = ',';
} }
} }
nm_setting_bond_add_option (s_bond, *options, value); nm_setting_bond_add_option (s_bond, option, value);
} }
} }
} }
@@ -261,40 +320,6 @@ set_bond_attr_or_default (NMDevice *device,
_set_bond_attr (device, opt, value); _set_bond_attr (device, opt, value);
} }
static void
set_bond_attr_active_slave (NMDevice *device, NMSettingBond *s_bond)
{
NMDeviceBond *self = NM_DEVICE_BOND (device);
const NMPlatformLink *plink;
const char *value;
const char *error_reason;
int ifindex;
value = nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
if (!value)
return;
if (!nm_str_is_empty (value)) {
ifindex = nm_device_get_ifindex (device);
plink = nm_platform_link_get_by_ifname (nm_device_get_platform (device), value);
if (!plink)
error_reason = "does not exist";
else if (plink->master != ifindex)
error_reason = "is not yet enslaved";
else if (!NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP))
error_reason = "is not up";
else
error_reason = NULL;
if (error_reason) {
_LOGT (LOGD_BOND, "bond option 'active_slave' not set as device \"%s\" %s", value, error_reason);
return;
}
}
_set_bond_attr (device, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, value);
}
static void static void
set_bond_attrs_or_default (NMDevice *device, NMSettingBond *s_bond, const char *const *attr_v) set_bond_attrs_or_default (NMDevice *device, NMSettingBond *s_bond, const char *const *attr_v)
{ {
@@ -342,33 +367,10 @@ apply_bonding_config (NMDeviceBond *self)
set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MODE); set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MODE);
set_bond_arp_ip_targets (device, s_bond); set_bond_arp_ip_targets (device, s_bond);
set_bond_attr_active_slave (device, s_bond);
set_bond_attrs_or_default (device, set_bond_attrs_or_default (device,
s_bond, s_bond,
NM_MAKE_STRV (NM_SETTING_BOND_OPTION_MIIMON, NM_MAKE_STRV (OPTIONS_APPLY_SUBSET));
NM_SETTING_BOND_OPTION_UPDELAY,
NM_SETTING_BOND_OPTION_DOWNDELAY,
NM_SETTING_BOND_OPTION_ARP_INTERVAL,
NM_SETTING_BOND_OPTION_ARP_VALIDATE,
NM_SETTING_BOND_OPTION_PRIMARY,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
NM_SETTING_BOND_OPTION_AD_SELECT,
NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY,
NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
NM_SETTING_BOND_OPTION_LACP_RATE,
NM_SETTING_BOND_OPTION_LP_INTERVAL,
NM_SETTING_BOND_OPTION_MIN_LINKS,
NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
NM_SETTING_BOND_OPTION_RESEND_IGMP,
NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB,
NM_SETTING_BOND_OPTION_USE_CARRIER,
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP));
return TRUE; return TRUE;
} }
@@ -400,45 +402,26 @@ enslave_slave (NMDevice *device,
gboolean configure) gboolean configure)
{ {
NMDeviceBond *self = NM_DEVICE_BOND (device); NMDeviceBond *self = NM_DEVICE_BOND (device);
gboolean success = TRUE;
const char *slave_iface = nm_device_get_ip_iface (slave);
NMConnection *master_con;
nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND); nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND);
if (configure) { if (configure) {
gboolean success;
nm_device_take_down (slave, TRUE); nm_device_take_down (slave, TRUE);
success = nm_platform_link_enslave (nm_device_get_platform (device), success = nm_platform_link_enslave (nm_device_get_platform (device),
nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (device),
nm_device_get_ip_ifindex (slave)); nm_device_get_ip_ifindex (slave));
nm_device_bring_up (slave, TRUE, NULL); nm_device_bring_up (slave, TRUE, NULL);
if (!success) if (!success) {
_LOGI (LOGD_BOND, "enslaved bond slave %s: failed", nm_device_get_ip_iface (slave));
return FALSE; return FALSE;
_LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface);
/* The active_slave option can be set only after the interface is enslaved */
master_con = nm_device_get_applied_connection (device);
if (master_con) {
NMSettingBond *s_bond = nm_connection_get_setting_bond (master_con);
const char *active;
if (s_bond) {
active = nm_setting_bond_get_option_or_default (s_bond,
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
if (nm_streq0 (active, nm_device_get_iface (slave))) {
nm_platform_sysctl_master_set_option (nm_device_get_platform (device),
nm_device_get_ifindex (device),
NM_SETTING_BOND_OPTION_ACTIVE_SLAVE,
active);
_LOGD (LOGD_BOND, "setting slave %s as active one for master %s",
active, nm_device_get_iface (device));
}
}
} }
_LOGI (LOGD_BOND, "enslaved bond slave %s", nm_device_get_ip_iface (slave));
} else } else
_LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface); _LOGI (LOGD_BOND, "bond slave %s was enslaved", nm_device_get_ip_iface (slave));
return TRUE; return TRUE;
} }
@@ -530,56 +513,6 @@ create_and_realize (NMDevice *device,
return TRUE; return TRUE;
} }
static gboolean
check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error)
{
const char **option_list;
option_list = nm_setting_bond_get_valid_options (NULL);
for (; *option_list; ++option_list) {
const char *name = *option_list;
/* We support changes to these */
if (NM_IN_STRSET (name,
NM_SETTING_BOND_OPTION_PRIMARY,
NM_SETTING_BOND_OPTION_MIIMON,
NM_SETTING_BOND_OPTION_UPDELAY,
NM_SETTING_BOND_OPTION_DOWNDELAY,
NM_SETTING_BOND_OPTION_ARP_INTERVAL,
NM_SETTING_BOND_OPTION_ARP_VALIDATE,
NM_SETTING_BOND_OPTION_PRIMARY,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
NM_SETTING_BOND_OPTION_LP_INTERVAL,
NM_SETTING_BOND_OPTION_MIN_LINKS,
NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
NM_SETTING_BOND_OPTION_RESEND_IGMP,
NM_SETTING_BOND_OPTION_USE_CARRIER,
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)) {
continue;
}
/* Reject any other changes */
if (!nm_streq0 (nm_setting_bond_get_option_normalized (s_a, name),
nm_setting_bond_get_option_normalized (s_b, name))) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply '%s' bond option",
name);
return FALSE;
}
}
return TRUE;
}
static gboolean static gboolean
can_reapply_change (NMDevice *device, can_reapply_change (NMDevice *device,
const char *setting_name, const char *setting_name,
@@ -592,13 +525,38 @@ can_reapply_change (NMDevice *device,
/* Only handle bond setting here, delegate other settings to parent class */ /* Only handle bond setting here, delegate other settings to parent class */
if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) { if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) {
NMSettingBond *s_a = NM_SETTING_BOND (s_old);
NMSettingBond *s_b = NM_SETTING_BOND (s_new);
const char **option_list;
if (!nm_device_hash_check_invalid_keys (diffs, if (!nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_SETTING_NAME,
error, error,
NM_SETTING_BOND_OPTIONS)) NM_SETTING_BOND_OPTIONS))
return FALSE; return FALSE;
return check_changed_options (NM_SETTING_BOND (s_old), NM_SETTING_BOND (s_new), error); option_list = nm_setting_bond_get_valid_options (NULL);
for (; *option_list; ++option_list) {
const char *name = *option_list;
/* We support changes to these */
if (NM_IN_STRSET (name, OPTIONS_REAPPLY_FULL))
continue;
/* Reject any other changes */
if (!nm_streq0 (nm_setting_bond_get_option_normalized (s_a, name),
nm_setting_bond_get_option_normalized (s_b, name))) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply '%s' bond option",
name);
return FALSE;
}
}
return TRUE;
} }
device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class); device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class);
@@ -633,31 +591,11 @@ reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_n
/* Below we set only the bond options that kernel allows to modify /* Below we set only the bond options that kernel allows to modify
* while keeping the bond interface up */ * while keeping the bond interface up */
set_bond_attr_active_slave (device, s_bond);
set_bond_arp_ip_targets (device, s_bond); set_bond_arp_ip_targets (device, s_bond);
set_bond_attrs_or_default (device, set_bond_attrs_or_default (device,
s_bond, s_bond,
NM_MAKE_STRV (NM_SETTING_BOND_OPTION_PRIMARY, NM_MAKE_STRV (OPTIONS_REAPPLY_SUBSET));
NM_SETTING_BOND_OPTION_MIIMON,
NM_SETTING_BOND_OPTION_UPDELAY,
NM_SETTING_BOND_OPTION_DOWNDELAY,
NM_SETTING_BOND_OPTION_ARP_INTERVAL,
NM_SETTING_BOND_OPTION_ARP_VALIDATE,
NM_SETTING_BOND_OPTION_PRIMARY,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
NM_SETTING_BOND_OPTION_LP_INTERVAL,
NM_SETTING_BOND_OPTION_MIN_LINKS,
NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
NM_SETTING_BOND_OPTION_RESEND_IGMP,
NM_SETTING_BOND_OPTION_USE_CARRIER,
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP));
} }
/*****************************************************************************/ /*****************************************************************************/