ipv4      IP version 4        x25        X.25 protocol
  ipx       IPX                 token-ring IBM token ring
  bridge    Bridging            decnet     DEC net
- ipv6      IP version 6
+ ipv6      IP version 6        tipc       TIPC
 ..............................................................................
 
 1. /proc/sys/net/core - Network core options
 The /proc/net/ipx_route  table  holds  a list of IPX routes. For each route it
 gives the  destination  network, the router node (or Directly) and the network
 address of the router (or Connected) for internal networks.
+
+6. TIPC
+-------------------------------------------------------
+
+The TIPC protocol now has a tunable for the receive memory, similar to the
+tcp_rmem - i.e. a vector of 3 INTEGERs: (min, default, max)
+
+    # cat /proc/sys/net/tipc/tipc_rmem
+    4252725 34021800        68043600
+    #
+
+The max value is set to CONN_OVERLOAD_LIMIT, and the default and min values
+are scaled (shifted) versions of that same value.  Note that the min value
+is not at this point in time used in any meaningful way, but the triplet is
+preserved in order to be consistent with things like tcp_rmem.
 
           socket.o log.o eth_media.o
 
 tipc-$(CONFIG_TIPC_MEDIA_IB)   += ib_media.o
+tipc-$(CONFIG_SYSCTL)          += sysctl.o
 
 #include "name_table.h"
 #include "subscr.h"
 #include "config.h"
+#include "port.h"
 
 #include <linux/module.h>
 
 int tipc_max_ports __read_mostly;
 int tipc_net_id __read_mostly;
 int tipc_remote_management __read_mostly;
-
+int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */
 
 /**
  * tipc_buf_acquire - creates a TIPC message buffer
        tipc_nametbl_stop();
        tipc_ref_table_stop();
        tipc_socket_stop();
+       tipc_unregister_sysctl();
 }
 
 /**
                res = tipc_netlink_start();
        if (!res)
                res = tipc_socket_init();
+       if (!res)
+               res = tipc_register_sysctl();
        if (res)
                tipc_core_stop();
 
        return res;
 }
 
-
 static int __init tipc_init(void)
 {
        int res;
        tipc_max_ports = CONFIG_TIPC_PORTS;
        tipc_net_id = 4711;
 
+       sysctl_tipc_rmem[0] = CONN_OVERLOAD_LIMIT >> 4 << TIPC_LOW_IMPORTANCE;
+       sysctl_tipc_rmem[1] = CONN_OVERLOAD_LIMIT >> 4 <<
+                             TIPC_CRITICAL_IMPORTANCE;
+       sysctl_tipc_rmem[2] = CONN_OVERLOAD_LIMIT;
+
        res = tipc_core_start();
        if (res)
                pr_err("Unable to start in single node mode\n");
 
 extern int tipc_max_ports __read_mostly;
 extern int tipc_net_id __read_mostly;
 extern int tipc_remote_management __read_mostly;
+extern int sysctl_tipc_rmem[3] __read_mostly;
 
 /*
  * Other global variables
 extern int  tipc_socket_init(void);
 extern void tipc_socket_stop(void);
 
+#ifdef CONFIG_SYSCTL
+extern int tipc_register_sysctl(void);
+extern void tipc_unregister_sysctl(void);
+#else
+#define tipc_register_sysctl() 0
+#define tipc_unregister_sysctl()
+#endif
+
 /*
  * TIPC timer and signal code
  */
 
 #include "node_subscr.h"
 
 #define TIPC_FLOW_CONTROL_WIN 512
+#define CONN_OVERLOAD_LIMIT    ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
+                               SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
 
 typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
                struct sk_buff **buf, unsigned char const *data,
 
 #define SS_LISTENING   -1      /* socket is listening */
 #define SS_READY       -2      /* socket is connectionless */
 
-#define CONN_OVERLOAD_LIMIT    ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
-                               SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
 #define CONN_TIMEOUT_DEFAULT   8000    /* default connect timeout = 8s */
 
 struct tipc_sock {
 
        sock_init_data(sock, sk);
        sk->sk_backlog_rcv = backlog_rcv;
+       sk->sk_rcvbuf = sysctl_tipc_rmem[1];
        sk->sk_data_ready = tipc_data_ready;
        sk->sk_write_space = tipc_write_space;
        tipc_sk(sk)->p = tp_ptr;
  * For all connectionless messages, by default new queue limits are
  * as belows:
  *
- * TIPC_LOW_IMPORTANCE       (5MB)
- * TIPC_MEDIUM_IMPORTANCE    (10MB)
- * TIPC_HIGH_IMPORTANCE      (20MB)
- * TIPC_CRITICAL_IMPORTANCE  (40MB)
+ * TIPC_LOW_IMPORTANCE       (4 MB)
+ * TIPC_MEDIUM_IMPORTANCE    (8 MB)
+ * TIPC_HIGH_IMPORTANCE      (16 MB)
+ * TIPC_CRITICAL_IMPORTANCE  (32 MB)
  *
  * Returns overload limit according to corresponding message importance
  */
        unsigned int limit;
 
        if (msg_connected(msg))
-               limit = CONN_OVERLOAD_LIMIT;
+               limit = sysctl_tipc_rmem[2];
        else
-               limit = sk->sk_rcvbuf << (msg_importance(msg) + 5);
+               limit = sk->sk_rcvbuf >> TIPC_CRITICAL_IMPORTANCE <<
+                       msg_importance(msg);
        return limit;
 }
 
 static struct proto tipc_proto = {
        .name           = "TIPC",
        .owner          = THIS_MODULE,
-       .obj_size       = sizeof(struct tipc_sock)
+       .obj_size       = sizeof(struct tipc_sock),
+       .sysctl_rmem    = sysctl_tipc_rmem
 };
 
 /**
 
--- /dev/null
+/*
+ * net/tipc/sysctl.c: sysctl interface to TIPC subsystem
+ *
+ * Copyright (c) 2013, Wind River Systems
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "core.h"
+
+#include <linux/sysctl.h>
+
+static struct ctl_table_header *tipc_ctl_hdr;
+
+static struct ctl_table tipc_table[] = {
+       {
+               .procname       = "tipc_rmem",
+               .data           = &sysctl_tipc_rmem,
+               .maxlen         = sizeof(sysctl_tipc_rmem),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+       {}
+};
+
+int tipc_register_sysctl(void)
+{
+       tipc_ctl_hdr = register_net_sysctl(&init_net, "net/tipc", tipc_table);
+       if (tipc_ctl_hdr == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
+void tipc_unregister_sysctl(void)
+{
+       unregister_net_sysctl_table(tipc_ctl_hdr);
+}