|
@@ -1238,6 +1238,20 @@ static int bond_compute_features(struct bonding *bond)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static void bond_setup_by_slave(struct net_device *bond_dev,
|
|
|
+ struct net_device *slave_dev)
|
|
|
+{
|
|
|
+ bond_dev->neigh_setup = slave_dev->neigh_setup;
|
|
|
+
|
|
|
+ bond_dev->type = slave_dev->type;
|
|
|
+ bond_dev->hard_header_len = slave_dev->hard_header_len;
|
|
|
+ bond_dev->addr_len = slave_dev->addr_len;
|
|
|
+
|
|
|
+ memcpy(bond_dev->broadcast, slave_dev->broadcast,
|
|
|
+ slave_dev->addr_len);
|
|
|
+}
|
|
|
+
|
|
|
/* enslave device <slave> to bond device <master> */
|
|
|
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|
|
{
|
|
@@ -1312,6 +1326,25 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|
|
goto err_undo_flags;
|
|
|
}
|
|
|
|
|
|
+ /* set bonding device ether type by slave - bonding netdevices are
|
|
|
+ * created with ether_setup, so when the slave type is not ARPHRD_ETHER
|
|
|
+ * there is a need to override some of the type dependent attribs/funcs.
|
|
|
+ *
|
|
|
+ * bond ether type mutual exclusion - don't allow slaves of dissimilar
|
|
|
+ * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
|
|
|
+ */
|
|
|
+ if (bond->slave_cnt == 0) {
|
|
|
+ if (slave_dev->type != ARPHRD_ETHER)
|
|
|
+ bond_setup_by_slave(bond_dev, slave_dev);
|
|
|
+ } else if (bond_dev->type != slave_dev->type) {
|
|
|
+ printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
|
|
|
+ "from other slaves (%d), can not enslave it.\n",
|
|
|
+ slave_dev->name,
|
|
|
+ slave_dev->type, bond_dev->type);
|
|
|
+ res = -EINVAL;
|
|
|
+ goto err_undo_flags;
|
|
|
+ }
|
|
|
+
|
|
|
if (slave_dev->set_mac_address == NULL) {
|
|
|
printk(KERN_ERR DRV_NAME
|
|
|
": %s: Error: The slave device you specified does "
|