mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
bonding: 3ad: add lacp_strict configuration knob
When an 802.3ad (LACP) bonding interface has no slaves in the
collecting/distributing state, the bonding master still reports
carrier as up as long as at least 'min_links' slaves have carrier.
In this situation, only one slave is effectively used for TX/RX,
while traffic received on other slaves is dropped. Upper-layer
daemons therefore consider the interface operational, even though
traffic may be blackholed if the lack of LACP negotiation means
the partner is not ready to deal with traffic.
Introduce a configuration knob to control this behavior. It allows
the bonding master to assert carrier only when at least 'min_links'
slaves are in Collecting_Distributing state.
The default mode preserves the existing behavior. This patch only
introduces the knob; its behavior is implemented in the subsequent
commit.
Fixes: 655f8919d5 ("bonding: add min links parameter to 802.3ad")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Acked-by: Jay Vosburgh <jv@jvosburgh.net>
Link: https://patch.msgid.link/20260603150331.1919611-4-louis.scalbert@6wind.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
363037983c
commit
32b0b89533
|
|
@ -1356,6 +1356,9 @@ attribute-sets:
|
|||
-
|
||||
name: broadcast-neigh
|
||||
type: u8
|
||||
-
|
||||
name: lacp-strict
|
||||
type: u8
|
||||
-
|
||||
name: bond-ad-info-attrs
|
||||
name-prefix: ifla-bond-ad-info-
|
||||
|
|
|
|||
|
|
@ -619,6 +619,29 @@ min_links
|
|||
aggregator cannot be active without at least one available link,
|
||||
setting this option to 0 or to 1 has the exact same effect.
|
||||
|
||||
lacp_strict
|
||||
|
||||
Specifies the fallback behavior of a bonding when LACP negotiation
|
||||
fails on all slave links, i.e. when no slave is in the
|
||||
Collecting_Distributing state, while at least `min_links` link still
|
||||
reports carrier up.
|
||||
|
||||
This option is only applicable to 802.3ad mode (mode 4).
|
||||
|
||||
Valid values are:
|
||||
|
||||
off or 0
|
||||
One interface of the bond is selected to be active, in order to
|
||||
facilitate communication with peer devices that do not implement
|
||||
LACP.
|
||||
|
||||
on or 1
|
||||
Interfaces are only permitted to be made active if they have an
|
||||
active LACP partner and have successfully reached
|
||||
Collecting_Distributing state.
|
||||
|
||||
The default value is 0 (off).
|
||||
|
||||
mode
|
||||
|
||||
Specifies one of the bonding policies. The default is
|
||||
|
|
|
|||
|
|
@ -6457,6 +6457,7 @@ static int __init bond_check_params(struct bond_params *params)
|
|||
params->ad_user_port_key = ad_user_port_key;
|
||||
params->coupled_control = 1;
|
||||
params->broadcast_neighbor = 0;
|
||||
params->lacp_strict = 0;
|
||||
if (packets_per_slave > 0) {
|
||||
params->reciprocal_packets_per_slave =
|
||||
reciprocal_value(packets_per_slave);
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
|
|||
[IFLA_BOND_NS_IP6_TARGET] = { .type = NLA_NESTED },
|
||||
[IFLA_BOND_COUPLED_CONTROL] = { .type = NLA_U8 },
|
||||
[IFLA_BOND_BROADCAST_NEIGH] = { .type = NLA_U8 },
|
||||
[IFLA_BOND_LACP_STRICT] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
|
||||
|
|
@ -599,6 +600,16 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
|||
return err;
|
||||
}
|
||||
|
||||
if (data[IFLA_BOND_LACP_STRICT]) {
|
||||
int fallback_mode = nla_get_u8(data[IFLA_BOND_LACP_STRICT]);
|
||||
|
||||
bond_opt_initval(&newval, fallback_mode);
|
||||
err = __bond_opt_set(bond, BOND_OPT_LACP_STRICT, &newval,
|
||||
data[IFLA_BOND_LACP_STRICT], extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -671,6 +682,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
|
|||
nla_total_size(sizeof(struct in6_addr)) * BOND_MAX_NS_TARGETS +
|
||||
nla_total_size(sizeof(u8)) + /* IFLA_BOND_COUPLED_CONTROL */
|
||||
nla_total_size(sizeof(u8)) + /* IFLA_BOND_BROADCAST_NEIGH */
|
||||
nla_total_size(sizeof(u8)) + /* IFLA_BOND_LACP_STRICT */
|
||||
0;
|
||||
}
|
||||
|
||||
|
|
@ -838,6 +850,10 @@ static int bond_fill_info(struct sk_buff *skb,
|
|||
bond->params.broadcast_neighbor))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(skb, IFLA_BOND_LACP_STRICT,
|
||||
bond->params.lacp_strict))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||
struct ad_info info;
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ static int bond_option_lacp_active_set(struct bonding *bond,
|
|||
const struct bond_opt_value *newval);
|
||||
static int bond_option_lacp_rate_set(struct bonding *bond,
|
||||
const struct bond_opt_value *newval);
|
||||
static int bond_option_lacp_strict_set(struct bonding *bond,
|
||||
const struct bond_opt_value *newval);
|
||||
static int bond_option_ad_select_set(struct bonding *bond,
|
||||
const struct bond_opt_value *newval);
|
||||
static int bond_option_queue_id_set(struct bonding *bond,
|
||||
|
|
@ -162,6 +164,12 @@ static const struct bond_opt_value bond_lacp_rate_tbl[] = {
|
|||
{ NULL, -1, 0},
|
||||
};
|
||||
|
||||
static const struct bond_opt_value bond_lacp_strict_tbl[] = {
|
||||
{ "off", 0, BOND_VALFLAG_DEFAULT},
|
||||
{ "on", 1, 0},
|
||||
{ NULL, -1, 0 }
|
||||
};
|
||||
|
||||
static const struct bond_opt_value bond_ad_select_tbl[] = {
|
||||
{ "stable", BOND_AD_STABLE, BOND_VALFLAG_DEFAULT},
|
||||
{ "bandwidth", BOND_AD_BANDWIDTH, 0},
|
||||
|
|
@ -363,6 +371,14 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
|
|||
.values = bond_lacp_rate_tbl,
|
||||
.set = bond_option_lacp_rate_set
|
||||
},
|
||||
[BOND_OPT_LACP_STRICT] = {
|
||||
.id = BOND_OPT_LACP_STRICT,
|
||||
.name = "lacp_strict",
|
||||
.desc = "Define the LACP fallback mode when no slaves have negotiated",
|
||||
.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
|
||||
.values = bond_lacp_strict_tbl,
|
||||
.set = bond_option_lacp_strict_set
|
||||
},
|
||||
[BOND_OPT_MINLINKS] = {
|
||||
.id = BOND_OPT_MINLINKS,
|
||||
.name = "min_links",
|
||||
|
|
@ -1685,6 +1701,16 @@ static int bond_option_lacp_rate_set(struct bonding *bond,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bond_option_lacp_strict_set(struct bonding *bond,
|
||||
const struct bond_opt_value *newval)
|
||||
{
|
||||
netdev_dbg(bond->dev, "Setting LACP fallback to %s (%llu)\n",
|
||||
newval->string, newval->value);
|
||||
bond->params.lacp_strict = newval->value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bond_option_ad_select_set(struct bonding *bond,
|
||||
const struct bond_opt_value *newval)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ enum {
|
|||
BOND_OPT_COUPLED_CONTROL,
|
||||
BOND_OPT_BROADCAST_NEIGH,
|
||||
BOND_OPT_ACTOR_PORT_PRIO,
|
||||
BOND_OPT_LACP_STRICT,
|
||||
BOND_OPT_LAST
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ struct bond_params {
|
|||
int peer_notif_delay;
|
||||
int lacp_active;
|
||||
int lacp_fast;
|
||||
int lacp_strict;
|
||||
unsigned int min_links;
|
||||
int ad_select;
|
||||
char primary[IFNAMSIZ];
|
||||
|
|
|
|||
|
|
@ -1603,6 +1603,7 @@ enum {
|
|||
IFLA_BOND_NS_IP6_TARGET,
|
||||
IFLA_BOND_COUPLED_CONTROL,
|
||||
IFLA_BOND_BROADCAST_NEIGH,
|
||||
IFLA_BOND_LACP_STRICT,
|
||||
__IFLA_BOND_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1527,6 +1527,7 @@ enum {
|
|||
IFLA_BOND_NS_IP6_TARGET,
|
||||
IFLA_BOND_COUPLED_CONTROL,
|
||||
IFLA_BOND_BROADCAST_NEIGH,
|
||||
IFLA_BOND_LACP_STRICT,
|
||||
__IFLA_BOND_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user