Commit c7b67aef authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc'

Paul Gortmaker says:

====================
This is a rework of the content sent earlier[1], with the following changes:

	-drop the Kconfig --> modparam conversion patch; this was
	 requested to be replaced[2] with a dynamic port quantity resizing.
	 Ying and Erik were discussing how best to achieve this, and then
	 vacation schedules got in the way, so implementing that will
	 come (hopefully) in the next round.

	-rework the sk_rcvbuf patch to allow memory resizing via sysctl
	 as per what Ying and Neil discussed[3]

	-add 4 more seemingly straigtforward and relatively small changes
	 from Ying (the last 4 in the series).

	-add cosmetic UAPI comment update patch from Ying.

That said, the largest change is still the one where we make use of
the fact that linux supports kernel threads and do the server like
operations within kernel threads.  As Jon says:

   We remove the last remnants of the TIPC native API, to make it
   possible to simplify locking policy and solve a problem with lost
   topology events.

   First, we introduce a socket-based alternative to the native API.

   Second, we convert the two remaining users of the native API, the
   TIPC internal topology server and the configuarion server, to use the
   new API.

   Third, we remove the remaining code pertaining to the native API.

I have re-tested this collection of commits between 32 and 64 bit x86
machines using the standard tipc test suite, and build tested for ppc.

[1] http://patchwork.ozlabs.org/patch/247687/
[2] http://patchwork.ozlabs.org/patch/247680/
[3] http://patchwork.ozlabs.org/patch/247688/
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dafcc438 2537af9d
......@@ -26,7 +26,7 @@ Table : Subdirectories in /proc/sys/net
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
......@@ -207,3 +207,18 @@ IPX.
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.
/*
* include/linux/tipc.h: Include file for TIPC socket interface
* include/uapi/linux/tipc.h: Header for TIPC socket interface
*
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005, 2010-2011, Wind River Systems
......
/*
* include/linux/tipc_config.h: Include file for TIPC configuration interface
* include/uapi/linux/tipc_config.h: Header for TIPC configuration interface
*
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005-2007, 2010-2011, Wind River Systems
......
......@@ -8,6 +8,7 @@ tipc-y += addr.o bcast.o bearer.o config.o \
core.o handler.o link.o discover.o msg.o \
name_distr.o subscr.o name_table.o net.o \
netlink.o node.o node_subscr.o port.o ref.o \
socket.o log.o eth_media.o
socket.o log.o eth_media.o server.o
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
tipc-$(CONFIG_SYSCTL) += sysctl.o
......@@ -578,8 +578,7 @@ u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
* Returns 0 (packet sent successfully) under all circumstances,
* since the broadcast link's pseudo-bearer never blocks
*/
static int tipc_bcbearer_send(struct sk_buff *buf,
struct tipc_bearer *unused1,
static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
struct tipc_media_addr *unused2)
{
int bp_index;
......
......@@ -75,7 +75,8 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
/**
* tipc_nmap_equal - test for equality of node maps
*/
static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b)
static inline int tipc_nmap_equal(struct tipc_node_map *nm_a,
struct tipc_node_map *nm_b)
{
return !memcmp(nm_a, nm_b, sizeof(*nm_a));
}
......
......@@ -2,7 +2,7 @@
* net/tipc/config.c: TIPC configuration management code
*
* Copyright (c) 2002-2006, Ericsson AB
* Copyright (c) 2004-2007, 2010-2012, Wind River Systems
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -38,12 +38,12 @@
#include "port.h"
#include "name_table.h"
#include "config.h"
#include "server.h"
#define REPLY_TRUNCATED "<truncated>\n"
static u32 config_port_ref;
static DEFINE_SPINLOCK(config_lock);
static DEFINE_MUTEX(config_mutex);
static struct tipc_server cfgsrv;
static const void *req_tlv_area; /* request message TLV area */
static int req_tlv_space; /* request message TLV area size */
......@@ -181,18 +181,7 @@ static struct sk_buff *cfg_set_own_addr(void)
if (tipc_own_addr)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change node address once assigned)");
/*
* Must temporarily release configuration spinlock while switching into
* networking mode as it calls tipc_eth_media_start(), which may sleep.
* Releasing the lock is harmless as other locally-issued configuration
* commands won't occur until this one completes, and remotely-issued
* configuration commands can't be received until a local configuration
* command to enable the first bearer is received and processed.
*/
spin_unlock_bh(&config_lock);
tipc_core_start_net(addr);
spin_lock_bh(&config_lock);
return tipc_cfg_reply_none();
}
......@@ -248,7 +237,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
{
struct sk_buff *rep_tlv_buf;
spin_lock_bh(&config_lock);
mutex_lock(&config_mutex);
/* Save request and reply details in a well-known location */
req_tlv_area = request_area;
......@@ -377,37 +366,31 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
/* Return reply buffer */
exit:
spin_unlock_bh(&config_lock);
mutex_unlock(&config_mutex);
return rep_tlv_buf;
}
static void cfg_named_msg_event(void *userdata,
u32 port_ref,
struct sk_buff **buf,
const unchar *msg,
u32 size,
u32 importance,
struct tipc_portid const *orig,
struct tipc_name_seq const *dest)
static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
void *usr_data, void *buf, size_t len)
{
struct tipc_cfg_msg_hdr *req_hdr;
struct tipc_cfg_msg_hdr *rep_hdr;
struct sk_buff *rep_buf;
int ret;
/* Validate configuration message header (ignore invalid message) */
req_hdr = (struct tipc_cfg_msg_hdr *)msg;
if ((size < sizeof(*req_hdr)) ||
(size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
req_hdr = (struct tipc_cfg_msg_hdr *)buf;
if ((len < sizeof(*req_hdr)) ||
(len != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
(ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
pr_warn("Invalid configuration message discarded\n");
return;
}
/* Generate reply for request (if can't, return request) */
rep_buf = tipc_cfg_do_cmd(orig->node,
ntohs(req_hdr->tcm_type),
msg + sizeof(*req_hdr),
size - sizeof(*req_hdr),
rep_buf = tipc_cfg_do_cmd(addr->addr.id.node, ntohs(req_hdr->tcm_type),
buf + sizeof(*req_hdr),
len - sizeof(*req_hdr),
BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
if (rep_buf) {
skb_push(rep_buf, sizeof(*rep_hdr));
......@@ -415,57 +398,51 @@ static void cfg_named_msg_event(void *userdata,
memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
rep_hdr->tcm_len = htonl(rep_buf->len);
rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
} else {
rep_buf = *buf;
*buf = NULL;
}
/* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */
tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
rep_buf->len);
if (ret < 0)
pr_err("Sending cfg reply message failed, no memory\n");
kfree_skb(rep_buf);
}
}
static struct sockaddr_tipc cfgsrv_addr __read_mostly = {
.family = AF_TIPC,
.addrtype = TIPC_ADDR_NAMESEQ,
.addr.nameseq.type = TIPC_CFG_SRV,
.addr.nameseq.lower = 0,
.addr.nameseq.upper = 0,
.scope = TIPC_ZONE_SCOPE
};
static struct tipc_server cfgsrv __read_mostly = {
.saddr = &cfgsrv_addr,
.imp = TIPC_CRITICAL_IMPORTANCE,
.type = SOCK_RDM,
.max_rcvbuf_size = 64 * 1024,
.name = "cfg_server",
.tipc_conn_recvmsg = cfg_conn_msg_event,
.tipc_conn_new = NULL,
.tipc_conn_shutdown = NULL
};
int tipc_cfg_init(void)
{
struct tipc_name_seq seq;
int res;
res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
NULL, NULL, NULL,
NULL, cfg_named_msg_event, NULL,
NULL, &config_port_ref);
if (res)
goto failed;
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = tipc_own_addr;
res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
goto failed;
return 0;
failed:
pr_err("Unable to create configuration service\n");
return res;
return tipc_server_start(&cfgsrv);
}
void tipc_cfg_reinit(void)
{
struct tipc_name_seq seq;
int res;
seq.type = TIPC_CFG_SRV;
seq.lower = seq.upper = 0;
tipc_withdraw(config_port_ref, TIPC_ZONE_SCOPE, &seq);
tipc_server_stop(&cfgsrv);
seq.lower = seq.upper = tipc_own_addr;
res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
if (res)
pr_err("Unable to reinitialize configuration service\n");
cfgsrv_addr.addr.nameseq.lower = tipc_own_addr;
cfgsrv_addr.addr.nameseq.upper = tipc_own_addr;
tipc_server_start(&cfgsrv);
}
void tipc_cfg_stop(void)
{
tipc_deleteport(config_port_ref);
config_port_ref = 0;
tipc_server_stop(&cfgsrv);
}
......@@ -2,7 +2,7 @@
* net/tipc/core.c: TIPC module code
*
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005-2006, 2010-2011, Wind River Systems
* Copyright (c) 2005-2006, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -39,6 +39,7 @@
#include "name_table.h"
#include "subscr.h"
#include "config.h"
#include "port.h"
#include <linux/module.h>
......@@ -50,7 +51,7 @@ u32 tipc_own_addr __read_mostly;
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
......@@ -118,6 +119,7 @@ static void tipc_core_stop(void)
tipc_nametbl_stop();
tipc_ref_table_stop();
tipc_socket_stop();
tipc_unregister_sysctl();
}
/**
......@@ -134,21 +136,22 @@ static int tipc_core_start(void)
res = tipc_ref_table_init(tipc_max_ports, tipc_random);
if (!res)
res = tipc_nametbl_init();
if (!res)
res = tipc_subscr_start();
if (!res)
res = tipc_cfg_init();
if (!res)
res = tipc_netlink_start();
if (!res)
res = tipc_socket_init();
if (!res)
res = tipc_register_sysctl();
if (!res)
res = tipc_subscr_start();
if (!res)
res = tipc_cfg_init();
if (res)
tipc_core_stop();
return res;
}
static int __init tipc_init(void)
{
int res;
......@@ -160,6 +163,11 @@ static int __init tipc_init(void)
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");
......
/*
* net/tipc/core.h: Include file for TIPC global declarations
*
* Copyright (c) 2005-2006, Ericsson AB
* Copyright (c) 2005-2007, 2010-2011, Wind River Systems
* Copyright (c) 2005-2006, 2013 Ericsson AB
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -80,6 +80,7 @@ extern u32 tipc_own_addr __read_mostly;
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
......@@ -96,6 +97,18 @@ extern int tipc_netlink_start(void);
extern void tipc_netlink_stop(void);
extern int tipc_socket_init(void);
extern void tipc_socket_stop(void);
extern int tipc_sock_create_local(int type, struct socket **res);
extern void tipc_sock_release_local(struct socket *sock);
extern int tipc_sock_accept_local(struct socket *sock,
struct socket **newsock, int flags);
#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
......
......@@ -70,8 +70,7 @@ struct tipc_link_req {
* @dest_domain: network domain of node(s) which should respond to message
* @b_ptr: ptr to bearer issuing message
*/
static struct sk_buff *tipc_disc_init_msg(u32 type,
u32 dest_domain,
static struct sk_buff *tipc_disc_init_msg(u32 type, u32 dest_domain,
struct tipc_bearer *b_ptr)
{
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
......@@ -346,8 +345,8 @@ static void disc_timeout(struct tipc_link_req *req)
*
* Returns 0 if successful, otherwise -errno.
*/
int tipc_disc_create(struct tipc_bearer *b_ptr,
struct tipc_media_addr *dest, u32 dest_domain)
int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
u32 dest_domain)
{
struct tipc_link_req *req;
......
......@@ -162,8 +162,7 @@ static void setup_bearer(struct work_struct *work)
*/
static int enable_bearer(struct tipc_bearer *tb_ptr)
{
struct net_device *dev = NULL;
struct net_device *pdev = NULL;
struct net_device *dev;
struct eth_bearer *eb_ptr = &eth_bearers[0];
struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
......@@ -178,15 +177,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
}
/* Find device with specified name */
read_lock(&dev_base_lock);
for_each_netdev(&init_net, pdev) {
if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
dev = pdev;
dev_hold(dev);
break;
}
}
read_unlock(&dev_base_lock);
dev = dev_get_by_name(&init_net, driver_name);
if (!dev)
return -ENODEV;
......
......@@ -155,8 +155,7 @@ static void setup_bearer(struct work_struct *work)
*/
static int enable_bearer(struct tipc_bearer *tb_ptr)
{
struct net_device *dev = NULL;
struct net_device *pdev = NULL;
struct net_device *dev;
struct ib_bearer *ib_ptr = &ib_bearers[0];
struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS];
char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
......@@ -171,15 +170,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
}
/* Find device with specified name */
read_lock(&dev_base_lock);
for_each_netdev(&init_net, pdev) {
if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
dev = pdev;
dev_hold(dev);
break;
}
}
read_unlock(&dev_base_lock);
dev = dev_get_by_name(&init_net, driver_name);
if (!dev)
return -ENODEV;
......
......@@ -2,7 +2,7 @@
* net/tipc/link.c: TIPC link code
*
* Copyright (c) 1996-2007, 2012, Ericsson AB
* Copyright (c) 2004-2007, 2010-2011, Wind River Systems
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -41,6 +41,8 @@
#include "discover.h"
#include "config.h"
#include <linux/pkt_sched.h>
/*
* Error message prefixes
*/
......@@ -771,8 +773,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
* link_bundle_buf(): Append contents of a buffer to
* the tail of an existing one.
*/
static int link_bundle_buf(struct tipc_link *l_ptr,
struct sk_buff *bundler,
static int link_bundle_buf(struct tipc_link *l_ptr, struct sk_buff *bundler,
struct sk_buff *buf)
{
struct tipc_msg *bundler_msg = buf_msg(bundler);
......@@ -1056,40 +1057,6 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
return tipc_link_send_buf(l_ptr, buf); /* All other cases */
}
/*
* tipc_send_buf_fast: Entry for data messages where the
* destination node is known and the header is complete,
* inclusive total message length.
* Returns user data length.
*/
int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
{
struct tipc_link *l_ptr;
struct tipc_node *n_ptr;
int res;
u32 selector = msg_origport(buf_msg(buf)) & 1;
u32 dummy;
read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(destnode);
if (likely(n_ptr)) {
tipc_node_lock(n_ptr);
l_ptr = n_ptr->active_links[selector];
if (likely(l_ptr)) {
res = link_send_buf_fast(l_ptr, buf, &dummy);
tipc_node_unlock(n_ptr);
read_unlock_bh(&tipc_net_lock);
return res;
}
tipc_node_unlock(n_ptr);
}
read_unlock_bh(&tipc_net_lock);
res = msg_data_sz(buf_msg(buf));
tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
return res;
}
/*
* tipc_link_send_sections_fast: Entry for messages where the
* destination processor is known and the header is complete,
......@@ -1098,8 +1065,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
*/
int tipc_link_send_sections_fast(struct tipc_port *sender,
struct iovec const *msg_sect,
const u32 num_sect,
unsigned int total_len,
const u32 num_sect, unsigned int total_len,
u32 destaddr)
{
struct tipc_msg *hdr = &sender->phdr;
......@@ -1115,7 +1081,10 @@ int tipc_link_send_sections_fast(struct tipc_port *sender,
* (Must not hold any locks while building message.)
*/
res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
sender->max_pkt, !sender->user_port, &buf);
sender->max_pkt, &buf);
/* Exit if build request was invalid */
if (unlikely(res < 0))
return res;
read_lock_bh(&tipc_net_lock);
node = tipc_node_find(destaddr);
......@@ -1132,10 +1101,6 @@ int tipc_link_send_sections_fast(struct tipc_port *sender,
return res;
}
/* Exit if build request was invalid */
if (unlikely(res < 0))
goto exit;
/* Exit if link (or bearer) is congested */
if (link_congested(l_ptr) ||
tipc_bearer_blocked(l_ptr->b_ptr)) {
......@@ -1189,8 +1154,7 @@ int tipc_link_send_sections_fast(struct tipc_port *sender,
*/
static int link_send_sections_long(struct tipc_port *sender,
struct iovec const *msg_sect,
u32 num_sect,
unsigned int total_len,
u32 num_sect, unsigned int total_len,
u32 destaddr)
{
struct tipc_link *l_ptr;
......@@ -1204,6 +1168,7 @@ static int link_send_sections_long(struct tipc_port *sender,
const unchar *sect_crs;
int curr_sect;
u32 fragm_no;
int res = 0;
again:
fragm_no = 1;
......@@ -1250,18 +1215,15 @@ static int link_send_sections_long(struct tipc_port *sender,
else
sz = fragm_rest;
if (likely(!sender->user_port)) {
if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) {
res = -EFAULT;
error:
for (; buf_chain; buf_chain = buf) {
buf = buf_chain->next;
kfree_skb(buf_chain);
}
return -EFAULT;
return res;
}
} else
skb_copy_to_linear_data_offset(buf, fragm_crs,
sect_crs, sz);
sect_crs += sz;
sect_rest -= sz;
fragm_crs += sz;
......@@ -1281,8 +1243,10 @@ static int link_send_sections_long(struct tipc_port *sender,
msg_set_fragm_no(&fragm_hdr, ++fragm_no);
prev = buf;
buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
if (!buf)
if (!buf) {
res = -ENOMEM;
goto error;
}
buf->next = NULL;
prev->next = buf;
......@@ -1988,6 +1952,7 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
return;
skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
buf->priority = TC_PRIO_CONTROL;
/* Defer message if bearer is already blocked */
if (tipc_bearer_blocked(l_ptr->b_ptr)) {
......@@ -2145,8 +2110,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
* another bearer. Owner node is locked.
*/
static void tipc_link_tunnel(struct tipc_link *l_ptr,
struct tipc_msg *tunnel_hdr,
struct tipc_msg *msg,
struct tipc_msg *tunnel_hdr, struct tipc_msg *msg,
u32 selector)
{
struct tipc_link *tunnel;
......
......@@ -51,8 +51,8 @@ u32 tipc_msg_tot_importance(struct tipc_msg *m)
}
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode)
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
u32 destnode)
{
memset(m, 0, hsize);
msg_set_version(m);
......@@ -73,8 +73,8 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
* Returns message data size or errno
*/
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
u32 num_sect, unsigned int total_len,
int max_size, int usrmem, struct sk_buff **buf)
u32 num_sect, unsigned int total_len, int max_size,
struct sk_buff **buf)
{
int dsz, sz, hsz, pos, res, cnt;
......@@ -92,11 +92,6 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
return -ENOMEM;
skb_copy_to_linear_data(*buf, hdr, hsz);
for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
if (likely(usrmem))
res = !copy_from_user((*buf)->data + pos,
msg_sect[cnt].iov_base,
msg_sect[cnt].iov_len);
else
skb_copy_to_linear_data_offset(*buf, pos,
msg_sect[cnt].iov_base,
msg_sect[cnt].iov_len);
......
......@@ -719,9 +719,9 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
}
u32 tipc_msg_tot_importance(struct tipc_msg *m);
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode);
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
u32 destnode);
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
u32 num_sect, unsigned int total_len,
int max_size, int usrmem, struct sk_buff **buf);
u32 num_sect, unsigned int total_len, int max_size,
struct sk_buff **buf);
#endif
......@@ -92,9 +92,10 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
u32 scope, u32 port_ref, u32 key);
int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
u32 scope, u32 node, u32 ref, u32 key);
struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
u32 node, u32 ref, u32 key);
u32 scope, u32 node, u32 ref,
u32 key);
struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, u32 node,
u32 ref, u32 key);
void tipc_nametbl_subscribe(struct tipc_subscription *s);
void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
int tipc_nametbl_init(void);
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* net/tipc/port.h: Include file for TIPC port code
*
* Copyright (c) 1994-2007, Ericsson AB
* Copyright (c) 2004-2007, 2010-2011, Wind River Systems
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -43,60 +43,12 @@
#include "node_subscr.h"
#define TIPC_FLOW_CONTROL_WIN 512
typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size, int reason,
struct tipc_portid const *attmpt_destid);
typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size, int reason,
struct tipc_name_seq const *attmpt_dest);
typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size, int reason);
typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size, unsigned int importance,
struct tipc_portid const *origin);
typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size, unsigned int importance,
struct tipc_portid const *orig,
struct tipc_name_seq const *dest);
typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
struct sk_buff **buf, unsigned char const *data,
unsigned int size);
typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
/**
* struct user_port - TIPC user port (used with native API)
* @usr_handle: user-specified field
* @ref: object reference to associated TIPC port
*
* <various callback routines>
*/
struct user_port {
void *usr_handle;
u32 ref;
tipc_msg_err_event err_cb;
tipc_named_msg_err_event named_err_cb;
tipc_conn_shutdown_event conn_err_cb;
tipc_msg_event msg_cb;
tipc_named_msg_event named_msg_cb;
tipc_conn_msg_event conn_msg_cb;
tipc_continue_event continue_event_cb;
};
#define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
/**
* struct tipc_port - TIPC port structure
* @usr_handle: pointer to additional user-defined information about port
* @sk: pointer to socket handle
* @lock: pointer to spinlock for controlling access to port
* @connected: non-zero if port is currently connected to a peer port
* @conn_type: TIPC type used when connection was established
......@@ -110,7 +62,6 @@ struct user_port {
* @port_list: adjacent ports in TIPC's global list of ports
* @dispatcher: ptr to routine which handles received messages
* @wakeup: ptr to routine to call when port is no longer congested
* @user_port: ptr to user port associated with port (if any)
* @wait_list: adjacent ports in list of ports waiting on link congestion
* @waiting_pkts:
* @sent: # of non-empty messages sent by port
......@@ -123,7 +74,7 @@ struct user_port {
* @subscription: "node down" subscription used to terminate failed connections
*/
struct tipc_port {
void *usr_handle;
struct sock *sk;
spinlock_t *lock;
int connected;
u32 conn_type;
......@@ -137,7 +88,6 @@ struct tipc_port {
struct list_head port_list;
u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
void (*wakeup)(struct tipc_port *);
struct user_port *user_port;
struct list_head wait_list;
u32 waiting_pkts;
u32 sent;
......@@ -156,24 +106,16 @@ struct tipc_port_list;
/*
* TIPC port manipulation routines
*/
struct tipc_port *tipc_createport_raw(void *usr_handle,
u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
void (*wakeup)(struct tipc_port *), const u32 importance);
struct tipc_port *tipc_createport(struct sock *sk,
u32 (*dispatcher)(struct tipc_port *,
struct sk_buff *),
void (*wakeup)(struct tipc_port *),
const u32 importance);
int tipc_reject_msg(struct sk_buff *buf, u32 err);
int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
void tipc_acknowledge(u32 port_ref, u32 ack);
int tipc_createport(void *usr_handle,
unsigned int importance, tipc_msg_err_event error_cb,
tipc_named_msg_err_event named_error_cb,
tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
tipc_named_msg_event named_msg_cb,
tipc_conn_msg_event conn_msg_cb,
tipc_continue_event continue_event_cb, u32 *portref);
int tipc_deleteport(u32 portref);
int tipc_portimportance(u32 portref, unsigned int *importance);
......@@ -220,9 +162,6 @@ int tipc_send2port(u32 portref, struct tipc_portid const *dest,
unsigned int num_sect, struct iovec const *msg_sect,
unsigned int total_len);
int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
struct sk_buff *buf, unsigned int dsz);
int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
unsigned int section_count, struct iovec const *msg,
unsigned int total_len);
......
This diff is collapsed.
/*
* net/tipc/server.h: Include file for TIPC server code
*
* Copyright (c) 2012-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.
*/
#ifndef _TIPC_SERVER_H
#define _TIPC_SERVER_H
#include "core.h"
#define TIPC_SERVER_NAME_LEN 32
/**
* struct tipc_server - TIPC server structure
* @conn_idr: identifier set of connection
* @idr_lock: protect the connection identifier set
* @idr_in_use: amount of allocated identifier entry
* @rcvbuf_cache: memory cache of server receive buffer
* @rcv_wq: receive workqueue
* @send_wq: send workqueue
* @max_rcvbuf_size: maximum permitted receive message length
* @tipc_conn_new: callback will be called when new connection is incoming
* @tipc_conn_shutdown: callback will be called when connection is shut down
* @tipc_conn_recvmsg: callback will be called when message arrives
* @saddr: TIPC server address
* @name: server name
* @imp: message importance
* @type: socket type
* @enabled: identify whether server is launched or not
*/
struct tipc_server {
struct idr conn_idr;
spinlock_t idr_lock;
int idr_in_use;
struct kmem_cache *rcvbuf_cache;
struct workqueue_struct *rcv_wq;
struct workqueue_struct *send_wq;
int max_rcvbuf_size;
void *(*tipc_conn_new) (int conid);
void (*tipc_conn_shutdown) (int conid, void *usr_data);
void (*tipc_conn_recvmsg) (int conid, struct sockaddr_tipc *addr,
void *usr_data, void *buf, size_t len);
struct sockaddr_tipc *saddr;
const char name[TIPC_SERVER_NAME_LEN];
int imp;
int type;
int enabled;
};
int tipc_conn_sendmsg(struct tipc_server *s, int conid,
struct sockaddr_tipc *addr, void *data, size_t len);
/**
* tipc_conn_terminate - terminate connection with server
*
* Note: Must call it in process context since it might sleep
*/
void tipc_conn_terminate(struct tipc_server *s, int conid);
int tipc_server_start(struct tipc_server *s);
void tipc_server_stop(struct tipc_server *s);
#endif
......@@ -2,7 +2,7 @@
* net/tipc/socket.c: TIPC socket API
*
* Copyright (c) 2001-2007, 2012 Ericsson AB
* Copyright (c) 2004-2008, 2010-2012, Wind River Systems
* Copyright (c) 2004-2008, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -43,8 +43,6 @@
#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 {
......@@ -65,12 +63,15 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
static void wakeupdispatch(struct tipc_port *tport);
static void tipc_data_ready(struct sock *sk, int len);
static void tipc_write_space(struct sock *sk);
static int release(struct socket *sock);
static int accept(struct socket *sock, struct socket *new_sock, int flags);
static const struct proto_ops packet_ops;
static const struct proto_ops stream_ops;
static const struct proto_ops msg_ops;
static struct proto tipc_proto;
static struct proto tipc_proto_kern;
static int sockets_enabled;
......@@ -143,7 +144,7 @@ static void reject_rx_queue(struct sock *sk)
}
/**
* tipc_create - create a TIPC socket
* tipc_sk_create - create a TIPC socket
* @net: network namespace (must be default network)
* @sock: pre-allocated socket structure
* @protocol: protocol indicator (must be 0)
......@@ -154,7 +155,7 @@ static void reject_rx_queue(struct sock *sk)
*
* Returns 0 on success, errno otherwise
*/
static int tipc_create(struct net *net, struct socket *sock, int protocol,
static int tipc_sk_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
const struct proto_ops *ops;
......@@ -185,12 +186,16 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
}
/* Allocate socket's protocol area */
if (!kern)
sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
else
sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern);
if (sk == NULL)
return -ENOMEM;
/* Allocate TIPC port for socket to use */
tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch,
tp_ptr = tipc_createport(sk, &dispatch, &wakeupdispatch,
TIPC_LOW_IMPORTANCE);
if (unlikely(!tp_ptr)) {
sk_free(sk);
......@@ -203,6 +208,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
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;
......@@ -219,6 +225,78 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
return 0;
}
/**
* tipc_sock_create_local - create TIPC socket from inside TIPC module
* @type: socket type - SOCK_RDM or SOCK_SEQPACKET
*
* We cannot use sock_creat_kern here because it bumps module user count.
* Since socket owner and creator is the same module we must make sure
* that module count remains zero for module local sockets, otherwise
* we cannot do rmmod.
*
* Returns 0 on success, errno otherwise
*/
int tipc_sock_create_local(int type, struct socket **res)
{
int rc;
struct sock *sk;
rc = sock_create_lite(AF_TIPC, type, 0, res);
if (rc < 0) {
pr_err("Failed to create kernel socket\n");
return rc;
}
tipc_sk_create(&init_net, *res, 0, 1);
sk = (*res)->sk;
return 0;
}
/**
* tipc_sock_release_local - release socket created by tipc_sock_create_local
* @sock: the socket to be released.
*
* Module reference count is not incremented when such sockets are created,
* so we must keep it from being decremented when they are released.
*/
void tipc_sock_release_local(struct socket *sock)
{
release(sock);
sock->ops = NULL;
sock_release(sock);
}
/**
* tipc_sock_accept_local - accept a connection on a socket created
* with tipc_sock_create_local. Use this function to avoid that
* module reference count is inadvertently incremented.
*
* @sock: the accepting socket
* @newsock: reference to the new socket to be created
* @flags: socket flags
*/
int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
int flags)
{
struct sock *sk = sock->sk;
int ret;
ret = sock_create_lite(sk->sk_family, sk->sk_type,
sk->sk_protocol, newsock);
if (ret < 0)
return ret;
ret = accept(sock, *newsock, flags);
if (ret < 0) {
sock_release(*newsock);
return ret;
}
(*newsock)->ops = sock->ops;
return ret;
}
/**
* release - destroy a TIPC socket
* @sock: socket to destroy
......@@ -324,7 +402,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
else if (addr->addrtype != TIPC_ADDR_NAMESEQ)
return -EAFNOSUPPORT;
if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES)
if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
(addr->addr.nameseq.type != TIPC_TOP_SRV) &&
(addr->addr.nameseq.type != TIPC_CFG_SRV))
return -EACCES;
return (addr->scope > 0) ?
......@@ -519,8 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
res = -EISCONN;
goto exit;
}
if ((tport->published) ||
((sock->type == SOCK_STREAM) && (total_len != 0))) {
if (tport->published) {
res = -EOPNOTSUPP;
goto exit;
}
......@@ -1011,8 +1090,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
lock_sock(sk);
if (unlikely((sock->state == SS_UNCONNECTED) ||
(sock->state == SS_CONNECTING))) {
if (unlikely((sock->state == SS_UNCONNECTED))) {
res = -ENOTCONN;
goto exit;
}
......@@ -1233,10 +1311,10 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf)
* 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
*/
......@@ -1246,9 +1324,10 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
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;
}
......@@ -1327,7 +1406,7 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf)
*/
static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
{
struct sock *sk = (struct sock *)tport->usr_handle;
struct sock *sk = tport->sk;
u32 res;
/*
......@@ -1358,7 +1437,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
*/
static void wakeupdispatch(struct tipc_port *tport)
{
struct sock *sk = (struct sock *)tport->usr_handle;
struct sock *sk = tport->sk;
sk->sk_write_space(sk);
}
......@@ -1531,7 +1610,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
buf = skb_peek(&sk->sk_receive_queue);
res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1);
if (res)
goto exit;
......@@ -1657,8 +1736,8 @@ static int shutdown(struct socket *sock, int how)
*
* Returns 0 on success, errno otherwise
*/
static int setsockopt(struct socket *sock,
int lvl, int opt, char __user *ov, unsigned int ol)
static int setsockopt(struct socket *sock, int lvl, int opt, char __user *ov,
unsigned int ol)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
......@@ -1716,8 +1795,8 @@ static int setsockopt(struct socket *sock,
*
* Returns 0 on success, errno otherwise
*/
static int getsockopt(struct socket *sock,
int lvl, int opt, char __user *ov, int __user *ol)
static int getsockopt(struct socket *sock, int lvl, int opt, char __user *ov,
int __user *ol)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
......@@ -1841,13 +1920,20 @@ static const struct proto_ops stream_ops = {
static const struct net_proto_family tipc_family_ops = {
.owner = THIS_MODULE,
.family = AF_TIPC,
.create = tipc_create
.create = tipc_sk_create
};
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
};
static struct proto tipc_proto_kern = {
.name = "TIPC",
.obj_size = sizeof(struct tipc_sock),
.sysctl_rmem = sysctl_tipc_rmem
};
/**
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* net/tipc/subscr.h: Include file for TIPC network topology service
*
* Copyright (c) 2003-2006, Ericsson AB
* Copyright (c) 2005-2007, Wind River Systems
* Copyright (c) 2005-2007, 2012-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -37,10 +37,14 @@
#ifndef _TIPC_SUBSCR_H
#define _TIPC_SUBSCR_H
#include "server.h"
struct tipc_subscription;
struct tipc_subscriber;
/**
* struct tipc_subscription - TIPC network topology subscription object
* @subscriber: pointer to its subscriber
* @seq: name sequence associated with subscription
* @timeout: duration of subscription (in ms)
* @filter: event filtering to be done for subscription
......@@ -52,28 +56,23 @@ struct tipc_subscription;
* @evt: template for events generated by subscription
*/
struct tipc_subscription {
struct tipc_subscriber *subscriber;
struct tipc_name_seq seq;
u32 timeout;
u32 filter;
struct timer_list timer;
struct list_head nameseq_list;
struct list_head subscription_list;
u32 server_ref;
int swap;
struct tipc_event evt;
};
int tipc_subscr_overlap(struct tipc_subscription *sub,
u32 found_lower,
int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
u32 found_upper);
void tipc_subscr_report_overlap(struct tipc_subscription *sub,
u32 found_lower,
u32 found_upper,
u32 event,
u32 port_ref,
u32 node,
int must_report);
void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
u32 found_upper, u32 event, u32 port_ref,
u32 node, int must);
int tipc_subscr_start(void);
......
/*
* 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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment