aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2009-10-29 10:18:26 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-30 15:41:21 -0400
commitec87fd3b4e111e8bc367d247a963e27e5b86df26 (patch)
tree8c33611b3e0afb37bcad232c2ad8d8f52d469634 /drivers/net/bonding/bond_main.c
parent88ead977109da926a03068e277869ea8fedd170d (diff)
bond: Add support for multiple network namespaces
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c111
1 files changed, 74 insertions, 37 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 405971374fe2..208d2c4ef068 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -75,6 +75,7 @@
75#include <linux/jiffies.h> 75#include <linux/jiffies.h>
76#include <net/route.h> 76#include <net/route.h>
77#include <net/net_namespace.h> 77#include <net/net_namespace.h>
78#include <net/netns/generic.h>
78#include "bonding.h" 79#include "bonding.h"
79#include "bond_3ad.h" 80#include "bond_3ad.h"
80#include "bond_alb.h" 81#include "bond_alb.h"
@@ -157,11 +158,7 @@ MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the
157static const char * const version = 158static const char * const version =
158 DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; 159 DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
159 160
160LIST_HEAD(bond_dev_list); 161int bond_net_id;
161
162#ifdef CONFIG_PROC_FS
163static struct proc_dir_entry *bond_proc_dir;
164#endif
165 162
166static __be32 arp_target[BOND_MAX_ARP_TARGETS]; 163static __be32 arp_target[BOND_MAX_ARP_TARGETS];
167static int arp_ip_count; 164static int arp_ip_count;
@@ -2586,7 +2583,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2586 fl.fl4_dst = targets[i]; 2583 fl.fl4_dst = targets[i];
2587 fl.fl4_tos = RTO_ONLINK; 2584 fl.fl4_tos = RTO_ONLINK;
2588 2585
2589 rv = ip_route_output_key(&init_net, &rt, &fl); 2586 rv = ip_route_output_key(dev_net(bond->dev), &rt, &fl);
2590 if (rv) { 2587 if (rv) {
2591 if (net_ratelimit()) { 2588 if (net_ratelimit()) {
2592 pr_warning(DRV_NAME 2589 pr_warning(DRV_NAME
@@ -2694,9 +2691,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
2694 unsigned char *arp_ptr; 2691 unsigned char *arp_ptr;
2695 __be32 sip, tip; 2692 __be32 sip, tip;
2696 2693
2697 if (dev_net(dev) != &init_net)
2698 goto out;
2699
2700 if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) 2694 if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
2701 goto out; 2695 goto out;
2702 2696
@@ -3359,10 +3353,11 @@ static const struct file_operations bond_info_fops = {
3359static void bond_create_proc_entry(struct bonding *bond) 3353static void bond_create_proc_entry(struct bonding *bond)
3360{ 3354{
3361 struct net_device *bond_dev = bond->dev; 3355 struct net_device *bond_dev = bond->dev;
3356 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
3362 3357
3363 if (bond_proc_dir) { 3358 if (bn->proc_dir) {
3364 bond->proc_entry = proc_create_data(bond_dev->name, 3359 bond->proc_entry = proc_create_data(bond_dev->name,
3365 S_IRUGO, bond_proc_dir, 3360 S_IRUGO, bn->proc_dir,
3366 &bond_info_fops, bond); 3361 &bond_info_fops, bond);
3367 if (bond->proc_entry == NULL) 3362 if (bond->proc_entry == NULL)
3368 pr_warning(DRV_NAME 3363 pr_warning(DRV_NAME
@@ -3375,8 +3370,11 @@ static void bond_create_proc_entry(struct bonding *bond)
3375 3370
3376static void bond_remove_proc_entry(struct bonding *bond) 3371static void bond_remove_proc_entry(struct bonding *bond)
3377{ 3372{
3378 if (bond_proc_dir && bond->proc_entry) { 3373 struct net_device *bond_dev = bond->dev;
3379 remove_proc_entry(bond->proc_file_name, bond_proc_dir); 3374 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
3375
3376 if (bn->proc_dir && bond->proc_entry) {
3377 remove_proc_entry(bond->proc_file_name, bn->proc_dir);
3380 memset(bond->proc_file_name, 0, IFNAMSIZ); 3378 memset(bond->proc_file_name, 0, IFNAMSIZ);
3381 bond->proc_entry = NULL; 3379 bond->proc_entry = NULL;
3382 } 3380 }
@@ -3385,11 +3383,11 @@ static void bond_remove_proc_entry(struct bonding *bond)
3385/* Create the bonding directory under /proc/net, if doesn't exist yet. 3383/* Create the bonding directory under /proc/net, if doesn't exist yet.
3386 * Caller must hold rtnl_lock. 3384 * Caller must hold rtnl_lock.
3387 */ 3385 */
3388static void bond_create_proc_dir(void) 3386static void bond_create_proc_dir(struct bond_net *bn)
3389{ 3387{
3390 if (!bond_proc_dir) { 3388 if (!bn->proc_dir) {
3391 bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net); 3389 bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
3392 if (!bond_proc_dir) 3390 if (!bn->proc_dir)
3393 pr_warning(DRV_NAME 3391 pr_warning(DRV_NAME
3394 ": Warning: cannot create /proc/net/%s\n", 3392 ": Warning: cannot create /proc/net/%s\n",
3395 DRV_NAME); 3393 DRV_NAME);
@@ -3399,11 +3397,11 @@ static void bond_create_proc_dir(void)
3399/* Destroy the bonding directory under /proc/net, if empty. 3397/* Destroy the bonding directory under /proc/net, if empty.
3400 * Caller must hold rtnl_lock. 3398 * Caller must hold rtnl_lock.
3401 */ 3399 */
3402static void bond_destroy_proc_dir(void) 3400static void bond_destroy_proc_dir(struct bond_net *bn)
3403{ 3401{
3404 if (bond_proc_dir) { 3402 if (bn->proc_dir) {
3405 remove_proc_entry(DRV_NAME, init_net.proc_net); 3403 remove_proc_entry(DRV_NAME, bn->net->proc_net);
3406 bond_proc_dir = NULL; 3404 bn->proc_dir = NULL;
3407 } 3405 }
3408} 3406}
3409 3407
@@ -3417,11 +3415,11 @@ static void bond_remove_proc_entry(struct bonding *bond)
3417{ 3415{
3418} 3416}
3419 3417
3420static void bond_create_proc_dir(void) 3418static void bond_create_proc_dir(struct bond_net *bn)
3421{ 3419{
3422} 3420}
3423 3421
3424static void bond_destroy_proc_dir(void) 3422static void bond_destroy_proc_dir(struct bond_net *bn)
3425{ 3423{
3426} 3424}
3427 3425
@@ -3540,9 +3538,6 @@ static int bond_netdev_event(struct notifier_block *this,
3540{ 3538{
3541 struct net_device *event_dev = (struct net_device *)ptr; 3539 struct net_device *event_dev = (struct net_device *)ptr;
3542 3540
3543 if (dev_net(event_dev) != &init_net)
3544 return NOTIFY_DONE;
3545
3546 pr_debug("event_dev: %s, event: %lx\n", 3541 pr_debug("event_dev: %s, event: %lx\n",
3547 (event_dev ? event_dev->name : "None"), 3542 (event_dev ? event_dev->name : "None"),
3548 event); 3543 event);
@@ -3575,13 +3570,11 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
3575{ 3570{
3576 struct in_ifaddr *ifa = ptr; 3571 struct in_ifaddr *ifa = ptr;
3577 struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; 3572 struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
3573 struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id);
3578 struct bonding *bond; 3574 struct bonding *bond;
3579 struct vlan_entry *vlan; 3575 struct vlan_entry *vlan;
3580 3576
3581 if (dev_net(ifa->ifa_dev->dev) != &init_net) 3577 list_for_each_entry(bond, &bn->dev_list, bond_list) {
3582 return NOTIFY_DONE;
3583
3584 list_for_each_entry(bond, &bond_dev_list, bond_list) {
3585 if (bond->dev == event_dev) { 3578 if (bond->dev == event_dev) {
3586 switch (event) { 3579 switch (event) {
3587 case NETDEV_UP: 3580 case NETDEV_UP:
@@ -3950,7 +3943,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
3950 if (!capable(CAP_NET_ADMIN)) 3943 if (!capable(CAP_NET_ADMIN))
3951 return -EPERM; 3944 return -EPERM;
3952 3945
3953 slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave); 3946 slave_dev = dev_get_by_name(dev_net(bond_dev), ifr->ifr_slave);
3954 3947
3955 pr_debug("slave_dev=%p: \n", slave_dev); 3948 pr_debug("slave_dev=%p: \n", slave_dev);
3956 3949
@@ -5031,6 +5024,7 @@ static void bond_set_lockdep_class(struct net_device *dev)
5031static int bond_init(struct net_device *bond_dev) 5024static int bond_init(struct net_device *bond_dev)
5032{ 5025{
5033 struct bonding *bond = netdev_priv(bond_dev); 5026 struct bonding *bond = netdev_priv(bond_dev);
5027 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
5034 5028
5035 pr_debug("Begin bond_init for %s\n", bond_dev->name); 5029 pr_debug("Begin bond_init for %s\n", bond_dev->name);
5036 5030
@@ -5043,7 +5037,7 @@ static int bond_init(struct net_device *bond_dev)
5043 netif_carrier_off(bond_dev); 5037 netif_carrier_off(bond_dev);
5044 5038
5045 bond_create_proc_entry(bond); 5039 bond_create_proc_entry(bond);
5046 list_add_tail(&bond->bond_list, &bond_dev_list); 5040 list_add_tail(&bond->bond_list, &bn->dev_list);
5047 5041
5048 bond_prepare_sysfs_group(bond); 5042 bond_prepare_sysfs_group(bond);
5049 return 0; 5043 return 0;
@@ -5071,7 +5065,7 @@ static struct rtnl_link_ops bond_link_ops __read_mostly = {
5071 * Caller must NOT hold rtnl_lock; we need to release it here before we 5065 * Caller must NOT hold rtnl_lock; we need to release it here before we
5072 * set up our sysfs entries. 5066 * set up our sysfs entries.
5073 */ 5067 */
5074int bond_create(const char *name) 5068int bond_create(struct net *net, const char *name)
5075{ 5069{
5076 struct net_device *bond_dev; 5070 struct net_device *bond_dev;
5077 int res; 5071 int res;
@@ -5087,6 +5081,7 @@ int bond_create(const char *name)
5087 goto out; 5081 goto out;
5088 } 5082 }
5089 5083
5084 dev_net_set(bond_dev, net);
5090 bond_dev->rtnl_link_ops = &bond_link_ops; 5085 bond_dev->rtnl_link_ops = &bond_link_ops;
5091 5086
5092 if (!name) { 5087 if (!name) {
@@ -5105,6 +5100,46 @@ out_netdev:
5105 goto out; 5100 goto out;
5106} 5101}
5107 5102
5103static int bond_net_init(struct net *net)
5104{
5105 struct bond_net *bn;
5106 int err;
5107
5108 err = -ENOMEM;
5109 bn = kzalloc(sizeof(struct bond_net), GFP_KERNEL);
5110 if (bn == NULL)
5111 goto out;
5112
5113 bn->net = net;
5114 INIT_LIST_HEAD(&bn->dev_list);
5115
5116 err = net_assign_generic(net, bond_net_id, bn);
5117 if (err)
5118 goto out_free;
5119
5120 bond_create_proc_dir(bn);
5121out:
5122 return err;
5123out_free:
5124 kfree(bn);
5125 goto out;
5126}
5127
5128static void bond_net_exit(struct net *net)
5129{
5130 struct bond_net *bn;
5131
5132 bn = net_generic(net, bond_net_id);
5133
5134 bond_destroy_proc_dir(bn);
5135 kfree(bn);
5136}
5137
5138static struct pernet_operations bond_net_ops = {
5139 .init = bond_net_init,
5140 .exit = bond_net_exit,
5141};
5142
5108static int __init bonding_init(void) 5143static int __init bonding_init(void)
5109{ 5144{
5110 int i; 5145 int i;
@@ -5116,14 +5151,16 @@ static int __init bonding_init(void)
5116 if (res) 5151 if (res)
5117 goto out; 5152 goto out;
5118 5153
5119 bond_create_proc_dir(); 5154 res = register_pernet_gen_subsys(&bond_net_id, &bond_net_ops);
5155 if (res)
5156 goto out;
5120 5157
5121 res = rtnl_link_register(&bond_link_ops); 5158 res = rtnl_link_register(&bond_link_ops);
5122 if (res) 5159 if (res)
5123 goto err; 5160 goto err;
5124 5161
5125 for (i = 0; i < max_bonds; i++) { 5162 for (i = 0; i < max_bonds; i++) {
5126 res = bond_create(NULL); 5163 res = bond_create(&init_net, NULL);
5127 if (res) 5164 if (res)
5128 goto err; 5165 goto err;
5129 } 5166 }
@@ -5139,7 +5176,7 @@ out:
5139 return res; 5176 return res;
5140err: 5177err:
5141 rtnl_link_unregister(&bond_link_ops); 5178 rtnl_link_unregister(&bond_link_ops);
5142 bond_destroy_proc_dir(); 5179 unregister_pernet_gen_subsys(bond_net_id, &bond_net_ops);
5143 goto out; 5180 goto out;
5144 5181
5145} 5182}
@@ -5153,7 +5190,7 @@ static void __exit bonding_exit(void)
5153 bond_destroy_sysfs(); 5190 bond_destroy_sysfs();
5154 5191
5155 rtnl_link_unregister(&bond_link_ops); 5192 rtnl_link_unregister(&bond_link_ops);
5156 bond_destroy_proc_dir(); 5193 unregister_pernet_gen_subsys(bond_net_id, &bond_net_ops);
5157} 5194}
5158 5195
5159module_init(bonding_init); 5196module_init(bonding_init);