aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorBrian Haley <brian.haley@hp.com>2008-11-04 20:51:14 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-11-06 00:49:37 -0500
commit305d552accae6afb859c493ebc7d98ca3371dae2 (patch)
treeaa1230b1a6cf85ceb36d3e8a8a155ef4348523b6 /drivers/net/bonding/bond_main.c
parent61c9eaf90081cbe6dc4f389e0056bff76eca19ec (diff)
bonding: send IPv6 neighbor advertisement on failover
This patch adds better IPv6 failover support for bonding devices, especially when in active-backup mode and there are only IPv6 addresses configured, as reported by Alex Sidorenko. - Creates a new file, net/drivers/bonding/bond_ipv6.c, for the IPv6-specific routines. Both regular bonds and VLANs over bonds are supported. - Adds a new tunable, num_unsol_na, to limit the number of unsolicited IPv6 Neighbor Advertisements that are sent on a failover event. Default is 1. - Creates two new IPv6 neighbor discovery functions: ndisc_build_skb() ndisc_send_skb() These were required to support VLANs since we have to be able to add the VLAN id to the skb since ndisc_send_na() and friends shouldn't be asked to do this. These two routines are basically __ndisc_send() split into two pieces, in a slightly different order. - Updates Documentation/networking/bonding.txt and bumps the rev of bond support to 3.4.0. On failover, this new code will generate one packet: - An unsolicited IPv6 Neighbor Advertisement, which helps the switch learn that the address has moved to the new slave. Testing has shown that sending just the NA results in pretty good behavior when in active-back mode, I saw no lost ping packets for example. Signed-off-by: Brian Haley <brian.haley@hp.com> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 39575d764974..798d98ce2d97 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -89,6 +89,7 @@
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 num_grat_arp = 1;
92static int num_unsol_na = 1;
92static int miimon = BOND_LINK_MON_INTERV; 93static int miimon = BOND_LINK_MON_INTERV;
93static int updelay = 0; 94static int updelay = 0;
94static int downdelay = 0; 95static int downdelay = 0;
@@ -107,6 +108,8 @@ module_param(max_bonds, int, 0);
107MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); 108MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
108module_param(num_grat_arp, int, 0644); 109module_param(num_grat_arp, int, 0644);
109MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); 110MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
111module_param(num_unsol_na, int, 0644);
112MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
110module_param(miimon, int, 0); 113module_param(miimon, int, 0);
111MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); 114MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
112module_param(updelay, int, 0); 115module_param(updelay, int, 0);
@@ -242,14 +245,13 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
242 dprintk("bond: %s, vlan id %d\n", 245 dprintk("bond: %s, vlan id %d\n",
243 (bond ? bond->dev->name: "None"), vlan_id); 246 (bond ? bond->dev->name: "None"), vlan_id);
244 247
245 vlan = kmalloc(sizeof(struct vlan_entry), GFP_KERNEL); 248 vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
246 if (!vlan) { 249 if (!vlan) {
247 return -ENOMEM; 250 return -ENOMEM;
248 } 251 }
249 252
250 INIT_LIST_HEAD(&vlan->vlan_list); 253 INIT_LIST_HEAD(&vlan->vlan_list);
251 vlan->vlan_id = vlan_id; 254 vlan->vlan_id = vlan_id;
252 vlan->vlan_ip = 0;
253 255
254 write_lock_bh(&bond->lock); 256 write_lock_bh(&bond->lock);
255 257
@@ -1208,6 +1210,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1208 bond->send_grat_arp = bond->params.num_grat_arp; 1210 bond->send_grat_arp = bond->params.num_grat_arp;
1209 bond_send_gratuitous_arp(bond); 1211 bond_send_gratuitous_arp(bond);
1210 1212
1213 bond->send_unsol_na = bond->params.num_unsol_na;
1214 bond_send_unsolicited_na(bond);
1215
1211 write_unlock_bh(&bond->curr_slave_lock); 1216 write_unlock_bh(&bond->curr_slave_lock);
1212 read_unlock(&bond->lock); 1217 read_unlock(&bond->lock);
1213 1218
@@ -2463,6 +2468,12 @@ void bond_mii_monitor(struct work_struct *work)
2463 read_unlock(&bond->curr_slave_lock); 2468 read_unlock(&bond->curr_slave_lock);
2464 } 2469 }
2465 2470
2471 if (bond->send_unsol_na) {
2472 read_lock(&bond->curr_slave_lock);
2473 bond_send_unsolicited_na(bond);
2474 read_unlock(&bond->curr_slave_lock);
2475 }
2476
2466 if (bond_miimon_inspect(bond)) { 2477 if (bond_miimon_inspect(bond)) {
2467 read_unlock(&bond->lock); 2478 read_unlock(&bond->lock);
2468 rtnl_lock(); 2479 rtnl_lock();
@@ -3158,6 +3169,12 @@ void bond_activebackup_arp_mon(struct work_struct *work)
3158 read_unlock(&bond->curr_slave_lock); 3169 read_unlock(&bond->curr_slave_lock);
3159 } 3170 }
3160 3171
3172 if (bond->send_unsol_na) {
3173 read_lock(&bond->curr_slave_lock);
3174 bond_send_unsolicited_na(bond);
3175 read_unlock(&bond->curr_slave_lock);
3176 }
3177
3161 if (bond_ab_arp_inspect(bond, delta_in_ticks)) { 3178 if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
3162 read_unlock(&bond->lock); 3179 read_unlock(&bond->lock);
3163 rtnl_lock(); 3180 rtnl_lock();
@@ -3827,6 +3844,7 @@ static int bond_close(struct net_device *bond_dev)
3827 write_lock_bh(&bond->lock); 3844 write_lock_bh(&bond->lock);
3828 3845
3829 bond->send_grat_arp = 0; 3846 bond->send_grat_arp = 0;
3847 bond->send_unsol_na = 0;
3830 3848
3831 /* signal timers not to re-arm */ 3849 /* signal timers not to re-arm */
3832 bond->kill_timers = 1; 3850 bond->kill_timers = 1;
@@ -4542,6 +4560,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4542 bond->primary_slave = NULL; 4560 bond->primary_slave = NULL;
4543 bond->dev = bond_dev; 4561 bond->dev = bond_dev;
4544 bond->send_grat_arp = 0; 4562 bond->send_grat_arp = 0;
4563 bond->send_unsol_na = 0;
4545 bond->setup_by_slave = 0; 4564 bond->setup_by_slave = 0;
4546 INIT_LIST_HEAD(&bond->vlan_list); 4565 INIT_LIST_HEAD(&bond->vlan_list);
4547 4566
@@ -4791,6 +4810,13 @@ static int bond_check_params(struct bond_params *params)
4791 num_grat_arp = 1; 4810 num_grat_arp = 1;
4792 } 4811 }
4793 4812
4813 if (num_unsol_na < 0 || num_unsol_na > 255) {
4814 printk(KERN_WARNING DRV_NAME
4815 ": Warning: num_unsol_na (%d) not in range 0-255 so it "
4816 "was reset to 1 \n", num_unsol_na);
4817 num_unsol_na = 1;
4818 }
4819
4794 /* reset values for 802.3ad */ 4820 /* reset values for 802.3ad */
4795 if (bond_mode == BOND_MODE_8023AD) { 4821 if (bond_mode == BOND_MODE_8023AD) {
4796 if (!miimon) { 4822 if (!miimon) {
@@ -4992,6 +5018,7 @@ static int bond_check_params(struct bond_params *params)
4992 params->xmit_policy = xmit_hashtype; 5018 params->xmit_policy = xmit_hashtype;
4993 params->miimon = miimon; 5019 params->miimon = miimon;
4994 params->num_grat_arp = num_grat_arp; 5020 params->num_grat_arp = num_grat_arp;
5021 params->num_unsol_na = num_unsol_na;
4995 params->arp_interval = arp_interval; 5022 params->arp_interval = arp_interval;
4996 params->arp_validate = arp_validate_value; 5023 params->arp_validate = arp_validate_value;
4997 params->updelay = updelay; 5024 params->updelay = updelay;
@@ -5144,6 +5171,7 @@ static int __init bonding_init(void)
5144 5171
5145 register_netdevice_notifier(&bond_netdev_notifier); 5172 register_netdevice_notifier(&bond_netdev_notifier);
5146 register_inetaddr_notifier(&bond_inetaddr_notifier); 5173 register_inetaddr_notifier(&bond_inetaddr_notifier);
5174 bond_register_ipv6_notifier();
5147 5175
5148 goto out; 5176 goto out;
5149err: 5177err:
@@ -5166,6 +5194,7 @@ static void __exit bonding_exit(void)
5166{ 5194{
5167 unregister_netdevice_notifier(&bond_netdev_notifier); 5195 unregister_netdevice_notifier(&bond_netdev_notifier);
5168 unregister_inetaddr_notifier(&bond_inetaddr_notifier); 5196 unregister_inetaddr_notifier(&bond_inetaddr_notifier);
5197 bond_unregister_ipv6_notifier();
5169 5198
5170 bond_destroy_sysfs(); 5199 bond_destroy_sysfs();
5171 5200