aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2013-05-31 07:57:30 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-07 18:05:51 -0400
commit303d1cbf610eef31e039efc2e8da30cf94cf5ebc (patch)
tree5b7d13ea626dd0eda7122efa93afb7a4013a257a /drivers/net/bonding
parentca162a82f56921442f5db72a3a472010e5a62c4b (diff)
bonding: Convert hw addr handling to sync/unsync, support ucast addresses
This patch converts bonding to use the dev_uc/mc_sync and dev_uc/mc_sync_multiple functions for updating the hardware addresses of bonding slaves. The existing functions to add or remove addresses are removed, and their functionality is replaced with calls to dev_mc_sync or dev_mc_sync_multiple, depending upon the bonding mode. Calls to dev_uc_sync and dev_uc_sync_multiple are also added, so that unicast addresses added to a bond will be properly synced with its slaves. Various functions are renamed to better reflect the new situation, and relevant comments are updated. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Cc: Vlad Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c168
-rw-r--r--drivers/net/bonding/bonding.h1
2 files changed, 43 insertions, 126 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f4489d65bf33..4953f66a29a4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -706,45 +706,6 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
706 return err; 706 return err;
707} 707}
708 708
709/*
710 * Add a Multicast address to slaves
711 * according to mode
712 */
713static void bond_mc_add(struct bonding *bond, void *addr)
714{
715 if (USES_PRIMARY(bond->params.mode)) {
716 /* write lock already acquired */
717 if (bond->curr_active_slave)
718 dev_mc_add(bond->curr_active_slave->dev, addr);
719 } else {
720 struct slave *slave;
721 int i;
722
723 bond_for_each_slave(bond, slave, i)
724 dev_mc_add(slave->dev, addr);
725 }
726}
727
728/*
729 * Remove a multicast address from slave
730 * according to mode
731 */
732static void bond_mc_del(struct bonding *bond, void *addr)
733{
734 if (USES_PRIMARY(bond->params.mode)) {
735 /* write lock already acquired */
736 if (bond->curr_active_slave)
737 dev_mc_del(bond->curr_active_slave->dev, addr);
738 } else {
739 struct slave *slave;
740 int i;
741 bond_for_each_slave(bond, slave, i) {
742 dev_mc_del(slave->dev, addr);
743 }
744 }
745}
746
747
748static void __bond_resend_igmp_join_requests(struct net_device *dev) 709static void __bond_resend_igmp_join_requests(struct net_device *dev)
749{ 710{
750 struct in_device *in_dev; 711 struct in_device *in_dev;
@@ -803,17 +764,15 @@ static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
803 bond_resend_igmp_join_requests(bond); 764 bond_resend_igmp_join_requests(bond);
804} 765}
805 766
806/* 767/* Flush bond's hardware addresses from slave
807 * flush all members of flush->mc_list from device dev->mc_list
808 */ 768 */
809static void bond_mc_list_flush(struct net_device *bond_dev, 769static void bond_hw_addr_flush(struct net_device *bond_dev,
810 struct net_device *slave_dev) 770 struct net_device *slave_dev)
811{ 771{
812 struct bonding *bond = netdev_priv(bond_dev); 772 struct bonding *bond = netdev_priv(bond_dev);
813 struct netdev_hw_addr *ha;
814 773
815 netdev_for_each_mc_addr(ha, bond_dev) 774 dev_uc_unsync(slave_dev, bond_dev);
816 dev_mc_del(slave_dev, ha->addr); 775 dev_mc_unsync(slave_dev, bond_dev);
817 776
818 if (bond->params.mode == BOND_MODE_8023AD) { 777 if (bond->params.mode == BOND_MODE_8023AD) {
819 /* del lacpdu mc addr from mc list */ 778 /* del lacpdu mc addr from mc list */
@@ -825,22 +784,14 @@ static void bond_mc_list_flush(struct net_device *bond_dev,
825 784
826/*--------------------------- Active slave change ---------------------------*/ 785/*--------------------------- Active slave change ---------------------------*/
827 786
828/* 787/* Update the hardware address list and promisc/allmulti for the new and
829 * Update the mc list and multicast-related flags for the new and 788 * old active slaves (if any). Modes that are !USES_PRIMARY keep all
830 * old active slaves (if any) according to the multicast mode, and 789 * slaves up date at all times; only the USES_PRIMARY modes need to call
831 * promiscuous flags unconditionally. 790 * this function to swap these settings during a failover.
832 */ 791 */
833static void bond_mc_swap(struct bonding *bond, struct slave *new_active, 792static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
834 struct slave *old_active) 793 struct slave *old_active)
835{ 794{
836 struct netdev_hw_addr *ha;
837
838 if (!USES_PRIMARY(bond->params.mode))
839 /* nothing to do - mc list is already up-to-date on
840 * all slaves
841 */
842 return;
843
844 if (old_active) { 795 if (old_active) {
845 if (bond->dev->flags & IFF_PROMISC) 796 if (bond->dev->flags & IFF_PROMISC)
846 dev_set_promiscuity(old_active->dev, -1); 797 dev_set_promiscuity(old_active->dev, -1);
@@ -848,10 +799,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
848 if (bond->dev->flags & IFF_ALLMULTI) 799 if (bond->dev->flags & IFF_ALLMULTI)
849 dev_set_allmulti(old_active->dev, -1); 800 dev_set_allmulti(old_active->dev, -1);
850 801
851 netif_addr_lock_bh(bond->dev); 802 bond_hw_addr_flush(bond->dev, old_active->dev);
852 netdev_for_each_mc_addr(ha, bond->dev)
853 dev_mc_del(old_active->dev, ha->addr);
854 netif_addr_unlock_bh(bond->dev);
855 } 803 }
856 804
857 if (new_active) { 805 if (new_active) {
@@ -863,8 +811,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
863 dev_set_allmulti(new_active->dev, 1); 811 dev_set_allmulti(new_active->dev, 1);
864 812
865 netif_addr_lock_bh(bond->dev); 813 netif_addr_lock_bh(bond->dev);
866 netdev_for_each_mc_addr(ha, bond->dev) 814 dev_uc_sync(new_active->dev, bond->dev);
867 dev_mc_add(new_active->dev, ha->addr); 815 dev_mc_sync(new_active->dev, bond->dev);
868 netif_addr_unlock_bh(bond->dev); 816 netif_addr_unlock_bh(bond->dev);
869 } 817 }
870} 818}
@@ -1083,7 +1031,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1083 } 1031 }
1084 1032
1085 if (USES_PRIMARY(bond->params.mode)) 1033 if (USES_PRIMARY(bond->params.mode))
1086 bond_mc_swap(bond, new_active, old_active); 1034 bond_hw_addr_swap(bond, new_active, old_active);
1087 1035
1088 if (bond_is_lb(bond)) { 1036 if (bond_is_lb(bond)) {
1089 bond_alb_handle_active_change(bond, new_active); 1037 bond_alb_handle_active_change(bond, new_active);
@@ -1526,7 +1474,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1526 struct bonding *bond = netdev_priv(bond_dev); 1474 struct bonding *bond = netdev_priv(bond_dev);
1527 const struct net_device_ops *slave_ops = slave_dev->netdev_ops; 1475 const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
1528 struct slave *new_slave = NULL; 1476 struct slave *new_slave = NULL;
1529 struct netdev_hw_addr *ha;
1530 struct sockaddr addr; 1477 struct sockaddr addr;
1531 int link_reporting; 1478 int link_reporting;
1532 int res = 0; 1479 int res = 0;
@@ -1706,10 +1653,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1706 goto err_close; 1653 goto err_close;
1707 } 1654 }
1708 1655
1709 /* If the mode USES_PRIMARY, then the new slave gets the 1656 /* If the mode USES_PRIMARY, then the following is handled by
1710 * master's promisc (and mc) settings only if it becomes the 1657 * bond_change_active_slave().
1711 * curr_active_slave, and that is taken care of later when calling
1712 * bond_change_active()
1713 */ 1658 */
1714 if (!USES_PRIMARY(bond->params.mode)) { 1659 if (!USES_PRIMARY(bond->params.mode)) {
1715 /* set promiscuity level to new slave */ 1660 /* set promiscuity level to new slave */
@@ -1727,9 +1672,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1727 } 1672 }
1728 1673
1729 netif_addr_lock_bh(bond_dev); 1674 netif_addr_lock_bh(bond_dev);
1730 /* upload master's mc_list to new slave */ 1675
1731 netdev_for_each_mc_addr(ha, bond_dev) 1676 dev_mc_sync_multiple(slave_dev, bond_dev);
1732 dev_mc_add(slave_dev, ha->addr); 1677 dev_uc_sync_multiple(slave_dev, bond_dev);
1678
1733 netif_addr_unlock_bh(bond_dev); 1679 netif_addr_unlock_bh(bond_dev);
1734 } 1680 }
1735 1681
@@ -1908,11 +1854,9 @@ err_dest_symlinks:
1908 bond_destroy_slave_symlinks(bond_dev, slave_dev); 1854 bond_destroy_slave_symlinks(bond_dev, slave_dev);
1909 1855
1910err_detach: 1856err_detach:
1911 if (!USES_PRIMARY(bond->params.mode)) { 1857 if (!USES_PRIMARY(bond->params.mode))
1912 netif_addr_lock_bh(bond_dev); 1858 bond_hw_addr_flush(bond_dev, slave_dev);
1913 bond_mc_list_flush(bond_dev, slave_dev); 1859
1914 netif_addr_unlock_bh(bond_dev);
1915 }
1916 bond_del_vlans_from_slave(bond, slave_dev); 1860 bond_del_vlans_from_slave(bond, slave_dev);
1917 write_lock_bh(&bond->lock); 1861 write_lock_bh(&bond->lock);
1918 bond_detach_slave(bond, new_slave); 1862 bond_detach_slave(bond, new_slave);
@@ -2107,9 +2051,8 @@ static int __bond_release_one(struct net_device *bond_dev,
2107 2051
2108 bond_del_vlans_from_slave(bond, slave_dev); 2052 bond_del_vlans_from_slave(bond, slave_dev);
2109 2053
2110 /* If the mode USES_PRIMARY, then we should only remove its 2054 /* If the mode USES_PRIMARY, then this cases was handled above by
2111 * promisc and mc settings if it was the curr_active_slave, but that was 2055 * bond_change_active_slave(..., NULL)
2112 * already taken care of above when we detached the slave
2113 */ 2056 */
2114 if (!USES_PRIMARY(bond->params.mode)) { 2057 if (!USES_PRIMARY(bond->params.mode)) {
2115 /* unset promiscuity level from slave */ 2058 /* unset promiscuity level from slave */
@@ -2120,10 +2063,7 @@ static int __bond_release_one(struct net_device *bond_dev,
2120 if (bond_dev->flags & IFF_ALLMULTI) 2063 if (bond_dev->flags & IFF_ALLMULTI)
2121 dev_set_allmulti(slave_dev, -1); 2064 dev_set_allmulti(slave_dev, -1);
2122 2065
2123 /* flush master's mc_list from slave */ 2066 bond_hw_addr_flush(bond_dev, slave_dev);
2124 netif_addr_lock_bh(bond_dev);
2125 bond_mc_list_flush(bond_dev, slave_dev);
2126 netif_addr_unlock_bh(bond_dev);
2127 } 2067 }
2128 2068
2129 bond_upper_dev_unlink(bond_dev, slave_dev); 2069 bond_upper_dev_unlink(bond_dev, slave_dev);
@@ -3660,19 +3600,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
3660 return res; 3600 return res;
3661} 3601}
3662 3602
3663static bool bond_addr_in_mc_list(unsigned char *addr,
3664 struct netdev_hw_addr_list *list,
3665 int addrlen)
3666{
3667 struct netdev_hw_addr *ha;
3668
3669 netdev_hw_addr_list_for_each(ha, list)
3670 if (!memcmp(ha->addr, addr, addrlen))
3671 return true;
3672
3673 return false;
3674}
3675
3676static void bond_change_rx_flags(struct net_device *bond_dev, int change) 3603static void bond_change_rx_flags(struct net_device *bond_dev, int change)
3677{ 3604{
3678 struct bonding *bond = netdev_priv(bond_dev); 3605 struct bonding *bond = netdev_priv(bond_dev);
@@ -3686,35 +3613,29 @@ static void bond_change_rx_flags(struct net_device *bond_dev, int change)
3686 bond_dev->flags & IFF_ALLMULTI ? 1 : -1); 3613 bond_dev->flags & IFF_ALLMULTI ? 1 : -1);
3687} 3614}
3688 3615
3689static void bond_set_multicast_list(struct net_device *bond_dev) 3616static void bond_set_rx_mode(struct net_device *bond_dev)
3690{ 3617{
3691 struct bonding *bond = netdev_priv(bond_dev); 3618 struct bonding *bond = netdev_priv(bond_dev);
3692 struct netdev_hw_addr *ha; 3619 struct slave *slave;
3693 bool found; 3620 int i;
3694 3621
3695 read_lock(&bond->lock); 3622 read_lock(&bond->lock);
3696 3623
3697 /* looking for addresses to add to slaves' mc list */ 3624 if (USES_PRIMARY(bond->params.mode)) {
3698 netdev_for_each_mc_addr(ha, bond_dev) { 3625 read_lock(&bond->curr_slave_lock);
3699 found = bond_addr_in_mc_list(ha->addr, &bond->mc_list, 3626 slave = bond->curr_active_slave;
3700 bond_dev->addr_len); 3627 if (slave) {
3701 if (!found) 3628 dev_uc_sync(slave->dev, bond_dev);
3702 bond_mc_add(bond, ha->addr); 3629 dev_mc_sync(slave->dev, bond_dev);
3703 } 3630 }
3704 3631 read_unlock(&bond->curr_slave_lock);
3705 /* looking for addresses to delete from slaves' list */ 3632 } else {
3706 netdev_hw_addr_list_for_each(ha, &bond->mc_list) { 3633 bond_for_each_slave(bond, slave, i) {
3707 found = bond_addr_in_mc_list(ha->addr, &bond_dev->mc, 3634 dev_uc_sync_multiple(slave->dev, bond_dev);
3708 bond_dev->addr_len); 3635 dev_mc_sync_multiple(slave->dev, bond_dev);
3709 if (!found) 3636 }
3710 bond_mc_del(bond, ha->addr);
3711 } 3637 }
3712 3638
3713 /* save master's multicast list */
3714 __hw_addr_flush(&bond->mc_list);
3715 __hw_addr_add_multiple(&bond->mc_list, &bond_dev->mc,
3716 bond_dev->addr_len, NETDEV_HW_ADDR_T_MULTICAST);
3717
3718 read_unlock(&bond->lock); 3639 read_unlock(&bond->lock);
3719} 3640}
3720 3641
@@ -4321,7 +4242,7 @@ static const struct net_device_ops bond_netdev_ops = {
4321 .ndo_get_stats64 = bond_get_stats, 4242 .ndo_get_stats64 = bond_get_stats,
4322 .ndo_do_ioctl = bond_do_ioctl, 4243 .ndo_do_ioctl = bond_do_ioctl,
4323 .ndo_change_rx_flags = bond_change_rx_flags, 4244 .ndo_change_rx_flags = bond_change_rx_flags,
4324 .ndo_set_rx_mode = bond_set_multicast_list, 4245 .ndo_set_rx_mode = bond_set_rx_mode,
4325 .ndo_change_mtu = bond_change_mtu, 4246 .ndo_change_mtu = bond_change_mtu,
4326 .ndo_set_mac_address = bond_set_mac_address, 4247 .ndo_set_mac_address = bond_set_mac_address,
4327 .ndo_neigh_setup = bond_neigh_setup, 4248 .ndo_neigh_setup = bond_neigh_setup,
@@ -4426,8 +4347,6 @@ static void bond_uninit(struct net_device *bond_dev)
4426 4347
4427 bond_debug_unregister(bond); 4348 bond_debug_unregister(bond);
4428 4349
4429 __hw_addr_flush(&bond->mc_list);
4430
4431 list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) { 4350 list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) {
4432 list_del(&vlan->vlan_list); 4351 list_del(&vlan->vlan_list);
4433 kfree(vlan); 4352 kfree(vlan);
@@ -4838,7 +4757,6 @@ static int bond_init(struct net_device *bond_dev)
4838 bond->dev_addr_from_first = true; 4757 bond->dev_addr_from_first = true;
4839 } 4758 }
4840 4759
4841 __hw_addr_init(&bond->mc_list);
4842 return 0; 4760 return 0;
4843} 4761}
4844 4762
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 2baec24388b1..b38609b967b7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -231,7 +231,6 @@ struct bonding {
231 char proc_file_name[IFNAMSIZ]; 231 char proc_file_name[IFNAMSIZ];
232#endif /* CONFIG_PROC_FS */ 232#endif /* CONFIG_PROC_FS */
233 struct list_head bond_list; 233 struct list_head bond_list;
234 struct netdev_hw_addr_list mc_list;
235 int (*xmit_hash_policy)(struct sk_buff *, int); 234 int (*xmit_hash_policy)(struct sk_buff *, int);
236 u16 rr_tx_counter; 235 u16 rr_tx_counter;
237 struct ad_bond_info ad_info; 236 struct ad_bond_info ad_info;