diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 116 |
1 files changed, 73 insertions, 43 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 423298c84a1d..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 | ||
@@ -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); |
@@ -4462,6 +4492,27 @@ static void bond_deinit(struct net_device *bond_dev) | |||
4462 | #endif | 4492 | #endif |
4463 | } | 4493 | } |
4464 | 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 | |||
4465 | /* Unregister and free all bond devices. | 4516 | /* Unregister and free all bond devices. |
4466 | * Caller must hold rtnl_lock. | 4517 | * Caller must hold rtnl_lock. |
4467 | */ | 4518 | */ |
@@ -4472,6 +4523,7 @@ static void bond_free_all(void) | |||
4472 | 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) { |
4473 | struct net_device *bond_dev = bond->dev; | 4524 | struct net_device *bond_dev = bond->dev; |
4474 | 4525 | ||
4526 | bond_work_cancel_all(bond); | ||
4475 | bond_mc_list_destroy(bond); | 4527 | bond_mc_list_destroy(bond); |
4476 | /* Release the bonded slaves */ | 4528 | /* Release the bonded slaves */ |
4477 | bond_release_all(bond_dev); | 4529 | bond_release_all(bond_dev); |
@@ -4497,8 +4549,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) | |||
4497 | for (i = 0; tbl[i].modename; i++) { | 4549 | for (i = 0; tbl[i].modename; i++) { |
4498 | if ((isdigit(*mode_arg) && | 4550 | if ((isdigit(*mode_arg) && |
4499 | tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || | 4551 | tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || |
4500 | (strncmp(mode_arg, tbl[i].modename, | 4552 | (strcmp(mode_arg, tbl[i].modename) == 0)) { |
4501 | strlen(tbl[i].modename)) == 0)) { | ||
4502 | return tbl[i].mode; | 4553 | return tbl[i].mode; |
4503 | } | 4554 | } |
4504 | } | 4555 | } |
@@ -4873,27 +4924,6 @@ out_rtnl: | |||
4873 | return res; | 4924 | return res; |
4874 | } | 4925 | } |
4875 | 4926 | ||
4876 | static void bond_work_cancel_all(struct bonding *bond) | ||
4877 | { | ||
4878 | write_lock_bh(&bond->lock); | ||
4879 | bond->kill_timers = 1; | ||
4880 | write_unlock_bh(&bond->lock); | ||
4881 | |||
4882 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4883 | cancel_delayed_work(&bond->mii_work); | ||
4884 | |||
4885 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4886 | cancel_delayed_work(&bond->arp_work); | ||
4887 | |||
4888 | if (bond->params.mode == BOND_MODE_ALB && | ||
4889 | delayed_work_pending(&bond->alb_work)) | ||
4890 | cancel_delayed_work(&bond->alb_work); | ||
4891 | |||
4892 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4893 | delayed_work_pending(&bond->ad_work)) | ||
4894 | cancel_delayed_work(&bond->ad_work); | ||
4895 | } | ||
4896 | |||
4897 | static int __init bonding_init(void) | 4927 | static int __init bonding_init(void) |
4898 | { | 4928 | { |
4899 | int i; | 4929 | int i; |