Commit b59f9f74 authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik

bonding: Rework / fix multiple gratuitous ARP support

	Support for sending multiple gratuitous ARPs during failovers
was added by commit:

commit 7893b249
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: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 01f3109d
...@@ -539,6 +539,17 @@ mode ...@@ -539,6 +539,17 @@ mode
swapped with the new curr_active_slave that was swapped with the new curr_active_slave that was
chosen. 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 primary
A string (eth0, eth2, etc) specifying which slave is the A string (eth0, eth2, etc) specifying which slave is the
......
...@@ -1195,14 +1195,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) ...@@ -1195,14 +1195,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
old_active); old_active);
bond->send_grat_arp = bond->params.num_grat_arp; 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_gratuitous_arp(bond);
bond->send_grat_arp--;
} else {
dprintk("delaying gratuitous arp on %s\n",
bond->curr_active_slave->dev->name);
}
write_unlock_bh(&bond->curr_slave_lock); write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock); read_unlock(&bond->lock);
...@@ -2241,17 +2234,6 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks) ...@@ -2241,17 +2234,6 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
* 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); read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave; oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
...@@ -2492,6 +2474,13 @@ void bond_mii_monitor(struct work_struct *work) ...@@ -2492,6 +2474,13 @@ void bond_mii_monitor(struct work_struct *work)
read_unlock(&bond->lock); read_unlock(&bond->lock);
return; 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)) { if (__bond_mii_monitor(bond, 0)) {
read_unlock(&bond->lock); read_unlock(&bond->lock);
rtnl_lock(); rtnl_lock();
...@@ -2657,6 +2646,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) ...@@ -2657,6 +2646,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
/* /*
* Kick out a gratuitous ARP for an IP on the bonding master plus one * Kick out a gratuitous ARP for an IP on the bonding master plus one
* for each VLAN above us. * 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)
{ {
...@@ -2666,9 +2657,13 @@ static void bond_send_gratuitous_arp(struct bonding *bond) ...@@ -2666,9 +2657,13 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
slave ? slave->dev->name : "NULL"); slave ? slave->dev->name : "NULL");
if (!slave)
if (!slave || !bond->send_grat_arp ||
test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
return; return;
bond->send_grat_arp--;
if (bond->master_ip) { if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0); bond->master_ip, 0);
...@@ -3172,6 +3167,12 @@ void bond_activebackup_arp_mon(struct work_struct *work) ...@@ -3172,6 +3167,12 @@ void bond_activebackup_arp_mon(struct work_struct *work)
if (bond->slave_cnt == 0) if (bond->slave_cnt == 0)
goto re_arm; 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)) { if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
read_unlock(&bond->lock); read_unlock(&bond->lock);
rtnl_lock(); rtnl_lock();
...@@ -3846,6 +3847,7 @@ static int bond_close(struct net_device *bond_dev) ...@@ -3846,6 +3847,7 @@ static int bond_close(struct net_device *bond_dev)
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
bond->send_grat_arp = 0;
/* signal timers not to re-arm */ /* signal timers not to re-arm */
bond->kill_timers = 1; bond->kill_timers = 1;
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include "bond_3ad.h" #include "bond_3ad.h"
#include "bond_alb.h" #include "bond_alb.h"
#define DRV_VERSION "3.2.5" #define DRV_VERSION "3.3.0"
#define DRV_RELDATE "March 21, 2008" #define DRV_RELDATE "June 10, 2008"
#define DRV_NAME "bonding" #define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
......
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