diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 38 |
1 files changed, 38 insertions, 0 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 */ |