Browse Source

net/bonding: Handlle wrong assumptions that slave is always an Ethernet device

bonding sometimes uses Ethernet constants (such as MTU and address length) which
are not good when it enslaves non Ethernet devices (such as InfiniBand).

Signed-off-by: Moni Shoua <monis at voltaire.com>
Acked-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Moni Shoua 17 years ago
parent
commit
3158bf7d41

+ 2 - 1
drivers/net/bonding/bond_main.c

@@ -1225,7 +1225,8 @@ static int bond_compute_features(struct bonding *bond)
 	struct slave *slave;
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
 	struct net_device *bond_dev = bond->dev;
 	unsigned long features = bond_dev->features;
 	unsigned long features = bond_dev->features;
-	unsigned short max_hard_header_len = ETH_HLEN;
+	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
+						bond_dev->hard_header_len);
 	int i;
 	int i;
 
 
 	features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
 	features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);

+ 8 - 2
drivers/net/bonding/bond_sysfs.c

@@ -260,6 +260,7 @@ static ssize_t bonding_store_slaves(struct device *d,
 	char command[IFNAMSIZ + 1] = { 0, };
 	char command[IFNAMSIZ + 1] = { 0, };
 	char *ifname;
 	char *ifname;
 	int i, res, found, ret = count;
 	int i, res, found, ret = count;
+	u32 original_mtu;
 	struct slave *slave;
 	struct slave *slave;
 	struct net_device *dev = NULL;
 	struct net_device *dev = NULL;
 	struct bonding *bond = to_bond(d);
 	struct bonding *bond = to_bond(d);
@@ -325,6 +326,7 @@ static ssize_t bonding_store_slaves(struct device *d,
 		}
 		}
 
 
 		/* Set the slave's MTU to match the bond */
 		/* Set the slave's MTU to match the bond */
+		original_mtu = dev->mtu;
 		if (dev->mtu != bond->dev->mtu) {
 		if (dev->mtu != bond->dev->mtu) {
 			if (dev->change_mtu) {
 			if (dev->change_mtu) {
 				res = dev->change_mtu(dev,
 				res = dev->change_mtu(dev,
@@ -339,6 +341,9 @@ static ssize_t bonding_store_slaves(struct device *d,
 		}
 		}
 		rtnl_lock();
 		rtnl_lock();
 		res = bond_enslave(bond->dev, dev);
 		res = bond_enslave(bond->dev, dev);
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
+				slave->original_mtu = original_mtu;
 		rtnl_unlock();
 		rtnl_unlock();
 		if (res) {
 		if (res) {
 			ret = res;
 			ret = res;
@@ -351,6 +356,7 @@ static ssize_t bonding_store_slaves(struct device *d,
 		bond_for_each_slave(bond, slave, i)
 		bond_for_each_slave(bond, slave, i)
 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
 				dev = slave->dev;
 				dev = slave->dev;
+				original_mtu = slave->original_mtu;
 				break;
 				break;
 			}
 			}
 		if (dev) {
 		if (dev) {
@@ -365,9 +371,9 @@ static ssize_t bonding_store_slaves(struct device *d,
 			}
 			}
 			/* set the slave MTU to the default */
 			/* set the slave MTU to the default */
 			if (dev->change_mtu) {
 			if (dev->change_mtu) {
-				dev->change_mtu(dev, 1500);
+				dev->change_mtu(dev, original_mtu);
 			} else {
 			} else {
-				dev->mtu = 1500;
+				dev->mtu = original_mtu;
 			}
 			}
 		}
 		}
 		else {
 		else {

+ 1 - 0
drivers/net/bonding/bonding.h

@@ -156,6 +156,7 @@ struct slave {
 	s8     link;    /* one of BOND_LINK_XXXX */
 	s8     link;    /* one of BOND_LINK_XXXX */
 	s8     state;   /* one of BOND_STATE_XXXX */
 	s8     state;   /* one of BOND_STATE_XXXX */
 	u32    original_flags;
 	u32    original_flags;
+	u32    original_mtu;
 	u32    link_failure_count;
 	u32    link_failure_count;
 	u16    speed;
 	u16    speed;
 	u8     duplex;
 	u8     duplex;