tipc: make tipc socket support net namespace
[firefly-linux-kernel-4.4.55.git] / net / tipc / core.c
index a5737b8407ddbf63f9ecfb024bde3b079f979098..23ff3caa1ce6175c082543a0867453e216c7ea7e 100644 (file)
@@ -34,6 +34,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "core.h"
 #include "name_table.h"
 #include "subscr.h"
@@ -47,60 +49,54 @@ int tipc_random __read_mostly;
 
 /* configurable TIPC parameters */
 u32 tipc_own_addr __read_mostly;
-int tipc_max_ports __read_mostly;
 int tipc_net_id __read_mostly;
 int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */
 
-/**
- * tipc_buf_acquire - creates a TIPC message buffer
- * @size: message size (including TIPC header)
- *
- * Returns a new buffer with data pointers set to the specified size.
- *
- * NOTE: Headroom is reserved to allow prepending of a data link header.
- *       There may also be unrequested tailroom present at the buffer's end.
- */
-struct sk_buff *tipc_buf_acquire(u32 size)
+static int __net_init tipc_init_net(struct net *net)
 {
-       struct sk_buff *skb;
-       unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
-
-       skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
-       if (skb) {
-               skb_reserve(skb, BUF_HEADROOM);
-               skb_put(skb, size);
-               skb->next = NULL;
-       }
-       return skb;
+       struct tipc_net *tn = net_generic(net, tipc_net_id);
+       int err;
+
+       tn->net_id = 4711;
+       INIT_LIST_HEAD(&tn->node_list);
+       spin_lock_init(&tn->node_list_lock);
+
+       err = tipc_sk_rht_init(net);
+       return err;
 }
 
-/**
- * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
- */
-static void tipc_core_stop(void)
+static void __net_exit tipc_exit_net(struct net *net)
 {
-       tipc_net_stop();
-       tipc_bearer_cleanup();
-       tipc_netlink_stop();
-       tipc_subscr_stop();
-       tipc_nametbl_stop();
-       tipc_sk_ref_table_stop();
-       tipc_socket_stop();
-       tipc_unregister_sysctl();
+       tipc_net_stop(net);
+       tipc_sk_rht_destroy(net);
 }
 
-/**
- * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
- */
-static int tipc_core_start(void)
+static struct pernet_operations tipc_net_ops = {
+       .init = tipc_init_net,
+       .exit = tipc_exit_net,
+       .id   = &tipc_net_id,
+       .size = sizeof(struct tipc_net),
+};
+
+static int __init tipc_init(void)
 {
        int err;
 
+       pr_info("Activated (version " TIPC_MOD_VER ")\n");
+
+       tipc_own_addr = 0;
+
+       sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
+                             TIPC_LOW_IMPORTANCE;
+       sysctl_tipc_rmem[1] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
+                             TIPC_CRITICAL_IMPORTANCE;
+       sysctl_tipc_rmem[2] = TIPC_CONN_OVERLOAD_LIMIT;
+
        get_random_bytes(&tipc_random, sizeof(tipc_random));
 
-       err = tipc_sk_ref_table_init(tipc_max_ports, tipc_random);
+       err = register_pernet_subsys(&tipc_net_ops);
        if (err)
-               goto out_reftbl;
+               goto out_pernet;
 
        err = tipc_nametbl_init();
        if (err)
@@ -126,6 +122,7 @@ static int tipc_core_start(void)
        if (err)
                goto out_bearer;
 
+       pr_info("Started in single node mode\n");
        return 0;
 out_bearer:
        tipc_subscr_stop();
@@ -138,38 +135,22 @@ out_socket:
 out_netlink:
        tipc_nametbl_stop();
 out_nametbl:
-       tipc_sk_ref_table_stop();
-out_reftbl:
+       unregister_pernet_subsys(&tipc_net_ops);
+out_pernet:
+       pr_err("Unable to start in single node mode\n");
        return err;
 }
 
-static int __init tipc_init(void)
-{
-       int res;
-
-       pr_info("Activated (version " TIPC_MOD_VER ")\n");
-
-       tipc_own_addr = 0;
-       tipc_max_ports = CONFIG_TIPC_PORTS;
-       tipc_net_id = 4711;
-
-       sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
-                             TIPC_LOW_IMPORTANCE;
-       sysctl_tipc_rmem[1] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
-                             TIPC_CRITICAL_IMPORTANCE;
-       sysctl_tipc_rmem[2] = TIPC_CONN_OVERLOAD_LIMIT;
-
-       res = tipc_core_start();
-       if (res)
-               pr_err("Unable to start in single node mode\n");
-       else
-               pr_info("Started in single node mode\n");
-       return res;
-}
-
 static void __exit tipc_exit(void)
 {
-       tipc_core_stop();
+       unregister_pernet_subsys(&tipc_net_ops);
+       tipc_bearer_cleanup();
+       tipc_netlink_stop();
+       tipc_subscr_stop();
+       tipc_nametbl_stop();
+       tipc_socket_stop();
+       tipc_unregister_sysctl();
+
        pr_info("Deactivated\n");
 }