diff options
| -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); |
