Commit 3a755cd8 authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

bonding: add new option lacp_active

Add an option lacp_active, which is similar with team's runner.active.
This option specifies whether to send LACPDU frames periodically. If set
on, the LACPDU frames are sent along with the configured lacp_rate
setting. If set off, the LACPDU frames acts as "speak when spoken to".

Note, the LACPDU state frames still will be sent when init or unbind port.

v2: remove module parameter
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2414d628
...@@ -501,6 +501,18 @@ fail_over_mac ...@@ -501,6 +501,18 @@ fail_over_mac
This option was added in bonding version 3.2.0. The "follow" This option was added in bonding version 3.2.0. The "follow"
policy was added in bonding version 3.3.0. policy was added in bonding version 3.3.0.
lacp_active
Option specifying whether to send LACPDU frames periodically.
off or 0
LACPDU frames acts as "speak when spoken to".
on or 1
LACPDU frames are sent along the configured links
periodically. See lacp_rate for more details.
The default is on.
lacp_rate lacp_rate
Option specifying the rate in which we'll ask our link partner Option specifying the rate in which we'll ask our link partner
......
...@@ -96,7 +96,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker); ...@@ -96,7 +96,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker);
static void ad_mux_machine(struct port *port, bool *update_slave_arr); static void ad_mux_machine(struct port *port, bool *update_slave_arr);
static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port); static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);
static void ad_tx_machine(struct port *port); static void ad_tx_machine(struct port *port);
static void ad_periodic_machine(struct port *port); static void ad_periodic_machine(struct port *port, struct bond_params bond_params);
static void ad_port_selection_logic(struct port *port, bool *update_slave_arr); static void ad_port_selection_logic(struct port *port, bool *update_slave_arr);
static void ad_agg_selection_logic(struct aggregator *aggregator, static void ad_agg_selection_logic(struct aggregator *aggregator,
bool *update_slave_arr); bool *update_slave_arr);
...@@ -1294,10 +1294,11 @@ static void ad_tx_machine(struct port *port) ...@@ -1294,10 +1294,11 @@ static void ad_tx_machine(struct port *port)
/** /**
* ad_periodic_machine - handle a port's periodic state machine * ad_periodic_machine - handle a port's periodic state machine
* @port: the port we're looking at * @port: the port we're looking at
* @bond_params: bond parameters we will use
* *
* Turn ntt flag on priodically to perform periodic transmission of lacpdu's. * Turn ntt flag on priodically to perform periodic transmission of lacpdu's.
*/ */
static void ad_periodic_machine(struct port *port) static void ad_periodic_machine(struct port *port, struct bond_params bond_params)
{ {
periodic_states_t last_state; periodic_states_t last_state;
...@@ -1306,8 +1307,8 @@ static void ad_periodic_machine(struct port *port) ...@@ -1306,8 +1307,8 @@ static void ad_periodic_machine(struct port *port)
/* check if port was reinitialized */ /* check if port was reinitialized */
if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) || if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) ||
(!(port->actor_oper_port_state & LACP_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & LACP_STATE_LACP_ACTIVITY)) (!(port->actor_oper_port_state & LACP_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & LACP_STATE_LACP_ACTIVITY)) ||
) { !bond_params.lacp_active) {
port->sm_periodic_state = AD_NO_PERIODIC; port->sm_periodic_state = AD_NO_PERIODIC;
} }
/* check if state machine should change state */ /* check if state machine should change state */
...@@ -2341,7 +2342,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ...@@ -2341,7 +2342,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
} }
ad_rx_machine(NULL, port); ad_rx_machine(NULL, port);
ad_periodic_machine(port); ad_periodic_machine(port, bond->params);
ad_port_selection_logic(port, &update_slave_arr); ad_port_selection_logic(port, &update_slave_arr);
ad_mux_machine(port, &update_slave_arr); ad_mux_machine(port, &update_slave_arr);
ad_tx_machine(port); ad_tx_machine(port);
......
...@@ -5478,6 +5478,7 @@ static int bond_check_params(struct bond_params *params) ...@@ -5478,6 +5478,7 @@ static int bond_check_params(struct bond_params *params)
params->downdelay = downdelay; params->downdelay = downdelay;
params->peer_notif_delay = 0; params->peer_notif_delay = 0;
params->use_carrier = use_carrier; params->use_carrier = use_carrier;
params->lacp_active = 1;
params->lacp_fast = lacp_fast; params->lacp_fast = lacp_fast;
params->primary[0] = 0; params->primary[0] = 0;
params->primary_reselect = primary_reselect_value; params->primary_reselect = primary_reselect_value;
......
...@@ -100,6 +100,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { ...@@ -100,6 +100,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
[IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 }, [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
[IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 }, [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
[IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 }, [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
[IFLA_BOND_AD_LACP_ACTIVE] = { .type = NLA_U8 },
[IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 }, [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
[IFLA_BOND_AD_SELECT] = { .type = NLA_U8 }, [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
[IFLA_BOND_AD_INFO] = { .type = NLA_NESTED }, [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
...@@ -387,6 +388,16 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], ...@@ -387,6 +388,16 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
if (err) if (err)
return err; return err;
} }
if (data[IFLA_BOND_AD_LACP_ACTIVE]) {
int lacp_active = nla_get_u8(data[IFLA_BOND_AD_LACP_ACTIVE]);
bond_opt_initval(&newval, lacp_active);
err = __bond_opt_set(bond, BOND_OPT_LACP_ACTIVE, &newval);
if (err)
return err;
}
if (data[IFLA_BOND_AD_LACP_RATE]) { if (data[IFLA_BOND_AD_LACP_RATE]) {
int lacp_rate = int lacp_rate =
nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]); nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]);
...@@ -490,6 +501,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) ...@@ -490,6 +501,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIN_LINKS */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIN_LINKS */
nla_total_size(sizeof(u32)) + /* IFLA_BOND_LP_INTERVAL */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_LP_INTERVAL */
nla_total_size(sizeof(u32)) + /* IFLA_BOND_PACKETS_PER_SLAVE */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_PACKETS_PER_SLAVE */
nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_ACTIVE */
nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_RATE */ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_RATE */
nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_SELECT */ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_SELECT */
nla_total_size(sizeof(struct nlattr)) + /* IFLA_BOND_AD_INFO */ nla_total_size(sizeof(struct nlattr)) + /* IFLA_BOND_AD_INFO */
...@@ -622,6 +634,10 @@ static int bond_fill_info(struct sk_buff *skb, ...@@ -622,6 +634,10 @@ static int bond_fill_info(struct sk_buff *skb,
packets_per_slave)) packets_per_slave))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_u8(skb, IFLA_BOND_AD_LACP_ACTIVE,
bond->params.lacp_active))
goto nla_put_failure;
if (nla_put_u8(skb, IFLA_BOND_AD_LACP_RATE, if (nla_put_u8(skb, IFLA_BOND_AD_LACP_RATE,
bond->params.lacp_fast)) bond->params.lacp_fast))
goto nla_put_failure; goto nla_put_failure;
......
...@@ -58,6 +58,8 @@ static int bond_option_lp_interval_set(struct bonding *bond, ...@@ -58,6 +58,8 @@ static int bond_option_lp_interval_set(struct bonding *bond,
const struct bond_opt_value *newval); const struct bond_opt_value *newval);
static int bond_option_pps_set(struct bonding *bond, static int bond_option_pps_set(struct bonding *bond,
const struct bond_opt_value *newval); const struct bond_opt_value *newval);
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, static int bond_option_lacp_rate_set(struct bonding *bond,
const struct bond_opt_value *newval); const struct bond_opt_value *newval);
static int bond_option_ad_select_set(struct bonding *bond, static int bond_option_ad_select_set(struct bonding *bond,
...@@ -135,6 +137,12 @@ static const struct bond_opt_value bond_intmax_tbl[] = { ...@@ -135,6 +137,12 @@ static const struct bond_opt_value bond_intmax_tbl[] = {
{ NULL, -1, 0} { NULL, -1, 0}
}; };
static const struct bond_opt_value bond_lacp_active[] = {
{ "off", 0, 0},
{ "on", 1, BOND_VALFLAG_DEFAULT},
{ NULL, -1, 0}
};
static const struct bond_opt_value bond_lacp_rate_tbl[] = { static const struct bond_opt_value bond_lacp_rate_tbl[] = {
{ "slow", AD_LACP_SLOW, 0}, { "slow", AD_LACP_SLOW, 0},
{ "fast", AD_LACP_FAST, 0}, { "fast", AD_LACP_FAST, 0},
...@@ -283,6 +291,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { ...@@ -283,6 +291,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
.values = bond_intmax_tbl, .values = bond_intmax_tbl,
.set = bond_option_updelay_set .set = bond_option_updelay_set
}, },
[BOND_OPT_LACP_ACTIVE] = {
.id = BOND_OPT_LACP_ACTIVE,
.name = "lacp_active",
.desc = "Send LACPDU frames with configured lacp rate or acts as speak when spoken to",
.flags = BOND_OPTFLAG_IFDOWN,
.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
.values = bond_lacp_active,
.set = bond_option_lacp_active_set
},
[BOND_OPT_LACP_RATE] = { [BOND_OPT_LACP_RATE] = {
.id = BOND_OPT_LACP_RATE, .id = BOND_OPT_LACP_RATE,
.name = "lacp_rate", .name = "lacp_rate",
...@@ -1333,6 +1350,16 @@ static int bond_option_pps_set(struct bonding *bond, ...@@ -1333,6 +1350,16 @@ static int bond_option_pps_set(struct bonding *bond,
return 0; return 0;
} }
static int bond_option_lacp_active_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
netdev_dbg(bond->dev, "Setting LACP active to %s (%llu)\n",
newval->string, newval->value);
bond->params.lacp_active = newval->value;
return 0;
}
static int bond_option_lacp_rate_set(struct bonding *bond, static int bond_option_lacp_rate_set(struct bonding *bond,
const struct bond_opt_value *newval) const struct bond_opt_value *newval)
{ {
......
...@@ -133,6 +133,8 @@ static void bond_info_show_master(struct seq_file *seq) ...@@ -133,6 +133,8 @@ static void bond_info_show_master(struct seq_file *seq)
struct ad_info ad_info; struct ad_info ad_info;
seq_puts(seq, "\n802.3ad info\n"); seq_puts(seq, "\n802.3ad info\n");
seq_printf(seq, "LACP active: %s\n",
(bond->params.lacp_active) ? "on" : "off");
seq_printf(seq, "LACP rate: %s\n", seq_printf(seq, "LACP rate: %s\n",
(bond->params.lacp_fast) ? "fast" : "slow"); (bond->params.lacp_fast) ? "fast" : "slow");
seq_printf(seq, "Min links: %d\n", bond->params.min_links); seq_printf(seq, "Min links: %d\n", bond->params.min_links);
......
...@@ -339,10 +339,24 @@ static ssize_t bonding_show_peer_notif_delay(struct device *d, ...@@ -339,10 +339,24 @@ static ssize_t bonding_show_peer_notif_delay(struct device *d,
static DEVICE_ATTR(peer_notif_delay, 0644, static DEVICE_ATTR(peer_notif_delay, 0644,
bonding_show_peer_notif_delay, bonding_sysfs_store_option); bonding_show_peer_notif_delay, bonding_sysfs_store_option);
/* Show the LACP interval. */ /* Show the LACP activity and interval. */
static ssize_t bonding_show_lacp(struct device *d, static ssize_t bonding_show_lacp_active(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{
struct bonding *bond = to_bond(d);
const struct bond_opt_value *val;
val = bond_opt_get_val(BOND_OPT_LACP_ACTIVE, bond->params.lacp_active);
return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_active);
}
static DEVICE_ATTR(lacp_active, 0644,
bonding_show_lacp_active, bonding_sysfs_store_option);
static ssize_t bonding_show_lacp_rate(struct device *d,
struct device_attribute *attr,
char *buf)
{ {
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
const struct bond_opt_value *val; const struct bond_opt_value *val;
...@@ -352,7 +366,7 @@ static ssize_t bonding_show_lacp(struct device *d, ...@@ -352,7 +366,7 @@ static ssize_t bonding_show_lacp(struct device *d,
return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast); return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast);
} }
static DEVICE_ATTR(lacp_rate, 0644, static DEVICE_ATTR(lacp_rate, 0644,
bonding_show_lacp, bonding_sysfs_store_option); bonding_show_lacp_rate, bonding_sysfs_store_option);
static ssize_t bonding_show_min_links(struct device *d, static ssize_t bonding_show_min_links(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
...@@ -738,6 +752,7 @@ static struct attribute *per_bond_attrs[] = { ...@@ -738,6 +752,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_downdelay.attr, &dev_attr_downdelay.attr,
&dev_attr_updelay.attr, &dev_attr_updelay.attr,
&dev_attr_peer_notif_delay.attr, &dev_attr_peer_notif_delay.attr,
&dev_attr_lacp_active.attr,
&dev_attr_lacp_rate.attr, &dev_attr_lacp_rate.attr,
&dev_attr_ad_select.attr, &dev_attr_ad_select.attr,
&dev_attr_xmit_hash_policy.attr, &dev_attr_xmit_hash_policy.attr,
......
...@@ -303,6 +303,7 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond, ...@@ -303,6 +303,7 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond,
int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
struct slave *slave); struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond); int bond_3ad_set_carrier(struct bonding *bond);
void bond_3ad_update_lacp_active(struct bonding *bond);
void bond_3ad_update_lacp_rate(struct bonding *bond); void bond_3ad_update_lacp_rate(struct bonding *bond);
void bond_3ad_update_ad_actor_settings(struct bonding *bond); void bond_3ad_update_ad_actor_settings(struct bonding *bond);
int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats); int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats);
......
...@@ -64,6 +64,7 @@ enum { ...@@ -64,6 +64,7 @@ enum {
BOND_OPT_AD_USER_PORT_KEY, BOND_OPT_AD_USER_PORT_KEY,
BOND_OPT_NUM_PEER_NOTIF_ALIAS, BOND_OPT_NUM_PEER_NOTIF_ALIAS,
BOND_OPT_PEER_NOTIF_DELAY, BOND_OPT_PEER_NOTIF_DELAY,
BOND_OPT_LACP_ACTIVE,
BOND_OPT_LAST BOND_OPT_LAST
}; };
......
...@@ -129,6 +129,7 @@ struct bond_params { ...@@ -129,6 +129,7 @@ struct bond_params {
int updelay; int updelay;
int downdelay; int downdelay;
int peer_notif_delay; int peer_notif_delay;
int lacp_active;
int lacp_fast; int lacp_fast;
unsigned int min_links; unsigned int min_links;
int ad_select; int ad_select;
......
...@@ -855,6 +855,7 @@ enum { ...@@ -855,6 +855,7 @@ enum {
IFLA_BOND_AD_ACTOR_SYSTEM, IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB, IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY, IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
__IFLA_BOND_MAX, __IFLA_BOND_MAX,
}; };
......
...@@ -653,6 +653,7 @@ enum { ...@@ -653,6 +653,7 @@ enum {
IFLA_BOND_AD_ACTOR_SYSTEM, IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB, IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY, IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
__IFLA_BOND_MAX, __IFLA_BOND_MAX,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment