diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 113 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
2 files changed, 62 insertions, 52 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b8d617626c90..2475b76e10e4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -4898,81 +4898,90 @@ static int bond_check_params(struct bond_params *params) | |||
4898 | return 0; | 4898 | return 0; |
4899 | } | 4899 | } |
4900 | 4900 | ||
4901 | /* Create a new bond based on the specified name and bonding parameters. | ||
4902 | * Caller must NOT hold rtnl_lock; we need to release it here before we | ||
4903 | * set up our sysfs entries. | ||
4904 | */ | ||
4905 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond) | ||
4906 | { | ||
4907 | struct net_device *bond_dev; | ||
4908 | int res; | ||
4909 | |||
4910 | rtnl_lock(); | ||
4911 | bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup); | ||
4912 | if (!bond_dev) { | ||
4913 | printk(KERN_ERR DRV_NAME | ||
4914 | ": %s: eek! can't alloc netdev!\n", | ||
4915 | name); | ||
4916 | res = -ENOMEM; | ||
4917 | goto out_rtnl; | ||
4918 | } | ||
4919 | |||
4920 | /* bond_init() must be called after dev_alloc_name() (for the | ||
4921 | * /proc files), but before register_netdevice(), because we | ||
4922 | * need to set function pointers. | ||
4923 | */ | ||
4924 | |||
4925 | res = bond_init(bond_dev, params); | ||
4926 | if (res < 0) { | ||
4927 | goto out_netdev; | ||
4928 | } | ||
4929 | |||
4930 | SET_MODULE_OWNER(bond_dev); | ||
4931 | |||
4932 | res = register_netdevice(bond_dev); | ||
4933 | if (res < 0) { | ||
4934 | goto out_bond; | ||
4935 | } | ||
4936 | if (newbond) | ||
4937 | *newbond = bond_dev->priv; | ||
4938 | |||
4939 | rtnl_unlock(); /* allows sysfs registration of net device */ | ||
4940 | goto done; | ||
4941 | out_bond: | ||
4942 | bond_deinit(bond_dev); | ||
4943 | out_netdev: | ||
4944 | free_netdev(bond_dev); | ||
4945 | out_rtnl: | ||
4946 | rtnl_unlock(); | ||
4947 | done: | ||
4948 | return res; | ||
4949 | } | ||
4950 | |||
4901 | static int __init bonding_init(void) | 4951 | static int __init bonding_init(void) |
4902 | { | 4952 | { |
4903 | struct bond_params params; | ||
4904 | int i; | 4953 | int i; |
4905 | int res; | 4954 | int res; |
4955 | char new_bond_name[8]; /* Enough room for 999 bonds at init. */ | ||
4906 | 4956 | ||
4907 | printk(KERN_INFO "%s", version); | 4957 | printk(KERN_INFO "%s", version); |
4908 | 4958 | ||
4909 | res = bond_check_params(¶ms); | 4959 | res = bond_check_params(&bonding_defaults); |
4910 | if (res) { | 4960 | if (res) { |
4911 | return res; | 4961 | goto out; |
4912 | } | 4962 | } |
4913 | 4963 | ||
4914 | rtnl_lock(); | ||
4915 | |||
4916 | #ifdef CONFIG_PROC_FS | 4964 | #ifdef CONFIG_PROC_FS |
4917 | bond_create_proc_dir(); | 4965 | bond_create_proc_dir(); |
4918 | #endif | 4966 | #endif |
4919 | |||
4920 | for (i = 0; i < max_bonds; i++) { | 4967 | for (i = 0; i < max_bonds; i++) { |
4921 | struct net_device *bond_dev; | 4968 | sprintf(new_bond_name, "bond%d",i); |
4922 | 4969 | res = bond_create(new_bond_name,&bonding_defaults, NULL); | |
4923 | bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup); | 4970 | if (res) |
4924 | if (!bond_dev) { | 4971 | goto err; |
4925 | res = -ENOMEM; | ||
4926 | goto out_err; | ||
4927 | } | ||
4928 | |||
4929 | res = dev_alloc_name(bond_dev, "bond%d"); | ||
4930 | if (res < 0) { | ||
4931 | free_netdev(bond_dev); | ||
4932 | goto out_err; | ||
4933 | } | ||
4934 | |||
4935 | /* bond_init() must be called after dev_alloc_name() (for the | ||
4936 | * /proc files), but before register_netdevice(), because we | ||
4937 | * need to set function pointers. | ||
4938 | */ | ||
4939 | res = bond_init(bond_dev, ¶ms); | ||
4940 | if (res < 0) { | ||
4941 | free_netdev(bond_dev); | ||
4942 | goto out_err; | ||
4943 | } | ||
4944 | |||
4945 | SET_MODULE_OWNER(bond_dev); | ||
4946 | |||
4947 | res = register_netdevice(bond_dev); | ||
4948 | if (res < 0) { | ||
4949 | bond_deinit(bond_dev); | ||
4950 | free_netdev(bond_dev); | ||
4951 | goto out_err; | ||
4952 | } | ||
4953 | } | 4972 | } |
4954 | 4973 | ||
4955 | rtnl_unlock(); | ||
4956 | register_netdevice_notifier(&bond_netdev_notifier); | 4974 | register_netdevice_notifier(&bond_netdev_notifier); |
4957 | register_inetaddr_notifier(&bond_inetaddr_notifier); | 4975 | register_inetaddr_notifier(&bond_inetaddr_notifier); |
4958 | 4976 | ||
4959 | return 0; | 4977 | goto out; |
4960 | 4978 | err: | |
4961 | out_err: | ||
4962 | /* | ||
4963 | * rtnl_unlock() will run netdev_run_todo(), putting the | ||
4964 | * thus-far-registered bonding devices into a state which | ||
4965 | * unregigister_netdevice() will accept | ||
4966 | */ | ||
4967 | rtnl_unlock(); | ||
4968 | rtnl_lock(); | 4979 | rtnl_lock(); |
4969 | |||
4970 | /* free and unregister all bonds that were successfully added */ | ||
4971 | bond_free_all(); | 4980 | bond_free_all(); |
4972 | |||
4973 | rtnl_unlock(); | 4981 | rtnl_unlock(); |
4974 | 4982 | out: | |
4975 | return res; | 4983 | return res; |
4984 | |||
4976 | } | 4985 | } |
4977 | 4986 | ||
4978 | static void __exit bonding_exit(void) | 4987 | static void __exit bonding_exit(void) |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 96a733f2337a..863605aab204 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -260,6 +260,7 @@ extern inline void bond_set_slave_active_flags(struct slave *slave) | |||
260 | 260 | ||
261 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); | 261 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); |
262 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); | 262 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); |
263 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond); | ||
263 | void bond_deinit(struct net_device *bond_dev); | 264 | void bond_deinit(struct net_device *bond_dev); |
264 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); | 265 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); |
265 | int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); | 266 | int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); |