diff options
-rw-r--r-- | Documentation/networking/bonding.txt | 34 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 59 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 26 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 6 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 1 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 1 |
6 files changed, 105 insertions, 22 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index e27202bb8d7..1f45bd887d6 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | Linux Ethernet Bonding Driver HOWTO | 2 | Linux Ethernet Bonding Driver HOWTO |
3 | 3 | ||
4 | Latest update: 23 September 2009 | 4 | Latest update: 27 April 2011 |
5 | 5 | ||
6 | Initial release : Thomas Davis <tadavis at lbl.gov> | 6 | Initial release : Thomas Davis <tadavis at lbl.gov> |
7 | Corrections, HA extensions : 2000/10/03-15 : | 7 | Corrections, HA extensions : 2000/10/03-15 : |
@@ -585,25 +585,23 @@ mode | |||
585 | chosen. | 585 | chosen. |
586 | 586 | ||
587 | num_grat_arp | 587 | num_grat_arp |
588 | |||
589 | Specifies the number of gratuitous ARPs to be issued after a | ||
590 | failover event. One gratuitous ARP is issued immediately after | ||
591 | the failover, subsequent ARPs are sent at a rate of one per link | ||
592 | monitor interval (arp_interval or miimon, whichever is active). | ||
593 | |||
594 | The valid range is 0 - 255; the default value is 1. This option | ||
595 | affects only the active-backup mode. This option was added for | ||
596 | bonding version 3.3.0. | ||
597 | |||
598 | num_unsol_na | 588 | num_unsol_na |
599 | 589 | ||
600 | Specifies the number of unsolicited IPv6 Neighbor Advertisements | 590 | Specify the number of peer notifications (gratuitous ARPs and |
601 | to be issued after a failover event. One unsolicited NA is issued | 591 | unsolicited IPv6 Neighbor Advertisements) to be issued after a |
602 | immediately after the failover. | 592 | failover event. As soon as the link is up on the new slave |
603 | 593 | (possibly immediately) a peer notification is sent on the | |
604 | The valid range is 0 - 255; the default value is 1. This option | 594 | bonding device and each VLAN sub-device. This is repeated at |
605 | affects only the active-backup mode. This option was added for | 595 | each link monitor interval (arp_interval or miimon, whichever |
606 | bonding version 3.4.0. | 596 | is active) if the number is greater than 1. |
597 | |||
598 | The valid range is 0 - 255; the default value is 1. These options | ||
599 | affect only the active-backup mode. These options were added for | ||
600 | bonding versions 3.3.0 and 3.4.0 respectively. | ||
601 | |||
602 | From Linux 2.6.40 and bonding version 3.7.1, these notifications | ||
603 | are generated by the ipv4 and ipv6 code and the numbers of | ||
604 | repetitions cannot be set independently. | ||
607 | 605 | ||
608 | primary | 606 | primary |
609 | 607 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 66d9dc6e5ca..22bd03bd1d3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -89,6 +89,7 @@ | |||
89 | 89 | ||
90 | static int max_bonds = BOND_DEFAULT_MAX_BONDS; | 90 | static int max_bonds = BOND_DEFAULT_MAX_BONDS; |
91 | static int tx_queues = BOND_DEFAULT_TX_QUEUES; | 91 | static int tx_queues = BOND_DEFAULT_TX_QUEUES; |
92 | static int num_peer_notif = 1; | ||
92 | static int miimon = BOND_LINK_MON_INTERV; | 93 | static int miimon = BOND_LINK_MON_INTERV; |
93 | static int updelay; | 94 | static int updelay; |
94 | static int downdelay; | 95 | static int downdelay; |
@@ -111,6 +112,10 @@ module_param(max_bonds, int, 0); | |||
111 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); | 112 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); |
112 | module_param(tx_queues, int, 0); | 113 | module_param(tx_queues, int, 0); |
113 | MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)"); | 114 | MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)"); |
115 | module_param_named(num_grat_arp, num_peer_notif, int, 0644); | ||
116 | MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on failover event (alias of num_unsol_na)"); | ||
117 | module_param_named(num_unsol_na, num_peer_notif, int, 0644); | ||
118 | MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event (alias of num_grat_arp)"); | ||
114 | module_param(miimon, int, 0); | 119 | module_param(miimon, int, 0); |
115 | MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); | 120 | MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); |
116 | module_param(updelay, int, 0); | 121 | module_param(updelay, int, 0); |
@@ -1082,6 +1087,21 @@ static struct slave *bond_find_best_slave(struct bonding *bond) | |||
1082 | return bestslave; | 1087 | return bestslave; |
1083 | } | 1088 | } |
1084 | 1089 | ||
1090 | static bool bond_should_notify_peers(struct bonding *bond) | ||
1091 | { | ||
1092 | struct slave *slave = bond->curr_active_slave; | ||
1093 | |||
1094 | pr_debug("bond_should_notify_peers: bond %s slave %s\n", | ||
1095 | bond->dev->name, slave ? slave->dev->name : "NULL"); | ||
1096 | |||
1097 | if (!slave || !bond->send_peer_notif || | ||
1098 | test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) | ||
1099 | return false; | ||
1100 | |||
1101 | bond->send_peer_notif--; | ||
1102 | return true; | ||
1103 | } | ||
1104 | |||
1085 | /** | 1105 | /** |
1086 | * change_active_interface - change the active slave into the specified one | 1106 | * change_active_interface - change the active slave into the specified one |
1087 | * @bond: our bonding struct | 1107 | * @bond: our bonding struct |
@@ -1149,16 +1169,28 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1149 | bond_set_slave_inactive_flags(old_active); | 1169 | bond_set_slave_inactive_flags(old_active); |
1150 | 1170 | ||
1151 | if (new_active) { | 1171 | if (new_active) { |
1172 | bool should_notify_peers = false; | ||
1173 | |||
1152 | bond_set_slave_active_flags(new_active); | 1174 | bond_set_slave_active_flags(new_active); |
1153 | 1175 | ||
1154 | if (bond->params.fail_over_mac) | 1176 | if (bond->params.fail_over_mac) |
1155 | bond_do_fail_over_mac(bond, new_active, | 1177 | bond_do_fail_over_mac(bond, new_active, |
1156 | old_active); | 1178 | old_active); |
1157 | 1179 | ||
1180 | if (netif_running(bond->dev)) { | ||
1181 | bond->send_peer_notif = | ||
1182 | bond->params.num_peer_notif; | ||
1183 | should_notify_peers = | ||
1184 | bond_should_notify_peers(bond); | ||
1185 | } | ||
1186 | |||
1158 | write_unlock_bh(&bond->curr_slave_lock); | 1187 | write_unlock_bh(&bond->curr_slave_lock); |
1159 | read_unlock(&bond->lock); | 1188 | read_unlock(&bond->lock); |
1160 | 1189 | ||
1161 | netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER); | 1190 | netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER); |
1191 | if (should_notify_peers) | ||
1192 | netdev_bonding_change(bond->dev, | ||
1193 | NETDEV_NOTIFY_PEERS); | ||
1162 | 1194 | ||
1163 | read_lock(&bond->lock); | 1195 | read_lock(&bond->lock); |
1164 | write_lock_bh(&bond->curr_slave_lock); | 1196 | write_lock_bh(&bond->curr_slave_lock); |
@@ -2556,6 +2588,7 @@ void bond_mii_monitor(struct work_struct *work) | |||
2556 | { | 2588 | { |
2557 | struct bonding *bond = container_of(work, struct bonding, | 2589 | struct bonding *bond = container_of(work, struct bonding, |
2558 | mii_work.work); | 2590 | mii_work.work); |
2591 | bool should_notify_peers = false; | ||
2559 | 2592 | ||
2560 | read_lock(&bond->lock); | 2593 | read_lock(&bond->lock); |
2561 | if (bond->kill_timers) | 2594 | if (bond->kill_timers) |
@@ -2564,6 +2597,8 @@ void bond_mii_monitor(struct work_struct *work) | |||
2564 | if (bond->slave_cnt == 0) | 2597 | if (bond->slave_cnt == 0) |
2565 | goto re_arm; | 2598 | goto re_arm; |
2566 | 2599 | ||
2600 | should_notify_peers = bond_should_notify_peers(bond); | ||
2601 | |||
2567 | if (bond_miimon_inspect(bond)) { | 2602 | if (bond_miimon_inspect(bond)) { |
2568 | read_unlock(&bond->lock); | 2603 | read_unlock(&bond->lock); |
2569 | rtnl_lock(); | 2604 | rtnl_lock(); |
@@ -2582,6 +2617,12 @@ re_arm: | |||
2582 | msecs_to_jiffies(bond->params.miimon)); | 2617 | msecs_to_jiffies(bond->params.miimon)); |
2583 | out: | 2618 | out: |
2584 | read_unlock(&bond->lock); | 2619 | read_unlock(&bond->lock); |
2620 | |||
2621 | if (should_notify_peers) { | ||
2622 | rtnl_lock(); | ||
2623 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); | ||
2624 | rtnl_unlock(); | ||
2625 | } | ||
2585 | } | 2626 | } |
2586 | 2627 | ||
2587 | static __be32 bond_glean_dev_ip(struct net_device *dev) | 2628 | static __be32 bond_glean_dev_ip(struct net_device *dev) |
@@ -3154,6 +3195,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3154 | { | 3195 | { |
3155 | struct bonding *bond = container_of(work, struct bonding, | 3196 | struct bonding *bond = container_of(work, struct bonding, |
3156 | arp_work.work); | 3197 | arp_work.work); |
3198 | bool should_notify_peers = false; | ||
3157 | int delta_in_ticks; | 3199 | int delta_in_ticks; |
3158 | 3200 | ||
3159 | read_lock(&bond->lock); | 3201 | read_lock(&bond->lock); |
@@ -3166,6 +3208,8 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3166 | if (bond->slave_cnt == 0) | 3208 | if (bond->slave_cnt == 0) |
3167 | goto re_arm; | 3209 | goto re_arm; |
3168 | 3210 | ||
3211 | should_notify_peers = bond_should_notify_peers(bond); | ||
3212 | |||
3169 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { | 3213 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { |
3170 | read_unlock(&bond->lock); | 3214 | read_unlock(&bond->lock); |
3171 | rtnl_lock(); | 3215 | rtnl_lock(); |
@@ -3185,6 +3229,12 @@ re_arm: | |||
3185 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 3229 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
3186 | out: | 3230 | out: |
3187 | read_unlock(&bond->lock); | 3231 | read_unlock(&bond->lock); |
3232 | |||
3233 | if (should_notify_peers) { | ||
3234 | rtnl_lock(); | ||
3235 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); | ||
3236 | rtnl_unlock(); | ||
3237 | } | ||
3188 | } | 3238 | } |
3189 | 3239 | ||
3190 | /*-------------------------- netdev event handling --------------------------*/ | 3240 | /*-------------------------- netdev event handling --------------------------*/ |
@@ -3494,6 +3544,8 @@ static int bond_close(struct net_device *bond_dev) | |||
3494 | 3544 | ||
3495 | write_lock_bh(&bond->lock); | 3545 | write_lock_bh(&bond->lock); |
3496 | 3546 | ||
3547 | bond->send_peer_notif = 0; | ||
3548 | |||
3497 | /* signal timers not to re-arm */ | 3549 | /* signal timers not to re-arm */ |
3498 | bond->kill_timers = 1; | 3550 | bond->kill_timers = 1; |
3499 | 3551 | ||
@@ -4571,6 +4623,12 @@ static int bond_check_params(struct bond_params *params) | |||
4571 | use_carrier = 1; | 4623 | use_carrier = 1; |
4572 | } | 4624 | } |
4573 | 4625 | ||
4626 | if (num_peer_notif < 0 || num_peer_notif > 255) { | ||
4627 | pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n", | ||
4628 | num_peer_notif); | ||
4629 | num_peer_notif = 1; | ||
4630 | } | ||
4631 | |||
4574 | /* reset values for 802.3ad */ | 4632 | /* reset values for 802.3ad */ |
4575 | if (bond_mode == BOND_MODE_8023AD) { | 4633 | if (bond_mode == BOND_MODE_8023AD) { |
4576 | if (!miimon) { | 4634 | if (!miimon) { |
@@ -4760,6 +4818,7 @@ static int bond_check_params(struct bond_params *params) | |||
4760 | params->mode = bond_mode; | 4818 | params->mode = bond_mode; |
4761 | params->xmit_policy = xmit_hashtype; | 4819 | params->xmit_policy = xmit_hashtype; |
4762 | params->miimon = miimon; | 4820 | params->miimon = miimon; |
4821 | params->num_peer_notif = num_peer_notif; | ||
4763 | params->arp_interval = arp_interval; | 4822 | params->arp_interval = arp_interval; |
4764 | params->arp_validate = arp_validate_value; | 4823 | params->arp_validate = arp_validate_value; |
4765 | params->updelay = updelay; | 4824 | params->updelay = updelay; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 935406aa5f0..4059bfc73db 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -869,6 +869,30 @@ static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, | |||
869 | bonding_show_ad_select, bonding_store_ad_select); | 869 | bonding_show_ad_select, bonding_store_ad_select); |
870 | 870 | ||
871 | /* | 871 | /* |
872 | * Show and set the number of peer notifications to send after a failover event. | ||
873 | */ | ||
874 | static ssize_t bonding_show_num_peer_notif(struct device *d, | ||
875 | struct device_attribute *attr, | ||
876 | char *buf) | ||
877 | { | ||
878 | struct bonding *bond = to_bond(d); | ||
879 | return sprintf(buf, "%d\n", bond->params.num_peer_notif); | ||
880 | } | ||
881 | |||
882 | static ssize_t bonding_store_num_peer_notif(struct device *d, | ||
883 | struct device_attribute *attr, | ||
884 | const char *buf, size_t count) | ||
885 | { | ||
886 | struct bonding *bond = to_bond(d); | ||
887 | int err = kstrtou8(buf, 10, &bond->params.num_peer_notif); | ||
888 | return err ? err : count; | ||
889 | } | ||
890 | static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, | ||
891 | bonding_show_num_peer_notif, bonding_store_num_peer_notif); | ||
892 | static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR, | ||
893 | bonding_show_num_peer_notif, bonding_store_num_peer_notif); | ||
894 | |||
895 | /* | ||
872 | * Show and set the MII monitor interval. There are two tricky bits | 896 | * Show and set the MII monitor interval. There are two tricky bits |
873 | * here. First, if MII monitoring is activated, then we must disable | 897 | * here. First, if MII monitoring is activated, then we must disable |
874 | * ARP monitoring. Second, if the timer isn't running, we must | 898 | * ARP monitoring. Second, if the timer isn't running, we must |
@@ -1566,6 +1590,8 @@ static struct attribute *per_bond_attrs[] = { | |||
1566 | &dev_attr_lacp_rate.attr, | 1590 | &dev_attr_lacp_rate.attr, |
1567 | &dev_attr_ad_select.attr, | 1591 | &dev_attr_ad_select.attr, |
1568 | &dev_attr_xmit_hash_policy.attr, | 1592 | &dev_attr_xmit_hash_policy.attr, |
1593 | &dev_attr_num_grat_arp.attr, | ||
1594 | &dev_attr_num_unsol_na.attr, | ||
1569 | &dev_attr_miimon.attr, | 1595 | &dev_attr_miimon.attr, |
1570 | &dev_attr_primary.attr, | 1596 | &dev_attr_primary.attr, |
1571 | &dev_attr_primary_reselect.attr, | 1597 | &dev_attr_primary_reselect.attr, |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 85fb8220e28..d08362e1a0d 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -24,8 +24,8 @@ | |||
24 | #include "bond_3ad.h" | 24 | #include "bond_3ad.h" |
25 | #include "bond_alb.h" | 25 | #include "bond_alb.h" |
26 | 26 | ||
27 | #define DRV_VERSION "3.7.0" | 27 | #define DRV_VERSION "3.7.1" |
28 | #define DRV_RELDATE "June 2, 2010" | 28 | #define DRV_RELDATE "April 27, 2011" |
29 | #define DRV_NAME "bonding" | 29 | #define DRV_NAME "bonding" |
30 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 30 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
31 | 31 | ||
@@ -149,6 +149,7 @@ struct bond_params { | |||
149 | int mode; | 149 | int mode; |
150 | int xmit_policy; | 150 | int xmit_policy; |
151 | int miimon; | 151 | int miimon; |
152 | u8 num_peer_notif; | ||
152 | int arp_interval; | 153 | int arp_interval; |
153 | int arp_validate; | 154 | int arp_validate; |
154 | int use_carrier; | 155 | int use_carrier; |
@@ -231,6 +232,7 @@ struct bonding { | |||
231 | rwlock_t lock; | 232 | rwlock_t lock; |
232 | rwlock_t curr_slave_lock; | 233 | rwlock_t curr_slave_lock; |
233 | s8 kill_timers; | 234 | s8 kill_timers; |
235 | u8 send_peer_notif; | ||
234 | s8 setup_by_slave; | 236 | s8 setup_by_slave; |
235 | s8 igmp_retrans; | 237 | s8 igmp_retrans; |
236 | #ifdef CONFIG_PROC_FS | 238 | #ifdef CONFIG_PROC_FS |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index acf553f95b5..5345b0bee6d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1203,7 +1203,6 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1203 | break; | 1203 | break; |
1204 | /* fall through */ | 1204 | /* fall through */ |
1205 | case NETDEV_NOTIFY_PEERS: | 1205 | case NETDEV_NOTIFY_PEERS: |
1206 | case NETDEV_BONDING_FAILOVER: | ||
1207 | /* Send gratuitous ARP to notify of link change */ | 1206 | /* Send gratuitous ARP to notify of link change */ |
1208 | inetdev_send_gratuitous_arp(dev, in_dev); | 1207 | inetdev_send_gratuitous_arp(dev, in_dev); |
1209 | break; | 1208 | break; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 69aacd18e06..7596f071d30 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1747,7 +1747,6 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, | |||
1747 | fib6_run_gc(~0UL, net); | 1747 | fib6_run_gc(~0UL, net); |
1748 | break; | 1748 | break; |
1749 | case NETDEV_NOTIFY_PEERS: | 1749 | case NETDEV_NOTIFY_PEERS: |
1750 | case NETDEV_BONDING_FAILOVER: | ||
1751 | ndisc_send_unsol_na(dev); | 1750 | ndisc_send_unsol_na(dev); |
1752 | break; | 1751 | break; |
1753 | default: | 1752 | default: |