net/bonding: Handlle wrong assumptions that slave is always an Ethernet device
Moni Shoua [Wed, 10 Oct 2007 02:43:41 +0000 (19:43 -0700)]
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>

drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h

index 3eebfe2..7be2336 100644 (file)
@@ -1225,7 +1225,8 @@ static int bond_compute_features(struct bonding *bond)
        struct slave *slave;
        struct net_device *bond_dev = bond->dev;
        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;
 
        features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
index ca4e429..583c568 100644 (file)
@@ -260,6 +260,7 @@ static ssize_t bonding_store_slaves(struct device *d,
        char command[IFNAMSIZ + 1] = { 0, };
        char *ifname;
        int i, res, found, ret = count;
+       u32 original_mtu;
        struct slave *slave;
        struct net_device *dev = NULL;
        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 */
+               original_mtu = dev->mtu;
                if (dev->mtu != bond->dev->mtu) {
                        if (dev->change_mtu) {
                                res = dev->change_mtu(dev,
@@ -339,6 +341,9 @@ static ssize_t bonding_store_slaves(struct device *d,
                }
                rtnl_lock();
                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();
                if (res) {
                        ret = res;
@@ -351,6 +356,7 @@ static ssize_t bonding_store_slaves(struct device *d,
                bond_for_each_slave(bond, slave, i)
                        if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
                                dev = slave->dev;
+                               original_mtu = slave->original_mtu;
                                break;
                        }
                if (dev) {
@@ -365,9 +371,9 @@ static ssize_t bonding_store_slaves(struct device *d,
                        }
                        /* set the slave MTU to the default */
                        if (dev->change_mtu) {
-                               dev->change_mtu(dev, 1500);
+                               dev->change_mtu(dev, original_mtu);
                        } else {
-                               dev->mtu = 1500;
+                               dev->mtu = original_mtu;
                        }
                }
                else {
index 5011ba9..ad9c632 100644 (file)
@@ -156,6 +156,7 @@ struct slave {
        s8     link;    /* one of BOND_LINK_XXXX */
        s8     state;   /* one of BOND_STATE_XXXX */
        u32    original_flags;
+       u32    original_mtu;
        u32    link_failure_count;
        u16    speed;
        u8     duplex;