aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 19eb990d398c..317a49480475 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -689,40 +689,57 @@ out:
689 689
690} 690}
691 691
692static bool bond_should_change_active(struct bonding *bond) 692static struct slave *bond_choose_primary_or_current(struct bonding *bond)
693{ 693{
694 struct slave *prim = rtnl_dereference(bond->primary_slave); 694 struct slave *prim = rtnl_dereference(bond->primary_slave);
695 struct slave *curr = rtnl_dereference(bond->curr_active_slave); 695 struct slave *curr = rtnl_dereference(bond->curr_active_slave);
696 696
697 if (!prim || !curr || curr->link != BOND_LINK_UP) 697 if (!prim || prim->link != BOND_LINK_UP) {
698 return true; 698 if (!curr || curr->link != BOND_LINK_UP)
699 return NULL;
700 return curr;
701 }
702
699 if (bond->force_primary) { 703 if (bond->force_primary) {
700 bond->force_primary = false; 704 bond->force_primary = false;
701 return true; 705 return prim;
706 }
707
708 if (!curr || curr->link != BOND_LINK_UP)
709 return prim;
710
711 /* At this point, prim and curr are both up */
712 switch (bond->params.primary_reselect) {
713 case BOND_PRI_RESELECT_ALWAYS:
714 return prim;
715 case BOND_PRI_RESELECT_BETTER:
716 if (prim->speed < curr->speed)
717 return curr;
718 if (prim->speed == curr->speed && prim->duplex <= curr->duplex)
719 return curr;
720 return prim;
721 case BOND_PRI_RESELECT_FAILURE:
722 return curr;
723 default:
724 netdev_err(bond->dev, "impossible primary_reselect %d\n",
725 bond->params.primary_reselect);
726 return curr;
702 } 727 }
703 if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
704 (prim->speed < curr->speed ||
705 (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
706 return false;
707 if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
708 return false;
709 return true;
710} 728}
711 729
712/** 730/**
713 * find_best_interface - select the best available slave to be the active one 731 * bond_find_best_slave - select the best available slave to be the active one
714 * @bond: our bonding struct 732 * @bond: our bonding struct
715 */ 733 */
716static struct slave *bond_find_best_slave(struct bonding *bond) 734static struct slave *bond_find_best_slave(struct bonding *bond)
717{ 735{
718 struct slave *slave, *bestslave = NULL, *primary; 736 struct slave *slave, *bestslave = NULL;
719 struct list_head *iter; 737 struct list_head *iter;
720 int mintime = bond->params.updelay; 738 int mintime = bond->params.updelay;
721 739
722 primary = rtnl_dereference(bond->primary_slave); 740 slave = bond_choose_primary_or_current(bond);
723 if (primary && primary->link == BOND_LINK_UP && 741 if (slave)
724 bond_should_change_active(bond)) 742 return slave;
725 return primary;
726 743
727 bond_for_each_slave(bond, slave, iter) { 744 bond_for_each_slave(bond, slave, iter) {
728 if (slave->link == BOND_LINK_UP) 745 if (slave->link == BOND_LINK_UP)