diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 38 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 9 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 3 |
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) | |||
1257 | static void bond_setup_by_slave(struct net_device *bond_dev, | 1257 | static 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 | */ | ||
1837 | void 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 | */ | ||
1848 | int 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 | */ |
1833 | static int bond_release_all(struct net_device *bond_dev) | 1865 | static 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) | |||
295 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); | 296 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); |
296 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); | 297 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); |
297 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond); | 298 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond); |
299 | void bond_destroy(struct bonding *bond); | ||
300 | int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev); | ||
298 | void bond_deinit(struct net_device *bond_dev); | 301 | void bond_deinit(struct net_device *bond_dev); |
299 | int bond_create_sysfs(void); | 302 | int bond_create_sysfs(void); |
300 | void bond_destroy_sysfs(void); | 303 | void bond_destroy_sysfs(void); |