diff options
| -rw-r--r-- | drivers/net/bonding/bond_alb.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 2ec945c3b9ba..93580a47cc54 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
| @@ -82,7 +82,8 @@ static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | /* Forward declaration */ | 84 | /* Forward declaration */ |
| 85 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]); | 85 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], |
| 86 | bool strict_match); | ||
| 86 | static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp); | 87 | static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp); |
| 87 | static void rlb_src_unlink(struct bonding *bond, u32 index); | 88 | static void rlb_src_unlink(struct bonding *bond, u32 index); |
| 88 | static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, | 89 | static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, |
| @@ -459,7 +460,7 @@ static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) | |||
| 459 | 460 | ||
| 460 | bond->alb_info.rlb_promisc_timeout_counter = 0; | 461 | bond->alb_info.rlb_promisc_timeout_counter = 0; |
| 461 | 462 | ||
| 462 | alb_send_learning_packets(bond->curr_active_slave, addr); | 463 | alb_send_learning_packets(bond->curr_active_slave, addr, true); |
| 463 | } | 464 | } |
| 464 | 465 | ||
| 465 | /* slave being removed should not be active at this point | 466 | /* slave being removed should not be active at this point |
| @@ -1032,8 +1033,8 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], | |||
| 1032 | dev_queue_xmit(skb); | 1033 | dev_queue_xmit(skb); |
| 1033 | } | 1034 | } |
| 1034 | 1035 | ||
| 1035 | 1036 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], | |
| 1036 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) | 1037 | bool strict_match) |
| 1037 | { | 1038 | { |
| 1038 | struct bonding *bond = bond_get_bond_by_slave(slave); | 1039 | struct bonding *bond = bond_get_bond_by_slave(slave); |
| 1039 | struct net_device *upper; | 1040 | struct net_device *upper; |
| @@ -1045,10 +1046,19 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) | |||
| 1045 | /* loop through vlans and send one packet for each */ | 1046 | /* loop through vlans and send one packet for each */ |
| 1046 | rcu_read_lock(); | 1047 | rcu_read_lock(); |
| 1047 | netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { | 1048 | netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { |
| 1048 | if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) | 1049 | if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { |
| 1049 | alb_send_lp_vid(slave, mac_addr, | 1050 | if (strict_match && |
| 1050 | vlan_dev_vlan_proto(upper), | 1051 | ether_addr_equal_64bits(mac_addr, |
| 1051 | vlan_dev_vlan_id(upper)); | 1052 | upper->dev_addr)) { |
| 1053 | alb_send_lp_vid(slave, mac_addr, | ||
| 1054 | vlan_dev_vlan_proto(upper), | ||
| 1055 | vlan_dev_vlan_id(upper)); | ||
| 1056 | } else if (!strict_match) { | ||
| 1057 | alb_send_lp_vid(slave, upper->dev_addr, | ||
| 1058 | vlan_dev_vlan_proto(upper), | ||
| 1059 | vlan_dev_vlan_id(upper)); | ||
| 1060 | } | ||
| 1061 | } | ||
| 1052 | } | 1062 | } |
| 1053 | rcu_read_unlock(); | 1063 | rcu_read_unlock(); |
| 1054 | } | 1064 | } |
| @@ -1108,7 +1118,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, | |||
| 1108 | 1118 | ||
| 1109 | /* fasten the change in the switch */ | 1119 | /* fasten the change in the switch */ |
| 1110 | if (SLAVE_IS_OK(slave1)) { | 1120 | if (SLAVE_IS_OK(slave1)) { |
| 1111 | alb_send_learning_packets(slave1, slave1->dev->dev_addr); | 1121 | alb_send_learning_packets(slave1, slave1->dev->dev_addr, false); |
| 1112 | if (bond->alb_info.rlb_enabled) { | 1122 | if (bond->alb_info.rlb_enabled) { |
| 1113 | /* inform the clients that the mac address | 1123 | /* inform the clients that the mac address |
| 1114 | * has changed | 1124 | * has changed |
| @@ -1120,7 +1130,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, | |||
| 1120 | } | 1130 | } |
| 1121 | 1131 | ||
| 1122 | if (SLAVE_IS_OK(slave2)) { | 1132 | if (SLAVE_IS_OK(slave2)) { |
| 1123 | alb_send_learning_packets(slave2, slave2->dev->dev_addr); | 1133 | alb_send_learning_packets(slave2, slave2->dev->dev_addr, false); |
| 1124 | if (bond->alb_info.rlb_enabled) { | 1134 | if (bond->alb_info.rlb_enabled) { |
| 1125 | /* inform the clients that the mac address | 1135 | /* inform the clients that the mac address |
| 1126 | * has changed | 1136 | * has changed |
| @@ -1491,6 +1501,8 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1491 | 1501 | ||
| 1492 | /* send learning packets */ | 1502 | /* send learning packets */ |
| 1493 | if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) { | 1503 | if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) { |
| 1504 | bool strict_match; | ||
| 1505 | |||
| 1494 | /* change of curr_active_slave involves swapping of mac addresses. | 1506 | /* change of curr_active_slave involves swapping of mac addresses. |
| 1495 | * in order to avoid this swapping from happening while | 1507 | * in order to avoid this swapping from happening while |
| 1496 | * sending the learning packets, the curr_slave_lock must be held for | 1508 | * sending the learning packets, the curr_slave_lock must be held for |
| @@ -1498,8 +1510,15 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1498 | */ | 1510 | */ |
| 1499 | read_lock(&bond->curr_slave_lock); | 1511 | read_lock(&bond->curr_slave_lock); |
| 1500 | 1512 | ||
| 1501 | bond_for_each_slave_rcu(bond, slave, iter) | 1513 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1502 | alb_send_learning_packets(slave, slave->dev->dev_addr); | 1514 | /* If updating current_active, use all currently |
| 1515 | * user mac addreses (!strict_match). Otherwise, only | ||
| 1516 | * use mac of the slave device. | ||
| 1517 | */ | ||
| 1518 | strict_match = (slave != bond->curr_active_slave); | ||
| 1519 | alb_send_learning_packets(slave, slave->dev->dev_addr, | ||
| 1520 | strict_match); | ||
| 1521 | } | ||
| 1503 | 1522 | ||
| 1504 | read_unlock(&bond->curr_slave_lock); | 1523 | read_unlock(&bond->curr_slave_lock); |
| 1505 | 1524 | ||
| @@ -1722,7 +1741,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave | |||
| 1722 | } else { | 1741 | } else { |
| 1723 | /* set the new_slave to the bond mac address */ | 1742 | /* set the new_slave to the bond mac address */ |
| 1724 | alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); | 1743 | alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); |
| 1725 | alb_send_learning_packets(new_slave, bond->dev->dev_addr); | 1744 | alb_send_learning_packets(new_slave, bond->dev->dev_addr, |
| 1745 | false); | ||
| 1726 | } | 1746 | } |
| 1727 | 1747 | ||
| 1728 | write_lock_bh(&bond->curr_slave_lock); | 1748 | write_lock_bh(&bond->curr_slave_lock); |
| @@ -1765,7 +1785,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) | |||
| 1765 | alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr); | 1785 | alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr); |
| 1766 | 1786 | ||
| 1767 | read_lock(&bond->lock); | 1787 | read_lock(&bond->lock); |
| 1768 | alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr); | 1788 | alb_send_learning_packets(bond->curr_active_slave, |
| 1789 | bond_dev->dev_addr, false); | ||
| 1769 | if (bond->alb_info.rlb_enabled) { | 1790 | if (bond->alb_info.rlb_enabled) { |
| 1770 | /* inform clients mac address has changed */ | 1791 | /* inform clients mac address has changed */ |
| 1771 | rlb_req_update_slave_clients(bond, bond->curr_active_slave); | 1792 | rlb_req_update_slave_clients(bond, bond->curr_active_slave); |
