diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 131 |
1 files changed, 41 insertions, 90 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a7e731f8a0d..69c5b15e22d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1093,15 +1093,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond) | |||
1093 | return NULL; /* still no slave, return NULL */ | 1093 | return NULL; /* still no slave, return NULL */ |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* | ||
1097 | * first try the primary link; if arping, a link must tx/rx | ||
1098 | * traffic before it can be considered the curr_active_slave. | ||
1099 | * also, we would skip slaves between the curr_active_slave | ||
1100 | * and primary_slave that may be up and able to arp | ||
1101 | */ | ||
1102 | if ((bond->primary_slave) && | 1096 | if ((bond->primary_slave) && |
1103 | (!bond->params.arp_interval) && | 1097 | bond->primary_slave->link == BOND_LINK_UP) { |
1104 | (IS_UP(bond->primary_slave->dev))) { | ||
1105 | new_active = bond->primary_slave; | 1098 | new_active = bond->primary_slave; |
1106 | } | 1099 | } |
1107 | 1100 | ||
@@ -1109,15 +1102,14 @@ static struct slave *bond_find_best_slave(struct bonding *bond) | |||
1109 | old_active = new_active; | 1102 | old_active = new_active; |
1110 | 1103 | ||
1111 | bond_for_each_slave_from(bond, new_active, i, old_active) { | 1104 | bond_for_each_slave_from(bond, new_active, i, old_active) { |
1112 | if (IS_UP(new_active->dev)) { | 1105 | if (new_active->link == BOND_LINK_UP) { |
1113 | if (new_active->link == BOND_LINK_UP) { | 1106 | return new_active; |
1114 | return new_active; | 1107 | } else if (new_active->link == BOND_LINK_BACK && |
1115 | } else if (new_active->link == BOND_LINK_BACK) { | 1108 | IS_UP(new_active->dev)) { |
1116 | /* link up, but waiting for stabilization */ | 1109 | /* link up, but waiting for stabilization */ |
1117 | if (new_active->delay < mintime) { | 1110 | if (new_active->delay < mintime) { |
1118 | mintime = new_active->delay; | 1111 | mintime = new_active->delay; |
1119 | bestslave = new_active; | 1112 | bestslave = new_active; |
1120 | } | ||
1121 | } | 1113 | } |
1122 | } | 1114 | } |
1123 | } | 1115 | } |
@@ -1211,7 +1203,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1211 | write_unlock_bh(&bond->curr_slave_lock); | 1203 | write_unlock_bh(&bond->curr_slave_lock); |
1212 | read_unlock(&bond->lock); | 1204 | read_unlock(&bond->lock); |
1213 | 1205 | ||
1214 | netdev_bonding_change(bond->dev); | 1206 | netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER); |
1215 | 1207 | ||
1216 | read_lock(&bond->lock); | 1208 | read_lock(&bond->lock); |
1217 | write_lock_bh(&bond->curr_slave_lock); | 1209 | write_lock_bh(&bond->curr_slave_lock); |
@@ -1469,14 +1461,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1469 | */ | 1461 | */ |
1470 | if (bond->slave_cnt == 0) { | 1462 | if (bond->slave_cnt == 0) { |
1471 | if (bond_dev->type != slave_dev->type) { | 1463 | if (bond_dev->type != slave_dev->type) { |
1472 | dev_close(bond_dev); | ||
1473 | pr_debug("%s: change device type from %d to %d\n", | 1464 | pr_debug("%s: change device type from %d to %d\n", |
1474 | bond_dev->name, bond_dev->type, slave_dev->type); | 1465 | bond_dev->name, bond_dev->type, slave_dev->type); |
1466 | |||
1467 | netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE); | ||
1468 | |||
1475 | if (slave_dev->type != ARPHRD_ETHER) | 1469 | if (slave_dev->type != ARPHRD_ETHER) |
1476 | bond_setup_by_slave(bond_dev, slave_dev); | 1470 | bond_setup_by_slave(bond_dev, slave_dev); |
1477 | else | 1471 | else |
1478 | ether_setup(bond_dev); | 1472 | ether_setup(bond_dev); |
1479 | dev_open(bond_dev); | 1473 | |
1474 | netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE); | ||
1480 | } | 1475 | } |
1481 | } else if (bond_dev->type != slave_dev->type) { | 1476 | } else if (bond_dev->type != slave_dev->type) { |
1482 | pr_err(DRV_NAME ": %s ether type (%d) is different " | 1477 | pr_err(DRV_NAME ": %s ether type (%d) is different " |
@@ -2929,18 +2924,6 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2929 | } | 2924 | } |
2930 | } | 2925 | } |
2931 | 2926 | ||
2932 | read_lock(&bond->curr_slave_lock); | ||
2933 | |||
2934 | /* | ||
2935 | * Trigger a commit if the primary option setting has changed. | ||
2936 | */ | ||
2937 | if (bond->primary_slave && | ||
2938 | (bond->primary_slave != bond->curr_active_slave) && | ||
2939 | (bond->primary_slave->link == BOND_LINK_UP)) | ||
2940 | commit++; | ||
2941 | |||
2942 | read_unlock(&bond->curr_slave_lock); | ||
2943 | |||
2944 | return commit; | 2927 | return commit; |
2945 | } | 2928 | } |
2946 | 2929 | ||
@@ -2961,90 +2944,58 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2961 | continue; | 2944 | continue; |
2962 | 2945 | ||
2963 | case BOND_LINK_UP: | 2946 | case BOND_LINK_UP: |
2964 | write_lock_bh(&bond->curr_slave_lock); | 2947 | if ((!bond->curr_active_slave && |
2965 | 2948 | time_before_eq(jiffies, | |
2966 | if (!bond->curr_active_slave && | 2949 | dev_trans_start(slave->dev) + |
2967 | time_before_eq(jiffies, dev_trans_start(slave->dev) + | 2950 | delta_in_ticks)) || |
2968 | delta_in_ticks)) { | 2951 | bond->curr_active_slave != slave) { |
2969 | slave->link = BOND_LINK_UP; | 2952 | slave->link = BOND_LINK_UP; |
2970 | bond_change_active_slave(bond, slave); | ||
2971 | bond->current_arp_slave = NULL; | 2953 | bond->current_arp_slave = NULL; |
2972 | 2954 | ||
2973 | pr_info(DRV_NAME | 2955 | pr_info(DRV_NAME |
2974 | ": %s: %s is up and now the " | 2956 | ": %s: link status definitely " |
2975 | "active interface\n", | 2957 | "up for interface %s.\n", |
2976 | bond->dev->name, slave->dev->name); | 2958 | bond->dev->name, slave->dev->name); |
2977 | |||
2978 | } else if (bond->curr_active_slave != slave) { | ||
2979 | /* this slave has just come up but we | ||
2980 | * already have a current slave; this can | ||
2981 | * also happen if bond_enslave adds a new | ||
2982 | * slave that is up while we are searching | ||
2983 | * for a new slave | ||
2984 | */ | ||
2985 | slave->link = BOND_LINK_UP; | ||
2986 | bond_set_slave_inactive_flags(slave); | ||
2987 | bond->current_arp_slave = NULL; | ||
2988 | 2959 | ||
2989 | pr_info(DRV_NAME | 2960 | if (!bond->curr_active_slave || |
2990 | ": %s: backup interface %s is now up\n", | 2961 | (slave == bond->primary_slave)) |
2991 | bond->dev->name, slave->dev->name); | 2962 | goto do_failover; |
2992 | } | ||
2993 | 2963 | ||
2994 | write_unlock_bh(&bond->curr_slave_lock); | 2964 | } |
2995 | 2965 | ||
2996 | break; | 2966 | continue; |
2997 | 2967 | ||
2998 | case BOND_LINK_DOWN: | 2968 | case BOND_LINK_DOWN: |
2999 | if (slave->link_failure_count < UINT_MAX) | 2969 | if (slave->link_failure_count < UINT_MAX) |
3000 | slave->link_failure_count++; | 2970 | slave->link_failure_count++; |
3001 | 2971 | ||
3002 | slave->link = BOND_LINK_DOWN; | 2972 | slave->link = BOND_LINK_DOWN; |
2973 | bond_set_slave_inactive_flags(slave); | ||
3003 | 2974 | ||
3004 | if (slave == bond->curr_active_slave) { | 2975 | pr_info(DRV_NAME |
3005 | pr_info(DRV_NAME | 2976 | ": %s: link status definitely down for " |
3006 | ": %s: link status down for active " | 2977 | "interface %s, disabling it\n", |
3007 | "interface %s, disabling it\n", | 2978 | bond->dev->name, slave->dev->name); |
3008 | bond->dev->name, slave->dev->name); | ||
3009 | |||
3010 | bond_set_slave_inactive_flags(slave); | ||
3011 | |||
3012 | write_lock_bh(&bond->curr_slave_lock); | ||
3013 | |||
3014 | bond_select_active_slave(bond); | ||
3015 | if (bond->curr_active_slave) | ||
3016 | bond->curr_active_slave->jiffies = | ||
3017 | jiffies; | ||
3018 | |||
3019 | write_unlock_bh(&bond->curr_slave_lock); | ||
3020 | 2979 | ||
2980 | if (slave == bond->curr_active_slave) { | ||
3021 | bond->current_arp_slave = NULL; | 2981 | bond->current_arp_slave = NULL; |
3022 | 2982 | goto do_failover; | |
3023 | } else if (slave->state == BOND_STATE_BACKUP) { | ||
3024 | pr_info(DRV_NAME | ||
3025 | ": %s: backup interface %s is now down\n", | ||
3026 | bond->dev->name, slave->dev->name); | ||
3027 | |||
3028 | bond_set_slave_inactive_flags(slave); | ||
3029 | } | 2983 | } |
3030 | break; | 2984 | |
2985 | continue; | ||
3031 | 2986 | ||
3032 | default: | 2987 | default: |
3033 | pr_err(DRV_NAME | 2988 | pr_err(DRV_NAME |
3034 | ": %s: impossible: new_link %d on slave %s\n", | 2989 | ": %s: impossible: new_link %d on slave %s\n", |
3035 | bond->dev->name, slave->new_link, | 2990 | bond->dev->name, slave->new_link, |
3036 | slave->dev->name); | 2991 | slave->dev->name); |
2992 | continue; | ||
3037 | } | 2993 | } |
3038 | } | ||
3039 | 2994 | ||
3040 | /* | 2995 | do_failover: |
3041 | * No race with changes to primary via sysfs, as we hold rtnl. | 2996 | ASSERT_RTNL(); |
3042 | */ | ||
3043 | if (bond->primary_slave && | ||
3044 | (bond->primary_slave != bond->curr_active_slave) && | ||
3045 | (bond->primary_slave->link == BOND_LINK_UP)) { | ||
3046 | write_lock_bh(&bond->curr_slave_lock); | 2997 | write_lock_bh(&bond->curr_slave_lock); |
3047 | bond_change_active_slave(bond, bond->primary_slave); | 2998 | bond_select_active_slave(bond); |
3048 | write_unlock_bh(&bond->curr_slave_lock); | 2999 | write_unlock_bh(&bond->curr_slave_lock); |
3049 | } | 3000 | } |
3050 | 3001 | ||