Bonding: add arp_missed_max option
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>
This commit is contained in:
parent
2680ce7fc9
commit
5944b5abd8
10 changed files with 82 additions and 8 deletions
|
@ -421,6 +421,17 @@ arp_all_targets
|
||||||
consider the slave up only when all of the arp_ip_targets
|
consider the slave up only when all of the arp_ip_targets
|
||||||
are reachable
|
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
|
downdelay
|
||||||
|
|
||||||
Specifies the time, in milliseconds, to wait before disabling
|
Specifies the time, in milliseconds, to wait before disabling
|
||||||
|
|
|
@ -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
|
* when the source ip is 0, so don't take the link down
|
||||||
* if we don't know our ip yet
|
* if we don't know our ip yet
|
||||||
*/
|
*/
|
||||||
if (!bond_time_in_interval(bond, trans_start, 2) ||
|
if (!bond_time_in_interval(bond, trans_start, bond->params.missed_max) ||
|
||||||
!bond_time_in_interval(bond, slave->last_rx, 2)) {
|
!bond_time_in_interval(bond, slave->last_rx, bond->params.missed_max)) {
|
||||||
|
|
||||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||||
slave_state_changed = 1;
|
slave_state_changed = 1;
|
||||||
|
@ -3224,7 +3224,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||||
|
|
||||||
/* Backup slave is down if:
|
/* Backup slave is down if:
|
||||||
* - No current_arp_slave AND
|
* - 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
|
* - the bond has an IP address
|
||||||
*
|
*
|
||||||
* Note: a non-null current_arp_slave indicates
|
* Note: a non-null current_arp_slave indicates
|
||||||
|
@ -3236,20 +3236,20 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||||
*/
|
*/
|
||||||
if (!bond_is_active_slave(slave) &&
|
if (!bond_is_active_slave(slave) &&
|
||||||
!rcu_access_pointer(bond->current_arp_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);
|
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||||
commit++;
|
commit++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Active slave is down if:
|
/* Active slave is down if:
|
||||||
* - more than 2*delta since transmitting OR
|
* - more than missed_max*delta since transmitting OR
|
||||||
* - (more than 2*delta since receive AND
|
* - (more than missed_max*delta since receive AND
|
||||||
* the bond has an IP address)
|
* the bond has an IP address)
|
||||||
*/
|
*/
|
||||||
trans_start = dev_trans_start(slave->dev);
|
trans_start = dev_trans_start(slave->dev);
|
||||||
if (bond_is_active_slave(slave) &&
|
if (bond_is_active_slave(slave) &&
|
||||||
(!bond_time_in_interval(bond, trans_start, 2) ||
|
(!bond_time_in_interval(bond, trans_start, bond->params.missed_max) ||
|
||||||
!bond_time_in_interval(bond, last_rx, 2))) {
|
!bond_time_in_interval(bond, last_rx, bond->params.missed_max))) {
|
||||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||||
commit++;
|
commit++;
|
||||||
}
|
}
|
||||||
|
@ -5822,6 +5822,7 @@ static int bond_check_params(struct bond_params *params)
|
||||||
params->arp_interval = arp_interval;
|
params->arp_interval = arp_interval;
|
||||||
params->arp_validate = arp_validate_value;
|
params->arp_validate = arp_validate_value;
|
||||||
params->arp_all_targets = arp_all_targets_value;
|
params->arp_all_targets = arp_all_targets_value;
|
||||||
|
params->missed_max = 2;
|
||||||
params->updelay = updelay;
|
params->updelay = updelay;
|
||||||
params->downdelay = downdelay;
|
params->downdelay = downdelay;
|
||||||
params->peer_notif_delay = 0;
|
params->peer_notif_delay = 0;
|
||||||
|
|
|
@ -110,6 +110,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
|
||||||
.len = ETH_ALEN },
|
.len = ETH_ALEN },
|
||||||
[IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NLA_U8 },
|
[IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NLA_U8 },
|
||||||
[IFLA_BOND_PEER_NOTIF_DELAY] = { .type = NLA_U32 },
|
[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] = {
|
static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
|
||||||
|
@ -453,6 +454,15 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
|
||||||
return err;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(ETH_ALEN) + /* IFLA_BOND_AD_ACTOR_SYSTEM */
|
||||||
nla_total_size(sizeof(u8)) + /* IFLA_BOND_TLB_DYNAMIC_LB */
|
nla_total_size(sizeof(u8)) + /* IFLA_BOND_TLB_DYNAMIC_LB */
|
||||||
nla_total_size(sizeof(u32)) + /* IFLA_BOND_PEER_NOTIF_DELAY */
|
nla_total_size(sizeof(u32)) + /* IFLA_BOND_PEER_NOTIF_DELAY */
|
||||||
|
nla_total_size(sizeof(u8)) + /* IFLA_BOND_MISSED_MAX */
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,6 +661,10 @@ static int bond_fill_info(struct sk_buff *skb,
|
||||||
bond->params.tlb_dynamic_lb))
|
bond->params.tlb_dynamic_lb))
|
||||||
goto nla_put_failure;
|
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) {
|
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||||
struct ad_info info;
|
struct ad_info info;
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,8 @@ static int bond_option_ad_actor_system_set(struct bonding *bond,
|
||||||
const struct bond_opt_value *newval);
|
const struct bond_opt_value *newval);
|
||||||
static int bond_option_ad_user_port_key_set(struct bonding *bond,
|
static int bond_option_ad_user_port_key_set(struct bonding *bond,
|
||||||
const struct bond_opt_value *newval);
|
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[] = {
|
static const struct bond_opt_value bond_mode_tbl[] = {
|
||||||
|
@ -213,6 +215,13 @@ static const struct bond_opt_value bond_ad_user_port_key_tbl[] = {
|
||||||
{ NULL, -1, 0},
|
{ 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] = {
|
static const struct bond_option bond_opts[BOND_OPT_LAST] = {
|
||||||
[BOND_OPT_MODE] = {
|
[BOND_OPT_MODE] = {
|
||||||
.id = BOND_OPT_MODE,
|
.id = BOND_OPT_MODE,
|
||||||
|
@ -270,6 +279,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
|
||||||
.values = bond_intmax_tbl,
|
.values = bond_intmax_tbl,
|
||||||
.set = bond_option_arp_interval_set
|
.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] = {
|
[BOND_OPT_ARP_TARGETS] = {
|
||||||
.id = BOND_OPT_ARP_TARGETS,
|
.id = BOND_OPT_ARP_TARGETS,
|
||||||
.name = "arp_ip_target",
|
.name = "arp_ip_target",
|
||||||
|
@ -1186,6 +1204,16 @@ static int bond_option_arp_all_targets_set(struct bonding *bond,
|
||||||
return 0;
|
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,
|
static int bond_option_primary_set(struct bonding *bond,
|
||||||
const struct bond_opt_value *newval)
|
const struct bond_opt_value *newval)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,6 +115,8 @@ static void bond_info_show_master(struct seq_file *seq)
|
||||||
|
|
||||||
seq_printf(seq, "ARP Polling Interval (ms): %d\n",
|
seq_printf(seq, "ARP Polling Interval (ms): %d\n",
|
||||||
bond->params.arp_interval);
|
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):");
|
seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
|
||||||
|
|
||||||
|
|
|
@ -303,6 +303,18 @@ static ssize_t bonding_show_arp_targets(struct device *d,
|
||||||
static DEVICE_ATTR(arp_ip_target, 0644,
|
static DEVICE_ATTR(arp_ip_target, 0644,
|
||||||
bonding_show_arp_targets, bonding_sysfs_store_option);
|
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. */
|
/* Show the up and down delays. */
|
||||||
static ssize_t bonding_show_downdelay(struct device *d,
|
static ssize_t bonding_show_downdelay(struct device *d,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
|
@ -779,6 +791,7 @@ static struct attribute *per_bond_attrs[] = {
|
||||||
&dev_attr_ad_actor_sys_prio.attr,
|
&dev_attr_ad_actor_sys_prio.attr,
|
||||||
&dev_attr_ad_actor_system.attr,
|
&dev_attr_ad_actor_system.attr,
|
||||||
&dev_attr_ad_user_port_key.attr,
|
&dev_attr_ad_user_port_key.attr,
|
||||||
|
&dev_attr_arp_missed_max.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ enum {
|
||||||
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_LACP_ACTIVE,
|
||||||
|
BOND_OPT_MISSED_MAX,
|
||||||
BOND_OPT_LAST
|
BOND_OPT_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct bond_params {
|
||||||
int xmit_policy;
|
int xmit_policy;
|
||||||
int miimon;
|
int miimon;
|
||||||
u8 num_peer_notif;
|
u8 num_peer_notif;
|
||||||
|
u8 missed_max;
|
||||||
int arp_interval;
|
int arp_interval;
|
||||||
int arp_validate;
|
int arp_validate;
|
||||||
int arp_all_targets;
|
int arp_all_targets;
|
||||||
|
|
|
@ -858,6 +858,7 @@ enum {
|
||||||
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_AD_LACP_ACTIVE,
|
||||||
|
IFLA_BOND_MISSED_MAX,
|
||||||
__IFLA_BOND_MAX,
|
__IFLA_BOND_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -858,6 +858,7 @@ enum {
|
||||||
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_AD_LACP_ACTIVE,
|
||||||
|
IFLA_BOND_MISSED_MAX,
|
||||||
__IFLA_BOND_MAX,
|
__IFLA_BOND_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue