Support for sending multiple gratuitous ARPs during failovers
was added by commit:
commit
7893b2491a2d5f716540ac5643d78d37a7f6628b
Author: Moni Shoua <monis@voltaire.com>
Date: Sat May 17 21:10:12 2008 -0700
bonding: Send more than one gratuitous ARP when slave takes over
This change modifies that support to remove duplicated code,
add support for ARP monitor (the original only supported miimon), clear
the grat ARP counter in bond_close (lest a later "ifconfig up" immediately
start spewing ARPs), and add documentation for the module parameter.
Also updated driver version to 3.3.0.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
swapped with the new curr_active_slave that was
chosen.
swapped with the new curr_active_slave that was
chosen.
+num_grat_arp
+
+ Specifies the number of gratuitous ARPs to be issued after a
+ failover event. One gratuitous ARP is issued immediately after
+ the failover, subsequent ARPs are sent at a rate of one per link
+ monitor interval (arp_interval or miimon, whichever is active).
+
+ The valid range is 0 - 255; the default value is 1. This option
+ affects only the active-backup mode. This option was added for
+ bonding version 3.3.0.
+
primary
A string (eth0, eth2, etc) specifying which slave is the
primary
A string (eth0, eth2, etc) specifying which slave is the
old_active);
bond->send_grat_arp = bond->params.num_grat_arp;
old_active);
bond->send_grat_arp = bond->params.num_grat_arp;
- if (!test_bit(__LINK_STATE_LINKWATCH_PENDING,
- &bond->curr_active_slave->dev->state)) {
- bond_send_gratuitous_arp(bond);
- bond->send_grat_arp--;
- } else {
- dprintk("delaying gratuitous arp on %s\n",
- bond->curr_active_slave->dev->name);
- }
+ bond_send_gratuitous_arp(bond);
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
* program could monitor the link itself if needed.
*/
* program could monitor the link itself if needed.
*/
- if (bond->send_grat_arp) {
- if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
- &bond->curr_active_slave->dev->state))
- dprintk("Needs to send gratuitous arp but not yet\n");
- else {
- dprintk("sending delayed gratuitous arp on on %s\n",
- bond->curr_active_slave->dev->name);
- bond_send_gratuitous_arp(bond);
- bond->send_grat_arp--;
- }
- }
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
return;
}
read_unlock(&bond->lock);
return;
}
+
+ if (bond->send_grat_arp) {
+ read_lock(&bond->curr_slave_lock);
+ bond_send_gratuitous_arp(bond);
+ read_unlock(&bond->curr_slave_lock);
+ }
+
if (__bond_mii_monitor(bond, 0)) {
read_unlock(&bond->lock);
rtnl_lock();
if (__bond_mii_monitor(bond, 0)) {
read_unlock(&bond->lock);
rtnl_lock();
/*
* Kick out a gratuitous ARP for an IP on the bonding master plus one
* for each VLAN above us.
/*
* Kick out a gratuitous ARP for an IP on the bonding master plus one
* for each VLAN above us.
+ *
+ * Caller must hold curr_slave_lock for read or better
*/
static void bond_send_gratuitous_arp(struct bonding *bond)
{
*/
static void bond_send_gratuitous_arp(struct bonding *bond)
{
dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
slave ? slave->dev->name : "NULL");
dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
slave ? slave->dev->name : "NULL");
+
+ if (!slave || !bond->send_grat_arp ||
+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+ bond->send_grat_arp--;
+
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0);
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0);
if (bond->slave_cnt == 0)
goto re_arm;
if (bond->slave_cnt == 0)
goto re_arm;
+ if (bond->send_grat_arp) {
+ read_lock(&bond->curr_slave_lock);
+ bond_send_gratuitous_arp(bond);
+ read_unlock(&bond->curr_slave_lock);
+ }
+
if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
read_unlock(&bond->lock);
rtnl_lock();
if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
read_unlock(&bond->lock);
rtnl_lock();
write_lock_bh(&bond->lock);
write_lock_bh(&bond->lock);
+ bond->send_grat_arp = 0;
/* signal timers not to re-arm */
bond->kill_timers = 1;
/* signal timers not to re-arm */
bond->kill_timers = 1;
#include "bond_3ad.h"
#include "bond_alb.h"
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.2.5"
-#define DRV_RELDATE "March 21, 2008"
+#define DRV_VERSION "3.3.0"
+#define DRV_RELDATE "June 10, 2008"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"