aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorWang Chen <wangchen@cn.fujitsu.com>2008-07-14 23:51:36 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-14 23:51:36 -0400
commit7e1a1ac1fbaa88fe254400b7f30b775502932ad3 (patch)
tree5084fc1e90687cdec4ad62cd1ae81b75e6efe765 /drivers/net/bonding/bond_main.c
parent2aeb0b88b3c7a0e3bef55e7ff0efffd5d971aa57 (diff)
bonding: Check return of dev_set_promiscuity/allmulti
dev_set_promiscuity/allmulti might overflow. Commit: "netdevice: Fix promiscuity and allmulti overflow" in net-next makes dev_set_promiscuity/allmulti return error number if overflow happened. In bond_alb and bond_main, we check all positive increment for promiscuity and allmulti to get error return. But there are still two problems left. 1. Some code path has no mechanism to signal errors upstream. 2. If there are multi slaves, it's hard to tell which slaves increment promisc/allmulti successfully and which failed. So I left these problems to be FIXME. Fortunately, the overflow is very rare case. Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index dc733d75a5e9..8ae7ff313218 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -772,39 +772,49 @@ static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct
772/* 772/*
773 * Push the promiscuity flag down to appropriate slaves 773 * Push the promiscuity flag down to appropriate slaves
774 */ 774 */
775static void bond_set_promiscuity(struct bonding *bond, int inc) 775static int bond_set_promiscuity(struct bonding *bond, int inc)
776{ 776{
777 int err = 0;
777 if (USES_PRIMARY(bond->params.mode)) { 778 if (USES_PRIMARY(bond->params.mode)) {
778 /* write lock already acquired */ 779 /* write lock already acquired */
779 if (bond->curr_active_slave) { 780 if (bond->curr_active_slave) {
780 dev_set_promiscuity(bond->curr_active_slave->dev, inc); 781 err = dev_set_promiscuity(bond->curr_active_slave->dev,
782 inc);
781 } 783 }
782 } else { 784 } else {
783 struct slave *slave; 785 struct slave *slave;
784 int i; 786 int i;
785 bond_for_each_slave(bond, slave, i) { 787 bond_for_each_slave(bond, slave, i) {
786 dev_set_promiscuity(slave->dev, inc); 788 err = dev_set_promiscuity(slave->dev, inc);
789 if (err)
790 return err;
787 } 791 }
788 } 792 }
793 return err;
789} 794}
790 795
791/* 796/*
792 * Push the allmulti flag down to all slaves 797 * Push the allmulti flag down to all slaves
793 */ 798 */
794static void bond_set_allmulti(struct bonding *bond, int inc) 799static int bond_set_allmulti(struct bonding *bond, int inc)
795{ 800{
801 int err = 0;
796 if (USES_PRIMARY(bond->params.mode)) { 802 if (USES_PRIMARY(bond->params.mode)) {
797 /* write lock already acquired */ 803 /* write lock already acquired */
798 if (bond->curr_active_slave) { 804 if (bond->curr_active_slave) {
799 dev_set_allmulti(bond->curr_active_slave->dev, inc); 805 err = dev_set_allmulti(bond->curr_active_slave->dev,
806 inc);
800 } 807 }
801 } else { 808 } else {
802 struct slave *slave; 809 struct slave *slave;
803 int i; 810 int i;
804 bond_for_each_slave(bond, slave, i) { 811 bond_for_each_slave(bond, slave, i) {
805 dev_set_allmulti(slave->dev, inc); 812 err = dev_set_allmulti(slave->dev, inc);
813 if (err)
814 return err;
806 } 815 }
807 } 816 }
817 return err;
808} 818}
809 819
810/* 820/*
@@ -965,6 +975,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
965 } 975 }
966 976
967 if (new_active) { 977 if (new_active) {
978 /* FIXME: Signal errors upstream. */
968 if (bond->dev->flags & IFF_PROMISC) { 979 if (bond->dev->flags & IFF_PROMISC) {
969 dev_set_promiscuity(new_active->dev, 1); 980 dev_set_promiscuity(new_active->dev, 1);
970 } 981 }
@@ -1544,12 +1555,16 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1544 if (!USES_PRIMARY(bond->params.mode)) { 1555 if (!USES_PRIMARY(bond->params.mode)) {
1545 /* set promiscuity level to new slave */ 1556 /* set promiscuity level to new slave */
1546 if (bond_dev->flags & IFF_PROMISC) { 1557 if (bond_dev->flags & IFF_PROMISC) {
1547 dev_set_promiscuity(slave_dev, 1); 1558 res = dev_set_promiscuity(slave_dev, 1);
1559 if (res)
1560 goto err_close;
1548 } 1561 }
1549 1562
1550 /* set allmulti level to new slave */ 1563 /* set allmulti level to new slave */
1551 if (bond_dev->flags & IFF_ALLMULTI) { 1564 if (bond_dev->flags & IFF_ALLMULTI) {
1552 dev_set_allmulti(slave_dev, 1); 1565 res = dev_set_allmulti(slave_dev, 1);
1566 if (res)
1567 goto err_close;
1553 } 1568 }
1554 1569
1555 netif_tx_lock_bh(bond_dev); 1570 netif_tx_lock_bh(bond_dev);
@@ -4065,6 +4080,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
4065 * Do promisc before checking multicast_mode 4080 * Do promisc before checking multicast_mode
4066 */ 4081 */
4067 if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) { 4082 if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
4083 /*
4084 * FIXME: Need to handle the error when one of the multi-slaves
4085 * encounters error.
4086 */
4068 bond_set_promiscuity(bond, 1); 4087 bond_set_promiscuity(bond, 1);
4069 } 4088 }
4070 4089
@@ -4074,6 +4093,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
4074 4093
4075 /* set allmulti flag to slaves */ 4094 /* set allmulti flag to slaves */
4076 if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) { 4095 if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
4096 /*
4097 * FIXME: Need to handle the error when one of the multi-slaves
4098 * encounters error.
4099 */
4077 bond_set_allmulti(bond, 1); 4100 bond_set_allmulti(bond, 1);
4078 } 4101 }
4079 4102