#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"
 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;
                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
        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;
 
 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
 
 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;
        }
 /* 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);
 /* 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;
        }
 }
 
 {
 }
 
-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)
 {
 }
 
 {
        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);
 {
        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:
        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);
 
 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);
 
        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;
  * 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;
                goto out;
        }
 
+       dev_net_set(bond_dev, net);
        bond_dev->rtnl_link_ops = &bond_link_ops;
 
        if (!name) {
        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;
        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;
        }
        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;
 
 }
        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);
 
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <linux/nsproxy.h>
 
 #include "bonding.h"
 
  */
 static ssize_t bonding_show_bonds(struct class *cls, char *buf)
 {
+       struct net *net = current->nsproxy->net_ns;
+       struct bond_net *bn = net_generic(net, bond_net_id);
        int res = 0;
        struct bonding *bond;
 
        rtnl_lock();
 
-       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+       list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (res > (PAGE_SIZE - IFNAMSIZ)) {
                        /* not enough space for another interface name */
                        if ((PAGE_SIZE - res) > 10)
        return res;
 }
 
-static struct net_device *bond_get_by_name(const char *ifname)
+static struct net_device *bond_get_by_name(struct net *net, const char *ifname)
 {
+       struct bond_net *bn = net_generic(net, bond_net_id);
        struct bonding *bond;
 
-       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+       list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
                        return bond->dev;
        }
 static ssize_t bonding_store_bonds(struct class *cls,
                                   const char *buffer, size_t count)
 {
+       struct net *net = current->nsproxy->net_ns;
        char command[IFNAMSIZ + 1] = {0, };
        char *ifname;
        int rv, res = count;
        if (command[0] == '+') {
                pr_info(DRV_NAME
                        ": %s is being created...\n", ifname);
-               rv = bond_create(ifname);
+               rv = bond_create(net, ifname);
                if (rv) {
                        pr_info(DRV_NAME ": Bond creation failed.\n");
                        res = rv;
                struct net_device *bond_dev;
 
                rtnl_lock();
-               bond_dev = bond_get_by_name(ifname);
+               bond_dev = bond_get_by_name(net, ifname);
                if (bond_dev) {
                        pr_info(DRV_NAME ": %s is being deleted...\n",
                                ifname);
                /* Got a slave name in ifname.  Is it already in the list? */
                found = 0;
 
-               /* FIXME: get netns from sysfs object */
-               dev = __dev_get_by_name(&init_net, ifname);
+               dev = __dev_get_by_name(dev_net(bond->dev), ifname);
                if (!dev) {
                        pr_info(DRV_NAME
                               ": %s: Interface %s does not exist!\n",