merge: branch 'ff/new_bond_options'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1553
This commit is contained in:
@@ -39,7 +39,8 @@
|
||||
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, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY
|
||||
NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY, \
|
||||
NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, NM_SETTING_BOND_OPTION_LACP_ACTIVE
|
||||
|
||||
#define OPTIONS_REAPPLY_SUBSET \
|
||||
NM_SETTING_BOND_OPTION_MIIMON, NM_SETTING_BOND_OPTION_UPDELAY, \
|
||||
@@ -51,11 +52,12 @@
|
||||
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, \
|
||||
NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY
|
||||
NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, \
|
||||
NM_SETTING_BOND_OPTION_LACP_ACTIVE
|
||||
|
||||
#define OPTIONS_REAPPLY_FULL \
|
||||
OPTIONS_REAPPLY_SUBSET, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, \
|
||||
NM_SETTING_BOND_OPTION_ARP_IP_TARGET
|
||||
NM_SETTING_BOND_OPTION_ARP_IP_TARGET, NM_SETTING_BOND_OPTION_NS_IP6_TARGET
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -268,7 +270,7 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new
|
||||
|
||||
cur_strv =
|
||||
nm_strsplit_set_full(cur_arp_ip_target, NM_ASCII_SPACES, NM_STRSPLIT_SET_FLAGS_STRSTRIP);
|
||||
new_strv = nm_utils_bond_option_arp_ip_targets_split(new_arp_ip_target);
|
||||
new_strv = nm_utils_bond_option_ip_split(new_arp_ip_target);
|
||||
|
||||
cur_len = NM_PTRARRAY_LEN(cur_strv);
|
||||
new_len = NM_PTRARRAY_LEN(new_strv);
|
||||
@@ -365,7 +367,7 @@ _bond_arp_ip_target_to_platform(const char *value, in_addr_t out[static NM_BOND_
|
||||
int i;
|
||||
int added = 0;
|
||||
|
||||
ip = nm_utils_bond_option_arp_ip_targets_split(value);
|
||||
ip = nm_utils_bond_option_ip_split(value);
|
||||
|
||||
if (!ip)
|
||||
return added;
|
||||
@@ -381,6 +383,31 @@ _bond_arp_ip_target_to_platform(const char *value, in_addr_t out[static NM_BOND_
|
||||
return added;
|
||||
}
|
||||
|
||||
static guint8
|
||||
_bond_ns_ip6_target_to_platform(const char *value,
|
||||
struct in6_addr out[static NM_BOND_MAX_ARP_TARGETS])
|
||||
{
|
||||
gs_free const char **ip = NULL;
|
||||
struct in6_addr in6_a;
|
||||
int i;
|
||||
int added = 0;
|
||||
|
||||
ip = nm_utils_bond_option_ip_split(value);
|
||||
|
||||
if (!ip)
|
||||
return added;
|
||||
|
||||
for (i = 0; ip[i]; i++) {
|
||||
if (added > NM_BOND_MAX_ARP_TARGETS - 1)
|
||||
break;
|
||||
if (!nm_inet_parse_bin(AF_INET6, ip[i], NULL, &in6_a))
|
||||
nm_assert_not_reached(); /* verify() already validated the IP addresses */
|
||||
|
||||
out[added++] = in6_a;
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
static int
|
||||
_setting_bond_primary_opt_as_ifindex(NMSettingBond *s_bond)
|
||||
{
|
||||
@@ -437,6 +464,10 @@ _platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *p
|
||||
NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY),
|
||||
.num_grat_arp = _v_u8(s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP),
|
||||
.all_ports_active = _v_u8(s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE),
|
||||
.arp_missed_max = _v_u8(s_bond, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX),
|
||||
.lacp_active = _v_fcn(_nm_setting_bond_lacp_active_from_string,
|
||||
s_bond,
|
||||
NM_SETTING_BOND_OPTION_LACP_ACTIVE),
|
||||
.lacp_rate = _v_fcn(_nm_setting_bond_lacp_rate_from_string,
|
||||
s_bond,
|
||||
NM_SETTING_BOND_OPTION_LACP_RATE),
|
||||
@@ -456,6 +487,11 @@ _platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *p
|
||||
props->arp_ip_targets_num =
|
||||
_bond_arp_ip_target_to_platform(opt_value, props->arp_ip_target);
|
||||
|
||||
opt_value = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_NS_IP6_TARGET);
|
||||
if (opt_value != NULL)
|
||||
props->ns_ip6_targets_num =
|
||||
_bond_ns_ip6_target_to_platform(opt_value, props->ns_ip6_target);
|
||||
|
||||
props->miimon_has = !props->arp_interval && !props->arp_validate;
|
||||
props->updelay_has = props->miimon_has && props->miimon;
|
||||
props->downdelay_has = props->miimon_has && props->miimon;
|
||||
@@ -463,6 +499,7 @@ _platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *p
|
||||
props->resend_igmp_has = props->resend_igmp != 1;
|
||||
props->lp_interval_has = props->lp_interval != 1;
|
||||
props->tlb_dynamic_lb_has = NM_IN_SET(props->mode, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB);
|
||||
props->lacp_active_has = NM_IN_SET(props->mode, NM_BOND_MODE_8023AD);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -13,7 +13,7 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
const char **
|
||||
nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target)
|
||||
nm_utils_bond_option_ip_split(const char *arp_ip_target)
|
||||
{
|
||||
return nm_strsplit_set_full(arp_ip_target, ",", NM_STRSPLIT_SET_FLAGS_STRSTRIP);
|
||||
}
|
||||
@@ -36,6 +36,7 @@ _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond)
|
||||
|
||||
nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
|
||||
nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_NS_IP6_TARGET);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -86,6 +87,20 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
{"follow", NM_BOND_FAIL_OVER_MAC_FOLLOW},
|
||||
{"none", NM_BOND_FAIL_OVER_MAC_NONE}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_lacp_active_from_string,
|
||||
NMBondLacpActive,
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR(_NM_BOND_LACP_ACTIVE_NUM <= 2);
|
||||
|
||||
if (name && name[0] < '0' + _NM_BOND_LACP_ACTIVE_NUM && name[0] >= '0' && name[1] == '\0') {
|
||||
return name[0] - '0';
|
||||
}
|
||||
},
|
||||
{ return NM_BOND_LACP_ACTIVE_ON; },
|
||||
{"off", NM_BOND_LACP_ACTIVE_OFF},
|
||||
{"on", NM_BOND_LACP_ACTIVE_ON}, );
|
||||
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE(
|
||||
_nm_setting_bond_lacp_rate_from_string,
|
||||
NMBondLacpRate,
|
||||
|
@@ -52,7 +52,7 @@ NM_AUTO_DEFINE_FCN0(NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
const char **nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target);
|
||||
const char **nm_utils_bond_option_ip_split(const char *arp_ip_target);
|
||||
|
||||
void _nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond);
|
||||
void _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond);
|
||||
@@ -95,6 +95,18 @@ typedef enum {
|
||||
|
||||
NMBondFailOverMac _nm_setting_bond_fail_over_mac_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_LACP_ACTIVE_UNKNOWN = -1,
|
||||
|
||||
/* The numeric values correspond to kernel's numbering. */
|
||||
NM_BOND_LACP_ACTIVE_OFF = 0,
|
||||
NM_BOND_LACP_ACTIVE_ON = 1,
|
||||
|
||||
_NM_BOND_LACP_ACTIVE_NUM,
|
||||
} NMBondLacpActive;
|
||||
|
||||
NMBondLacpActive _nm_setting_bond_lacp_active_from_string(const char *str);
|
||||
|
||||
typedef enum {
|
||||
NM_BOND_LACP_RATE_UNKNOWN = -1,
|
||||
|
||||
|
@@ -92,6 +92,9 @@ static const char *const valid_options_lst[] = {
|
||||
NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB,
|
||||
NM_SETTING_BOND_OPTION_LP_INTERVAL,
|
||||
NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY,
|
||||
NM_SETTING_BOND_OPTION_ARP_MISSED_MAX,
|
||||
NM_SETTING_BOND_OPTION_LACP_ACTIVE,
|
||||
NM_SETTING_BOND_OPTION_NS_IP6_TARGET,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -133,6 +136,7 @@ _nm_assert_bond_meta(const OptionMeta *option_meta)
|
||||
}));
|
||||
return TRUE;
|
||||
case NM_BOND_OPTION_TYPE_IP:
|
||||
case NM_BOND_OPTION_TYPE_IP6:
|
||||
nm_assert(option_meta->val);
|
||||
/* fall-through */
|
||||
case NM_BOND_OPTION_TYPE_IFNAME:
|
||||
@@ -154,8 +158,9 @@ static char const *const _option_default_strv_arp_validate[] =
|
||||
NM_MAKE_STRV("none", "active", "backup", "all", "filter", "filter_active", "filter_backup");
|
||||
static char const *const _option_default_strv_fail_over_mac[] =
|
||||
NM_MAKE_STRV("none", "active", "follow");
|
||||
static char const *const _option_default_strv_lacp_rate[] = NM_MAKE_STRV("slow", "fast");
|
||||
static char const *const _option_default_strv_mode[] = NM_MAKE_STRV("balance-rr",
|
||||
static char const *const _option_default_strv_lacp_rate[] = NM_MAKE_STRV("slow", "fast");
|
||||
static char const *const _option_default_strv_lacp_active[] = NM_MAKE_STRV("off", "on");
|
||||
static char const *const _option_default_strv_mode[] = NM_MAKE_STRV("balance-rr",
|
||||
"active-backup",
|
||||
"balance-xor",
|
||||
"broadcast",
|
||||
@@ -194,12 +199,15 @@ static NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE(
|
||||
{"any", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_arp_all_targets}},
|
||||
{NM_SETTING_BOND_OPTION_ARP_INTERVAL, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}},
|
||||
{NM_SETTING_BOND_OPTION_ARP_IP_TARGET, {"", NM_BOND_OPTION_TYPE_IP}},
|
||||
{NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, {"0", NM_BOND_OPTION_TYPE_INT, 0, 255}},
|
||||
{NM_SETTING_BOND_OPTION_ARP_VALIDATE,
|
||||
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_arp_validate}},
|
||||
{NM_SETTING_BOND_OPTION_BALANCE_SLB, {"0", NM_BOND_OPTION_TYPE_INT, 0, 1}},
|
||||
{NM_SETTING_BOND_OPTION_DOWNDELAY, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}},
|
||||
{NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
|
||||
{"none", NM_BOND_OPTION_TYPE_BOTH, 0, 2, _option_default_strv_fail_over_mac}},
|
||||
{NM_SETTING_BOND_OPTION_LACP_ACTIVE,
|
||||
{"on", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_lacp_active}},
|
||||
{NM_SETTING_BOND_OPTION_LACP_RATE,
|
||||
{"slow", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_lacp_rate}},
|
||||
{NM_SETTING_BOND_OPTION_LP_INTERVAL, {"1", NM_BOND_OPTION_TYPE_INT, 1, G_MAXINT}},
|
||||
@@ -207,6 +215,7 @@ static NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE(
|
||||
{NM_SETTING_BOND_OPTION_MIN_LINKS, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}},
|
||||
{NM_SETTING_BOND_OPTION_MODE,
|
||||
{"balance-rr", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_mode}},
|
||||
{NM_SETTING_BOND_OPTION_NS_IP6_TARGET, {"", NM_BOND_OPTION_TYPE_IP6}},
|
||||
{NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, {"1", NM_BOND_OPTION_TYPE_INT, 0, 255}},
|
||||
{NM_SETTING_BOND_OPTION_NUM_UNSOL_NA, {"1", NM_BOND_OPTION_TYPE_INT, 0, 255}},
|
||||
{NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, {"1", NM_BOND_OPTION_TYPE_INT, 0, 65535}},
|
||||
@@ -504,12 +513,12 @@ validate_list(const char *name, const char *value, const OptionMeta *option_meta
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_ip(const char *name, const char *value, GError **error)
|
||||
validate_ip(int addr_family, const char *name, const char *value, GError **error)
|
||||
{
|
||||
gs_free const char **addrs = NULL;
|
||||
gsize i;
|
||||
|
||||
addrs = nm_utils_bond_option_arp_ip_targets_split(value);
|
||||
addrs = nm_utils_bond_option_ip_split(value);
|
||||
if (!addrs) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
@@ -518,13 +527,18 @@ validate_ip(const char *name, const char *value, GError **error)
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* An empty list is invalid. */
|
||||
nm_assert(addrs[0]);
|
||||
|
||||
for (i = 0; addrs[i]; i++) {
|
||||
if (!nm_inet_parse_bin(AF_INET, addrs[i], NULL, NULL)) {
|
||||
if (!nm_inet_parse_bin(addr_family, addrs[i], NULL, NULL)) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s' is not a valid IPv4 address for '%s' option"),
|
||||
_("'%s' is not a valid %s address for '%s' option"),
|
||||
addrs[i],
|
||||
addr_family == AF_INET ? "IPv4" : "IPv6",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -574,7 +588,10 @@ _nm_setting_bond_validate_option(const char *name, const char *value, GError **e
|
||||
goto handle_error;
|
||||
case NM_BOND_OPTION_TYPE_IP:
|
||||
nm_assert(nm_streq0(name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET));
|
||||
return validate_ip(name, value, error);
|
||||
return validate_ip(AF_INET, name, value, error);
|
||||
case NM_BOND_OPTION_TYPE_IP6:
|
||||
nm_assert(nm_streq0(name, NM_SETTING_BOND_OPTION_NS_IP6_TARGET));
|
||||
return validate_ip(AF_INET6, name, value, error);
|
||||
case NM_BOND_OPTION_TYPE_MAC:
|
||||
success = nm_utils_hwaddr_valid(value, ETH_ALEN);
|
||||
goto handle_error;
|
||||
@@ -846,12 +863,15 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE(setting);
|
||||
int miimon;
|
||||
int arp_interval;
|
||||
int arp_missed_max;
|
||||
int num_grat_arp;
|
||||
int num_unsol_na;
|
||||
int peer_notif_delay;
|
||||
const char *mode_str;
|
||||
const char *arp_ip_target = NULL;
|
||||
const char *ns_ip6_target;
|
||||
const char *lacp_rate;
|
||||
const char *lacp_active;
|
||||
const char *primary;
|
||||
const char *s;
|
||||
NMBondMode bond_mode;
|
||||
@@ -876,6 +896,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
|
||||
miimon = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_MIIMON));
|
||||
arp_interval = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_ARP_INTERVAL));
|
||||
arp_missed_max =
|
||||
_atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX));
|
||||
num_grat_arp = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP));
|
||||
num_unsol_na = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA));
|
||||
peer_notif_delay =
|
||||
@@ -886,6 +908,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
* arp_interval conflicts [ alb, tlb ]
|
||||
* arp_interval needs arp_ip_target
|
||||
* arp_validate does not work with [ BOND_MODE_8023AD, BOND_MODE_TLB, BOND_MODE_ALB ]
|
||||
* arp_missed_max does not work with [ BOND_MODE_8023AD, BOND_MODE_TLB, BOND_MODE_ALB ]
|
||||
* downdelay needs miimon
|
||||
* updelay needs miimon
|
||||
* peer_notif_delay needs miimon enabled
|
||||
@@ -929,6 +952,17 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
if (arp_missed_max > 0) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s=%s' is incompatible with '%s > 0'"),
|
||||
NM_SETTING_BOND_OPTION_MODE,
|
||||
mode_str,
|
||||
NM_SETTING_BOND_OPTION_ARP_MISSED_MAX);
|
||||
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
primary = _bond_get_option(self, NM_SETTING_BOND_OPTION_PRIMARY);
|
||||
@@ -1056,6 +1090,21 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
}
|
||||
}
|
||||
|
||||
/* ns_ip6_target can only be used with arp_interval, and must
|
||||
* contain a comma-separated list of IPv6 addresses.
|
||||
*/
|
||||
ns_ip6_target = _bond_get_option(self, NM_SETTING_BOND_OPTION_NS_IP6_TARGET);
|
||||
if (ns_ip6_target && arp_interval == 0) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s' option requires '%s' option to be set"),
|
||||
NM_SETTING_BOND_OPTION_NS_IP6_TARGET,
|
||||
NM_SETTING_BOND_OPTION_ARP_INTERVAL);
|
||||
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lacp_rate = _bond_get_option(self, NM_SETTING_BOND_OPTION_LACP_RATE);
|
||||
if (lacp_rate && bond_mode != NM_BOND_MODE_8023AD && !NM_IN_STRSET(lacp_rate, "0", "slow")) {
|
||||
g_set_error(error,
|
||||
@@ -1068,6 +1117,18 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lacp_active = _bond_get_option(self, NM_SETTING_BOND_OPTION_LACP_ACTIVE);
|
||||
if (lacp_active && bond_mode != NM_BOND_MODE_8023AD) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s' option is only valid with mode '%s'"),
|
||||
NM_SETTING_BOND_OPTION_LACP_RATE,
|
||||
"802.3ad");
|
||||
g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)
|
||||
&& _bond_get_option(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA)
|
||||
&& num_grat_arp != num_unsol_na) {
|
||||
|
@@ -5259,6 +5259,7 @@ test_bond_meta(void)
|
||||
_A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, 0, EINVAL);
|
||||
_A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, 0, EINVAL);
|
||||
_A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, 1, 0);
|
||||
_A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, 0, 0);
|
||||
_A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, 0, 0);
|
||||
_A(_nm_setting_bond_opt_value_as_intbool, set, NM_SETTING_BOND_OPTION_USE_CARRIER, 1, 0);
|
||||
_A(_nm_setting_bond_opt_value_as_intbool,
|
||||
|
@@ -471,6 +471,7 @@ typedef enum {
|
||||
NM_BOND_OPTION_TYPE_INT,
|
||||
NM_BOND_OPTION_TYPE_BOTH,
|
||||
NM_BOND_OPTION_TYPE_IP,
|
||||
NM_BOND_OPTION_TYPE_IP6,
|
||||
NM_BOND_OPTION_TYPE_MAC,
|
||||
NM_BOND_OPTION_TYPE_IFNAME,
|
||||
} NMBondOptionType;
|
||||
|
@@ -58,6 +58,9 @@ G_BEGIN_DECLS
|
||||
#define NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB "tlb_dynamic_lb"
|
||||
#define NM_SETTING_BOND_OPTION_LP_INTERVAL "lp_interval"
|
||||
#define NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY "peer_notif_delay"
|
||||
#define NM_SETTING_BOND_OPTION_ARP_MISSED_MAX "arp_missed_max"
|
||||
#define NM_SETTING_BOND_OPTION_LACP_ACTIVE "lacp_active"
|
||||
#define NM_SETTING_BOND_OPTION_NS_IP6_TARGET "ns_ip6_target"
|
||||
|
||||
typedef struct _NMSettingBondClass NMSettingBondClass;
|
||||
|
||||
|
@@ -180,6 +180,9 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1));
|
||||
/*****************************************************************************/
|
||||
|
||||
#define IFLA_BOND_PEER_NOTIF_DELAY 28
|
||||
#define IFLA_BOND_AD_LACP_ACTIVE 29
|
||||
#define IFLA_BOND_MISSED_MAX 30
|
||||
#define IFLA_BOND_NS_IP6_TARGET 31
|
||||
|
||||
#undef IFLA_BOND_MAX
|
||||
|
||||
@@ -1606,6 +1609,9 @@ _parse_lnk_bond(const char *kind, struct nlattr *info_data)
|
||||
[IFLA_BOND_AD_ACTOR_SYSTEM] = {.minlen = sizeof(NMEtherAddr)},
|
||||
[IFLA_BOND_TLB_DYNAMIC_LB] = {.type = NLA_U8},
|
||||
[IFLA_BOND_PEER_NOTIF_DELAY] = {.type = NLA_U32},
|
||||
[IFLA_BOND_MISSED_MAX] = {.type = NLA_U8},
|
||||
[IFLA_BOND_AD_LACP_ACTIVE] = {.type = NLA_U8},
|
||||
[IFLA_BOND_NS_IP6_TARGET] = {.type = NLA_NESTED},
|
||||
};
|
||||
NMPlatformLnkBond *props;
|
||||
struct nlattr *tb[G_N_ELEMENTS(policy)];
|
||||
@@ -1660,6 +1666,19 @@ _parse_lnk_bond(const char *kind, struct nlattr *info_data)
|
||||
props->arp_ip_target[props->arp_ip_targets_num++] = nla_get_u32(attr);
|
||||
}
|
||||
}
|
||||
if (tb[IFLA_BOND_NS_IP6_TARGET]) {
|
||||
struct nlattr *attr;
|
||||
int rem;
|
||||
|
||||
nla_for_each_nested (attr, tb[IFLA_BOND_NS_IP6_TARGET], rem) {
|
||||
if (props->ns_ip6_targets_num > NM_BOND_MAX_ARP_TARGETS - 1)
|
||||
break;
|
||||
if (nla_len(attr) < sizeof(struct in6_addr))
|
||||
break;
|
||||
|
||||
props->ns_ip6_target[props->ns_ip6_targets_num++] = nla_get_in6_addr(attr);
|
||||
}
|
||||
}
|
||||
if (tb[IFLA_BOND_ARP_VALIDATE])
|
||||
props->arp_validate = nla_get_u32(tb[IFLA_BOND_ARP_VALIDATE]);
|
||||
if (tb[IFLA_BOND_ARP_ALL_TARGETS])
|
||||
@@ -1680,6 +1699,8 @@ _parse_lnk_bond(const char *kind, struct nlattr *info_data)
|
||||
props->num_grat_arp = nla_get_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]);
|
||||
if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
|
||||
props->all_ports_active = nla_get_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]);
|
||||
if (tb[IFLA_BOND_MISSED_MAX])
|
||||
props->arp_missed_max = nla_get_u8(tb[IFLA_BOND_MISSED_MAX]);
|
||||
if (tb[IFLA_BOND_MIN_LINKS])
|
||||
props->min_links = nla_get_u32(tb[IFLA_BOND_MIN_LINKS]);
|
||||
if (tb[IFLA_BOND_LP_INTERVAL])
|
||||
@@ -1688,6 +1709,10 @@ _parse_lnk_bond(const char *kind, struct nlattr *info_data)
|
||||
props->packets_per_port = nla_get_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]);
|
||||
if (tb[IFLA_BOND_AD_LACP_RATE])
|
||||
props->lacp_rate = nla_get_u8(tb[IFLA_BOND_AD_LACP_RATE]);
|
||||
if (tb[IFLA_BOND_AD_LACP_ACTIVE]) {
|
||||
props->lacp_active = nla_get_u8(tb[IFLA_BOND_AD_LACP_ACTIVE]);
|
||||
props->lacp_active_has = TRUE;
|
||||
}
|
||||
if (tb[IFLA_BOND_AD_SELECT])
|
||||
props->ad_select = nla_get_u8(tb[IFLA_BOND_AD_SELECT]);
|
||||
if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO])
|
||||
@@ -4699,6 +4724,17 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
|
||||
nla_nest_end(msg, targets);
|
||||
}
|
||||
|
||||
if (props->ns_ip6_targets_num > 0) {
|
||||
targets = nla_nest_start(msg, IFLA_BOND_NS_IP6_TARGET);
|
||||
if (!targets)
|
||||
goto nla_put_failure;
|
||||
|
||||
for (i = 0; i < props->ns_ip6_targets_num; i++)
|
||||
NLA_PUT(msg, i, sizeof(struct in6_addr), &props->ns_ip6_target[i]);
|
||||
|
||||
nla_nest_end(msg, targets);
|
||||
}
|
||||
|
||||
if (props->arp_all_targets)
|
||||
NLA_PUT_U32(msg, IFLA_BOND_ARP_ALL_TARGETS, props->arp_all_targets);
|
||||
if (props->arp_interval)
|
||||
@@ -4734,6 +4770,8 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
|
||||
&props->ad_actor_system);
|
||||
if (props->ad_select)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_AD_SELECT, props->ad_select);
|
||||
if (props->arp_missed_max)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_MISSED_MAX, props->arp_missed_max);
|
||||
|
||||
NLA_PUT_U8(msg, IFLA_BOND_ALL_SLAVES_ACTIVE, props->all_ports_active);
|
||||
|
||||
@@ -4741,6 +4779,8 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
|
||||
NLA_PUT_U8(msg, IFLA_BOND_FAIL_OVER_MAC, props->fail_over_mac);
|
||||
if (props->lacp_rate)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_AD_LACP_RATE, props->lacp_rate);
|
||||
if (props->lacp_active_has)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_AD_LACP_ACTIVE, props->lacp_active);
|
||||
if (props->num_grat_arp)
|
||||
NLA_PUT_U8(msg, IFLA_BOND_NUM_PEER_NOTIF, props->num_grat_arp);
|
||||
|
||||
|
@@ -290,6 +290,17 @@ size_t nla_memcpy(void *dst, const struct nlattr *nla, size_t dstsize);
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
static inline struct in6_addr
|
||||
nla_get_in6_addr(const struct nlattr *nla)
|
||||
{
|
||||
struct in6_addr in6;
|
||||
|
||||
nm_assert(nla_len(nla) >= sizeof(struct in6_addr));
|
||||
|
||||
nla_memcpy(&in6, nla, sizeof(in6));
|
||||
return in6;
|
||||
}
|
||||
|
||||
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data);
|
||||
|
||||
static inline int
|
||||
|
@@ -6187,6 +6187,7 @@ nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize le
|
||||
char sbuf_miimon[30];
|
||||
char sbuf_updelay[30];
|
||||
char sbuf_downdelay[30];
|
||||
char sbuf_lacp_active[30];
|
||||
char sbuf_peer_notif_delay[60];
|
||||
char sbuf_resend_igmp[30];
|
||||
char sbuf_lp_interval[30];
|
||||
@@ -6221,7 +6222,9 @@ nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize le
|
||||
" xmit_hash_policy %u"
|
||||
" num_gray_arp %u"
|
||||
" all_ports_active %u"
|
||||
" arp_missed_max %u"
|
||||
" lacp_rate %u"
|
||||
"%s" /* lacp_active */
|
||||
" ad_select %u"
|
||||
" use_carrier %d"
|
||||
"%s" /* tlb_dynamic_lb */,
|
||||
@@ -6271,7 +6274,14 @@ nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize le
|
||||
lnk->xmit_hash_policy,
|
||||
lnk->num_grat_arp,
|
||||
lnk->all_ports_active,
|
||||
lnk->arp_missed_max,
|
||||
lnk->lacp_rate,
|
||||
lnk->lacp_active_has || lnk->lacp_active != 0
|
||||
? nm_sprintf_buf(sbuf_lacp_active,
|
||||
" lacp_active%s %u",
|
||||
!lnk->lacp_active_has ? "?" : "",
|
||||
lnk->lacp_active)
|
||||
: "",
|
||||
lnk->ad_select,
|
||||
(int) lnk->use_carrier,
|
||||
lnk->tlb_dynamic_lb_has ? nm_sprintf_buf(sbuf_tlb_dynamic_lb,
|
||||
@@ -6289,6 +6299,15 @@ nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize le
|
||||
nm_strbuf_append_str(&buf, &len, nm_inet4_ntop(lnk->arp_ip_target[i], target));
|
||||
}
|
||||
}
|
||||
if (lnk->ns_ip6_targets_num > 0) {
|
||||
nm_strbuf_append_str(&buf, &len, " ns_ip6_target");
|
||||
for (i = 0; i < lnk->ns_ip6_targets_num; i++) {
|
||||
char target[INET6_ADDRSTRLEN];
|
||||
|
||||
nm_strbuf_append_c(&buf, &len, ' ');
|
||||
nm_strbuf_append_str(&buf, &len, nm_inet6_ntop(&lnk->ns_ip6_target[i], target));
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -8037,15 +8056,19 @@ nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h)
|
||||
obj->ad_actor_system,
|
||||
obj->ad_select,
|
||||
obj->all_ports_active,
|
||||
obj->arp_missed_max,
|
||||
obj->arp_ip_targets_num,
|
||||
obj->fail_over_mac,
|
||||
obj->lacp_rate,
|
||||
obj->lacp_active,
|
||||
obj->ns_ip6_targets_num,
|
||||
obj->num_grat_arp,
|
||||
obj->mode,
|
||||
obj->primary_reselect,
|
||||
obj->xmit_hash_policy,
|
||||
NM_HASH_COMBINE_BOOLS(guint16,
|
||||
obj->downdelay_has,
|
||||
obj->lacp_active_has,
|
||||
obj->lp_interval_has,
|
||||
obj->miimon_has,
|
||||
obj->peer_notif_delay_has,
|
||||
@@ -8056,12 +8079,19 @@ nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h)
|
||||
obj->use_carrier));
|
||||
|
||||
nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0]));
|
||||
nm_hash_update(h, obj->ns_ip6_target, obj->ns_ip6_targets_num * sizeof(obj->ns_ip6_target[0]));
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
|
||||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
NM_CMP_FIELD(a, b, arp_ip_targets_num);
|
||||
NM_CMP_FIELD(a, b, ns_ip6_targets_num);
|
||||
NM_CMP_FIELD_MEMCMP_LEN(a,
|
||||
b,
|
||||
ns_ip6_target,
|
||||
a->ns_ip6_targets_num * sizeof(a->ns_ip6_target[0]));
|
||||
NM_CMP_FIELD_MEMCMP_LEN(a,
|
||||
b,
|
||||
arp_ip_target,
|
||||
@@ -8083,14 +8113,16 @@ nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
|
||||
NM_CMP_FIELD_MEMCMP(a, b, ad_actor_system);
|
||||
NM_CMP_FIELD(a, b, ad_select);
|
||||
NM_CMP_FIELD(a, b, all_ports_active);
|
||||
NM_CMP_FIELD(a, b, arp_ip_targets_num);
|
||||
NM_CMP_FIELD(a, b, arp_missed_max);
|
||||
NM_CMP_FIELD(a, b, fail_over_mac);
|
||||
NM_CMP_FIELD(a, b, lacp_rate);
|
||||
NM_CMP_FIELD(a, b, lacp_active);
|
||||
NM_CMP_FIELD(a, b, num_grat_arp);
|
||||
NM_CMP_FIELD(a, b, mode);
|
||||
NM_CMP_FIELD(a, b, primary_reselect);
|
||||
NM_CMP_FIELD(a, b, xmit_hash_policy);
|
||||
NM_CMP_FIELD_BOOL(a, b, downdelay_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, lacp_active_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, lp_interval_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, miimon_has);
|
||||
NM_CMP_FIELD_BOOL(a, b, peer_notif_delay_has);
|
||||
|
@@ -764,40 +764,45 @@ extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default;
|
||||
#define NM_BOND_MAX_ARP_TARGETS 16
|
||||
|
||||
typedef struct {
|
||||
int primary;
|
||||
in_addr_t arp_ip_target[NM_BOND_MAX_ARP_TARGETS];
|
||||
guint32 arp_all_targets;
|
||||
guint32 arp_interval;
|
||||
guint32 arp_validate;
|
||||
guint32 downdelay;
|
||||
guint32 lp_interval;
|
||||
guint32 miimon;
|
||||
guint32 min_links;
|
||||
guint32 packets_per_port;
|
||||
guint32 peer_notif_delay;
|
||||
guint32 resend_igmp;
|
||||
guint32 updelay;
|
||||
guint16 ad_actor_sys_prio;
|
||||
guint16 ad_user_port_key;
|
||||
NMEtherAddr ad_actor_system;
|
||||
guint8 ad_select;
|
||||
guint8 all_ports_active;
|
||||
guint8 arp_ip_targets_num;
|
||||
guint8 fail_over_mac;
|
||||
guint8 lacp_rate;
|
||||
guint8 num_grat_arp;
|
||||
guint8 mode;
|
||||
guint8 primary_reselect;
|
||||
guint8 xmit_hash_policy;
|
||||
bool downdelay_has : 1;
|
||||
bool lp_interval_has : 1;
|
||||
bool miimon_has : 1;
|
||||
bool peer_notif_delay_has : 1;
|
||||
bool resend_igmp_has : 1;
|
||||
bool tlb_dynamic_lb : 1;
|
||||
bool tlb_dynamic_lb_has : 1;
|
||||
bool updelay_has : 1;
|
||||
bool use_carrier : 1;
|
||||
struct in6_addr ns_ip6_target[NM_BOND_MAX_ARP_TARGETS];
|
||||
int primary;
|
||||
in_addr_t arp_ip_target[NM_BOND_MAX_ARP_TARGETS];
|
||||
guint32 arp_all_targets;
|
||||
guint32 arp_interval;
|
||||
guint32 arp_validate;
|
||||
guint32 downdelay;
|
||||
guint32 lp_interval;
|
||||
guint32 miimon;
|
||||
guint32 min_links;
|
||||
guint32 packets_per_port;
|
||||
guint32 peer_notif_delay;
|
||||
guint32 resend_igmp;
|
||||
guint32 updelay;
|
||||
guint16 ad_actor_sys_prio;
|
||||
guint16 ad_user_port_key;
|
||||
NMEtherAddr ad_actor_system;
|
||||
guint8 ad_select;
|
||||
guint8 all_ports_active;
|
||||
guint8 arp_missed_max;
|
||||
guint8 arp_ip_targets_num;
|
||||
guint8 fail_over_mac;
|
||||
guint8 lacp_active;
|
||||
guint8 lacp_rate;
|
||||
guint8 ns_ip6_targets_num;
|
||||
guint8 num_grat_arp;
|
||||
guint8 mode;
|
||||
guint8 primary_reselect;
|
||||
guint8 xmit_hash_policy;
|
||||
bool downdelay_has : 1;
|
||||
bool lacp_active_has : 1;
|
||||
bool lp_interval_has : 1;
|
||||
bool miimon_has : 1;
|
||||
bool peer_notif_delay_has : 1;
|
||||
bool resend_igmp_has : 1;
|
||||
bool tlb_dynamic_lb : 1;
|
||||
bool tlb_dynamic_lb_has : 1;
|
||||
bool updelay_has : 1;
|
||||
bool use_carrier : 1;
|
||||
} _nm_alignas(NMPlatformObject) NMPlatformLnkBond;
|
||||
|
||||
typedef struct {
|
||||
|
@@ -2474,7 +2474,9 @@ _get_fcn_bond_options(ARGS_GET_FCN)
|
||||
|
||||
nm_setting_bond_get_option(s_bond, i, &key, &val);
|
||||
|
||||
if (nm_streq(key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
|
||||
if (NM_IN_STRSET(key,
|
||||
NM_SETTING_BOND_OPTION_ARP_IP_TARGET,
|
||||
NM_SETTING_BOND_OPTION_NS_IP6_TARGET)) {
|
||||
val_tmp = g_strdup(val);
|
||||
for (p = val_tmp; p && *p; p++) {
|
||||
if (*p == ',')
|
||||
@@ -2516,7 +2518,8 @@ _nm_meta_setting_bond_add_option(NMSetting *setting,
|
||||
value = nmc_bond_validate_mode(value, error);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
} else if (nm_streq(name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
|
||||
} else if (nm_streq(name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)
|
||||
|| nm_streq(name, NM_SETTING_BOND_OPTION_NS_IP6_TARGET)) {
|
||||
value = tmp_value = g_strdup(value);
|
||||
for (p = tmp_value; p && *p; p++)
|
||||
if (*p == ' ')
|
||||
|
@@ -141,7 +141,7 @@ bond_options_changed(GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||
nmt_newt_entry_set_text(priv->arp_interval, val ?: "0");
|
||||
|
||||
val = nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
|
||||
ips = nm_utils_bond_option_arp_ip_targets_split(val);
|
||||
ips = nm_utils_bond_option_ip_split(val);
|
||||
g_object_set(G_OBJECT(priv->arp_ip_target),
|
||||
"strings",
|
||||
ips ?: NM_PTRARRAY_EMPTY(const char *),
|
||||
|
Reference in New Issue
Block a user