diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 39575d764974..02de3e031237 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 num_grat_arp = 1; | 91 | static int num_grat_arp = 1; |
92 | static int num_unsol_na = 1; | ||
92 | static int miimon = BOND_LINK_MON_INTERV; | 93 | static int miimon = BOND_LINK_MON_INTERV; |
93 | static int updelay = 0; | 94 | static int updelay = 0; |
94 | static int downdelay = 0; | 95 | static int downdelay = 0; |
@@ -96,6 +97,7 @@ static int use_carrier = 1; | |||
96 | static char *mode = NULL; | 97 | static char *mode = NULL; |
97 | static char *primary = NULL; | 98 | static char *primary = NULL; |
98 | static char *lacp_rate = NULL; | 99 | static char *lacp_rate = NULL; |
100 | static char *ad_select = NULL; | ||
99 | static char *xmit_hash_policy = NULL; | 101 | static char *xmit_hash_policy = NULL; |
100 | static int arp_interval = BOND_LINK_ARP_INTERV; | 102 | static int arp_interval = BOND_LINK_ARP_INTERV; |
101 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 103 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
@@ -107,6 +109,8 @@ module_param(max_bonds, int, 0); | |||
107 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); | 109 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); |
108 | module_param(num_grat_arp, int, 0644); | 110 | module_param(num_grat_arp, int, 0644); |
109 | MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); | 111 | MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); |
112 | module_param(num_unsol_na, int, 0644); | ||
113 | MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event"); | ||
110 | module_param(miimon, int, 0); | 114 | module_param(miimon, int, 0); |
111 | MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); | 115 | MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); |
112 | module_param(updelay, int, 0); | 116 | module_param(updelay, int, 0); |
@@ -127,6 +131,8 @@ MODULE_PARM_DESC(primary, "Primary network device to use"); | |||
127 | module_param(lacp_rate, charp, 0); | 131 | module_param(lacp_rate, charp, 0); |
128 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner " | 132 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner " |
129 | "(slow/fast)"); | 133 | "(slow/fast)"); |
134 | module_param(ad_select, charp, 0); | ||
135 | MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2)"); | ||
130 | module_param(xmit_hash_policy, charp, 0); | 136 | module_param(xmit_hash_policy, charp, 0); |
131 | MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)" | 137 | MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)" |
132 | ", 1 for layer 3+4"); | 138 | ", 1 for layer 3+4"); |
@@ -197,6 +203,13 @@ struct bond_parm_tbl fail_over_mac_tbl[] = { | |||
197 | { NULL, -1}, | 203 | { NULL, -1}, |
198 | }; | 204 | }; |
199 | 205 | ||
206 | struct bond_parm_tbl ad_select_tbl[] = { | ||
207 | { "stable", BOND_AD_STABLE}, | ||
208 | { "bandwidth", BOND_AD_BANDWIDTH}, | ||
209 | { "count", BOND_AD_COUNT}, | ||
210 | { NULL, -1}, | ||
211 | }; | ||
212 | |||
200 | /*-------------------------- Forward declarations ---------------------------*/ | 213 | /*-------------------------- Forward declarations ---------------------------*/ |
201 | 214 | ||
202 | static void bond_send_gratuitous_arp(struct bonding *bond); | 215 | static void bond_send_gratuitous_arp(struct bonding *bond); |
@@ -242,14 +255,13 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id) | |||
242 | dprintk("bond: %s, vlan id %d\n", | 255 | dprintk("bond: %s, vlan id %d\n", |
243 | (bond ? bond->dev->name: "None"), vlan_id); | 256 | (bond ? bond->dev->name: "None"), vlan_id); |
244 | 257 | ||
245 | vlan = kmalloc(sizeof(struct vlan_entry), GFP_KERNEL); | 258 | vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL); |
246 | if (!vlan) { | 259 | if (!vlan) { |
247 | return -ENOMEM; | 260 | return -ENOMEM; |
248 | } | 261 | } |
249 | 262 | ||
250 | INIT_LIST_HEAD(&vlan->vlan_list); | 263 | INIT_LIST_HEAD(&vlan->vlan_list); |
251 | vlan->vlan_id = vlan_id; | 264 | vlan->vlan_id = vlan_id; |
252 | vlan->vlan_ip = 0; | ||
253 | 265 | ||
254 | write_lock_bh(&bond->lock); | 266 | write_lock_bh(&bond->lock); |
255 | 267 | ||
@@ -1208,6 +1220,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1208 | bond->send_grat_arp = bond->params.num_grat_arp; | 1220 | bond->send_grat_arp = bond->params.num_grat_arp; |
1209 | bond_send_gratuitous_arp(bond); | 1221 | bond_send_gratuitous_arp(bond); |
1210 | 1222 | ||
1223 | bond->send_unsol_na = bond->params.num_unsol_na; | ||
1224 | bond_send_unsolicited_na(bond); | ||
1225 | |||
1211 | write_unlock_bh(&bond->curr_slave_lock); | 1226 | write_unlock_bh(&bond->curr_slave_lock); |
1212 | read_unlock(&bond->lock); | 1227 | read_unlock(&bond->lock); |
1213 | 1228 | ||
@@ -2463,6 +2478,12 @@ void bond_mii_monitor(struct work_struct *work) | |||
2463 | read_unlock(&bond->curr_slave_lock); | 2478 | read_unlock(&bond->curr_slave_lock); |
2464 | } | 2479 | } |
2465 | 2480 | ||
2481 | if (bond->send_unsol_na) { | ||
2482 | read_lock(&bond->curr_slave_lock); | ||
2483 | bond_send_unsolicited_na(bond); | ||
2484 | read_unlock(&bond->curr_slave_lock); | ||
2485 | } | ||
2486 | |||
2466 | if (bond_miimon_inspect(bond)) { | 2487 | if (bond_miimon_inspect(bond)) { |
2467 | read_unlock(&bond->lock); | 2488 | read_unlock(&bond->lock); |
2468 | rtnl_lock(); | 2489 | rtnl_lock(); |
@@ -3158,6 +3179,12 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3158 | read_unlock(&bond->curr_slave_lock); | 3179 | read_unlock(&bond->curr_slave_lock); |
3159 | } | 3180 | } |
3160 | 3181 | ||
3182 | if (bond->send_unsol_na) { | ||
3183 | read_lock(&bond->curr_slave_lock); | ||
3184 | bond_send_unsolicited_na(bond); | ||
3185 | read_unlock(&bond->curr_slave_lock); | ||
3186 | } | ||
3187 | |||
3161 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { | 3188 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { |
3162 | read_unlock(&bond->lock); | 3189 | read_unlock(&bond->lock); |
3163 | rtnl_lock(); | 3190 | rtnl_lock(); |
@@ -3301,6 +3328,8 @@ static void bond_info_show_master(struct seq_file *seq) | |||
3301 | seq_puts(seq, "\n802.3ad info\n"); | 3328 | seq_puts(seq, "\n802.3ad info\n"); |
3302 | seq_printf(seq, "LACP rate: %s\n", | 3329 | seq_printf(seq, "LACP rate: %s\n", |
3303 | (bond->params.lacp_fast) ? "fast" : "slow"); | 3330 | (bond->params.lacp_fast) ? "fast" : "slow"); |
3331 | seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", | ||
3332 | ad_select_tbl[bond->params.ad_select].modename); | ||
3304 | 3333 | ||
3305 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { | 3334 | if (bond_3ad_get_active_agg_info(bond, &ad_info)) { |
3306 | seq_printf(seq, "bond %s has no active aggregator\n", | 3335 | seq_printf(seq, "bond %s has no active aggregator\n", |
@@ -3807,6 +3836,7 @@ static int bond_open(struct net_device *bond_dev) | |||
3807 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3836 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3808 | /* register to receive LACPDUs */ | 3837 | /* register to receive LACPDUs */ |
3809 | bond_register_lacpdu(bond); | 3838 | bond_register_lacpdu(bond); |
3839 | bond_3ad_initiate_agg_selection(bond, 1); | ||
3810 | } | 3840 | } |
3811 | 3841 | ||
3812 | return 0; | 3842 | return 0; |
@@ -3827,6 +3857,7 @@ static int bond_close(struct net_device *bond_dev) | |||
3827 | write_lock_bh(&bond->lock); | 3857 | write_lock_bh(&bond->lock); |
3828 | 3858 | ||
3829 | bond->send_grat_arp = 0; | 3859 | bond->send_grat_arp = 0; |
3860 | bond->send_unsol_na = 0; | ||
3830 | 3861 | ||
3831 | /* signal timers not to re-arm */ | 3862 | /* signal timers not to re-arm */ |
3832 | bond->kill_timers = 1; | 3863 | bond->kill_timers = 1; |
@@ -4542,6 +4573,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4542 | bond->primary_slave = NULL; | 4573 | bond->primary_slave = NULL; |
4543 | bond->dev = bond_dev; | 4574 | bond->dev = bond_dev; |
4544 | bond->send_grat_arp = 0; | 4575 | bond->send_grat_arp = 0; |
4576 | bond->send_unsol_na = 0; | ||
4545 | bond->setup_by_slave = 0; | 4577 | bond->setup_by_slave = 0; |
4546 | INIT_LIST_HEAD(&bond->vlan_list); | 4578 | INIT_LIST_HEAD(&bond->vlan_list); |
4547 | 4579 | ||
@@ -4744,6 +4776,23 @@ static int bond_check_params(struct bond_params *params) | |||
4744 | } | 4776 | } |
4745 | } | 4777 | } |
4746 | 4778 | ||
4779 | if (ad_select) { | ||
4780 | params->ad_select = bond_parse_parm(ad_select, ad_select_tbl); | ||
4781 | if (params->ad_select == -1) { | ||
4782 | printk(KERN_ERR DRV_NAME | ||
4783 | ": Error: Invalid ad_select \"%s\"\n", | ||
4784 | ad_select == NULL ? "NULL" : ad_select); | ||
4785 | return -EINVAL; | ||
4786 | } | ||
4787 | |||
4788 | if (bond_mode != BOND_MODE_8023AD) { | ||
4789 | printk(KERN_WARNING DRV_NAME | ||
4790 | ": ad_select param only affects 802.3ad mode\n"); | ||
4791 | } | ||
4792 | } else { | ||
4793 | params->ad_select = BOND_AD_STABLE; | ||
4794 | } | ||
4795 | |||
4747 | if (max_bonds < 0 || max_bonds > INT_MAX) { | 4796 | if (max_bonds < 0 || max_bonds > INT_MAX) { |
4748 | printk(KERN_WARNING DRV_NAME | 4797 | printk(KERN_WARNING DRV_NAME |
4749 | ": Warning: max_bonds (%d) not in range %d-%d, so it " | 4798 | ": Warning: max_bonds (%d) not in range %d-%d, so it " |
@@ -4791,6 +4840,13 @@ static int bond_check_params(struct bond_params *params) | |||
4791 | num_grat_arp = 1; | 4840 | num_grat_arp = 1; |
4792 | } | 4841 | } |
4793 | 4842 | ||
4843 | if (num_unsol_na < 0 || num_unsol_na > 255) { | ||
4844 | printk(KERN_WARNING DRV_NAME | ||
4845 | ": Warning: num_unsol_na (%d) not in range 0-255 so it " | ||
4846 | "was reset to 1 \n", num_unsol_na); | ||
4847 | num_unsol_na = 1; | ||
4848 | } | ||
4849 | |||
4794 | /* reset values for 802.3ad */ | 4850 | /* reset values for 802.3ad */ |
4795 | if (bond_mode == BOND_MODE_8023AD) { | 4851 | if (bond_mode == BOND_MODE_8023AD) { |
4796 | if (!miimon) { | 4852 | if (!miimon) { |
@@ -4992,6 +5048,7 @@ static int bond_check_params(struct bond_params *params) | |||
4992 | params->xmit_policy = xmit_hashtype; | 5048 | params->xmit_policy = xmit_hashtype; |
4993 | params->miimon = miimon; | 5049 | params->miimon = miimon; |
4994 | params->num_grat_arp = num_grat_arp; | 5050 | params->num_grat_arp = num_grat_arp; |
5051 | params->num_unsol_na = num_unsol_na; | ||
4995 | params->arp_interval = arp_interval; | 5052 | params->arp_interval = arp_interval; |
4996 | params->arp_validate = arp_validate_value; | 5053 | params->arp_validate = arp_validate_value; |
4997 | params->updelay = updelay; | 5054 | params->updelay = updelay; |
@@ -5144,6 +5201,7 @@ static int __init bonding_init(void) | |||
5144 | 5201 | ||
5145 | register_netdevice_notifier(&bond_netdev_notifier); | 5202 | register_netdevice_notifier(&bond_netdev_notifier); |
5146 | register_inetaddr_notifier(&bond_inetaddr_notifier); | 5203 | register_inetaddr_notifier(&bond_inetaddr_notifier); |
5204 | bond_register_ipv6_notifier(); | ||
5147 | 5205 | ||
5148 | goto out; | 5206 | goto out; |
5149 | err: | 5207 | err: |
@@ -5166,6 +5224,7 @@ static void __exit bonding_exit(void) | |||
5166 | { | 5224 | { |
5167 | unregister_netdevice_notifier(&bond_netdev_notifier); | 5225 | unregister_netdevice_notifier(&bond_netdev_notifier); |
5168 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); | 5226 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); |
5227 | bond_unregister_ipv6_notifier(); | ||
5169 | 5228 | ||
5170 | bond_destroy_sysfs(); | 5229 | bond_destroy_sysfs(); |
5171 | 5230 | ||