[PATCH] fixes to bonding driver

From: Anton Blanchard (anton@linuxcare.com)
Date: Thu Jun 01 2000 - 12:52:44 EST


- We were not doing MOD_DEC_USE_COUNT and dev_put which meant both the
bonding module and the slave device module could not be removed.

- Implement multicast on bonding driver. I can't live without tcpdump :)

- Fix tx path so we skip the right interface if the carrier is down.
This requires the network driver to do netif_carrier_off, netif_carrier_on
in the correct place.

QUESTION: Why are the network drivers not using netif_carrier_off and
netif_carrier_on? Can I submit a patch to fix this?

Anton

--- linux/drivers/net/bonding.c Tue May 23 13:09:26 2000
+++ linux_work/drivers/net/bonding.c Thu Jun 1 10:29:27 2000
@@ -85,35 +85,49 @@
         return 0;
 }
 
-static int bond_close(struct net_device *master)
+static void release_one_slave(struct net_device *master, slave_t *slave)
 {
         bonding_t *bond = master->priv;
- slave_t *slave;
 
- while ((slave = bond->next) != (slave_t*)bond) {
+ spin_lock_bh(&master->xmit_lock);
+ if (bond->current_slave == slave)
+ bond->current_slave = slave->next;
+ slave->next->prev = slave->prev;
+ slave->prev->next = slave->next;
+ spin_unlock_bh(&master->xmit_lock);
 
- spin_lock_bh(&master->xmit_lock);
- slave->next->prev = slave->prev;
- slave->prev->next = slave->next;
- bond->current_slave = (slave_t*)bond;
- spin_unlock_bh(&master->xmit_lock);
+ netdev_set_master(slave->dev, NULL);
 
- netdev_set_master(slave->dev, NULL);
+ dev_put(slave->dev);
+ kfree(slave);
+ MOD_DEC_USE_COUNT;
+}
 
- kfree(slave);
- }
+static int bond_close(struct net_device *master)
+{
+ bonding_t *bond = master->priv;
+ slave_t *slave;
+
+ while ((slave = bond->next) != (slave_t*)bond)
+ release_one_slave(master, slave);
 
         MOD_DEC_USE_COUNT;
         return 0;
 }
 
-/* Fake multicast ability.
-
- NB. It is possible and necessary to make it true one, otherwise
- the device is not functional.
- */
-static void bond_set_multicast_list(struct net_device *dev)
+static void bond_set_multicast_list(struct net_device *master)
 {
+ bonding_t *bond = master->priv;
+ slave_t *slave;
+
+ for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
+ slave->dev->mc_list = master->mc_list;
+ slave->dev->mc_count = master->mc_count;
+ slave->dev->flags = master->flags;
+ slave->dev->set_multicast_list(slave->dev);
+ }
+
+ return 0;
 }
 
 static int bond_enslave(struct net_device *master, struct net_device *dev)
@@ -161,20 +175,9 @@
         if (dev->master != master)
                 return -EINVAL;
 
- netdev_set_master(dev, NULL);
-
         for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
                 if (slave->dev == dev) {
- spin_lock_bh(&master->xmit_lock);
- if (bond->current_slave == slave)
- bond->current_slave = slave->next;
- slave->next->prev = slave->prev;
- slave->prev->next = slave->next;
- spin_unlock_bh(&master->xmit_lock);
-
- kfree(slave);
- dev_put(dev);
- MOD_DEC_USE_COUNT;
+ release_one_slave(master, slave);
                         break;
                 }
         }
@@ -281,7 +284,7 @@
                 if (slave == (slave_t*)bond)
                         continue;
 
- if (netif_running(slave->dev) && netif_carrier_ok(dev)) {
+ if (netif_running(slave->dev) && netif_carrier_ok(slave->dev)) {
                         bond->current_slave = slave->next;
                         skb->dev = slave->dev;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Jun 07 2000 - 21:00:13 EST