merge: branch 'ff/new_bond_options'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1553
This commit is contained in:
Fernando Fernandez Mancera
2023-03-06 17:44:31 +01:00
13 changed files with 273 additions and 52 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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 == ' ')

View File

@@ -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 *),