diff options
author | Eric W. Biederman <ebiederm@aristanetworks.com> | 2009-10-29 10:18:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-30 15:41:21 -0400 |
commit | 88ead977109da926a03068e277869ea8fedd170d (patch) | |
tree | 81f1ef8acbb6e6aa49c020e6c1d6e7ed5f018341 /drivers/net/bonding | |
parent | c67dfb299e05a132154b9bfaae4a83de478ffaa9 (diff) |
bond: Implement a basic set of rtnl link ops
This implements a basic set of rtnl link ops and takes advantage of
the fact that rtnl_link_unregister kills all of the surviving
devices to all us to kill bond_free_all. A module alias
is added so ip link add can pull in the bonding module.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index db9640b43d01..405971374fe2 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -4612,22 +4612,6 @@ static void bond_uninit(struct net_device *bond_dev) | |||
4612 | netif_addr_unlock_bh(bond_dev); | 4612 | netif_addr_unlock_bh(bond_dev); |
4613 | } | 4613 | } |
4614 | 4614 | ||
4615 | /* Unregister and free all bond devices. | ||
4616 | * Caller must hold rtnl_lock. | ||
4617 | */ | ||
4618 | static void bond_free_all(void) | ||
4619 | { | ||
4620 | struct bonding *bond, *nxt; | ||
4621 | |||
4622 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { | ||
4623 | struct net_device *bond_dev = bond->dev; | ||
4624 | |||
4625 | unregister_netdevice(bond_dev); | ||
4626 | } | ||
4627 | |||
4628 | bond_destroy_proc_dir(); | ||
4629 | } | ||
4630 | |||
4631 | /*------------------------- Module initialization ---------------------------*/ | 4615 | /*------------------------- Module initialization ---------------------------*/ |
4632 | 4616 | ||
4633 | /* | 4617 | /* |
@@ -5065,6 +5049,23 @@ static int bond_init(struct net_device *bond_dev) | |||
5065 | return 0; | 5049 | return 0; |
5066 | } | 5050 | } |
5067 | 5051 | ||
5052 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
5053 | { | ||
5054 | if (tb[IFLA_ADDRESS]) { | ||
5055 | if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) | ||
5056 | return -EINVAL; | ||
5057 | if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) | ||
5058 | return -EADDRNOTAVAIL; | ||
5059 | } | ||
5060 | return 0; | ||
5061 | } | ||
5062 | |||
5063 | static struct rtnl_link_ops bond_link_ops __read_mostly = { | ||
5064 | .kind = "bond", | ||
5065 | .setup = bond_setup, | ||
5066 | .validate = bond_validate, | ||
5067 | }; | ||
5068 | |||
5068 | /* Create a new bond based on the specified name and bonding parameters. | 5069 | /* Create a new bond based on the specified name and bonding parameters. |
5069 | * If name is NULL, obtain a suitable "bond%d" name for us. | 5070 | * If name is NULL, obtain a suitable "bond%d" name for us. |
5070 | * Caller must NOT hold rtnl_lock; we need to release it here before we | 5071 | * Caller must NOT hold rtnl_lock; we need to release it here before we |
@@ -5086,6 +5087,8 @@ int bond_create(const char *name) | |||
5086 | goto out; | 5087 | goto out; |
5087 | } | 5088 | } |
5088 | 5089 | ||
5090 | bond_dev->rtnl_link_ops = &bond_link_ops; | ||
5091 | |||
5089 | if (!name) { | 5092 | if (!name) { |
5090 | res = dev_alloc_name(bond_dev, "bond%d"); | 5093 | res = dev_alloc_name(bond_dev, "bond%d"); |
5091 | if (res < 0) | 5094 | if (res < 0) |
@@ -5115,6 +5118,10 @@ static int __init bonding_init(void) | |||
5115 | 5118 | ||
5116 | bond_create_proc_dir(); | 5119 | bond_create_proc_dir(); |
5117 | 5120 | ||
5121 | res = rtnl_link_register(&bond_link_ops); | ||
5122 | if (res) | ||
5123 | goto err; | ||
5124 | |||
5118 | for (i = 0; i < max_bonds; i++) { | 5125 | for (i = 0; i < max_bonds; i++) { |
5119 | res = bond_create(NULL); | 5126 | res = bond_create(NULL); |
5120 | if (res) | 5127 | if (res) |
@@ -5128,14 +5135,12 @@ static int __init bonding_init(void) | |||
5128 | register_netdevice_notifier(&bond_netdev_notifier); | 5135 | register_netdevice_notifier(&bond_netdev_notifier); |
5129 | register_inetaddr_notifier(&bond_inetaddr_notifier); | 5136 | register_inetaddr_notifier(&bond_inetaddr_notifier); |
5130 | bond_register_ipv6_notifier(); | 5137 | bond_register_ipv6_notifier(); |
5131 | |||
5132 | goto out; | ||
5133 | err: | ||
5134 | rtnl_lock(); | ||
5135 | bond_free_all(); | ||
5136 | rtnl_unlock(); | ||
5137 | out: | 5138 | out: |
5138 | return res; | 5139 | return res; |
5140 | err: | ||
5141 | rtnl_link_unregister(&bond_link_ops); | ||
5142 | bond_destroy_proc_dir(); | ||
5143 | goto out; | ||
5139 | 5144 | ||
5140 | } | 5145 | } |
5141 | 5146 | ||
@@ -5147,9 +5152,8 @@ static void __exit bonding_exit(void) | |||
5147 | 5152 | ||
5148 | bond_destroy_sysfs(); | 5153 | bond_destroy_sysfs(); |
5149 | 5154 | ||
5150 | rtnl_lock(); | 5155 | rtnl_link_unregister(&bond_link_ops); |
5151 | bond_free_all(); | 5156 | bond_destroy_proc_dir(); |
5152 | rtnl_unlock(); | ||
5153 | } | 5157 | } |
5154 | 5158 | ||
5155 | module_init(bonding_init); | 5159 | module_init(bonding_init); |
@@ -5158,3 +5162,4 @@ MODULE_LICENSE("GPL"); | |||
5158 | MODULE_VERSION(DRV_VERSION); | 5162 | MODULE_VERSION(DRV_VERSION); |
5159 | MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION); | 5163 | MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION); |
5160 | MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others"); | 5164 | MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others"); |
5165 | MODULE_ALIAS_RTNL_LINK("bond"); | ||