Skip to content

Commit

Permalink
Bonding: add arp_missed_max option
Browse files Browse the repository at this point in the history
Currently, we use hard code number to verify if we are in the
arp_interval timeslice. But some user may want to reduce/extend
the verify timeslice. With the similar team option 'missed_max'
the uers could change that number based on their own environment.

Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hangbin Liu authored and David S. Miller committed Nov 30, 2021
1 parent 2680ce7 commit 5944b5a
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 8 deletions.
11 changes: 11 additions & 0 deletions Documentation/networking/bonding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,17 @@ arp_all_targets
consider the slave up only when all of the arp_ip_targets
are reachable

arp_missed_max

Specifies the number of arp_interval monitor checks that must
fail in order for an interface to be marked down by the ARP monitor.

In order to provide orderly failover semantics, backup interfaces
are permitted an extra monitor check (i.e., they must fail
arp_missed_max + 1 times before being marked down).

The default value is 2, and the allowable range is 1 - 255.

downdelay

Specifies the time, in milliseconds, to wait before disabling
Expand Down
17 changes: 9 additions & 8 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3129,8 +3129,8 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
* when the source ip is 0, so don't take the link down
* if we don't know our ip yet
*/
if (!bond_time_in_interval(bond, trans_start, 2) ||
!bond_time_in_interval(bond, slave->last_rx, 2)) {
if (!bond_time_in_interval(bond, trans_start, bond->params.missed_max) ||
!bond_time_in_interval(bond, slave->last_rx, bond->params.missed_max)) {

bond_propose_link_state(slave, BOND_LINK_DOWN);
slave_state_changed = 1;
Expand Down Expand Up @@ -3224,7 +3224,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)

/* Backup slave is down if:
* - No current_arp_slave AND
* - more than 3*delta since last receive AND
* - more than (missed_max+1)*delta since last receive AND
* - the bond has an IP address
*
* Note: a non-null current_arp_slave indicates
Expand All @@ -3236,20 +3236,20 @@ static int bond_ab_arp_inspect(struct bonding *bond)
*/
if (!bond_is_active_slave(slave) &&
!rcu_access_pointer(bond->current_arp_slave) &&
!bond_time_in_interval(bond, last_rx, 3)) {
!bond_time_in_interval(bond, last_rx, bond->params.missed_max + 1)) {
bond_propose_link_state(slave, BOND_LINK_DOWN);
commit++;
}

/* Active slave is down if:
* - more than 2*delta since transmitting OR
* - (more than 2*delta since receive AND
* - more than missed_max*delta since transmitting OR
* - (more than missed_max*delta since receive AND
* the bond has an IP address)
*/
trans_start = dev_trans_start(slave->dev);
if (bond_is_active_slave(slave) &&
(!bond_time_in_interval(bond, trans_start, 2) ||
!bond_time_in_interval(bond, last_rx, 2))) {
(!bond_time_in_interval(bond, trans_start, bond->params.missed_max) ||
!bond_time_in_interval(bond, last_rx, bond->params.missed_max))) {
bond_propose_link_state(slave, BOND_LINK_DOWN);
commit++;
}
Expand Down Expand Up @@ -5822,6 +5822,7 @@ static int bond_check_params(struct bond_params *params)
params->arp_interval = arp_interval;
params->arp_validate = arp_validate_value;
params->arp_all_targets = arp_all_targets_value;
params->missed_max = 2;
params->updelay = updelay;
params->downdelay = downdelay;
params->peer_notif_delay = 0;
Expand Down
15 changes: 15 additions & 0 deletions drivers/net/bonding/bond_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
.len = ETH_ALEN },
[IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NLA_U8 },
[IFLA_BOND_PEER_NOTIF_DELAY] = { .type = NLA_U32 },
[IFLA_BOND_MISSED_MAX] = { .type = NLA_U8 },
};

static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
Expand Down Expand Up @@ -453,6 +454,15 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
return err;
}

if (data[IFLA_BOND_MISSED_MAX]) {
int missed_max = nla_get_u8(data[IFLA_BOND_MISSED_MAX]);

bond_opt_initval(&newval, missed_max);
err = __bond_opt_set(bond, BOND_OPT_MISSED_MAX, &newval);
if (err)
return err;
}

return 0;
}

Expand Down Expand Up @@ -515,6 +525,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_ACTOR_SYSTEM */
nla_total_size(sizeof(u8)) + /* IFLA_BOND_TLB_DYNAMIC_LB */
nla_total_size(sizeof(u32)) + /* IFLA_BOND_PEER_NOTIF_DELAY */
nla_total_size(sizeof(u8)) + /* IFLA_BOND_MISSED_MAX */
0;
}

Expand Down Expand Up @@ -650,6 +661,10 @@ static int bond_fill_info(struct sk_buff *skb,
bond->params.tlb_dynamic_lb))
goto nla_put_failure;

if (nla_put_u8(skb, IFLA_BOND_MISSED_MAX,
bond->params.missed_max))
goto nla_put_failure;

if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info info;

Expand Down
28 changes: 28 additions & 0 deletions drivers/net/bonding/bond_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static int bond_option_ad_actor_system_set(struct bonding *bond,
const struct bond_opt_value *newval);
static int bond_option_ad_user_port_key_set(struct bonding *bond,
const struct bond_opt_value *newval);
static int bond_option_missed_max_set(struct bonding *bond,
const struct bond_opt_value *newval);


static const struct bond_opt_value bond_mode_tbl[] = {
Expand Down Expand Up @@ -213,6 +215,13 @@ static const struct bond_opt_value bond_ad_user_port_key_tbl[] = {
{ NULL, -1, 0},
};

static const struct bond_opt_value bond_missed_max_tbl[] = {
{ "minval", 1, BOND_VALFLAG_MIN},
{ "maxval", 255, BOND_VALFLAG_MAX},
{ "default", 2, BOND_VALFLAG_DEFAULT},
{ NULL, -1, 0},
};

static const struct bond_option bond_opts[BOND_OPT_LAST] = {
[BOND_OPT_MODE] = {
.id = BOND_OPT_MODE,
Expand Down Expand Up @@ -270,6 +279,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
.values = bond_intmax_tbl,
.set = bond_option_arp_interval_set
},
[BOND_OPT_MISSED_MAX] = {
.id = BOND_OPT_MISSED_MAX,
.name = "arp_missed_max",
.desc = "Maximum number of missed ARP interval",
.unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) |
BIT(BOND_MODE_ALB),
.values = bond_missed_max_tbl,
.set = bond_option_missed_max_set
},
[BOND_OPT_ARP_TARGETS] = {
.id = BOND_OPT_ARP_TARGETS,
.name = "arp_ip_target",
Expand Down Expand Up @@ -1186,6 +1204,16 @@ static int bond_option_arp_all_targets_set(struct bonding *bond,
return 0;
}

static int bond_option_missed_max_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
netdev_dbg(bond->dev, "Setting missed max to %s (%llu)\n",
newval->string, newval->value);
bond->params.missed_max = newval->value;

return 0;
}

static int bond_option_primary_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/bonding/bond_procfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ static void bond_info_show_master(struct seq_file *seq)

seq_printf(seq, "ARP Polling Interval (ms): %d\n",
bond->params.arp_interval);
seq_printf(seq, "ARP Missed Max: %u\n",
bond->params.missed_max);

seq_printf(seq, "ARP IP target/s (n.n.n.n form):");

Expand Down
13 changes: 13 additions & 0 deletions drivers/net/bonding/bond_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,18 @@ static ssize_t bonding_show_arp_targets(struct device *d,
static DEVICE_ATTR(arp_ip_target, 0644,
bonding_show_arp_targets, bonding_sysfs_store_option);

/* Show the arp missed max. */
static ssize_t bonding_show_missed_max(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct bonding *bond = to_bond(d);

return sprintf(buf, "%u\n", bond->params.missed_max);
}
static DEVICE_ATTR(arp_missed_max, 0644,
bonding_show_missed_max, bonding_sysfs_store_option);

/* Show the up and down delays. */
static ssize_t bonding_show_downdelay(struct device *d,
struct device_attribute *attr,
Expand Down Expand Up @@ -779,6 +791,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_ad_actor_sys_prio.attr,
&dev_attr_ad_actor_system.attr,
&dev_attr_ad_user_port_key.attr,
&dev_attr_arp_missed_max.attr,
NULL,
};

Expand Down
1 change: 1 addition & 0 deletions include/net/bond_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ enum {
BOND_OPT_NUM_PEER_NOTIF_ALIAS,
BOND_OPT_PEER_NOTIF_DELAY,
BOND_OPT_LACP_ACTIVE,
BOND_OPT_MISSED_MAX,
BOND_OPT_LAST
};

Expand Down
1 change: 1 addition & 0 deletions include/net/bonding.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct bond_params {
int xmit_policy;
int miimon;
u8 num_peer_notif;
u8 missed_max;
int arp_interval;
int arp_validate;
int arp_all_targets;
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ enum {
IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
IFLA_BOND_MISSED_MAX,
__IFLA_BOND_MAX,
};

Expand Down
1 change: 1 addition & 0 deletions tools/include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ enum {
IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
IFLA_BOND_MISSED_MAX,
__IFLA_BOND_MAX,
};

Expand Down

0 comments on commit 5944b5a

Please sign in to comment.