diff options
author | Eric W. Biederman <ebiederm@aristanetworks.com> | 2009-10-29 14:18:26 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-30 12:41:21 -0700 |
commit | ec87fd3b4e111e8bc367d247a963e27e5b86df26 (patch) | |
tree | 8c33611b3e0afb37bcad232c2ad8d8f52d469634 /drivers/net/bonding/bond_main.c | |
parent | 88ead977109da926a03068e277869ea8fedd170d (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.c | 111 |
1 files changed, 74 insertions, 37 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 405971374fe..208d2c4ef06 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -75,6 +75,7 @@ #include <linux/jiffies.h> #include <net/route.h> #include <net/net_namespace.h> +#include <net/netns/generic.h> #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -157,11 +158,7 @@ MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the static const char * const version = DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; -LIST_HEAD(bond_dev_list); - -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry *bond_proc_dir; -#endif +int bond_net_id; static __be32 arp_target[BOND_MAX_ARP_TARGETS]; static int arp_ip_count; @@ -2586,7 +2583,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) fl.fl4_dst = targets[i]; fl.fl4_tos = RTO_ONLINK; - rv = ip_route_output_key(&init_net, &rt, &fl); + rv = ip_route_output_key(dev_net(bond->dev), &rt, &fl); if (rv) { if (net_ratelimit()) { pr_warning(DRV_NAME @@ -2694,9 +2691,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack unsigned char *arp_ptr; __be32 sip, tip; - if (dev_net(dev) != &init_net) - goto out; - if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) goto out; @@ -3359,10 +3353,11 @@ static const struct file_operations bond_info_fops = { static void bond_create_proc_entry(struct bonding *bond) { struct net_device *bond_dev = bond->dev; + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); - if (bond_proc_dir) { + if (bn->proc_dir) { bond->proc_entry = proc_create_data(bond_dev->name, - S_IRUGO, bond_proc_dir, + S_IRUGO, bn->proc_dir, &bond_info_fops, bond); if (bond->proc_entry == NULL) pr_warning(DRV_NAME @@ -3375,8 +3370,11 @@ static void bond_create_proc_entry(struct bonding *bond) static void bond_remove_proc_entry(struct bonding *bond) { - if (bond_proc_dir && bond->proc_entry) { - remove_proc_entry(bond->proc_file_name, bond_proc_dir); + struct net_device *bond_dev = bond->dev; + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); + + if (bn->proc_dir && bond->proc_entry) { + remove_proc_entry(bond->proc_file_name, bn->proc_dir); memset(bond->proc_file_name, 0, IFNAMSIZ); bond->proc_entry = NULL; } @@ -3385,11 +3383,11 @@ static void bond_remove_proc_entry(struct bonding *bond) /* Create the bonding directory under /proc/net, if doesn't exist yet. * Caller must hold rtnl_lock. */ -static void bond_create_proc_dir(void) +static void bond_create_proc_dir(struct bond_net *bn) { - if (!bond_proc_dir) { - bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net); - if (!bond_proc_dir) + if (!bn->proc_dir) { + bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); + if (!bn->proc_dir) pr_warning(DRV_NAME ": Warning: cannot create /proc/net/%s\n", DRV_NAME); @@ -3399,11 +3397,11 @@ static void bond_create_proc_dir(void) /* Destroy the bonding directory under /proc/net, if empty. * Caller must hold rtnl_lock. */ -static void bond_destroy_proc_dir(void) +static void bond_destroy_proc_dir(struct bond_net *bn) { - if (bond_proc_dir) { - remove_proc_entry(DRV_NAME, init_net.proc_net); - bond_proc_dir = NULL; + if (bn->proc_dir) { + remove_proc_entry(DRV_NAME, bn->net->proc_net); + bn->proc_dir = NULL; } } @@ -3417,11 +3415,11 @@ static void bond_remove_proc_entry(struct bonding *bond) { } -static void bond_create_proc_dir(void) +static void bond_create_proc_dir(struct bond_net *bn) { } -static void bond_destroy_proc_dir(void) +static void bond_destroy_proc_dir(struct bond_net *bn) { } @@ -3540,9 +3538,6 @@ static int bond_netdev_event(struct notifier_block *this, { struct net_device *event_dev = (struct net_device *)ptr; - if (dev_net(event_dev) != &init_net) - return NOTIFY_DONE; - pr_debug("event_dev: %s, event: %lx\n", (event_dev ? event_dev->name : "None"), event); @@ -3575,13 +3570,11 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, { struct in_ifaddr *ifa = ptr; struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; + struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id); struct bonding *bond; struct vlan_entry *vlan; - if (dev_net(ifa->ifa_dev->dev) != &init_net) - return NOTIFY_DONE; - - list_for_each_entry(bond, &bond_dev_list, bond_list) { + list_for_each_entry(bond, &bn->dev_list, bond_list) { if (bond->dev == event_dev) { switch (event) { case NETDEV_UP: @@ -3950,7 +3943,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd if (!capable(CAP_NET_ADMIN)) return -EPERM; - slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave); + slave_dev = dev_get_by_name(dev_net(bond_dev), ifr->ifr_slave); pr_debug("slave_dev=%p: \n", slave_dev); @@ -5031,6 +5024,7 @@ static void bond_set_lockdep_class(struct net_device *dev) static int bond_init(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); pr_debug("Begin bond_init for %s\n", bond_dev->name); @@ -5043,7 +5037,7 @@ static int bond_init(struct net_device *bond_dev) netif_carrier_off(bond_dev); bond_create_proc_entry(bond); - list_add_tail(&bond->bond_list, &bond_dev_list); + list_add_tail(&bond->bond_list, &bn->dev_list); bond_prepare_sysfs_group(bond); return 0; @@ -5071,7 +5065,7 @@ static struct rtnl_link_ops bond_link_ops __read_mostly = { * Caller must NOT hold rtnl_lock; we need to release it here before we * set up our sysfs entries. */ -int bond_create(const char *name) +int bond_create(struct net *net, const char *name) { struct net_device *bond_dev; int res; @@ -5087,6 +5081,7 @@ int bond_create(const char *name) goto out; } + dev_net_set(bond_dev, net); bond_dev->rtnl_link_ops = &bond_link_ops; if (!name) { @@ -5105,6 +5100,46 @@ out_netdev: goto out; } +static int bond_net_init(struct net *net) +{ + struct bond_net *bn; + int err; + + err = -ENOMEM; + bn = kzalloc(sizeof(struct bond_net), GFP_KERNEL); + if (bn == NULL) + goto out; + + bn->net = net; + INIT_LIST_HEAD(&bn->dev_list); + + err = net_assign_generic(net, bond_net_id, bn); + if (err) + goto out_free; + + bond_create_proc_dir(bn); +out: + return err; +out_free: + kfree(bn); + goto out; +} + +static void bond_net_exit(struct net *net) +{ + struct bond_net *bn; + + bn = net_generic(net, bond_net_id); + + bond_destroy_proc_dir(bn); + kfree(bn); +} + +static struct pernet_operations bond_net_ops = { + .init = bond_net_init, + .exit = bond_net_exit, +}; + static int __init bonding_init(void) { int i; @@ -5116,14 +5151,16 @@ static int __init bonding_init(void) if (res) goto out; - bond_create_proc_dir(); + res = register_pernet_gen_subsys(&bond_net_id, &bond_net_ops); + if (res) + goto out; res = rtnl_link_register(&bond_link_ops); if (res) goto err; for (i = 0; i < max_bonds; i++) { - res = bond_create(NULL); + res = bond_create(&init_net, NULL); if (res) goto err; } @@ -5139,7 +5176,7 @@ out: return res; err: rtnl_link_unregister(&bond_link_ops); - bond_destroy_proc_dir(); + unregister_pernet_gen_subsys(bond_net_id, &bond_net_ops); goto out; } @@ -5153,7 +5190,7 @@ static void __exit bonding_exit(void) bond_destroy_sysfs(); rtnl_link_unregister(&bond_link_ops); - bond_destroy_proc_dir(); + unregister_pernet_gen_subsys(bond_net_id, &bond_net_ops); } module_init(bonding_init); |