diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 121 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 98 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 4 |
3 files changed, 109 insertions, 114 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6937ef0e7275..b0b26036266b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #include <linux/ethtool.h> | 74 | #include <linux/ethtool.h> |
75 | #include <linux/if_vlan.h> | 75 | #include <linux/if_vlan.h> |
76 | #include <linux/if_bonding.h> | 76 | #include <linux/if_bonding.h> |
77 | #include <linux/jiffies.h> | ||
77 | #include <net/route.h> | 78 | #include <net/route.h> |
78 | #include <net/net_namespace.h> | 79 | #include <net/net_namespace.h> |
79 | #include "bonding.h" | 80 | #include "bonding.h" |
@@ -174,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = { | |||
174 | struct bond_parm_tbl xmit_hashtype_tbl[] = { | 175 | struct bond_parm_tbl xmit_hashtype_tbl[] = { |
175 | { "layer2", BOND_XMIT_POLICY_LAYER2}, | 176 | { "layer2", BOND_XMIT_POLICY_LAYER2}, |
176 | { "layer3+4", BOND_XMIT_POLICY_LAYER34}, | 177 | { "layer3+4", BOND_XMIT_POLICY_LAYER34}, |
178 | { "layer2+3", BOND_XMIT_POLICY_LAYER23}, | ||
177 | { NULL, -1}, | 179 | { NULL, -1}, |
178 | }; | 180 | }; |
179 | 181 | ||
@@ -1847,9 +1849,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1847 | */ | 1849 | */ |
1848 | void bond_destroy(struct bonding *bond) | 1850 | void bond_destroy(struct bonding *bond) |
1849 | { | 1851 | { |
1850 | unregister_netdevice(bond->dev); | ||
1851 | bond_deinit(bond->dev); | 1852 | bond_deinit(bond->dev); |
1852 | bond_destroy_sysfs_entry(bond); | 1853 | bond_destroy_sysfs_entry(bond); |
1854 | unregister_netdevice(bond->dev); | ||
1853 | } | 1855 | } |
1854 | 1856 | ||
1855 | /* | 1857 | /* |
@@ -2722,8 +2724,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2722 | */ | 2724 | */ |
2723 | bond_for_each_slave(bond, slave, i) { | 2725 | bond_for_each_slave(bond, slave, i) { |
2724 | if (slave->link != BOND_LINK_UP) { | 2726 | if (slave->link != BOND_LINK_UP) { |
2725 | if (((jiffies - slave->dev->trans_start) <= delta_in_ticks) && | 2727 | if (time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks) && |
2726 | ((jiffies - slave->dev->last_rx) <= delta_in_ticks)) { | 2728 | time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) { |
2727 | 2729 | ||
2728 | slave->link = BOND_LINK_UP; | 2730 | slave->link = BOND_LINK_UP; |
2729 | slave->state = BOND_STATE_ACTIVE; | 2731 | slave->state = BOND_STATE_ACTIVE; |
@@ -2754,8 +2756,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2754 | * when the source ip is 0, so don't take the link down | 2756 | * when the source ip is 0, so don't take the link down |
2755 | * if we don't know our ip yet | 2757 | * if we don't know our ip yet |
2756 | */ | 2758 | */ |
2757 | if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 2759 | if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) || |
2758 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && | 2760 | (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks) && |
2759 | bond_has_ip(bond))) { | 2761 | bond_has_ip(bond))) { |
2760 | 2762 | ||
2761 | slave->link = BOND_LINK_DOWN; | 2763 | slave->link = BOND_LINK_DOWN; |
@@ -2848,8 +2850,8 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
2848 | */ | 2850 | */ |
2849 | bond_for_each_slave(bond, slave, i) { | 2851 | bond_for_each_slave(bond, slave, i) { |
2850 | if (slave->link != BOND_LINK_UP) { | 2852 | if (slave->link != BOND_LINK_UP) { |
2851 | if ((jiffies - slave_last_rx(bond, slave)) <= | 2853 | if (time_before_eq(jiffies, |
2852 | delta_in_ticks) { | 2854 | slave_last_rx(bond, slave) + delta_in_ticks)) { |
2853 | 2855 | ||
2854 | slave->link = BOND_LINK_UP; | 2856 | slave->link = BOND_LINK_UP; |
2855 | 2857 | ||
@@ -2858,7 +2860,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
2858 | write_lock_bh(&bond->curr_slave_lock); | 2860 | write_lock_bh(&bond->curr_slave_lock); |
2859 | 2861 | ||
2860 | if ((!bond->curr_active_slave) && | 2862 | if ((!bond->curr_active_slave) && |
2861 | ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { | 2863 | time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks)) { |
2862 | bond_change_active_slave(bond, slave); | 2864 | bond_change_active_slave(bond, slave); |
2863 | bond->current_arp_slave = NULL; | 2865 | bond->current_arp_slave = NULL; |
2864 | } else if (bond->curr_active_slave != slave) { | 2866 | } else if (bond->curr_active_slave != slave) { |
@@ -2897,7 +2899,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
2897 | 2899 | ||
2898 | if ((slave != bond->curr_active_slave) && | 2900 | if ((slave != bond->curr_active_slave) && |
2899 | (!bond->current_arp_slave) && | 2901 | (!bond->current_arp_slave) && |
2900 | (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) && | 2902 | (time_after_eq(jiffies, slave_last_rx(bond, slave) + 3*delta_in_ticks) && |
2901 | bond_has_ip(bond))) { | 2903 | bond_has_ip(bond))) { |
2902 | /* a backup slave has gone down; three times | 2904 | /* a backup slave has gone down; three times |
2903 | * the delta allows the current slave to be | 2905 | * the delta allows the current slave to be |
@@ -2943,10 +2945,10 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
2943 | * before being taken out. if a primary is being used, check | 2945 | * before being taken out. if a primary is being used, check |
2944 | * if it is up and needs to take over as the curr_active_slave | 2946 | * if it is up and needs to take over as the curr_active_slave |
2945 | */ | 2947 | */ |
2946 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 2948 | if ((time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) || |
2947 | (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) && | 2949 | (time_after_eq(jiffies, slave_last_rx(bond, slave) + 2*delta_in_ticks) && |
2948 | bond_has_ip(bond))) && | 2950 | bond_has_ip(bond))) && |
2949 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { | 2951 | time_after_eq(jiffies, slave->jiffies + 2*delta_in_ticks)) { |
2950 | 2952 | ||
2951 | slave->link = BOND_LINK_DOWN; | 2953 | slave->link = BOND_LINK_DOWN; |
2952 | 2954 | ||
@@ -3604,6 +3606,24 @@ void bond_unregister_arp(struct bonding *bond) | |||
3604 | /*---------------------------- Hashing Policies -----------------------------*/ | 3606 | /*---------------------------- Hashing Policies -----------------------------*/ |
3605 | 3607 | ||
3606 | /* | 3608 | /* |
3609 | * Hash for the output device based upon layer 2 and layer 3 data. If | ||
3610 | * the packet is not IP mimic bond_xmit_hash_policy_l2() | ||
3611 | */ | ||
3612 | static int bond_xmit_hash_policy_l23(struct sk_buff *skb, | ||
3613 | struct net_device *bond_dev, int count) | ||
3614 | { | ||
3615 | struct ethhdr *data = (struct ethhdr *)skb->data; | ||
3616 | struct iphdr *iph = ip_hdr(skb); | ||
3617 | |||
3618 | if (skb->protocol == __constant_htons(ETH_P_IP)) { | ||
3619 | return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ | ||
3620 | (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count; | ||
3621 | } | ||
3622 | |||
3623 | return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; | ||
3624 | } | ||
3625 | |||
3626 | /* | ||
3607 | * Hash for the output device based upon layer 3 and layer 4 data. If | 3627 | * Hash for the output device based upon layer 3 and layer 4 data. If |
3608 | * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is | 3628 | * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is |
3609 | * altogether not IP, mimic bond_xmit_hash_policy_l2() | 3629 | * altogether not IP, mimic bond_xmit_hash_policy_l2() |
@@ -4305,6 +4325,22 @@ out: | |||
4305 | 4325 | ||
4306 | /*------------------------- Device initialization ---------------------------*/ | 4326 | /*------------------------- Device initialization ---------------------------*/ |
4307 | 4327 | ||
4328 | static void bond_set_xmit_hash_policy(struct bonding *bond) | ||
4329 | { | ||
4330 | switch (bond->params.xmit_policy) { | ||
4331 | case BOND_XMIT_POLICY_LAYER23: | ||
4332 | bond->xmit_hash_policy = bond_xmit_hash_policy_l23; | ||
4333 | break; | ||
4334 | case BOND_XMIT_POLICY_LAYER34: | ||
4335 | bond->xmit_hash_policy = bond_xmit_hash_policy_l34; | ||
4336 | break; | ||
4337 | case BOND_XMIT_POLICY_LAYER2: | ||
4338 | default: | ||
4339 | bond->xmit_hash_policy = bond_xmit_hash_policy_l2; | ||
4340 | break; | ||
4341 | } | ||
4342 | } | ||
4343 | |||
4308 | /* | 4344 | /* |
4309 | * set bond mode specific net device operations | 4345 | * set bond mode specific net device operations |
4310 | */ | 4346 | */ |
@@ -4321,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4321 | break; | 4357 | break; |
4322 | case BOND_MODE_XOR: | 4358 | case BOND_MODE_XOR: |
4323 | bond_dev->hard_start_xmit = bond_xmit_xor; | 4359 | bond_dev->hard_start_xmit = bond_xmit_xor; |
4324 | if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) | 4360 | bond_set_xmit_hash_policy(bond); |
4325 | bond->xmit_hash_policy = bond_xmit_hash_policy_l34; | ||
4326 | else | ||
4327 | bond->xmit_hash_policy = bond_xmit_hash_policy_l2; | ||
4328 | break; | 4361 | break; |
4329 | case BOND_MODE_BROADCAST: | 4362 | case BOND_MODE_BROADCAST: |
4330 | bond_dev->hard_start_xmit = bond_xmit_broadcast; | 4363 | bond_dev->hard_start_xmit = bond_xmit_broadcast; |
@@ -4332,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4332 | case BOND_MODE_8023AD: | 4365 | case BOND_MODE_8023AD: |
4333 | bond_set_master_3ad_flags(bond); | 4366 | bond_set_master_3ad_flags(bond); |
4334 | bond_dev->hard_start_xmit = bond_3ad_xmit_xor; | 4367 | bond_dev->hard_start_xmit = bond_3ad_xmit_xor; |
4335 | if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) | 4368 | bond_set_xmit_hash_policy(bond); |
4336 | bond->xmit_hash_policy = bond_xmit_hash_policy_l34; | ||
4337 | else | ||
4338 | bond->xmit_hash_policy = bond_xmit_hash_policy_l2; | ||
4339 | break; | 4369 | break; |
4340 | case BOND_MODE_ALB: | 4370 | case BOND_MODE_ALB: |
4341 | bond_set_master_alb_flags(bond); | 4371 | bond_set_master_alb_flags(bond); |
@@ -4405,6 +4435,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4405 | bond_dev->set_multicast_list = bond_set_multicast_list; | 4435 | bond_dev->set_multicast_list = bond_set_multicast_list; |
4406 | bond_dev->change_mtu = bond_change_mtu; | 4436 | bond_dev->change_mtu = bond_change_mtu; |
4407 | bond_dev->set_mac_address = bond_set_mac_address; | 4437 | bond_dev->set_mac_address = bond_set_mac_address; |
4438 | bond_dev->validate_addr = NULL; | ||
4408 | 4439 | ||
4409 | bond_set_mode_ops(bond, bond->params.mode); | 4440 | bond_set_mode_ops(bond, bond->params.mode); |
4410 | 4441 | ||
@@ -4461,6 +4492,27 @@ static void bond_deinit(struct net_device *bond_dev) | |||
4461 | #endif | 4492 | #endif |
4462 | } | 4493 | } |
4463 | 4494 | ||
4495 | static void bond_work_cancel_all(struct bonding *bond) | ||
4496 | { | ||
4497 | write_lock_bh(&bond->lock); | ||
4498 | bond->kill_timers = 1; | ||
4499 | write_unlock_bh(&bond->lock); | ||
4500 | |||
4501 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4502 | cancel_delayed_work(&bond->mii_work); | ||
4503 | |||
4504 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4505 | cancel_delayed_work(&bond->arp_work); | ||
4506 | |||
4507 | if (bond->params.mode == BOND_MODE_ALB && | ||
4508 | delayed_work_pending(&bond->alb_work)) | ||
4509 | cancel_delayed_work(&bond->alb_work); | ||
4510 | |||
4511 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4512 | delayed_work_pending(&bond->ad_work)) | ||
4513 | cancel_delayed_work(&bond->ad_work); | ||
4514 | } | ||
4515 | |||
4464 | /* Unregister and free all bond devices. | 4516 | /* Unregister and free all bond devices. |
4465 | * Caller must hold rtnl_lock. | 4517 | * Caller must hold rtnl_lock. |
4466 | */ | 4518 | */ |
@@ -4471,11 +4523,12 @@ static void bond_free_all(void) | |||
4471 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { | 4523 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { |
4472 | struct net_device *bond_dev = bond->dev; | 4524 | struct net_device *bond_dev = bond->dev; |
4473 | 4525 | ||
4526 | bond_work_cancel_all(bond); | ||
4474 | bond_mc_list_destroy(bond); | 4527 | bond_mc_list_destroy(bond); |
4475 | /* Release the bonded slaves */ | 4528 | /* Release the bonded slaves */ |
4476 | bond_release_all(bond_dev); | 4529 | bond_release_all(bond_dev); |
4477 | unregister_netdevice(bond_dev); | ||
4478 | bond_deinit(bond_dev); | 4530 | bond_deinit(bond_dev); |
4531 | unregister_netdevice(bond_dev); | ||
4479 | } | 4532 | } |
4480 | 4533 | ||
4481 | #ifdef CONFIG_PROC_FS | 4534 | #ifdef CONFIG_PROC_FS |
@@ -4496,8 +4549,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) | |||
4496 | for (i = 0; tbl[i].modename; i++) { | 4549 | for (i = 0; tbl[i].modename; i++) { |
4497 | if ((isdigit(*mode_arg) && | 4550 | if ((isdigit(*mode_arg) && |
4498 | tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || | 4551 | tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || |
4499 | (strncmp(mode_arg, tbl[i].modename, | 4552 | (strcmp(mode_arg, tbl[i].modename) == 0)) { |
4500 | strlen(tbl[i].modename)) == 0)) { | ||
4501 | return tbl[i].mode; | 4553 | return tbl[i].mode; |
4502 | } | 4554 | } |
4503 | } | 4555 | } |
@@ -4872,27 +4924,6 @@ out_rtnl: | |||
4872 | return res; | 4924 | return res; |
4873 | } | 4925 | } |
4874 | 4926 | ||
4875 | static void bond_work_cancel_all(struct bonding *bond) | ||
4876 | { | ||
4877 | write_lock_bh(&bond->lock); | ||
4878 | bond->kill_timers = 1; | ||
4879 | write_unlock_bh(&bond->lock); | ||
4880 | |||
4881 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4882 | cancel_delayed_work(&bond->mii_work); | ||
4883 | |||
4884 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4885 | cancel_delayed_work(&bond->arp_work); | ||
4886 | |||
4887 | if (bond->params.mode == BOND_MODE_ALB && | ||
4888 | delayed_work_pending(&bond->alb_work)) | ||
4889 | cancel_delayed_work(&bond->alb_work); | ||
4890 | |||
4891 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4892 | delayed_work_pending(&bond->ad_work)) | ||
4893 | cancel_delayed_work(&bond->ad_work); | ||
4894 | } | ||
4895 | |||
4896 | static int __init bonding_init(void) | 4927 | static int __init bonding_init(void) |
4897 | { | 4928 | { |
4898 | int i; | 4929 | int i; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 7a06ade85b02..11b76b352415 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -74,7 +74,7 @@ struct rw_semaphore bonding_rwsem; | |||
74 | * "show" function for the bond_masters attribute. | 74 | * "show" function for the bond_masters attribute. |
75 | * The class parameter is ignored. | 75 | * The class parameter is ignored. |
76 | */ | 76 | */ |
77 | static ssize_t bonding_show_bonds(struct class *cls, char *buffer) | 77 | static ssize_t bonding_show_bonds(struct class *cls, char *buf) |
78 | { | 78 | { |
79 | int res = 0; | 79 | int res = 0; |
80 | struct bonding *bond; | 80 | struct bonding *bond; |
@@ -86,14 +86,13 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buffer) | |||
86 | /* not enough space for another interface name */ | 86 | /* not enough space for another interface name */ |
87 | if ((PAGE_SIZE - res) > 10) | 87 | if ((PAGE_SIZE - res) > 10) |
88 | res = PAGE_SIZE - 10; | 88 | res = PAGE_SIZE - 10; |
89 | res += sprintf(buffer + res, "++more++"); | 89 | res += sprintf(buf + res, "++more++ "); |
90 | break; | 90 | break; |
91 | } | 91 | } |
92 | res += sprintf(buffer + res, "%s ", | 92 | res += sprintf(buf + res, "%s ", bond->dev->name); |
93 | bond->dev->name); | ||
94 | } | 93 | } |
95 | res += sprintf(buffer + res, "\n"); | 94 | if (res) |
96 | res++; | 95 | buf[res-1] = '\n'; /* eat the leftover space */ |
97 | up_read(&(bonding_rwsem)); | 96 | up_read(&(bonding_rwsem)); |
98 | return res; | 97 | return res; |
99 | } | 98 | } |
@@ -235,14 +234,14 @@ static ssize_t bonding_show_slaves(struct device *d, | |||
235 | /* not enough space for another interface name */ | 234 | /* not enough space for another interface name */ |
236 | if ((PAGE_SIZE - res) > 10) | 235 | if ((PAGE_SIZE - res) > 10) |
237 | res = PAGE_SIZE - 10; | 236 | res = PAGE_SIZE - 10; |
238 | res += sprintf(buf + res, "++more++"); | 237 | res += sprintf(buf + res, "++more++ "); |
239 | break; | 238 | break; |
240 | } | 239 | } |
241 | res += sprintf(buf + res, "%s ", slave->dev->name); | 240 | res += sprintf(buf + res, "%s ", slave->dev->name); |
242 | } | 241 | } |
243 | read_unlock(&bond->lock); | 242 | read_unlock(&bond->lock); |
244 | res += sprintf(buf + res, "\n"); | 243 | if (res) |
245 | res++; | 244 | buf[res-1] = '\n'; /* eat the leftover space */ |
246 | return res; | 245 | return res; |
247 | } | 246 | } |
248 | 247 | ||
@@ -406,7 +405,7 @@ static ssize_t bonding_show_mode(struct device *d, | |||
406 | 405 | ||
407 | return sprintf(buf, "%s %d\n", | 406 | return sprintf(buf, "%s %d\n", |
408 | bond_mode_tbl[bond->params.mode].modename, | 407 | bond_mode_tbl[bond->params.mode].modename, |
409 | bond->params.mode) + 1; | 408 | bond->params.mode); |
410 | } | 409 | } |
411 | 410 | ||
412 | static ssize_t bonding_store_mode(struct device *d, | 411 | static ssize_t bonding_store_mode(struct device *d, |
@@ -457,20 +456,11 @@ static ssize_t bonding_show_xmit_hash(struct device *d, | |||
457 | struct device_attribute *attr, | 456 | struct device_attribute *attr, |
458 | char *buf) | 457 | char *buf) |
459 | { | 458 | { |
460 | int count; | ||
461 | struct bonding *bond = to_bond(d); | 459 | struct bonding *bond = to_bond(d); |
462 | 460 | ||
463 | if ((bond->params.mode != BOND_MODE_XOR) && | 461 | return sprintf(buf, "%s %d\n", |
464 | (bond->params.mode != BOND_MODE_8023AD)) { | 462 | xmit_hashtype_tbl[bond->params.xmit_policy].modename, |
465 | // Not Applicable | 463 | bond->params.xmit_policy); |
466 | count = sprintf(buf, "NA\n") + 1; | ||
467 | } else { | ||
468 | count = sprintf(buf, "%s %d\n", | ||
469 | xmit_hashtype_tbl[bond->params.xmit_policy].modename, | ||
470 | bond->params.xmit_policy) + 1; | ||
471 | } | ||
472 | |||
473 | return count; | ||
474 | } | 464 | } |
475 | 465 | ||
476 | static ssize_t bonding_store_xmit_hash(struct device *d, | 466 | static ssize_t bonding_store_xmit_hash(struct device *d, |
@@ -488,15 +478,6 @@ static ssize_t bonding_store_xmit_hash(struct device *d, | |||
488 | goto out; | 478 | goto out; |
489 | } | 479 | } |
490 | 480 | ||
491 | if ((bond->params.mode != BOND_MODE_XOR) && | ||
492 | (bond->params.mode != BOND_MODE_8023AD)) { | ||
493 | printk(KERN_ERR DRV_NAME | ||
494 | "%s: Transmit hash policy is irrelevant in this mode.\n", | ||
495 | bond->dev->name); | ||
496 | ret = -EPERM; | ||
497 | goto out; | ||
498 | } | ||
499 | |||
500 | new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl); | 481 | new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl); |
501 | if (new_value < 0) { | 482 | if (new_value < 0) { |
502 | printk(KERN_ERR DRV_NAME | 483 | printk(KERN_ERR DRV_NAME |
@@ -527,7 +508,7 @@ static ssize_t bonding_show_arp_validate(struct device *d, | |||
527 | 508 | ||
528 | return sprintf(buf, "%s %d\n", | 509 | return sprintf(buf, "%s %d\n", |
529 | arp_validate_tbl[bond->params.arp_validate].modename, | 510 | arp_validate_tbl[bond->params.arp_validate].modename, |
530 | bond->params.arp_validate) + 1; | 511 | bond->params.arp_validate); |
531 | } | 512 | } |
532 | 513 | ||
533 | static ssize_t bonding_store_arp_validate(struct device *d, | 514 | static ssize_t bonding_store_arp_validate(struct device *d, |
@@ -627,7 +608,7 @@ static ssize_t bonding_show_arp_interval(struct device *d, | |||
627 | { | 608 | { |
628 | struct bonding *bond = to_bond(d); | 609 | struct bonding *bond = to_bond(d); |
629 | 610 | ||
630 | return sprintf(buf, "%d\n", bond->params.arp_interval) + 1; | 611 | return sprintf(buf, "%d\n", bond->params.arp_interval); |
631 | } | 612 | } |
632 | 613 | ||
633 | static ssize_t bonding_store_arp_interval(struct device *d, | 614 | static ssize_t bonding_store_arp_interval(struct device *d, |
@@ -712,9 +693,7 @@ static ssize_t bonding_show_arp_targets(struct device *d, | |||
712 | NIPQUAD(bond->params.arp_targets[i])); | 693 | NIPQUAD(bond->params.arp_targets[i])); |
713 | } | 694 | } |
714 | if (res) | 695 | if (res) |
715 | res--; /* eat the leftover space */ | 696 | buf[res-1] = '\n'; /* eat the leftover space */ |
716 | res += sprintf(buf + res, "\n"); | ||
717 | res++; | ||
718 | return res; | 697 | return res; |
719 | } | 698 | } |
720 | 699 | ||
@@ -815,7 +794,7 @@ static ssize_t bonding_show_downdelay(struct device *d, | |||
815 | { | 794 | { |
816 | struct bonding *bond = to_bond(d); | 795 | struct bonding *bond = to_bond(d); |
817 | 796 | ||
818 | return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1; | 797 | return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon); |
819 | } | 798 | } |
820 | 799 | ||
821 | static ssize_t bonding_store_downdelay(struct device *d, | 800 | static ssize_t bonding_store_downdelay(struct device *d, |
@@ -872,7 +851,7 @@ static ssize_t bonding_show_updelay(struct device *d, | |||
872 | { | 851 | { |
873 | struct bonding *bond = to_bond(d); | 852 | struct bonding *bond = to_bond(d); |
874 | 853 | ||
875 | return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1; | 854 | return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon); |
876 | 855 | ||
877 | } | 856 | } |
878 | 857 | ||
@@ -936,7 +915,7 @@ static ssize_t bonding_show_lacp(struct device *d, | |||
936 | 915 | ||
937 | return sprintf(buf, "%s %d\n", | 916 | return sprintf(buf, "%s %d\n", |
938 | bond_lacp_tbl[bond->params.lacp_fast].modename, | 917 | bond_lacp_tbl[bond->params.lacp_fast].modename, |
939 | bond->params.lacp_fast) + 1; | 918 | bond->params.lacp_fast); |
940 | } | 919 | } |
941 | 920 | ||
942 | static ssize_t bonding_store_lacp(struct device *d, | 921 | static ssize_t bonding_store_lacp(struct device *d, |
@@ -992,7 +971,7 @@ static ssize_t bonding_show_miimon(struct device *d, | |||
992 | { | 971 | { |
993 | struct bonding *bond = to_bond(d); | 972 | struct bonding *bond = to_bond(d); |
994 | 973 | ||
995 | return sprintf(buf, "%d\n", bond->params.miimon) + 1; | 974 | return sprintf(buf, "%d\n", bond->params.miimon); |
996 | } | 975 | } |
997 | 976 | ||
998 | static ssize_t bonding_store_miimon(struct device *d, | 977 | static ssize_t bonding_store_miimon(struct device *d, |
@@ -1083,9 +1062,7 @@ static ssize_t bonding_show_primary(struct device *d, | |||
1083 | struct bonding *bond = to_bond(d); | 1062 | struct bonding *bond = to_bond(d); |
1084 | 1063 | ||
1085 | if (bond->primary_slave) | 1064 | if (bond->primary_slave) |
1086 | count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1; | 1065 | count = sprintf(buf, "%s\n", bond->primary_slave->dev->name); |
1087 | else | ||
1088 | count = sprintf(buf, "\n") + 1; | ||
1089 | 1066 | ||
1090 | return count; | 1067 | return count; |
1091 | } | 1068 | } |
@@ -1149,7 +1126,7 @@ static ssize_t bonding_show_carrier(struct device *d, | |||
1149 | { | 1126 | { |
1150 | struct bonding *bond = to_bond(d); | 1127 | struct bonding *bond = to_bond(d); |
1151 | 1128 | ||
1152 | return sprintf(buf, "%d\n", bond->params.use_carrier) + 1; | 1129 | return sprintf(buf, "%d\n", bond->params.use_carrier); |
1153 | } | 1130 | } |
1154 | 1131 | ||
1155 | static ssize_t bonding_store_carrier(struct device *d, | 1132 | static ssize_t bonding_store_carrier(struct device *d, |
@@ -1191,18 +1168,14 @@ static ssize_t bonding_show_active_slave(struct device *d, | |||
1191 | { | 1168 | { |
1192 | struct slave *curr; | 1169 | struct slave *curr; |
1193 | struct bonding *bond = to_bond(d); | 1170 | struct bonding *bond = to_bond(d); |
1194 | int count; | 1171 | int count = 0; |
1195 | |||
1196 | rtnl_lock(); | ||
1197 | 1172 | ||
1198 | read_lock(&bond->curr_slave_lock); | 1173 | read_lock(&bond->curr_slave_lock); |
1199 | curr = bond->curr_active_slave; | 1174 | curr = bond->curr_active_slave; |
1200 | read_unlock(&bond->curr_slave_lock); | 1175 | read_unlock(&bond->curr_slave_lock); |
1201 | 1176 | ||
1202 | if (USES_PRIMARY(bond->params.mode) && curr) | 1177 | if (USES_PRIMARY(bond->params.mode) && curr) |
1203 | count = sprintf(buf, "%s\n", curr->dev->name) + 1; | 1178 | count = sprintf(buf, "%s\n", curr->dev->name); |
1204 | else | ||
1205 | count = sprintf(buf, "\n") + 1; | ||
1206 | return count; | 1179 | return count; |
1207 | } | 1180 | } |
1208 | 1181 | ||
@@ -1216,7 +1189,9 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
1216 | struct slave *new_active = NULL; | 1189 | struct slave *new_active = NULL; |
1217 | struct bonding *bond = to_bond(d); | 1190 | struct bonding *bond = to_bond(d); |
1218 | 1191 | ||
1192 | rtnl_lock(); | ||
1219 | write_lock_bh(&bond->lock); | 1193 | write_lock_bh(&bond->lock); |
1194 | |||
1220 | if (!USES_PRIMARY(bond->params.mode)) { | 1195 | if (!USES_PRIMARY(bond->params.mode)) { |
1221 | printk(KERN_INFO DRV_NAME | 1196 | printk(KERN_INFO DRV_NAME |
1222 | ": %s: Unable to change active slave; %s is in mode %d\n", | 1197 | ": %s: Unable to change active slave; %s is in mode %d\n", |
@@ -1295,7 +1270,7 @@ static ssize_t bonding_show_mii_status(struct device *d, | |||
1295 | curr = bond->curr_active_slave; | 1270 | curr = bond->curr_active_slave; |
1296 | read_unlock(&bond->curr_slave_lock); | 1271 | read_unlock(&bond->curr_slave_lock); |
1297 | 1272 | ||
1298 | return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1; | 1273 | return sprintf(buf, "%s\n", (curr) ? "up" : "down"); |
1299 | } | 1274 | } |
1300 | static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); | 1275 | static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL); |
1301 | 1276 | ||
@@ -1312,10 +1287,8 @@ static ssize_t bonding_show_ad_aggregator(struct device *d, | |||
1312 | 1287 | ||
1313 | if (bond->params.mode == BOND_MODE_8023AD) { | 1288 | if (bond->params.mode == BOND_MODE_8023AD) { |
1314 | struct ad_info ad_info; | 1289 | struct ad_info ad_info; |
1315 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id) + 1; | 1290 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id); |
1316 | } | 1291 | } |
1317 | else | ||
1318 | count = sprintf(buf, "\n") + 1; | ||
1319 | 1292 | ||
1320 | return count; | 1293 | return count; |
1321 | } | 1294 | } |
@@ -1334,10 +1307,8 @@ static ssize_t bonding_show_ad_num_ports(struct device *d, | |||
1334 | 1307 | ||
1335 | if (bond->params.mode == BOND_MODE_8023AD) { | 1308 | if (bond->params.mode == BOND_MODE_8023AD) { |
1336 | struct ad_info ad_info; | 1309 | struct ad_info ad_info; |
1337 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports) + 1; | 1310 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports); |
1338 | } | 1311 | } |
1339 | else | ||
1340 | count = sprintf(buf, "\n") + 1; | ||
1341 | 1312 | ||
1342 | return count; | 1313 | return count; |
1343 | } | 1314 | } |
@@ -1356,10 +1327,8 @@ static ssize_t bonding_show_ad_actor_key(struct device *d, | |||
1356 | 1327 | ||
1357 | if (bond->params.mode == BOND_MODE_8023AD) { | 1328 | if (bond->params.mode == BOND_MODE_8023AD) { |
1358 | struct ad_info ad_info; | 1329 | struct ad_info ad_info; |
1359 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key) + 1; | 1330 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key); |
1360 | } | 1331 | } |
1361 | else | ||
1362 | count = sprintf(buf, "\n") + 1; | ||
1363 | 1332 | ||
1364 | return count; | 1333 | return count; |
1365 | } | 1334 | } |
@@ -1378,10 +1347,8 @@ static ssize_t bonding_show_ad_partner_key(struct device *d, | |||
1378 | 1347 | ||
1379 | if (bond->params.mode == BOND_MODE_8023AD) { | 1348 | if (bond->params.mode == BOND_MODE_8023AD) { |
1380 | struct ad_info ad_info; | 1349 | struct ad_info ad_info; |
1381 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key) + 1; | 1350 | count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key); |
1382 | } | 1351 | } |
1383 | else | ||
1384 | count = sprintf(buf, "\n") + 1; | ||
1385 | 1352 | ||
1386 | return count; | 1353 | return count; |
1387 | } | 1354 | } |
@@ -1403,12 +1370,9 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, | |||
1403 | struct ad_info ad_info; | 1370 | struct ad_info ad_info; |
1404 | if (!bond_3ad_get_active_agg_info(bond, &ad_info)) { | 1371 | if (!bond_3ad_get_active_agg_info(bond, &ad_info)) { |
1405 | count = sprintf(buf,"%s\n", | 1372 | count = sprintf(buf,"%s\n", |
1406 | print_mac(mac, ad_info.partner_system)) | 1373 | print_mac(mac, ad_info.partner_system)); |
1407 | + 1; | ||
1408 | } | 1374 | } |
1409 | } | 1375 | } |
1410 | else | ||
1411 | count = sprintf(buf, "\n") + 1; | ||
1412 | 1376 | ||
1413 | return count; | 1377 | return count; |
1414 | } | 1378 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 61c1b4536d34..e1e4734e23ce 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -22,8 +22,8 @@ | |||
22 | #include "bond_3ad.h" | 22 | #include "bond_3ad.h" |
23 | #include "bond_alb.h" | 23 | #include "bond_alb.h" |
24 | 24 | ||
25 | #define DRV_VERSION "3.2.1" | 25 | #define DRV_VERSION "3.2.3" |
26 | #define DRV_RELDATE "October 15, 2007" | 26 | #define DRV_RELDATE "December 6, 2007" |
27 | #define DRV_NAME "bonding" | 27 | #define DRV_NAME "bonding" |
28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
29 | 29 | ||