aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorMoni Shoua <monis@voltaire.com>2008-05-18 00:10:12 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-22 06:34:26 -0400
commit7893b2491a2d5f716540ac5643d78d37a7f6628b (patch)
tree2558b83e5a19b7d4a6b3c10c5bb90919bb1f3889 /drivers/net/bonding
parent8047637c70e4451e2ac1c17ed9a91a2f753daae7 (diff)
bonding: Send more than one gratuitous ARP when slave takes over
With IPoIB, reception of gratuitous ARP by neighboring hosts is essential for a successful change of slaves in case of failure. Otherwise, they won't learn about the HW address change and need to wait a long time until the neighboring system gives up and sends an ARP request to learn the new HW address. This patch decreases the chance for a lost of a gratuitous ARP packet by sending it more than once. The number retries is configurable and can be set with a module param. Signed-off-by: Moni Shoua <monis@voltaire.com> Acked-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c23
-rw-r--r--drivers/net/bonding/bond_sysfs.c40
-rw-r--r--drivers/net/bonding/bonding.h1
3 files changed, 60 insertions, 4 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2a0039f19377..fa3c2101fe75 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -88,6 +88,7 @@
88#define BOND_LINK_ARP_INTERV 0 88#define BOND_LINK_ARP_INTERV 0
89 89
90static int max_bonds = BOND_DEFAULT_MAX_BONDS; 90static int max_bonds = BOND_DEFAULT_MAX_BONDS;
91static int num_grat_arp = 1;
91static int miimon = BOND_LINK_MON_INTERV; 92static int miimon = BOND_LINK_MON_INTERV;
92static int updelay = 0; 93static int updelay = 0;
93static int downdelay = 0; 94static int downdelay = 0;
@@ -104,6 +105,8 @@ struct bond_params bonding_defaults;
104 105
105module_param(max_bonds, int, 0); 106module_param(max_bonds, int, 0);
106MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); 107MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
108module_param(num_grat_arp, int, 0644);
109MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
107module_param(miimon, int, 0); 110module_param(miimon, int, 0);
108MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); 111MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
109module_param(updelay, int, 0); 112module_param(updelay, int, 0);
@@ -1109,14 +1112,18 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1109 if (new_active && bond->params.fail_over_mac) 1112 if (new_active && bond->params.fail_over_mac)
1110 memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, 1113 memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
1111 new_active->dev->addr_len); 1114 new_active->dev->addr_len);
1115 bond->send_grat_arp = bond->params.num_grat_arp;
1112 if (bond->curr_active_slave && 1116 if (bond->curr_active_slave &&
1113 test_bit(__LINK_STATE_LINKWATCH_PENDING, 1117 test_bit(__LINK_STATE_LINKWATCH_PENDING,
1114 &bond->curr_active_slave->dev->state)) { 1118 &bond->curr_active_slave->dev->state)) {
1115 dprintk("delaying gratuitous arp on %s\n", 1119 dprintk("delaying gratuitous arp on %s\n",
1116 bond->curr_active_slave->dev->name); 1120 bond->curr_active_slave->dev->name);
1117 bond->send_grat_arp = 1; 1121 } else {
1118 } else 1122 if (bond->send_grat_arp > 0) {
1119 bond_send_gratuitous_arp(bond); 1123 bond_send_gratuitous_arp(bond);
1124 bond->send_grat_arp--;
1125 }
1126 }
1120 } 1127 }
1121} 1128}
1122 1129
@@ -2144,7 +2151,7 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
2144 dprintk("sending delayed gratuitous arp on on %s\n", 2151 dprintk("sending delayed gratuitous arp on on %s\n",
2145 bond->curr_active_slave->dev->name); 2152 bond->curr_active_slave->dev->name);
2146 bond_send_gratuitous_arp(bond); 2153 bond_send_gratuitous_arp(bond);
2147 bond->send_grat_arp = 0; 2154 bond->send_grat_arp--;
2148 } 2155 }
2149 } 2156 }
2150 read_lock(&bond->curr_slave_lock); 2157 read_lock(&bond->curr_slave_lock);
@@ -4626,6 +4633,13 @@ static int bond_check_params(struct bond_params *params)
4626 use_carrier = 1; 4633 use_carrier = 1;
4627 } 4634 }
4628 4635
4636 if (num_grat_arp < 0 || num_grat_arp > 255) {
4637 printk(KERN_WARNING DRV_NAME
4638 ": Warning: num_grat_arp (%d) not in range 0-255 so it "
4639 "was reset to 1 \n", num_grat_arp);
4640 num_grat_arp = 1;
4641 }
4642
4629 /* reset values for 802.3ad */ 4643 /* reset values for 802.3ad */
4630 if (bond_mode == BOND_MODE_8023AD) { 4644 if (bond_mode == BOND_MODE_8023AD) {
4631 if (!miimon) { 4645 if (!miimon) {
@@ -4813,6 +4827,7 @@ static int bond_check_params(struct bond_params *params)
4813 params->mode = bond_mode; 4827 params->mode = bond_mode;
4814 params->xmit_policy = xmit_hashtype; 4828 params->xmit_policy = xmit_hashtype;
4815 params->miimon = miimon; 4829 params->miimon = miimon;
4830 params->num_grat_arp = num_grat_arp;
4816 params->arp_interval = arp_interval; 4831 params->arp_interval = arp_interval;
4817 params->arp_validate = arp_validate_value; 4832 params->arp_validate = arp_validate_value;
4818 params->updelay = updelay; 4833 params->updelay = updelay;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 1f028579e53b..7a61e9a14386 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -951,6 +951,45 @@ out:
951static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); 951static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
952 952
953/* 953/*
954 * Show and set the number of grat ARP to send after a failover event.
955 */
956static ssize_t bonding_show_n_grat_arp(struct device *d,
957 struct device_attribute *attr,
958 char *buf)
959{
960 struct bonding *bond = to_bond(d);
961
962 return sprintf(buf, "%d\n", bond->params.num_grat_arp);
963}
964
965static ssize_t bonding_store_n_grat_arp(struct device *d,
966 struct device_attribute *attr,
967 const char *buf, size_t count)
968{
969 int new_value, ret = count;
970 struct bonding *bond = to_bond(d);
971
972 if (sscanf(buf, "%d", &new_value) != 1) {
973 printk(KERN_ERR DRV_NAME
974 ": %s: no num_grat_arp value specified.\n",
975 bond->dev->name);
976 ret = -EINVAL;
977 goto out;
978 }
979 if (new_value < 0 || new_value > 255) {
980 printk(KERN_ERR DRV_NAME
981 ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
982 bond->dev->name, new_value);
983 ret = -EINVAL;
984 goto out;
985 } else {
986 bond->params.num_grat_arp = new_value;
987 }
988out:
989 return ret;
990}
991static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
992/*
954 * Show and set the MII monitor interval. There are two tricky bits 993 * Show and set the MII monitor interval. There are two tricky bits
955 * here. First, if MII monitoring is activated, then we must disable 994 * here. First, if MII monitoring is activated, then we must disable
956 * ARP monitoring. Second, if the timer isn't running, we must 995 * ARP monitoring. Second, if the timer isn't running, we must
@@ -1387,6 +1426,7 @@ static struct attribute *per_bond_attrs[] = {
1387 &dev_attr_updelay.attr, 1426 &dev_attr_updelay.attr,
1388 &dev_attr_lacp_rate.attr, 1427 &dev_attr_lacp_rate.attr,
1389 &dev_attr_xmit_hash_policy.attr, 1428 &dev_attr_xmit_hash_policy.attr,
1429 &dev_attr_num_grat_arp.attr,
1390 &dev_attr_miimon.attr, 1430 &dev_attr_miimon.attr,
1391 &dev_attr_primary.attr, 1431 &dev_attr_primary.attr,
1392 &dev_attr_use_carrier.attr, 1432 &dev_attr_use_carrier.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 0ce7f4ae920f..46a2ed507b33 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -125,6 +125,7 @@ struct bond_params {
125 int mode; 125 int mode;
126 int xmit_policy; 126 int xmit_policy;
127 int miimon; 127 int miimon;
128 int num_grat_arp;
128 int arp_interval; 129 int arp_interval;
129 int arp_validate; 130 int arp_validate;
130 int use_carrier; 131 int use_carrier;