aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_main.c38
-rw-r--r--drivers/net/bonding/bond_sysfs.c9
-rw-r--r--drivers/net/bonding/bonding.h3
3 files changed, 46 insertions, 4 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 19fd35175a77..0e198dd87c20 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1257,6 +1257,8 @@ static int bond_compute_features(struct bonding *bond)
1257static void bond_setup_by_slave(struct net_device *bond_dev, 1257static void bond_setup_by_slave(struct net_device *bond_dev,
1258 struct net_device *slave_dev) 1258 struct net_device *slave_dev)
1259{ 1259{
1260 struct bonding *bond = bond_dev->priv;
1261
1260 bond_dev->neigh_setup = slave_dev->neigh_setup; 1262 bond_dev->neigh_setup = slave_dev->neigh_setup;
1261 1263
1262 bond_dev->type = slave_dev->type; 1264 bond_dev->type = slave_dev->type;
@@ -1265,6 +1267,7 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
1265 1267
1266 memcpy(bond_dev->broadcast, slave_dev->broadcast, 1268 memcpy(bond_dev->broadcast, slave_dev->broadcast,
1267 slave_dev->addr_len); 1269 slave_dev->addr_len);
1270 bond->setup_by_slave = 1;
1268} 1271}
1269 1272
1270/* enslave device <slave> to bond device <master> */ 1273/* enslave device <slave> to bond device <master> */
@@ -1828,6 +1831,35 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1828} 1831}
1829 1832
1830/* 1833/*
1834* Destroy a bonding device.
1835* Must be under rtnl_lock when this function is called.
1836*/
1837void bond_destroy(struct bonding *bond)
1838{
1839 bond_deinit(bond->dev);
1840 bond_destroy_sysfs_entry(bond);
1841 unregister_netdevice(bond->dev);
1842}
1843
1844/*
1845* First release a slave and than destroy the bond if no more slaves iare left.
1846* Must be under rtnl_lock when this function is called.
1847*/
1848int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
1849{
1850 struct bonding *bond = bond_dev->priv;
1851 int ret;
1852
1853 ret = bond_release(bond_dev, slave_dev);
1854 if ((ret == 0) && (bond->slave_cnt == 0)) {
1855 printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
1856 bond_dev->name, bond_dev->name);
1857 bond_destroy(bond);
1858 }
1859 return ret;
1860}
1861
1862/*
1831 * This function releases all slaves. 1863 * This function releases all slaves.
1832 */ 1864 */
1833static int bond_release_all(struct net_device *bond_dev) 1865static int bond_release_all(struct net_device *bond_dev)
@@ -3325,6 +3357,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
3325 * ... Or is it this? 3357 * ... Or is it this?
3326 */ 3358 */
3327 break; 3359 break;
3360 case NETDEV_GOING_DOWN:
3361 dprintk("slave %s is going down\n", slave_dev->name);
3362 if (bond->setup_by_slave)
3363 bond_release_and_destroy(bond_dev, slave_dev);
3364 break;
3328 case NETDEV_CHANGEMTU: 3365 case NETDEV_CHANGEMTU:
3329 /* 3366 /*
3330 * TODO: Should slaves be allowed to 3367 * TODO: Should slaves be allowed to
@@ -4298,6 +4335,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4298 bond->primary_slave = NULL; 4335 bond->primary_slave = NULL;
4299 bond->dev = bond_dev; 4336 bond->dev = bond_dev;
4300 bond->send_grat_arp = 0; 4337 bond->send_grat_arp = 0;
4338 bond->setup_by_slave = 0;
4301 INIT_LIST_HEAD(&bond->vlan_list); 4339 INIT_LIST_HEAD(&bond->vlan_list);
4302 4340
4303 /* Initialize the device entry points */ 4341 /* Initialize the device entry points */
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 583c568e1764..b5d2a13fe627 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -164,9 +164,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
164 printk(KERN_INFO DRV_NAME 164 printk(KERN_INFO DRV_NAME
165 ": %s is being deleted...\n", 165 ": %s is being deleted...\n",
166 bond->dev->name); 166 bond->dev->name);
167 bond_deinit(bond->dev); 167 bond_destroy(bond);
168 bond_destroy_sysfs_entry(bond);
169 unregister_netdevice(bond->dev);
170 rtnl_unlock(); 168 rtnl_unlock();
171 goto out; 169 goto out;
172 } 170 }
@@ -363,7 +361,10 @@ static ssize_t bonding_store_slaves(struct device *d,
363 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", 361 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
364 bond->dev->name, dev->name); 362 bond->dev->name, dev->name);
365 rtnl_lock(); 363 rtnl_lock();
366 res = bond_release(bond->dev, dev); 364 if (bond->setup_by_slave)
365 res = bond_release_and_destroy(bond->dev, dev);
366 else
367 res = bond_release(bond->dev, dev);
367 rtnl_unlock(); 368 rtnl_unlock();
368 if (res) { 369 if (res) {
369 ret = res; 370 ret = res;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index e0e06a84b5b9..85e579b0d6f4 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -188,6 +188,7 @@ struct bonding {
188 s8 kill_timers; 188 s8 kill_timers;
189 s8 do_set_mac_addr; 189 s8 do_set_mac_addr;
190 s8 send_grat_arp; 190 s8 send_grat_arp;
191 s8 setup_by_slave;
191 struct net_device_stats stats; 192 struct net_device_stats stats;
192#ifdef CONFIG_PROC_FS 193#ifdef CONFIG_PROC_FS
193 struct proc_dir_entry *proc_entry; 194 struct proc_dir_entry *proc_entry;
@@ -295,6 +296,8 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
295struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); 296struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
296int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); 297int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
297int bond_create(char *name, struct bond_params *params, struct bonding **newbond); 298int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
299void bond_destroy(struct bonding *bond);
300int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
298void bond_deinit(struct net_device *bond_dev); 301void bond_deinit(struct net_device *bond_dev);
299int bond_create_sysfs(void); 302int bond_create_sysfs(void);
300void bond_destroy_sysfs(void); 303void bond_destroy_sysfs(void);