aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMazhar Rana <mazhar.rana@cyberoam.com>2015-07-07 05:34:50 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-08 19:06:08 -0400
commitb5a983f3141239b5b0b4a4e66efa31f8a26354b8 (patch)
tree4a1cfe9504658e6ddc6ca5818b8bccf1b33911f9
parentfc24f2b2094366da8786f59f2606307e934cea17 (diff)
bonding: "primary_reselect" with "failure" is not working properly
When "primary_reselect" is set to "failure", primary interface should not become active until current active slave is down. But if we set first member of bond device as a "primary" interface and "primary_reselect" is set to "failure" then whenever primary interface's link get back(up) it become active slave even if current active slave is still up. With this patch, "bond_find_best_slave" will not traverse members if primary interface is not candidate for failover/reselection and current active slave is still up. Signed-off-by: Mazhar Rana <mazhar.rana@cyberoam.com> Signed-off-by: Jay Vosburgh <j.vosburgh@gmail.com> Signed-off-by: Jay Vosburgh <jay.vosburgh@canonical.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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)