diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2005-11-04 21:45:45 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2005-11-07 21:50:00 -0500 |
commit | 8e3babcd69ec0fde874838e276eb0b211c6a5647 (patch) | |
tree | e9ec29bf1d94ab8b77bb536c77433e21fa2f73ba /drivers/net/bonding/bond_main.c | |
parent | fd7a516efbcdabf5d7b9307ca9fe48b511b7d123 (diff) |
[PATCH] bonding: fix feature consolidation
This should resolve http://bugzilla.kernel.org/show_bug.cgi?id=5519
The current feature computation loses bits that it doesn't know about,
resulting in an inability to add VLANs and possibly other havoc.
Rewrote function to preserve bits it doesn't know about, remove an
unneeded state variable, and simplify the code.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8032126fd589..94cec3cf2a13 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_ | |||
1604 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | 1604 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) |
1605 | 1605 | ||
1606 | /* | 1606 | /* |
1607 | * Compute the features available to the bonding device by | 1607 | * Compute the common dev->feature set available to all slaves. Some |
1608 | * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. | 1608 | * feature bits are managed elsewhere, so preserve feature bits set on |
1609 | * Call this after attaching or detaching a slave to update the | 1609 | * master device that are not part of the examined set. |
1610 | * bond's features. | ||
1611 | */ | 1610 | */ |
1612 | static int bond_compute_features(struct bonding *bond) | 1611 | static int bond_compute_features(struct bonding *bond) |
1613 | { | 1612 | { |
1614 | int i; | 1613 | unsigned long features = BOND_INTERSECT_FEATURES; |
1615 | struct slave *slave; | 1614 | struct slave *slave; |
1616 | struct net_device *bond_dev = bond->dev; | 1615 | struct net_device *bond_dev = bond->dev; |
1617 | int features = bond->bond_features; | 1616 | int i; |
1618 | 1617 | ||
1619 | bond_for_each_slave(bond, slave, i) { | 1618 | bond_for_each_slave(bond, slave, i) |
1620 | struct net_device * slave_dev = slave->dev; | 1619 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); |
1621 | if (i == 0) { | ||
1622 | features |= BOND_INTERSECT_FEATURES; | ||
1623 | } | ||
1624 | features &= | ||
1625 | ~(~slave_dev->features & BOND_INTERSECT_FEATURES); | ||
1626 | } | ||
1627 | 1620 | ||
1628 | /* turn off NETIF_F_SG if we need a csum and h/w can't do it */ | ||
1629 | if ((features & NETIF_F_SG) && | 1621 | if ((features & NETIF_F_SG) && |
1630 | !(features & (NETIF_F_IP_CSUM | | 1622 | !(features & (NETIF_F_IP_CSUM | |
1631 | NETIF_F_NO_CSUM | | 1623 | NETIF_F_NO_CSUM | |
1632 | NETIF_F_HW_CSUM))) { | 1624 | NETIF_F_HW_CSUM))) |
1633 | features &= ~NETIF_F_SG; | 1625 | features &= ~NETIF_F_SG; |
1634 | } | ||
1635 | 1626 | ||
1627 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | ||
1636 | bond_dev->features = features; | 1628 | bond_dev->features = features; |
1637 | 1629 | ||
1638 | return 0; | 1630 | return 0; |
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4561 | NETIF_F_HW_VLAN_RX | | 4553 | NETIF_F_HW_VLAN_RX | |
4562 | NETIF_F_HW_VLAN_FILTER); | 4554 | NETIF_F_HW_VLAN_FILTER); |
4563 | 4555 | ||
4564 | bond->bond_features = bond_dev->features; | ||
4565 | |||
4566 | #ifdef CONFIG_PROC_FS | 4556 | #ifdef CONFIG_PROC_FS |
4567 | bond_create_proc_entry(bond); | 4557 | bond_create_proc_entry(bond); |
4568 | #endif | 4558 | #endif |