static void bond_setup_by_slave(struct net_device *bond_dev,
                                struct net_device *slave_dev)
 {
+       struct bonding *bond = bond_dev->priv;
+
        bond_dev->neigh_setup           = slave_dev->neigh_setup;
 
        bond_dev->type              = slave_dev->type;
 
        memcpy(bond_dev->broadcast, slave_dev->broadcast,
                slave_dev->addr_len);
+       bond->setup_by_slave = 1;
 }
 
 /* enslave device <slave> to bond device <master> */
        return 0;  /* deletion OK */
 }
 
+/*
+* Destroy a bonding device.
+* Must be under rtnl_lock when this function is called.
+*/
+void bond_destroy(struct bonding *bond)
+{
+       bond_deinit(bond->dev);
+       bond_destroy_sysfs_entry(bond);
+       unregister_netdevice(bond->dev);
+}
+
+/*
+* First release a slave and than destroy the bond if no more slaves iare left.
+* Must be under rtnl_lock when this function is called.
+*/
+int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+       struct bonding *bond = bond_dev->priv;
+       int ret;
+
+       ret = bond_release(bond_dev, slave_dev);
+       if ((ret == 0) && (bond->slave_cnt == 0)) {
+               printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
+                      bond_dev->name, bond_dev->name);
+               bond_destroy(bond);
+       }
+       return ret;
+}
+
 /*
  * This function releases all slaves.
  */
                 * ... Or is it this?
                 */
                break;
+       case NETDEV_GOING_DOWN:
+               dprintk("slave %s is going down\n", slave_dev->name);
+               if (bond->setup_by_slave)
+                       bond_release_and_destroy(bond_dev, slave_dev);
+               break;
        case NETDEV_CHANGEMTU:
                /*
                 * TODO: Should slaves be allowed to
        bond->primary_slave = NULL;
        bond->dev = bond_dev;
        bond->send_grat_arp = 0;
+       bond->setup_by_slave = 0;
        INIT_LIST_HEAD(&bond->vlan_list);
 
        /* Initialize the device entry points */
 
                                printk(KERN_INFO DRV_NAME
                                        ": %s is being deleted...\n",
                                        bond->dev->name);
-                               bond_deinit(bond->dev);
-                               bond_destroy_sysfs_entry(bond);
-                               unregister_netdevice(bond->dev);
+                               bond_destroy(bond);
                                rtnl_unlock();
                                goto out;
                        }
                        printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
                                bond->dev->name, dev->name);
                        rtnl_lock();
-                       res = bond_release(bond->dev, dev);
+                       if (bond->setup_by_slave)
+                               res = bond_release_and_destroy(bond->dev, dev);
+                       else
+                               res = bond_release(bond->dev, dev);
                        rtnl_unlock();
                        if (res) {
                                ret = res;
 
        s8       kill_timers;
        s8       do_set_mac_addr;
        s8       send_grat_arp;
+       s8       setup_by_slave;
        struct   net_device_stats stats;
 #ifdef CONFIG_PROC_FS
        struct   proc_dir_entry *proc_entry;
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
 int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_destroy(struct bonding *bond);
+int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
 void bond_deinit(struct net_device *bond_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);