aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Makefile3
-rw-r--r--net/tipc/bcast.c3
-rw-r--r--net/tipc/bcast.h3
-rw-r--r--net/tipc/config.c119
-rw-r--r--net/tipc/core.c22
-rw-r--r--net/tipc/core.h17
-rw-r--r--net/tipc/discover.c7
-rw-r--r--net/tipc/eth_media.c19
-rw-r--r--net/tipc/ib_media.c17
-rw-r--r--net/tipc/link.c88
-rw-r--r--net/tipc/msg.c19
-rw-r--r--net/tipc/msg.h8
-rw-r--r--net/tipc/name_table.c10
-rw-r--r--net/tipc/name_table.h11
-rw-r--r--net/tipc/node_subscr.c2
-rw-r--r--net/tipc/port.c320
-rw-r--r--net/tipc/port.h85
-rw-r--r--net/tipc/server.c596
-rw-r--r--net/tipc/server.h94
-rw-r--r--net/tipc/socket.c146
-rw-r--r--net/tipc/subscr.c348
-rw-r--r--net/tipc/subscr.h21
-rw-r--r--net/tipc/sysctl.c64
23 files changed, 1144 insertions, 878 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index 4df8e02d9008..b282f7130d2b 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -8,6 +8,7 @@ tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o handler.o link.o discover.o msg.o \ 8 core.o handler.o link.o discover.o msg.o \
9 name_distr.o subscr.o name_table.o net.o \ 9 name_distr.o subscr.o name_table.o net.o \
10 netlink.o node.o node_subscr.o port.o ref.o \ 10 netlink.o node.o node_subscr.o port.o ref.o \
11 socket.o log.o eth_media.o 11 socket.o log.o eth_media.o server.o
12 12
13tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o 13tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
14tipc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index e5f3da507823..716de1ac6cb5 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -578,8 +578,7 @@ u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
578 * Returns 0 (packet sent successfully) under all circumstances, 578 * Returns 0 (packet sent successfully) under all circumstances,
579 * since the broadcast link's pseudo-bearer never blocks 579 * since the broadcast link's pseudo-bearer never blocks
580 */ 580 */
581static int tipc_bcbearer_send(struct sk_buff *buf, 581static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
582 struct tipc_bearer *unused1,
583 struct tipc_media_addr *unused2) 582 struct tipc_media_addr *unused2)
584{ 583{
585 int bp_index; 584 int bp_index;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index a93306557e00..6ee587b469fd 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -75,7 +75,8 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
75/** 75/**
76 * tipc_nmap_equal - test for equality of node maps 76 * tipc_nmap_equal - test for equality of node maps
77 */ 77 */
78static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b) 78static inline int tipc_nmap_equal(struct tipc_node_map *nm_a,
79 struct tipc_node_map *nm_b)
79{ 80{
80 return !memcmp(nm_a, nm_b, sizeof(*nm_a)); 81 return !memcmp(nm_a, nm_b, sizeof(*nm_a));
81} 82}
diff --git a/net/tipc/config.c b/net/tipc/config.c
index f67866c765dd..c301a9a592d8 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -2,7 +2,7 @@
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2007, 2010-2012, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -38,12 +38,12 @@
38#include "port.h" 38#include "port.h"
39#include "name_table.h" 39#include "name_table.h"
40#include "config.h" 40#include "config.h"
41#include "server.h"
41 42
42#define REPLY_TRUNCATED "<truncated>\n" 43#define REPLY_TRUNCATED "<truncated>\n"
43 44
44static u32 config_port_ref; 45static DEFINE_MUTEX(config_mutex);
45 46static struct tipc_server cfgsrv;
46static DEFINE_SPINLOCK(config_lock);
47 47
48static const void *req_tlv_area; /* request message TLV area */ 48static const void *req_tlv_area; /* request message TLV area */
49static int req_tlv_space; /* request message TLV area size */ 49static int req_tlv_space; /* request message TLV area size */
@@ -181,18 +181,7 @@ static struct sk_buff *cfg_set_own_addr(void)
181 if (tipc_own_addr) 181 if (tipc_own_addr)
182 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 182 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
183 " (cannot change node address once assigned)"); 183 " (cannot change node address once assigned)");
184
185 /*
186 * Must temporarily release configuration spinlock while switching into
187 * networking mode as it calls tipc_eth_media_start(), which may sleep.
188 * Releasing the lock is harmless as other locally-issued configuration
189 * commands won't occur until this one completes, and remotely-issued
190 * configuration commands can't be received until a local configuration
191 * command to enable the first bearer is received and processed.
192 */
193 spin_unlock_bh(&config_lock);
194 tipc_core_start_net(addr); 184 tipc_core_start_net(addr);
195 spin_lock_bh(&config_lock);
196 return tipc_cfg_reply_none(); 185 return tipc_cfg_reply_none();
197} 186}
198 187
@@ -248,7 +237,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
248{ 237{
249 struct sk_buff *rep_tlv_buf; 238 struct sk_buff *rep_tlv_buf;
250 239
251 spin_lock_bh(&config_lock); 240 mutex_lock(&config_mutex);
252 241
253 /* Save request and reply details in a well-known location */ 242 /* Save request and reply details in a well-known location */
254 req_tlv_area = request_area; 243 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
377 366
378 /* Return reply buffer */ 367 /* Return reply buffer */
379exit: 368exit:
380 spin_unlock_bh(&config_lock); 369 mutex_unlock(&config_mutex);
381 return rep_tlv_buf; 370 return rep_tlv_buf;
382} 371}
383 372
384static void cfg_named_msg_event(void *userdata, 373static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
385 u32 port_ref, 374 void *usr_data, void *buf, size_t len)
386 struct sk_buff **buf,
387 const unchar *msg,
388 u32 size,
389 u32 importance,
390 struct tipc_portid const *orig,
391 struct tipc_name_seq const *dest)
392{ 375{
393 struct tipc_cfg_msg_hdr *req_hdr; 376 struct tipc_cfg_msg_hdr *req_hdr;
394 struct tipc_cfg_msg_hdr *rep_hdr; 377 struct tipc_cfg_msg_hdr *rep_hdr;
395 struct sk_buff *rep_buf; 378 struct sk_buff *rep_buf;
379 int ret;
396 380
397 /* Validate configuration message header (ignore invalid message) */ 381 /* Validate configuration message header (ignore invalid message) */
398 req_hdr = (struct tipc_cfg_msg_hdr *)msg; 382 req_hdr = (struct tipc_cfg_msg_hdr *)buf;
399 if ((size < sizeof(*req_hdr)) || 383 if ((len < sizeof(*req_hdr)) ||
400 (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || 384 (len != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
401 (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { 385 (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
402 pr_warn("Invalid configuration message discarded\n"); 386 pr_warn("Invalid configuration message discarded\n");
403 return; 387 return;
404 } 388 }
405 389
406 /* Generate reply for request (if can't, return request) */ 390 /* Generate reply for request (if can't, return request) */
407 rep_buf = tipc_cfg_do_cmd(orig->node, 391 rep_buf = tipc_cfg_do_cmd(addr->addr.id.node, ntohs(req_hdr->tcm_type),
408 ntohs(req_hdr->tcm_type), 392 buf + sizeof(*req_hdr),
409 msg + sizeof(*req_hdr), 393 len - sizeof(*req_hdr),
410 size - sizeof(*req_hdr),
411 BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr)); 394 BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
412 if (rep_buf) { 395 if (rep_buf) {
413 skb_push(rep_buf, sizeof(*rep_hdr)); 396 skb_push(rep_buf, sizeof(*rep_hdr));
@@ -415,57 +398,51 @@ static void cfg_named_msg_event(void *userdata,
415 memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); 398 memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
416 rep_hdr->tcm_len = htonl(rep_buf->len); 399 rep_hdr->tcm_len = htonl(rep_buf->len);
417 rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); 400 rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
418 } else {
419 rep_buf = *buf;
420 *buf = NULL;
421 }
422 401
423 /* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */ 402 ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
424 tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len); 403 rep_buf->len);
404 if (ret < 0)
405 pr_err("Sending cfg reply message failed, no memory\n");
406
407 kfree_skb(rep_buf);
408 }
425} 409}
426 410
411static struct sockaddr_tipc cfgsrv_addr __read_mostly = {
412 .family = AF_TIPC,
413 .addrtype = TIPC_ADDR_NAMESEQ,
414 .addr.nameseq.type = TIPC_CFG_SRV,
415 .addr.nameseq.lower = 0,
416 .addr.nameseq.upper = 0,
417 .scope = TIPC_ZONE_SCOPE
418};
419
420static struct tipc_server cfgsrv __read_mostly = {
421 .saddr = &cfgsrv_addr,
422 .imp = TIPC_CRITICAL_IMPORTANCE,
423 .type = SOCK_RDM,
424 .max_rcvbuf_size = 64 * 1024,
425 .name = "cfg_server",
426 .tipc_conn_recvmsg = cfg_conn_msg_event,
427 .tipc_conn_new = NULL,
428 .tipc_conn_shutdown = NULL
429};
430
427int tipc_cfg_init(void) 431int tipc_cfg_init(void)
428{ 432{
429 struct tipc_name_seq seq; 433 return tipc_server_start(&cfgsrv);
430 int res;
431
432 res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
433 NULL, NULL, NULL,
434 NULL, cfg_named_msg_event, NULL,
435 NULL, &config_port_ref);
436 if (res)
437 goto failed;
438
439 seq.type = TIPC_CFG_SRV;
440 seq.lower = seq.upper = tipc_own_addr;
441 res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq);
442 if (res)
443 goto failed;
444
445 return 0;
446
447failed:
448 pr_err("Unable to create configuration service\n");
449 return res;
450} 434}
451 435
452void tipc_cfg_reinit(void) 436void tipc_cfg_reinit(void)
453{ 437{
454 struct tipc_name_seq seq; 438 tipc_server_stop(&cfgsrv);
455 int res;
456
457 seq.type = TIPC_CFG_SRV;
458 seq.lower = seq.upper = 0;
459 tipc_withdraw(config_port_ref, TIPC_ZONE_SCOPE, &seq);
460 439
461 seq.lower = seq.upper = tipc_own_addr; 440 cfgsrv_addr.addr.nameseq.lower = tipc_own_addr;
462 res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq); 441 cfgsrv_addr.addr.nameseq.upper = tipc_own_addr;
463 if (res) 442 tipc_server_start(&cfgsrv);
464 pr_err("Unable to reinitialize configuration service\n");
465} 443}
466 444
467void tipc_cfg_stop(void) 445void tipc_cfg_stop(void)
468{ 446{
469 tipc_deleteport(config_port_ref); 447 tipc_server_stop(&cfgsrv);
470 config_port_ref = 0;
471} 448}
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 7ec2c1eb94f1..fd4eeeaa972a 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -2,7 +2,7 @@
2 * net/tipc/core.c: TIPC module code 2 * net/tipc/core.c: TIPC module code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
39#include "name_table.h" 39#include "name_table.h"
40#include "subscr.h" 40#include "subscr.h"
41#include "config.h" 41#include "config.h"
42#include "port.h"
42 43
43#include <linux/module.h> 44#include <linux/module.h>
44 45
@@ -50,7 +51,7 @@ u32 tipc_own_addr __read_mostly;
50int tipc_max_ports __read_mostly; 51int tipc_max_ports __read_mostly;
51int tipc_net_id __read_mostly; 52int tipc_net_id __read_mostly;
52int tipc_remote_management __read_mostly; 53int tipc_remote_management __read_mostly;
53 54int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */
54 55
55/** 56/**
56 * tipc_buf_acquire - creates a TIPC message buffer 57 * tipc_buf_acquire - creates a TIPC message buffer
@@ -118,6 +119,7 @@ static void tipc_core_stop(void)
118 tipc_nametbl_stop(); 119 tipc_nametbl_stop();
119 tipc_ref_table_stop(); 120 tipc_ref_table_stop();
120 tipc_socket_stop(); 121 tipc_socket_stop();
122 tipc_unregister_sysctl();
121} 123}
122 124
123/** 125/**
@@ -135,20 +137,21 @@ static int tipc_core_start(void)
135 if (!res) 137 if (!res)
136 res = tipc_nametbl_init(); 138 res = tipc_nametbl_init();
137 if (!res) 139 if (!res)
138 res = tipc_subscr_start();
139 if (!res)
140 res = tipc_cfg_init();
141 if (!res)
142 res = tipc_netlink_start(); 140 res = tipc_netlink_start();
143 if (!res) 141 if (!res)
144 res = tipc_socket_init(); 142 res = tipc_socket_init();
143 if (!res)
144 res = tipc_register_sysctl();
145 if (!res)
146 res = tipc_subscr_start();
147 if (!res)
148 res = tipc_cfg_init();
145 if (res) 149 if (res)
146 tipc_core_stop(); 150 tipc_core_stop();
147 151
148 return res; 152 return res;
149} 153}
150 154
151
152static int __init tipc_init(void) 155static int __init tipc_init(void)
153{ 156{
154 int res; 157 int res;
@@ -160,6 +163,11 @@ static int __init tipc_init(void)
160 tipc_max_ports = CONFIG_TIPC_PORTS; 163 tipc_max_ports = CONFIG_TIPC_PORTS;
161 tipc_net_id = 4711; 164 tipc_net_id = 4711;
162 165
166 sysctl_tipc_rmem[0] = CONN_OVERLOAD_LIMIT >> 4 << TIPC_LOW_IMPORTANCE;
167 sysctl_tipc_rmem[1] = CONN_OVERLOAD_LIMIT >> 4 <<
168 TIPC_CRITICAL_IMPORTANCE;
169 sysctl_tipc_rmem[2] = CONN_OVERLOAD_LIMIT;
170
163 res = tipc_core_start(); 171 res = tipc_core_start();
164 if (res) 172 if (res)
165 pr_err("Unable to start in single node mode\n"); 173 pr_err("Unable to start in single node mode\n");
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 0207db04179a..be72f8cebc53 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/core.h: Include file for TIPC global declarations 2 * net/tipc/core.h: Include file for TIPC global declarations
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, 2013 Ericsson AB
5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -80,6 +80,7 @@ extern u32 tipc_own_addr __read_mostly;
80extern int tipc_max_ports __read_mostly; 80extern int tipc_max_ports __read_mostly;
81extern int tipc_net_id __read_mostly; 81extern int tipc_net_id __read_mostly;
82extern int tipc_remote_management __read_mostly; 82extern int tipc_remote_management __read_mostly;
83extern int sysctl_tipc_rmem[3] __read_mostly;
83 84
84/* 85/*
85 * Other global variables 86 * Other global variables
@@ -96,6 +97,18 @@ extern int tipc_netlink_start(void);
96extern void tipc_netlink_stop(void); 97extern void tipc_netlink_stop(void);
97extern int tipc_socket_init(void); 98extern int tipc_socket_init(void);
98extern void tipc_socket_stop(void); 99extern void tipc_socket_stop(void);
100extern int tipc_sock_create_local(int type, struct socket **res);
101extern void tipc_sock_release_local(struct socket *sock);
102extern int tipc_sock_accept_local(struct socket *sock,
103 struct socket **newsock, int flags);
104
105#ifdef CONFIG_SYSCTL
106extern int tipc_register_sysctl(void);
107extern void tipc_unregister_sysctl(void);
108#else
109#define tipc_register_sysctl() 0
110#define tipc_unregister_sysctl()
111#endif
99 112
100/* 113/*
101 * TIPC timer and signal code 114 * TIPC timer and signal code
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index eedff58d0387..ecc758c6eacf 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -70,8 +70,7 @@ struct tipc_link_req {
70 * @dest_domain: network domain of node(s) which should respond to message 70 * @dest_domain: network domain of node(s) which should respond to message
71 * @b_ptr: ptr to bearer issuing message 71 * @b_ptr: ptr to bearer issuing message
72 */ 72 */
73static struct sk_buff *tipc_disc_init_msg(u32 type, 73static struct sk_buff *tipc_disc_init_msg(u32 type, u32 dest_domain,
74 u32 dest_domain,
75 struct tipc_bearer *b_ptr) 74 struct tipc_bearer *b_ptr)
76{ 75{
77 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE); 76 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
@@ -346,8 +345,8 @@ exit:
346 * 345 *
347 * Returns 0 if successful, otherwise -errno. 346 * Returns 0 if successful, otherwise -errno.
348 */ 347 */
349int tipc_disc_create(struct tipc_bearer *b_ptr, 348int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
350 struct tipc_media_addr *dest, u32 dest_domain) 349 u32 dest_domain)
351{ 350{
352 struct tipc_link_req *req; 351 struct tipc_link_req *req;
353 352
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 120a676a3360..40ea40cf6204 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -62,7 +62,7 @@ static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
62static int eth_started; 62static int eth_started;
63 63
64static int recv_notification(struct notifier_block *nb, unsigned long evt, 64static int recv_notification(struct notifier_block *nb, unsigned long evt,
65 void *dv); 65 void *dv);
66/* 66/*
67 * Network device notifier info 67 * Network device notifier info
68 */ 68 */
@@ -162,8 +162,7 @@ static void setup_bearer(struct work_struct *work)
162 */ 162 */
163static int enable_bearer(struct tipc_bearer *tb_ptr) 163static int enable_bearer(struct tipc_bearer *tb_ptr)
164{ 164{
165 struct net_device *dev = NULL; 165 struct net_device *dev;
166 struct net_device *pdev = NULL;
167 struct eth_bearer *eb_ptr = &eth_bearers[0]; 166 struct eth_bearer *eb_ptr = &eth_bearers[0];
168 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 167 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
169 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 168 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
@@ -178,15 +177,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
178 } 177 }
179 178
180 /* Find device with specified name */ 179 /* Find device with specified name */
181 read_lock(&dev_base_lock); 180 dev = dev_get_by_name(&init_net, driver_name);
182 for_each_netdev(&init_net, pdev) {
183 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
184 dev = pdev;
185 dev_hold(dev);
186 break;
187 }
188 }
189 read_unlock(&dev_base_lock);
190 if (!dev) 181 if (!dev)
191 return -ENODEV; 182 return -ENODEV;
192 183
@@ -251,9 +242,9 @@ static void disable_bearer(struct tipc_bearer *tb_ptr)
251 * specified device. 242 * specified device.
252 */ 243 */
253static int recv_notification(struct notifier_block *nb, unsigned long evt, 244static int recv_notification(struct notifier_block *nb, unsigned long evt,
254 void *dv) 245 void *ptr)
255{ 246{
256 struct net_device *dev = (struct net_device *)dv; 247 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
257 struct eth_bearer *eb_ptr = &eth_bearers[0]; 248 struct eth_bearer *eb_ptr = &eth_bearers[0];
258 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 249 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
259 250
diff --git a/net/tipc/ib_media.c b/net/tipc/ib_media.c
index 2a2864c25e15..ad2e1ec4117e 100644
--- a/net/tipc/ib_media.c
+++ b/net/tipc/ib_media.c
@@ -155,8 +155,7 @@ static void setup_bearer(struct work_struct *work)
155 */ 155 */
156static int enable_bearer(struct tipc_bearer *tb_ptr) 156static int enable_bearer(struct tipc_bearer *tb_ptr)
157{ 157{
158 struct net_device *dev = NULL; 158 struct net_device *dev;
159 struct net_device *pdev = NULL;
160 struct ib_bearer *ib_ptr = &ib_bearers[0]; 159 struct ib_bearer *ib_ptr = &ib_bearers[0];
161 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS]; 160 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS];
162 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; 161 char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
@@ -171,15 +170,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
171 } 170 }
172 171
173 /* Find device with specified name */ 172 /* Find device with specified name */
174 read_lock(&dev_base_lock); 173 dev = dev_get_by_name(&init_net, driver_name);
175 for_each_netdev(&init_net, pdev) {
176 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
177 dev = pdev;
178 dev_hold(dev);
179 break;
180 }
181 }
182 read_unlock(&dev_base_lock);
183 if (!dev) 174 if (!dev)
184 return -ENODEV; 175 return -ENODEV;
185 176
@@ -244,9 +235,9 @@ static void disable_bearer(struct tipc_bearer *tb_ptr)
244 * specified device. 235 * specified device.
245 */ 236 */
246static int recv_notification(struct notifier_block *nb, unsigned long evt, 237static int recv_notification(struct notifier_block *nb, unsigned long evt,
247 void *dv) 238 void *ptr)
248{ 239{
249 struct net_device *dev = (struct net_device *)dv; 240 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
250 struct ib_bearer *ib_ptr = &ib_bearers[0]; 241 struct ib_bearer *ib_ptr = &ib_bearers[0];
251 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS]; 242 struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS];
252 243
diff --git a/net/tipc/link.c b/net/tipc/link.c
index a80feee5197a..0cc3d9015c5d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2,7 +2,7 @@
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2007, 2012, Ericsson AB 4 * Copyright (c) 1996-2007, 2012, Ericsson AB
5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,8 @@
41#include "discover.h" 41#include "discover.h"
42#include "config.h" 42#include "config.h"
43 43
44#include <linux/pkt_sched.h>
45
44/* 46/*
45 * Error message prefixes 47 * Error message prefixes
46 */ 48 */
@@ -771,8 +773,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
771 * link_bundle_buf(): Append contents of a buffer to 773 * link_bundle_buf(): Append contents of a buffer to
772 * the tail of an existing one. 774 * the tail of an existing one.
773 */ 775 */
774static int link_bundle_buf(struct tipc_link *l_ptr, 776static int link_bundle_buf(struct tipc_link *l_ptr, struct sk_buff *bundler,
775 struct sk_buff *bundler,
776 struct sk_buff *buf) 777 struct sk_buff *buf)
777{ 778{
778 struct tipc_msg *bundler_msg = buf_msg(bundler); 779 struct tipc_msg *bundler_msg = buf_msg(bundler);
@@ -1057,40 +1058,6 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
1057} 1058}
1058 1059
1059/* 1060/*
1060 * tipc_send_buf_fast: Entry for data messages where the
1061 * destination node is known and the header is complete,
1062 * inclusive total message length.
1063 * Returns user data length.
1064 */
1065int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1066{
1067 struct tipc_link *l_ptr;
1068 struct tipc_node *n_ptr;
1069 int res;
1070 u32 selector = msg_origport(buf_msg(buf)) & 1;
1071 u32 dummy;
1072
1073 read_lock_bh(&tipc_net_lock);
1074 n_ptr = tipc_node_find(destnode);
1075 if (likely(n_ptr)) {
1076 tipc_node_lock(n_ptr);
1077 l_ptr = n_ptr->active_links[selector];
1078 if (likely(l_ptr)) {
1079 res = link_send_buf_fast(l_ptr, buf, &dummy);
1080 tipc_node_unlock(n_ptr);
1081 read_unlock_bh(&tipc_net_lock);
1082 return res;
1083 }
1084 tipc_node_unlock(n_ptr);
1085 }
1086 read_unlock_bh(&tipc_net_lock);
1087 res = msg_data_sz(buf_msg(buf));
1088 tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
1089 return res;
1090}
1091
1092
1093/*
1094 * tipc_link_send_sections_fast: Entry for messages where the 1061 * tipc_link_send_sections_fast: Entry for messages where the
1095 * destination processor is known and the header is complete, 1062 * destination processor is known and the header is complete,
1096 * except for total message length. 1063 * except for total message length.
@@ -1098,8 +1065,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1098 */ 1065 */
1099int tipc_link_send_sections_fast(struct tipc_port *sender, 1066int tipc_link_send_sections_fast(struct tipc_port *sender,
1100 struct iovec const *msg_sect, 1067 struct iovec const *msg_sect,
1101 const u32 num_sect, 1068 const u32 num_sect, unsigned int total_len,
1102 unsigned int total_len,
1103 u32 destaddr) 1069 u32 destaddr)
1104{ 1070{
1105 struct tipc_msg *hdr = &sender->phdr; 1071 struct tipc_msg *hdr = &sender->phdr;
@@ -1115,7 +1081,10 @@ again:
1115 * (Must not hold any locks while building message.) 1081 * (Must not hold any locks while building message.)
1116 */ 1082 */
1117 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, 1083 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
1118 sender->max_pkt, !sender->user_port, &buf); 1084 sender->max_pkt, &buf);
1085 /* Exit if build request was invalid */
1086 if (unlikely(res < 0))
1087 return res;
1119 1088
1120 read_lock_bh(&tipc_net_lock); 1089 read_lock_bh(&tipc_net_lock);
1121 node = tipc_node_find(destaddr); 1090 node = tipc_node_find(destaddr);
@@ -1132,10 +1101,6 @@ exit:
1132 return res; 1101 return res;
1133 } 1102 }
1134 1103
1135 /* Exit if build request was invalid */
1136 if (unlikely(res < 0))
1137 goto exit;
1138
1139 /* Exit if link (or bearer) is congested */ 1104 /* Exit if link (or bearer) is congested */
1140 if (link_congested(l_ptr) || 1105 if (link_congested(l_ptr) ||
1141 tipc_bearer_blocked(l_ptr->b_ptr)) { 1106 tipc_bearer_blocked(l_ptr->b_ptr)) {
@@ -1189,8 +1154,7 @@ exit:
1189 */ 1154 */
1190static int link_send_sections_long(struct tipc_port *sender, 1155static int link_send_sections_long(struct tipc_port *sender,
1191 struct iovec const *msg_sect, 1156 struct iovec const *msg_sect,
1192 u32 num_sect, 1157 u32 num_sect, unsigned int total_len,
1193 unsigned int total_len,
1194 u32 destaddr) 1158 u32 destaddr)
1195{ 1159{
1196 struct tipc_link *l_ptr; 1160 struct tipc_link *l_ptr;
@@ -1204,6 +1168,7 @@ static int link_send_sections_long(struct tipc_port *sender,
1204 const unchar *sect_crs; 1168 const unchar *sect_crs;
1205 int curr_sect; 1169 int curr_sect;
1206 u32 fragm_no; 1170 u32 fragm_no;
1171 int res = 0;
1207 1172
1208again: 1173again:
1209 fragm_no = 1; 1174 fragm_no = 1;
@@ -1250,18 +1215,15 @@ again:
1250 else 1215 else
1251 sz = fragm_rest; 1216 sz = fragm_rest;
1252 1217
1253 if (likely(!sender->user_port)) { 1218 if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) {
1254 if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { 1219 res = -EFAULT;
1255error: 1220error:
1256 for (; buf_chain; buf_chain = buf) { 1221 for (; buf_chain; buf_chain = buf) {
1257 buf = buf_chain->next; 1222 buf = buf_chain->next;
1258 kfree_skb(buf_chain); 1223 kfree_skb(buf_chain);
1259 }
1260 return -EFAULT;
1261 } 1224 }
1262 } else 1225 return res;
1263 skb_copy_to_linear_data_offset(buf, fragm_crs, 1226 }
1264 sect_crs, sz);
1265 sect_crs += sz; 1227 sect_crs += sz;
1266 sect_rest -= sz; 1228 sect_rest -= sz;
1267 fragm_crs += sz; 1229 fragm_crs += sz;
@@ -1281,8 +1243,10 @@ error:
1281 msg_set_fragm_no(&fragm_hdr, ++fragm_no); 1243 msg_set_fragm_no(&fragm_hdr, ++fragm_no);
1282 prev = buf; 1244 prev = buf;
1283 buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); 1245 buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
1284 if (!buf) 1246 if (!buf) {
1247 res = -ENOMEM;
1285 goto error; 1248 goto error;
1249 }
1286 1250
1287 buf->next = NULL; 1251 buf->next = NULL;
1288 prev->next = buf; 1252 prev->next = buf;
@@ -1446,7 +1410,7 @@ static void link_reset_all(unsigned long addr)
1446} 1410}
1447 1411
1448static void link_retransmit_failure(struct tipc_link *l_ptr, 1412static void link_retransmit_failure(struct tipc_link *l_ptr,
1449 struct sk_buff *buf) 1413 struct sk_buff *buf)
1450{ 1414{
1451 struct tipc_msg *msg = buf_msg(buf); 1415 struct tipc_msg *msg = buf_msg(buf);
1452 1416
@@ -1901,8 +1865,8 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
1901 * Send protocol message to the other endpoint. 1865 * Send protocol message to the other endpoint.
1902 */ 1866 */
1903void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, 1867void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1904 int probe_msg, u32 gap, u32 tolerance, 1868 int probe_msg, u32 gap, u32 tolerance,
1905 u32 priority, u32 ack_mtu) 1869 u32 priority, u32 ack_mtu)
1906{ 1870{
1907 struct sk_buff *buf = NULL; 1871 struct sk_buff *buf = NULL;
1908 struct tipc_msg *msg = l_ptr->pmsg; 1872 struct tipc_msg *msg = l_ptr->pmsg;
@@ -1988,6 +1952,7 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1988 return; 1952 return;
1989 1953
1990 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 1954 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
1955 buf->priority = TC_PRIO_CONTROL;
1991 1956
1992 /* Defer message if bearer is already blocked */ 1957 /* Defer message if bearer is already blocked */
1993 if (tipc_bearer_blocked(l_ptr->b_ptr)) { 1958 if (tipc_bearer_blocked(l_ptr->b_ptr)) {
@@ -2145,8 +2110,7 @@ exit:
2145 * another bearer. Owner node is locked. 2110 * another bearer. Owner node is locked.
2146 */ 2111 */
2147static void tipc_link_tunnel(struct tipc_link *l_ptr, 2112static void tipc_link_tunnel(struct tipc_link *l_ptr,
2148 struct tipc_msg *tunnel_hdr, 2113 struct tipc_msg *tunnel_hdr, struct tipc_msg *msg,
2149 struct tipc_msg *msg,
2150 u32 selector) 2114 u32 selector)
2151{ 2115{
2152 struct tipc_link *tunnel; 2116 struct tipc_link *tunnel;
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index f2db8a87d9c5..ced60e2fc4f7 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -51,8 +51,8 @@ u32 tipc_msg_tot_importance(struct tipc_msg *m)
51} 51}
52 52
53 53
54void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 54void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
55 u32 hsize, u32 destnode) 55 u32 destnode)
56{ 56{
57 memset(m, 0, hsize); 57 memset(m, 0, hsize);
58 msg_set_version(m); 58 msg_set_version(m);
@@ -73,8 +73,8 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
73 * Returns message data size or errno 73 * Returns message data size or errno
74 */ 74 */
75int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, 75int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
76 u32 num_sect, unsigned int total_len, 76 u32 num_sect, unsigned int total_len, int max_size,
77 int max_size, int usrmem, struct sk_buff **buf) 77 struct sk_buff **buf)
78{ 78{
79 int dsz, sz, hsz, pos, res, cnt; 79 int dsz, sz, hsz, pos, res, cnt;
80 80
@@ -92,14 +92,9 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
92 return -ENOMEM; 92 return -ENOMEM;
93 skb_copy_to_linear_data(*buf, hdr, hsz); 93 skb_copy_to_linear_data(*buf, hdr, hsz);
94 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { 94 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
95 if (likely(usrmem)) 95 skb_copy_to_linear_data_offset(*buf, pos,
96 res = !copy_from_user((*buf)->data + pos, 96 msg_sect[cnt].iov_base,
97 msg_sect[cnt].iov_base, 97 msg_sect[cnt].iov_len);
98 msg_sect[cnt].iov_len);
99 else
100 skb_copy_to_linear_data_offset(*buf, pos,
101 msg_sect[cnt].iov_base,
102 msg_sect[cnt].iov_len);
103 pos += msg_sect[cnt].iov_len; 98 pos += msg_sect[cnt].iov_len;
104 } 99 }
105 if (likely(res)) 100 if (likely(res))
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index ba2a72beea68..5e4ccf5c27df 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -719,9 +719,9 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
719} 719}
720 720
721u32 tipc_msg_tot_importance(struct tipc_msg *m); 721u32 tipc_msg_tot_importance(struct tipc_msg *m);
722void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 722void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
723 u32 hsize, u32 destnode); 723 u32 destnode);
724int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, 724int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
725 u32 num_sect, unsigned int total_len, 725 u32 num_sect, unsigned int total_len, int max_size,
726 int max_size, int usrmem, struct sk_buff **buf); 726 struct sk_buff **buf);
727#endif 727#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 24b167914311..09dcd54b04e1 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -440,7 +440,7 @@ found:
440 * sequence overlapping with the requested sequence 440 * sequence overlapping with the requested sequence
441 */ 441 */
442static void tipc_nameseq_subscribe(struct name_seq *nseq, 442static void tipc_nameseq_subscribe(struct name_seq *nseq,
443 struct tipc_subscription *s) 443 struct tipc_subscription *s)
444{ 444{
445 struct sub_seq *sseq = nseq->sseqs; 445 struct sub_seq *sseq = nseq->sseqs;
446 446
@@ -662,7 +662,7 @@ exit:
662 * tipc_nametbl_publish - add name publication to network name tables 662 * tipc_nametbl_publish - add name publication to network name tables
663 */ 663 */
664struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, 664struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
665 u32 scope, u32 port_ref, u32 key) 665 u32 scope, u32 port_ref, u32 key)
666{ 666{
667 struct publication *publ; 667 struct publication *publ;
668 668
@@ -753,7 +753,7 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
753 * subseq_list - print specified sub-sequence contents into the given buffer 753 * subseq_list - print specified sub-sequence contents into the given buffer
754 */ 754 */
755static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, 755static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth,
756 u32 index) 756 u32 index)
757{ 757{
758 char portIdStr[27]; 758 char portIdStr[27];
759 const char *scope_str[] = {"", " zone", " cluster", " node"}; 759 const char *scope_str[] = {"", " zone", " cluster", " node"};
@@ -792,7 +792,7 @@ static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth,
792 * nameseq_list - print specified name sequence contents into the given buffer 792 * nameseq_list - print specified name sequence contents into the given buffer
793 */ 793 */
794static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, 794static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth,
795 u32 type, u32 lowbound, u32 upbound, u32 index) 795 u32 type, u32 lowbound, u32 upbound, u32 index)
796{ 796{
797 struct sub_seq *sseq; 797 struct sub_seq *sseq;
798 char typearea[11]; 798 char typearea[11];
@@ -849,7 +849,7 @@ static int nametbl_header(char *buf, int len, u32 depth)
849 * nametbl_list - print specified name table contents into the given buffer 849 * nametbl_list - print specified name table contents into the given buffer
850 */ 850 */
851static int nametbl_list(char *buf, int len, u32 depth_info, 851static int nametbl_list(char *buf, int len, u32 depth_info,
852 u32 type, u32 lowbound, u32 upbound) 852 u32 type, u32 lowbound, u32 upbound)
853{ 853{
854 struct hlist_head *seq_head; 854 struct hlist_head *seq_head;
855 struct name_seq *seq; 855 struct name_seq *seq;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 71cb4dc712df..f02f48b9a216 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -87,14 +87,15 @@ extern rwlock_t tipc_nametbl_lock;
87struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space); 87struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
88u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node); 88u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
89int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, 89int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
90 struct tipc_port_list *dports); 90 struct tipc_port_list *dports);
91struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, 91struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
92 u32 scope, u32 port_ref, u32 key); 92 u32 scope, u32 port_ref, u32 key);
93int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key); 93int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
94struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, 94struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
95 u32 scope, u32 node, u32 ref, u32 key); 95 u32 scope, u32 node, u32 ref,
96struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, 96 u32 key);
97 u32 node, u32 ref, u32 key); 97struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, u32 node,
98 u32 ref, u32 key);
98void tipc_nametbl_subscribe(struct tipc_subscription *s); 99void tipc_nametbl_subscribe(struct tipc_subscription *s);
99void tipc_nametbl_unsubscribe(struct tipc_subscription *s); 100void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
100int tipc_nametbl_init(void); 101int tipc_nametbl_init(void);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 5e34b015da45..8a7384c04add 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -42,7 +42,7 @@
42 * tipc_nodesub_subscribe - create "node down" subscription for specified node 42 * tipc_nodesub_subscribe - create "node down" subscription for specified node
43 */ 43 */
44void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, 44void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
45 void *usr_handle, net_ev_handler handle_down) 45 void *usr_handle, net_ev_handler handle_down)
46{ 46{
47 if (in_own_node(addr)) { 47 if (in_own_node(addr)) {
48 node_sub->node = NULL; 48 node_sub->node = NULL;
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 18098cac62f2..b3ed2fcab4fb 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -2,7 +2,7 @@
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -46,11 +46,7 @@
46 46
47#define MAX_REJECT_SIZE 1024 47#define MAX_REJECT_SIZE 1024
48 48
49static struct sk_buff *msg_queue_head;
50static struct sk_buff *msg_queue_tail;
51
52DEFINE_SPINLOCK(tipc_port_list_lock); 49DEFINE_SPINLOCK(tipc_port_list_lock);
53static DEFINE_SPINLOCK(queue_lock);
54 50
55static LIST_HEAD(ports); 51static LIST_HEAD(ports);
56static void port_handle_node_down(unsigned long ref); 52static void port_handle_node_down(unsigned long ref);
@@ -119,7 +115,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
119 msg_set_nameupper(hdr, seq->upper); 115 msg_set_nameupper(hdr, seq->upper);
120 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 116 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
121 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, 117 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
122 !oport->user_port, &buf); 118 &buf);
123 if (unlikely(!buf)) 119 if (unlikely(!buf))
124 return res; 120 return res;
125 121
@@ -206,14 +202,15 @@ exit:
206} 202}
207 203
208/** 204/**
209 * tipc_createport_raw - create a generic TIPC port 205 * tipc_createport - create a generic TIPC port
210 * 206 *
211 * Returns pointer to (locked) TIPC port, or NULL if unable to create it 207 * Returns pointer to (locked) TIPC port, or NULL if unable to create it
212 */ 208 */
213struct tipc_port *tipc_createport_raw(void *usr_handle, 209struct tipc_port *tipc_createport(struct sock *sk,
214 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 210 u32 (*dispatcher)(struct tipc_port *,
215 void (*wakeup)(struct tipc_port *), 211 struct sk_buff *),
216 const u32 importance) 212 void (*wakeup)(struct tipc_port *),
213 const u32 importance)
217{ 214{
218 struct tipc_port *p_ptr; 215 struct tipc_port *p_ptr;
219 struct tipc_msg *msg; 216 struct tipc_msg *msg;
@@ -231,14 +228,13 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
231 return NULL; 228 return NULL;
232 } 229 }
233 230
234 p_ptr->usr_handle = usr_handle; 231 p_ptr->sk = sk;
235 p_ptr->max_pkt = MAX_PKT_DEFAULT; 232 p_ptr->max_pkt = MAX_PKT_DEFAULT;
236 p_ptr->ref = ref; 233 p_ptr->ref = ref;
237 INIT_LIST_HEAD(&p_ptr->wait_list); 234 INIT_LIST_HEAD(&p_ptr->wait_list);
238 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 235 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
239 p_ptr->dispatcher = dispatcher; 236 p_ptr->dispatcher = dispatcher;
240 p_ptr->wakeup = wakeup; 237 p_ptr->wakeup = wakeup;
241 p_ptr->user_port = NULL;
242 k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref); 238 k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
243 INIT_LIST_HEAD(&p_ptr->publications); 239 INIT_LIST_HEAD(&p_ptr->publications);
244 INIT_LIST_HEAD(&p_ptr->port_list); 240 INIT_LIST_HEAD(&p_ptr->port_list);
@@ -275,7 +271,6 @@ int tipc_deleteport(u32 ref)
275 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 271 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
276 tipc_nodesub_unsubscribe(&p_ptr->subscription); 272 tipc_nodesub_unsubscribe(&p_ptr->subscription);
277 } 273 }
278 kfree(p_ptr->user_port);
279 274
280 spin_lock_bh(&tipc_port_list_lock); 275 spin_lock_bh(&tipc_port_list_lock);
281 list_del(&p_ptr->port_list); 276 list_del(&p_ptr->port_list);
@@ -448,7 +443,7 @@ int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
448 int res; 443 int res;
449 444
450 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, 445 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
451 !p_ptr->user_port, &buf); 446 &buf);
452 if (!buf) 447 if (!buf)
453 return res; 448 return res;
454 449
@@ -668,215 +663,6 @@ void tipc_port_reinit(void)
668 spin_unlock_bh(&tipc_port_list_lock); 663 spin_unlock_bh(&tipc_port_list_lock);
669} 664}
670 665
671
672/*
673 * port_dispatcher_sigh(): Signal handler for messages destinated
674 * to the tipc_port interface.
675 */
676static void port_dispatcher_sigh(void *dummy)
677{
678 struct sk_buff *buf;
679
680 spin_lock_bh(&queue_lock);
681 buf = msg_queue_head;
682 msg_queue_head = NULL;
683 spin_unlock_bh(&queue_lock);
684
685 while (buf) {
686 struct tipc_port *p_ptr;
687 struct user_port *up_ptr;
688 struct tipc_portid orig;
689 struct tipc_name_seq dseq;
690 void *usr_handle;
691 int connected;
692 int peer_invalid;
693 int published;
694 u32 message_type;
695
696 struct sk_buff *next = buf->next;
697 struct tipc_msg *msg = buf_msg(buf);
698 u32 dref = msg_destport(msg);
699
700 message_type = msg_type(msg);
701 if (message_type > TIPC_DIRECT_MSG)
702 goto reject; /* Unsupported message type */
703
704 p_ptr = tipc_port_lock(dref);
705 if (!p_ptr)
706 goto reject; /* Port deleted while msg in queue */
707
708 orig.ref = msg_origport(msg);
709 orig.node = msg_orignode(msg);
710 up_ptr = p_ptr->user_port;
711 usr_handle = up_ptr->usr_handle;
712 connected = p_ptr->connected;
713 peer_invalid = connected && !tipc_port_peer_msg(p_ptr, msg);
714 published = p_ptr->published;
715
716 if (unlikely(msg_errcode(msg)))
717 goto err;
718
719 switch (message_type) {
720
721 case TIPC_CONN_MSG:{
722 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
723 u32 dsz;
724
725 tipc_port_unlock(p_ptr);
726 if (unlikely(!cb))
727 goto reject;
728 if (unlikely(!connected)) {
729 if (tipc_connect(dref, &orig))
730 goto reject;
731 } else if (peer_invalid)
732 goto reject;
733 dsz = msg_data_sz(msg);
734 if (unlikely(dsz &&
735 (++p_ptr->conn_unacked >=
736 TIPC_FLOW_CONTROL_WIN)))
737 tipc_acknowledge(dref,
738 p_ptr->conn_unacked);
739 skb_pull(buf, msg_hdr_sz(msg));
740 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
741 break;
742 }
743 case TIPC_DIRECT_MSG:{
744 tipc_msg_event cb = up_ptr->msg_cb;
745
746 tipc_port_unlock(p_ptr);
747 if (unlikely(!cb || connected))
748 goto reject;
749 skb_pull(buf, msg_hdr_sz(msg));
750 cb(usr_handle, dref, &buf, msg_data(msg),
751 msg_data_sz(msg), msg_importance(msg),
752 &orig);
753 break;
754 }
755 case TIPC_MCAST_MSG:
756 case TIPC_NAMED_MSG:{
757 tipc_named_msg_event cb = up_ptr->named_msg_cb;
758
759 tipc_port_unlock(p_ptr);
760 if (unlikely(!cb || connected || !published))
761 goto reject;
762 dseq.type = msg_nametype(msg);
763 dseq.lower = msg_nameinst(msg);
764 dseq.upper = (message_type == TIPC_NAMED_MSG)
765 ? dseq.lower : msg_nameupper(msg);
766 skb_pull(buf, msg_hdr_sz(msg));
767 cb(usr_handle, dref, &buf, msg_data(msg),
768 msg_data_sz(msg), msg_importance(msg),
769 &orig, &dseq);
770 break;
771 }
772 }
773 if (buf)
774 kfree_skb(buf);
775 buf = next;
776 continue;
777err:
778 switch (message_type) {
779
780 case TIPC_CONN_MSG:{
781 tipc_conn_shutdown_event cb =
782 up_ptr->conn_err_cb;
783
784 tipc_port_unlock(p_ptr);
785 if (!cb || !connected || peer_invalid)
786 break;
787 tipc_disconnect(dref);
788 skb_pull(buf, msg_hdr_sz(msg));
789 cb(usr_handle, dref, &buf, msg_data(msg),
790 msg_data_sz(msg), msg_errcode(msg));
791 break;
792 }
793 case TIPC_DIRECT_MSG:{
794 tipc_msg_err_event cb = up_ptr->err_cb;
795
796 tipc_port_unlock(p_ptr);
797 if (!cb || connected)
798 break;
799 skb_pull(buf, msg_hdr_sz(msg));
800 cb(usr_handle, dref, &buf, msg_data(msg),
801 msg_data_sz(msg), msg_errcode(msg), &orig);
802 break;
803 }
804 case TIPC_MCAST_MSG:
805 case TIPC_NAMED_MSG:{
806 tipc_named_msg_err_event cb =
807 up_ptr->named_err_cb;
808
809 tipc_port_unlock(p_ptr);
810 if (!cb || connected)
811 break;
812 dseq.type = msg_nametype(msg);
813 dseq.lower = msg_nameinst(msg);
814 dseq.upper = (message_type == TIPC_NAMED_MSG)
815 ? dseq.lower : msg_nameupper(msg);
816 skb_pull(buf, msg_hdr_sz(msg));
817 cb(usr_handle, dref, &buf, msg_data(msg),
818 msg_data_sz(msg), msg_errcode(msg), &dseq);
819 break;
820 }
821 }
822 if (buf)
823 kfree_skb(buf);
824 buf = next;
825 continue;
826reject:
827 tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
828 buf = next;
829 }
830}
831
832/*
833 * port_dispatcher(): Dispatcher for messages destinated
834 * to the tipc_port interface. Called with port locked.
835 */
836static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
837{
838 buf->next = NULL;
839 spin_lock_bh(&queue_lock);
840 if (msg_queue_head) {
841 msg_queue_tail->next = buf;
842 msg_queue_tail = buf;
843 } else {
844 msg_queue_tail = msg_queue_head = buf;
845 tipc_k_signal((Handler)port_dispatcher_sigh, 0);
846 }
847 spin_unlock_bh(&queue_lock);
848 return 0;
849}
850
851/*
852 * Wake up port after congestion: Called with port locked
853 */
854static void port_wakeup_sh(unsigned long ref)
855{
856 struct tipc_port *p_ptr;
857 struct user_port *up_ptr;
858 tipc_continue_event cb = NULL;
859 void *uh = NULL;
860
861 p_ptr = tipc_port_lock(ref);
862 if (p_ptr) {
863 up_ptr = p_ptr->user_port;
864 if (up_ptr) {
865 cb = up_ptr->continue_event_cb;
866 uh = up_ptr->usr_handle;
867 }
868 tipc_port_unlock(p_ptr);
869 }
870 if (cb)
871 cb(uh, ref);
872}
873
874
875static void port_wakeup(struct tipc_port *p_ptr)
876{
877 tipc_k_signal((Handler)port_wakeup_sh, p_ptr->ref);
878}
879
880void tipc_acknowledge(u32 ref, u32 ack) 666void tipc_acknowledge(u32 ref, u32 ack)
881{ 667{
882 struct tipc_port *p_ptr; 668 struct tipc_port *p_ptr;
@@ -893,50 +679,6 @@ void tipc_acknowledge(u32 ref, u32 ack)
893 tipc_net_route_msg(buf); 679 tipc_net_route_msg(buf);
894} 680}
895 681
896/*
897 * tipc_createport(): user level call.
898 */
899int tipc_createport(void *usr_handle,
900 unsigned int importance,
901 tipc_msg_err_event error_cb,
902 tipc_named_msg_err_event named_error_cb,
903 tipc_conn_shutdown_event conn_error_cb,
904 tipc_msg_event msg_cb,
905 tipc_named_msg_event named_msg_cb,
906 tipc_conn_msg_event conn_msg_cb,
907 tipc_continue_event continue_event_cb, /* May be zero */
908 u32 *portref)
909{
910 struct user_port *up_ptr;
911 struct tipc_port *p_ptr;
912
913 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
914 if (!up_ptr) {
915 pr_warn("Port creation failed, no memory\n");
916 return -ENOMEM;
917 }
918 p_ptr = tipc_createport_raw(NULL, port_dispatcher, port_wakeup,
919 importance);
920 if (!p_ptr) {
921 kfree(up_ptr);
922 return -ENOMEM;
923 }
924
925 p_ptr->user_port = up_ptr;
926 up_ptr->usr_handle = usr_handle;
927 up_ptr->ref = p_ptr->ref;
928 up_ptr->err_cb = error_cb;
929 up_ptr->named_err_cb = named_error_cb;
930 up_ptr->conn_err_cb = conn_error_cb;
931 up_ptr->msg_cb = msg_cb;
932 up_ptr->named_msg_cb = named_msg_cb;
933 up_ptr->conn_msg_cb = conn_msg_cb;
934 up_ptr->continue_event_cb = continue_event_cb;
935 *portref = p_ptr->ref;
936 tipc_port_unlock(p_ptr);
937 return 0;
938}
939
940int tipc_portimportance(u32 ref, unsigned int *importance) 682int tipc_portimportance(u32 ref, unsigned int *importance)
941{ 683{
942 struct tipc_port *p_ptr; 684 struct tipc_port *p_ptr;
@@ -1184,7 +926,7 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se
1184 int res; 926 int res;
1185 927
1186 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, 928 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
1187 MAX_MSG_SIZE, !sender->user_port, &buf); 929 MAX_MSG_SIZE, &buf);
1188 if (likely(buf)) 930 if (likely(buf))
1189 tipc_port_recv_msg(buf); 931 tipc_port_recv_msg(buf);
1190 return res; 932 return res;
@@ -1322,43 +1064,3 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1322 } 1064 }
1323 return -ELINKCONG; 1065 return -ELINKCONG;
1324} 1066}
1325
1326/**
1327 * tipc_send_buf2port - send message buffer to port identity
1328 */
1329int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1330 struct sk_buff *buf, unsigned int dsz)
1331{
1332 struct tipc_port *p_ptr;
1333 struct tipc_msg *msg;
1334 int res;
1335
1336 p_ptr = (struct tipc_port *)tipc_ref_deref(ref);
1337 if (!p_ptr || p_ptr->connected)
1338 return -EINVAL;
1339
1340 msg = &p_ptr->phdr;
1341 msg_set_type(msg, TIPC_DIRECT_MSG);
1342 msg_set_destnode(msg, dest->node);
1343 msg_set_destport(msg, dest->ref);
1344 msg_set_hdr_sz(msg, BASIC_H_SIZE);
1345 msg_set_size(msg, BASIC_H_SIZE + dsz);
1346 if (skb_cow(buf, BASIC_H_SIZE))
1347 return -ENOMEM;
1348
1349 skb_push(buf, BASIC_H_SIZE);
1350 skb_copy_to_linear_data(buf, msg, BASIC_H_SIZE);
1351
1352 if (in_own_node(dest->node))
1353 res = tipc_port_recv_msg(buf);
1354 else
1355 res = tipc_send_buf_fast(buf, dest->node);
1356 if (likely(res != -ELINKCONG)) {
1357 if (res > 0)
1358 p_ptr->sent++;
1359 return res;
1360 }
1361 if (port_unreliable(p_ptr))
1362 return dsz;
1363 return -ELINKCONG;
1364}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index fb66e2e5f4d1..5a7026b9c345 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -2,7 +2,7 @@
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2007, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -43,60 +43,12 @@
43#include "node_subscr.h" 43#include "node_subscr.h"
44 44
45#define TIPC_FLOW_CONTROL_WIN 512 45#define TIPC_FLOW_CONTROL_WIN 512
46 46#define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
47typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref, 47 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
48 struct sk_buff **buf, unsigned char const *data,
49 unsigned int size, int reason,
50 struct tipc_portid const *attmpt_destid);
51
52typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
53 struct sk_buff **buf, unsigned char const *data,
54 unsigned int size, int reason,
55 struct tipc_name_seq const *attmpt_dest);
56
57typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
58 struct sk_buff **buf, unsigned char const *data,
59 unsigned int size, int reason);
60
61typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
62 struct sk_buff **buf, unsigned char const *data,
63 unsigned int size, unsigned int importance,
64 struct tipc_portid const *origin);
65
66typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
67 struct sk_buff **buf, unsigned char const *data,
68 unsigned int size, unsigned int importance,
69 struct tipc_portid const *orig,
70 struct tipc_name_seq const *dest);
71
72typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
73 struct sk_buff **buf, unsigned char const *data,
74 unsigned int size);
75
76typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
77
78/**
79 * struct user_port - TIPC user port (used with native API)
80 * @usr_handle: user-specified field
81 * @ref: object reference to associated TIPC port
82 *
83 * <various callback routines>
84 */
85struct user_port {
86 void *usr_handle;
87 u32 ref;
88 tipc_msg_err_event err_cb;
89 tipc_named_msg_err_event named_err_cb;
90 tipc_conn_shutdown_event conn_err_cb;
91 tipc_msg_event msg_cb;
92 tipc_named_msg_event named_msg_cb;
93 tipc_conn_msg_event conn_msg_cb;
94 tipc_continue_event continue_event_cb;
95};
96 48
97/** 49/**
98 * struct tipc_port - TIPC port structure 50 * struct tipc_port - TIPC port structure
99 * @usr_handle: pointer to additional user-defined information about port 51 * @sk: pointer to socket handle
100 * @lock: pointer to spinlock for controlling access to port 52 * @lock: pointer to spinlock for controlling access to port
101 * @connected: non-zero if port is currently connected to a peer port 53 * @connected: non-zero if port is currently connected to a peer port
102 * @conn_type: TIPC type used when connection was established 54 * @conn_type: TIPC type used when connection was established
@@ -110,7 +62,6 @@ struct user_port {
110 * @port_list: adjacent ports in TIPC's global list of ports 62 * @port_list: adjacent ports in TIPC's global list of ports
111 * @dispatcher: ptr to routine which handles received messages 63 * @dispatcher: ptr to routine which handles received messages
112 * @wakeup: ptr to routine to call when port is no longer congested 64 * @wakeup: ptr to routine to call when port is no longer congested
113 * @user_port: ptr to user port associated with port (if any)
114 * @wait_list: adjacent ports in list of ports waiting on link congestion 65 * @wait_list: adjacent ports in list of ports waiting on link congestion
115 * @waiting_pkts: 66 * @waiting_pkts:
116 * @sent: # of non-empty messages sent by port 67 * @sent: # of non-empty messages sent by port
@@ -123,7 +74,7 @@ struct user_port {
123 * @subscription: "node down" subscription used to terminate failed connections 74 * @subscription: "node down" subscription used to terminate failed connections
124 */ 75 */
125struct tipc_port { 76struct tipc_port {
126 void *usr_handle; 77 struct sock *sk;
127 spinlock_t *lock; 78 spinlock_t *lock;
128 int connected; 79 int connected;
129 u32 conn_type; 80 u32 conn_type;
@@ -137,7 +88,6 @@ struct tipc_port {
137 struct list_head port_list; 88 struct list_head port_list;
138 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); 89 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
139 void (*wakeup)(struct tipc_port *); 90 void (*wakeup)(struct tipc_port *);
140 struct user_port *user_port;
141 struct list_head wait_list; 91 struct list_head wait_list;
142 u32 waiting_pkts; 92 u32 waiting_pkts;
143 u32 sent; 93 u32 sent;
@@ -156,24 +106,16 @@ struct tipc_port_list;
156/* 106/*
157 * TIPC port manipulation routines 107 * TIPC port manipulation routines
158 */ 108 */
159struct tipc_port *tipc_createport_raw(void *usr_handle, 109struct tipc_port *tipc_createport(struct sock *sk,
160 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 110 u32 (*dispatcher)(struct tipc_port *,
161 void (*wakeup)(struct tipc_port *), const u32 importance); 111 struct sk_buff *),
112 void (*wakeup)(struct tipc_port *),
113 const u32 importance);
162 114
163int tipc_reject_msg(struct sk_buff *buf, u32 err); 115int tipc_reject_msg(struct sk_buff *buf, u32 err);
164 116
165int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
166
167void tipc_acknowledge(u32 port_ref, u32 ack); 117void tipc_acknowledge(u32 port_ref, u32 ack);
168 118
169int tipc_createport(void *usr_handle,
170 unsigned int importance, tipc_msg_err_event error_cb,
171 tipc_named_msg_err_event named_error_cb,
172 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
173 tipc_named_msg_event named_msg_cb,
174 tipc_conn_msg_event conn_msg_cb,
175 tipc_continue_event continue_event_cb, u32 *portref);
176
177int tipc_deleteport(u32 portref); 119int tipc_deleteport(u32 portref);
178 120
179int tipc_portimportance(u32 portref, unsigned int *importance); 121int tipc_portimportance(u32 portref, unsigned int *importance);
@@ -186,9 +128,9 @@ int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
186int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); 128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
187 129
188int tipc_publish(u32 portref, unsigned int scope, 130int tipc_publish(u32 portref, unsigned int scope,
189 struct tipc_name_seq const *name_seq); 131 struct tipc_name_seq const *name_seq);
190int tipc_withdraw(u32 portref, unsigned int scope, 132int tipc_withdraw(u32 portref, unsigned int scope,
191 struct tipc_name_seq const *name_seq); 133 struct tipc_name_seq const *name_seq);
192 134
193int tipc_connect(u32 portref, struct tipc_portid const *port); 135int tipc_connect(u32 portref, struct tipc_portid const *port);
194 136
@@ -220,9 +162,6 @@ int tipc_send2port(u32 portref, struct tipc_portid const *dest,
220 unsigned int num_sect, struct iovec const *msg_sect, 162 unsigned int num_sect, struct iovec const *msg_sect,
221 unsigned int total_len); 163 unsigned int total_len);
222 164
223int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
224 struct sk_buff *buf, unsigned int dsz);
225
226int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 165int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
227 unsigned int section_count, struct iovec const *msg, 166 unsigned int section_count, struct iovec const *msg,
228 unsigned int total_len); 167 unsigned int total_len);
diff --git a/net/tipc/server.c b/net/tipc/server.c
new file mode 100644
index 000000000000..19da5abe0fa6
--- /dev/null
+++ b/net/tipc/server.c
@@ -0,0 +1,596 @@
1/*
2 * net/tipc/server.c: TIPC server infrastructure
3 *
4 * Copyright (c) 2012-2013, Wind River Systems
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "server.h"
37#include "core.h"
38#include <net/sock.h>
39
40/* Number of messages to send before rescheduling */
41#define MAX_SEND_MSG_COUNT 25
42#define MAX_RECV_MSG_COUNT 25
43#define CF_CONNECTED 1
44
45#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data)
46
47/**
48 * struct tipc_conn - TIPC connection structure
49 * @kref: reference counter to connection object
50 * @conid: connection identifier
51 * @sock: socket handler associated with connection
52 * @flags: indicates connection state
53 * @server: pointer to connected server
54 * @rwork: receive work item
55 * @usr_data: user-specified field
56 * @rx_action: what to do when connection socket is active
57 * @outqueue: pointer to first outbound message in queue
58 * @outqueue_lock: controll access to the outqueue
59 * @outqueue: list of connection objects for its server
60 * @swork: send work item
61 */
62struct tipc_conn {
63 struct kref kref;
64 int conid;
65 struct socket *sock;
66 unsigned long flags;
67 struct tipc_server *server;
68 struct work_struct rwork;
69 int (*rx_action) (struct tipc_conn *con);
70 void *usr_data;
71 struct list_head outqueue;
72 spinlock_t outqueue_lock;
73 struct work_struct swork;
74};
75
76/* An entry waiting to be sent */
77struct outqueue_entry {
78 struct list_head list;
79 struct kvec iov;
80 struct sockaddr_tipc dest;
81};
82
83static void tipc_recv_work(struct work_struct *work);
84static void tipc_send_work(struct work_struct *work);
85static void tipc_clean_outqueues(struct tipc_conn *con);
86
87static void tipc_conn_kref_release(struct kref *kref)
88{
89 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
90 struct tipc_server *s = con->server;
91
92 if (con->sock) {
93 tipc_sock_release_local(con->sock);
94 con->sock = NULL;
95 }
96
97 tipc_clean_outqueues(con);
98
99 if (con->conid)
100 s->tipc_conn_shutdown(con->conid, con->usr_data);
101
102 kfree(con);
103}
104
105static void conn_put(struct tipc_conn *con)
106{
107 kref_put(&con->kref, tipc_conn_kref_release);
108}
109
110static void conn_get(struct tipc_conn *con)
111{
112 kref_get(&con->kref);
113}
114
115static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid)
116{
117 struct tipc_conn *con;
118
119 spin_lock_bh(&s->idr_lock);
120 con = idr_find(&s->conn_idr, conid);
121 if (con)
122 conn_get(con);
123 spin_unlock_bh(&s->idr_lock);
124 return con;
125}
126
127static void sock_data_ready(struct sock *sk, int unused)
128{
129 struct tipc_conn *con;
130
131 read_lock(&sk->sk_callback_lock);
132 con = sock2con(sk);
133 if (con && test_bit(CF_CONNECTED, &con->flags)) {
134 conn_get(con);
135 if (!queue_work(con->server->rcv_wq, &con->rwork))
136 conn_put(con);
137 }
138 read_unlock(&sk->sk_callback_lock);
139}
140
141static void sock_write_space(struct sock *sk)
142{
143 struct tipc_conn *con;
144
145 read_lock(&sk->sk_callback_lock);
146 con = sock2con(sk);
147 if (con && test_bit(CF_CONNECTED, &con->flags)) {
148 conn_get(con);
149 if (!queue_work(con->server->send_wq, &con->swork))
150 conn_put(con);
151 }
152 read_unlock(&sk->sk_callback_lock);
153}
154
155static void tipc_register_callbacks(struct socket *sock, struct tipc_conn *con)
156{
157 struct sock *sk = sock->sk;
158
159 write_lock_bh(&sk->sk_callback_lock);
160
161 sk->sk_data_ready = sock_data_ready;
162 sk->sk_write_space = sock_write_space;
163 sk->sk_user_data = con;
164
165 con->sock = sock;
166
167 write_unlock_bh(&sk->sk_callback_lock);
168}
169
170static void tipc_unregister_callbacks(struct tipc_conn *con)
171{
172 struct sock *sk = con->sock->sk;
173
174 write_lock_bh(&sk->sk_callback_lock);
175 sk->sk_user_data = NULL;
176 write_unlock_bh(&sk->sk_callback_lock);
177}
178
179static void tipc_close_conn(struct tipc_conn *con)
180{
181 struct tipc_server *s = con->server;
182
183 if (test_and_clear_bit(CF_CONNECTED, &con->flags)) {
184 spin_lock_bh(&s->idr_lock);
185 idr_remove(&s->conn_idr, con->conid);
186 s->idr_in_use--;
187 spin_unlock_bh(&s->idr_lock);
188
189 tipc_unregister_callbacks(con);
190
191 /* We shouldn't flush pending works as we may be in the
192 * thread. In fact the races with pending rx/tx work structs
193 * are harmless for us here as we have already deleted this
194 * connection from server connection list and set
195 * sk->sk_user_data to 0 before releasing connection object.
196 */
197 kernel_sock_shutdown(con->sock, SHUT_RDWR);
198
199 conn_put(con);
200 }
201}
202
203static struct tipc_conn *tipc_alloc_conn(struct tipc_server *s)
204{
205 struct tipc_conn *con;
206 int ret;
207
208 con = kzalloc(sizeof(struct tipc_conn), GFP_ATOMIC);
209 if (!con)
210 return ERR_PTR(-ENOMEM);
211
212 kref_init(&con->kref);
213 INIT_LIST_HEAD(&con->outqueue);
214 spin_lock_init(&con->outqueue_lock);
215 INIT_WORK(&con->swork, tipc_send_work);
216 INIT_WORK(&con->rwork, tipc_recv_work);
217
218 spin_lock_bh(&s->idr_lock);
219 ret = idr_alloc(&s->conn_idr, con, 0, 0, GFP_ATOMIC);
220 if (ret < 0) {
221 kfree(con);
222 spin_unlock_bh(&s->idr_lock);
223 return ERR_PTR(-ENOMEM);
224 }
225 con->conid = ret;
226 s->idr_in_use++;
227 spin_unlock_bh(&s->idr_lock);
228
229 set_bit(CF_CONNECTED, &con->flags);
230 con->server = s;
231
232 return con;
233}
234
235static int tipc_receive_from_sock(struct tipc_conn *con)
236{
237 struct msghdr msg = {};
238 struct tipc_server *s = con->server;
239 struct sockaddr_tipc addr;
240 struct kvec iov;
241 void *buf;
242 int ret;
243
244 buf = kmem_cache_alloc(s->rcvbuf_cache, GFP_ATOMIC);
245 if (!buf) {
246 ret = -ENOMEM;
247 goto out_close;
248 }
249
250 iov.iov_base = buf;
251 iov.iov_len = s->max_rcvbuf_size;
252 msg.msg_name = &addr;
253 ret = kernel_recvmsg(con->sock, &msg, &iov, 1, iov.iov_len,
254 MSG_DONTWAIT);
255 if (ret <= 0) {
256 kmem_cache_free(s->rcvbuf_cache, buf);
257 goto out_close;
258 }
259
260 s->tipc_conn_recvmsg(con->conid, &addr, con->usr_data, buf, ret);
261
262 kmem_cache_free(s->rcvbuf_cache, buf);
263
264 return 0;
265
266out_close:
267 if (ret != -EWOULDBLOCK)
268 tipc_close_conn(con);
269 else if (ret == 0)
270 /* Don't return success if we really got EOF */
271 ret = -EAGAIN;
272
273 return ret;
274}
275
276static int tipc_accept_from_sock(struct tipc_conn *con)
277{
278 struct tipc_server *s = con->server;
279 struct socket *sock = con->sock;
280 struct socket *newsock;
281 struct tipc_conn *newcon;
282 int ret;
283
284 ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK);
285 if (ret < 0)
286 return ret;
287
288 newcon = tipc_alloc_conn(con->server);
289 if (IS_ERR(newcon)) {
290 ret = PTR_ERR(newcon);
291 sock_release(newsock);
292 return ret;
293 }
294
295 newcon->rx_action = tipc_receive_from_sock;
296 tipc_register_callbacks(newsock, newcon);
297
298 /* Notify that new connection is incoming */
299 newcon->usr_data = s->tipc_conn_new(newcon->conid);
300
301 /* Wake up receive process in case of 'SYN+' message */
302 newsock->sk->sk_data_ready(newsock->sk, 0);
303 return ret;
304}
305
306static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
307{
308 struct tipc_server *s = con->server;
309 struct socket *sock = NULL;
310 int ret;
311
312 ret = tipc_sock_create_local(s->type, &sock);
313 if (ret < 0)
314 return NULL;
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
316 (char *)&s->imp, sizeof(s->imp));
317 if (ret < 0)
318 goto create_err;
319 ret = kernel_bind(sock, (struct sockaddr *)s->saddr, sizeof(*s->saddr));
320 if (ret < 0)
321 goto create_err;
322
323 switch (s->type) {
324 case SOCK_STREAM:
325 case SOCK_SEQPACKET:
326 con->rx_action = tipc_accept_from_sock;
327
328 ret = kernel_listen(sock, 0);
329 if (ret < 0)
330 goto create_err;
331 break;
332 case SOCK_DGRAM:
333 case SOCK_RDM:
334 con->rx_action = tipc_receive_from_sock;
335 break;
336 default:
337 pr_err("Unknown socket type %d\n", s->type);
338 goto create_err;
339 }
340 return sock;
341
342create_err:
343 sock_release(sock);
344 con->sock = NULL;
345 return NULL;
346}
347
348static int tipc_open_listening_sock(struct tipc_server *s)
349{
350 struct socket *sock;
351 struct tipc_conn *con;
352
353 con = tipc_alloc_conn(s);
354 if (IS_ERR(con))
355 return PTR_ERR(con);
356
357 sock = tipc_create_listen_sock(con);
358 if (!sock)
359 return -EINVAL;
360
361 tipc_register_callbacks(sock, con);
362 return 0;
363}
364
365static struct outqueue_entry *tipc_alloc_entry(void *data, int len)
366{
367 struct outqueue_entry *entry;
368 void *buf;
369
370 entry = kmalloc(sizeof(struct outqueue_entry), GFP_ATOMIC);
371 if (!entry)
372 return NULL;
373
374 buf = kmalloc(len, GFP_ATOMIC);
375 if (!buf) {
376 kfree(entry);
377 return NULL;
378 }
379
380 memcpy(buf, data, len);
381 entry->iov.iov_base = buf;
382 entry->iov.iov_len = len;
383
384 return entry;
385}
386
387static void tipc_free_entry(struct outqueue_entry *e)
388{
389 kfree(e->iov.iov_base);
390 kfree(e);
391}
392
393static void tipc_clean_outqueues(struct tipc_conn *con)
394{
395 struct outqueue_entry *e, *safe;
396
397 spin_lock_bh(&con->outqueue_lock);
398 list_for_each_entry_safe(e, safe, &con->outqueue, list) {
399 list_del(&e->list);
400 tipc_free_entry(e);
401 }
402 spin_unlock_bh(&con->outqueue_lock);
403}
404
405int tipc_conn_sendmsg(struct tipc_server *s, int conid,
406 struct sockaddr_tipc *addr, void *data, size_t len)
407{
408 struct outqueue_entry *e;
409 struct tipc_conn *con;
410
411 con = tipc_conn_lookup(s, conid);
412 if (!con)
413 return -EINVAL;
414
415 e = tipc_alloc_entry(data, len);
416 if (!e) {
417 conn_put(con);
418 return -ENOMEM;
419 }
420
421 if (addr)
422 memcpy(&e->dest, addr, sizeof(struct sockaddr_tipc));
423
424 spin_lock_bh(&con->outqueue_lock);
425 list_add_tail(&e->list, &con->outqueue);
426 spin_unlock_bh(&con->outqueue_lock);
427
428 if (test_bit(CF_CONNECTED, &con->flags))
429 if (!queue_work(s->send_wq, &con->swork))
430 conn_put(con);
431
432 return 0;
433}
434
435void tipc_conn_terminate(struct tipc_server *s, int conid)
436{
437 struct tipc_conn *con;
438
439 con = tipc_conn_lookup(s, conid);
440 if (con) {
441 tipc_close_conn(con);
442 conn_put(con);
443 }
444}
445
446static void tipc_send_to_sock(struct tipc_conn *con)
447{
448 int count = 0;
449 struct tipc_server *s = con->server;
450 struct outqueue_entry *e;
451 struct msghdr msg;
452 int ret;
453
454 spin_lock_bh(&con->outqueue_lock);
455 while (1) {
456 e = list_entry(con->outqueue.next, struct outqueue_entry,
457 list);
458 if ((struct list_head *) e == &con->outqueue)
459 break;
460 spin_unlock_bh(&con->outqueue_lock);
461
462 memset(&msg, 0, sizeof(msg));
463 msg.msg_flags = MSG_DONTWAIT;
464
465 if (s->type == SOCK_DGRAM || s->type == SOCK_RDM) {
466 msg.msg_name = &e->dest;
467 msg.msg_namelen = sizeof(struct sockaddr_tipc);
468 }
469 ret = kernel_sendmsg(con->sock, &msg, &e->iov, 1,
470 e->iov.iov_len);
471 if (ret == -EWOULDBLOCK || ret == 0) {
472 cond_resched();
473 goto out;
474 } else if (ret < 0) {
475 goto send_err;
476 }
477
478 /* Don't starve users filling buffers */
479 if (++count >= MAX_SEND_MSG_COUNT) {
480 cond_resched();
481 count = 0;
482 }
483
484 spin_lock_bh(&con->outqueue_lock);
485 list_del(&e->list);
486 tipc_free_entry(e);
487 }
488 spin_unlock_bh(&con->outqueue_lock);
489out:
490 return;
491
492send_err:
493 tipc_close_conn(con);
494}
495
496static void tipc_recv_work(struct work_struct *work)
497{
498 struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
499 int count = 0;
500
501 while (test_bit(CF_CONNECTED, &con->flags)) {
502 if (con->rx_action(con))
503 break;
504
505 /* Don't flood Rx machine */
506 if (++count >= MAX_RECV_MSG_COUNT) {
507 cond_resched();
508 count = 0;
509 }
510 }
511 conn_put(con);
512}
513
514static void tipc_send_work(struct work_struct *work)
515{
516 struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
517
518 if (test_bit(CF_CONNECTED, &con->flags))
519 tipc_send_to_sock(con);
520
521 conn_put(con);
522}
523
524static void tipc_work_stop(struct tipc_server *s)
525{
526 destroy_workqueue(s->rcv_wq);
527 destroy_workqueue(s->send_wq);
528}
529
530static int tipc_work_start(struct tipc_server *s)
531{
532 s->rcv_wq = alloc_workqueue("tipc_rcv", WQ_UNBOUND, 1);
533 if (!s->rcv_wq) {
534 pr_err("can't start tipc receive workqueue\n");
535 return -ENOMEM;
536 }
537
538 s->send_wq = alloc_workqueue("tipc_send", WQ_UNBOUND, 1);
539 if (!s->send_wq) {
540 pr_err("can't start tipc send workqueue\n");
541 destroy_workqueue(s->rcv_wq);
542 return -ENOMEM;
543 }
544
545 return 0;
546}
547
548int tipc_server_start(struct tipc_server *s)
549{
550 int ret;
551
552 spin_lock_init(&s->idr_lock);
553 idr_init(&s->conn_idr);
554 s->idr_in_use = 0;
555
556 s->rcvbuf_cache = kmem_cache_create(s->name, s->max_rcvbuf_size,
557 0, SLAB_HWCACHE_ALIGN, NULL);
558 if (!s->rcvbuf_cache)
559 return -ENOMEM;
560
561 ret = tipc_work_start(s);
562 if (ret < 0) {
563 kmem_cache_destroy(s->rcvbuf_cache);
564 return ret;
565 }
566 s->enabled = 1;
567
568 return tipc_open_listening_sock(s);
569}
570
571void tipc_server_stop(struct tipc_server *s)
572{
573 struct tipc_conn *con;
574 int total = 0;
575 int id;
576
577 if (!s->enabled)
578 return;
579
580 s->enabled = 0;
581 spin_lock_bh(&s->idr_lock);
582 for (id = 0; total < s->idr_in_use; id++) {
583 con = idr_find(&s->conn_idr, id);
584 if (con) {
585 total++;
586 spin_unlock_bh(&s->idr_lock);
587 tipc_close_conn(con);
588 spin_lock_bh(&s->idr_lock);
589 }
590 }
591 spin_unlock_bh(&s->idr_lock);
592
593 tipc_work_stop(s);
594 kmem_cache_destroy(s->rcvbuf_cache);
595 idr_destroy(&s->conn_idr);
596}
diff --git a/net/tipc/server.h b/net/tipc/server.h
new file mode 100644
index 000000000000..98b23f20bc0f
--- /dev/null
+++ b/net/tipc/server.h
@@ -0,0 +1,94 @@
1/*
2 * net/tipc/server.h: Include file for TIPC server code
3 *
4 * Copyright (c) 2012-2013, Wind River Systems
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef _TIPC_SERVER_H
37#define _TIPC_SERVER_H
38
39#include "core.h"
40
41#define TIPC_SERVER_NAME_LEN 32
42
43/**
44 * struct tipc_server - TIPC server structure
45 * @conn_idr: identifier set of connection
46 * @idr_lock: protect the connection identifier set
47 * @idr_in_use: amount of allocated identifier entry
48 * @rcvbuf_cache: memory cache of server receive buffer
49 * @rcv_wq: receive workqueue
50 * @send_wq: send workqueue
51 * @max_rcvbuf_size: maximum permitted receive message length
52 * @tipc_conn_new: callback will be called when new connection is incoming
53 * @tipc_conn_shutdown: callback will be called when connection is shut down
54 * @tipc_conn_recvmsg: callback will be called when message arrives
55 * @saddr: TIPC server address
56 * @name: server name
57 * @imp: message importance
58 * @type: socket type
59 * @enabled: identify whether server is launched or not
60 */
61struct tipc_server {
62 struct idr conn_idr;
63 spinlock_t idr_lock;
64 int idr_in_use;
65 struct kmem_cache *rcvbuf_cache;
66 struct workqueue_struct *rcv_wq;
67 struct workqueue_struct *send_wq;
68 int max_rcvbuf_size;
69 void *(*tipc_conn_new) (int conid);
70 void (*tipc_conn_shutdown) (int conid, void *usr_data);
71 void (*tipc_conn_recvmsg) (int conid, struct sockaddr_tipc *addr,
72 void *usr_data, void *buf, size_t len);
73 struct sockaddr_tipc *saddr;
74 const char name[TIPC_SERVER_NAME_LEN];
75 int imp;
76 int type;
77 int enabled;
78};
79
80int tipc_conn_sendmsg(struct tipc_server *s, int conid,
81 struct sockaddr_tipc *addr, void *data, size_t len);
82
83/**
84 * tipc_conn_terminate - terminate connection with server
85 *
86 * Note: Must call it in process context since it might sleep
87 */
88void tipc_conn_terminate(struct tipc_server *s, int conid);
89
90int tipc_server_start(struct tipc_server *s);
91
92void tipc_server_stop(struct tipc_server *s);
93
94#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 515ce38e4f4c..ce8249c76827 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, 2012 Ericsson AB 4 * Copyright (c) 2001-2007, 2012 Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2012, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -43,8 +43,6 @@
43#define SS_LISTENING -1 /* socket is listening */ 43#define SS_LISTENING -1 /* socket is listening */
44#define SS_READY -2 /* socket is connectionless */ 44#define SS_READY -2 /* socket is connectionless */
45 45
46#define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
47 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
48#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 46#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
49 47
50struct tipc_sock { 48struct tipc_sock {
@@ -65,12 +63,15 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
65static void wakeupdispatch(struct tipc_port *tport); 63static void wakeupdispatch(struct tipc_port *tport);
66static void tipc_data_ready(struct sock *sk, int len); 64static void tipc_data_ready(struct sock *sk, int len);
67static void tipc_write_space(struct sock *sk); 65static void tipc_write_space(struct sock *sk);
66static int release(struct socket *sock);
67static int accept(struct socket *sock, struct socket *new_sock, int flags);
68 68
69static const struct proto_ops packet_ops; 69static const struct proto_ops packet_ops;
70static const struct proto_ops stream_ops; 70static const struct proto_ops stream_ops;
71static const struct proto_ops msg_ops; 71static const struct proto_ops msg_ops;
72 72
73static struct proto tipc_proto; 73static struct proto tipc_proto;
74static struct proto tipc_proto_kern;
74 75
75static int sockets_enabled; 76static int sockets_enabled;
76 77
@@ -143,7 +144,7 @@ static void reject_rx_queue(struct sock *sk)
143} 144}
144 145
145/** 146/**
146 * tipc_create - create a TIPC socket 147 * tipc_sk_create - create a TIPC socket
147 * @net: network namespace (must be default network) 148 * @net: network namespace (must be default network)
148 * @sock: pre-allocated socket structure 149 * @sock: pre-allocated socket structure
149 * @protocol: protocol indicator (must be 0) 150 * @protocol: protocol indicator (must be 0)
@@ -154,8 +155,8 @@ static void reject_rx_queue(struct sock *sk)
154 * 155 *
155 * Returns 0 on success, errno otherwise 156 * Returns 0 on success, errno otherwise
156 */ 157 */
157static int tipc_create(struct net *net, struct socket *sock, int protocol, 158static int tipc_sk_create(struct net *net, struct socket *sock, int protocol,
158 int kern) 159 int kern)
159{ 160{
160 const struct proto_ops *ops; 161 const struct proto_ops *ops;
161 socket_state state; 162 socket_state state;
@@ -185,13 +186,17 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
185 } 186 }
186 187
187 /* Allocate socket's protocol area */ 188 /* Allocate socket's protocol area */
188 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); 189 if (!kern)
190 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
191 else
192 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern);
193
189 if (sk == NULL) 194 if (sk == NULL)
190 return -ENOMEM; 195 return -ENOMEM;
191 196
192 /* Allocate TIPC port for socket to use */ 197 /* Allocate TIPC port for socket to use */
193 tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, 198 tp_ptr = tipc_createport(sk, &dispatch, &wakeupdispatch,
194 TIPC_LOW_IMPORTANCE); 199 TIPC_LOW_IMPORTANCE);
195 if (unlikely(!tp_ptr)) { 200 if (unlikely(!tp_ptr)) {
196 sk_free(sk); 201 sk_free(sk);
197 return -ENOMEM; 202 return -ENOMEM;
@@ -203,6 +208,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
203 208
204 sock_init_data(sock, sk); 209 sock_init_data(sock, sk);
205 sk->sk_backlog_rcv = backlog_rcv; 210 sk->sk_backlog_rcv = backlog_rcv;
211 sk->sk_rcvbuf = sysctl_tipc_rmem[1];
206 sk->sk_data_ready = tipc_data_ready; 212 sk->sk_data_ready = tipc_data_ready;
207 sk->sk_write_space = tipc_write_space; 213 sk->sk_write_space = tipc_write_space;
208 tipc_sk(sk)->p = tp_ptr; 214 tipc_sk(sk)->p = tp_ptr;
@@ -220,6 +226,78 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
220} 226}
221 227
222/** 228/**
229 * tipc_sock_create_local - create TIPC socket from inside TIPC module
230 * @type: socket type - SOCK_RDM or SOCK_SEQPACKET
231 *
232 * We cannot use sock_creat_kern here because it bumps module user count.
233 * Since socket owner and creator is the same module we must make sure
234 * that module count remains zero for module local sockets, otherwise
235 * we cannot do rmmod.
236 *
237 * Returns 0 on success, errno otherwise
238 */
239int tipc_sock_create_local(int type, struct socket **res)
240{
241 int rc;
242 struct sock *sk;
243
244 rc = sock_create_lite(AF_TIPC, type, 0, res);
245 if (rc < 0) {
246 pr_err("Failed to create kernel socket\n");
247 return rc;
248 }
249 tipc_sk_create(&init_net, *res, 0, 1);
250
251 sk = (*res)->sk;
252
253 return 0;
254}
255
256/**
257 * tipc_sock_release_local - release socket created by tipc_sock_create_local
258 * @sock: the socket to be released.
259 *
260 * Module reference count is not incremented when such sockets are created,
261 * so we must keep it from being decremented when they are released.
262 */
263void tipc_sock_release_local(struct socket *sock)
264{
265 release(sock);
266 sock->ops = NULL;
267 sock_release(sock);
268}
269
270/**
271 * tipc_sock_accept_local - accept a connection on a socket created
272 * with tipc_sock_create_local. Use this function to avoid that
273 * module reference count is inadvertently incremented.
274 *
275 * @sock: the accepting socket
276 * @newsock: reference to the new socket to be created
277 * @flags: socket flags
278 */
279
280int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
281 int flags)
282{
283 struct sock *sk = sock->sk;
284 int ret;
285
286 ret = sock_create_lite(sk->sk_family, sk->sk_type,
287 sk->sk_protocol, newsock);
288 if (ret < 0)
289 return ret;
290
291 ret = accept(sock, *newsock, flags);
292 if (ret < 0) {
293 sock_release(*newsock);
294 return ret;
295 }
296 (*newsock)->ops = sock->ops;
297 return ret;
298}
299
300/**
223 * release - destroy a TIPC socket 301 * release - destroy a TIPC socket
224 * @sock: socket to destroy 302 * @sock: socket to destroy
225 * 303 *
@@ -324,7 +402,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
324 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) 402 else if (addr->addrtype != TIPC_ADDR_NAMESEQ)
325 return -EAFNOSUPPORT; 403 return -EAFNOSUPPORT;
326 404
327 if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) 405 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
406 (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
407 (addr->addr.nameseq.type != TIPC_CFG_SRV))
328 return -EACCES; 408 return -EACCES;
329 409
330 return (addr->scope > 0) ? 410 return (addr->scope > 0) ?
@@ -519,8 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
519 res = -EISCONN; 599 res = -EISCONN;
520 goto exit; 600 goto exit;
521 } 601 }
522 if ((tport->published) || 602 if (tport->published) {
523 ((sock->type == SOCK_STREAM) && (total_len != 0))) {
524 res = -EOPNOTSUPP; 603 res = -EOPNOTSUPP;
525 goto exit; 604 goto exit;
526 } 605 }
@@ -810,7 +889,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
810 * Returns 0 if successful, otherwise errno 889 * Returns 0 if successful, otherwise errno
811 */ 890 */
812static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, 891static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
813 struct tipc_port *tport) 892 struct tipc_port *tport)
814{ 893{
815 u32 anc_data[3]; 894 u32 anc_data[3];
816 u32 err; 895 u32 err;
@@ -1011,8 +1090,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1011 1090
1012 lock_sock(sk); 1091 lock_sock(sk);
1013 1092
1014 if (unlikely((sock->state == SS_UNCONNECTED) || 1093 if (unlikely((sock->state == SS_UNCONNECTED))) {
1015 (sock->state == SS_CONNECTING))) {
1016 res = -ENOTCONN; 1094 res = -ENOTCONN;
1017 goto exit; 1095 goto exit;
1018 } 1096 }
@@ -1233,10 +1311,10 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf)
1233 * For all connectionless messages, by default new queue limits are 1311 * For all connectionless messages, by default new queue limits are
1234 * as belows: 1312 * as belows:
1235 * 1313 *
1236 * TIPC_LOW_IMPORTANCE (5MB) 1314 * TIPC_LOW_IMPORTANCE (4 MB)
1237 * TIPC_MEDIUM_IMPORTANCE (10MB) 1315 * TIPC_MEDIUM_IMPORTANCE (8 MB)
1238 * TIPC_HIGH_IMPORTANCE (20MB) 1316 * TIPC_HIGH_IMPORTANCE (16 MB)
1239 * TIPC_CRITICAL_IMPORTANCE (40MB) 1317 * TIPC_CRITICAL_IMPORTANCE (32 MB)
1240 * 1318 *
1241 * Returns overload limit according to corresponding message importance 1319 * Returns overload limit according to corresponding message importance
1242 */ 1320 */
@@ -1246,9 +1324,10 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
1246 unsigned int limit; 1324 unsigned int limit;
1247 1325
1248 if (msg_connected(msg)) 1326 if (msg_connected(msg))
1249 limit = CONN_OVERLOAD_LIMIT; 1327 limit = sysctl_tipc_rmem[2];
1250 else 1328 else
1251 limit = sk->sk_rcvbuf << (msg_importance(msg) + 5); 1329 limit = sk->sk_rcvbuf >> TIPC_CRITICAL_IMPORTANCE <<
1330 msg_importance(msg);
1252 return limit; 1331 return limit;
1253} 1332}
1254 1333
@@ -1327,7 +1406,7 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf)
1327 */ 1406 */
1328static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) 1407static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
1329{ 1408{
1330 struct sock *sk = (struct sock *)tport->usr_handle; 1409 struct sock *sk = tport->sk;
1331 u32 res; 1410 u32 res;
1332 1411
1333 /* 1412 /*
@@ -1358,7 +1437,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
1358 */ 1437 */
1359static void wakeupdispatch(struct tipc_port *tport) 1438static void wakeupdispatch(struct tipc_port *tport)
1360{ 1439{
1361 struct sock *sk = (struct sock *)tport->usr_handle; 1440 struct sock *sk = tport->sk;
1362 1441
1363 sk->sk_write_space(sk); 1442 sk->sk_write_space(sk);
1364} 1443}
@@ -1531,7 +1610,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1531 1610
1532 buf = skb_peek(&sk->sk_receive_queue); 1611 buf = skb_peek(&sk->sk_receive_queue);
1533 1612
1534 res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); 1613 res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1);
1535 if (res) 1614 if (res)
1536 goto exit; 1615 goto exit;
1537 1616
@@ -1657,8 +1736,8 @@ restart:
1657 * 1736 *
1658 * Returns 0 on success, errno otherwise 1737 * Returns 0 on success, errno otherwise
1659 */ 1738 */
1660static int setsockopt(struct socket *sock, 1739static int setsockopt(struct socket *sock, int lvl, int opt, char __user *ov,
1661 int lvl, int opt, char __user *ov, unsigned int ol) 1740 unsigned int ol)
1662{ 1741{
1663 struct sock *sk = sock->sk; 1742 struct sock *sk = sock->sk;
1664 struct tipc_port *tport = tipc_sk_port(sk); 1743 struct tipc_port *tport = tipc_sk_port(sk);
@@ -1716,8 +1795,8 @@ static int setsockopt(struct socket *sock,
1716 * 1795 *
1717 * Returns 0 on success, errno otherwise 1796 * Returns 0 on success, errno otherwise
1718 */ 1797 */
1719static int getsockopt(struct socket *sock, 1798static int getsockopt(struct socket *sock, int lvl, int opt, char __user *ov,
1720 int lvl, int opt, char __user *ov, int __user *ol) 1799 int __user *ol)
1721{ 1800{
1722 struct sock *sk = sock->sk; 1801 struct sock *sk = sock->sk;
1723 struct tipc_port *tport = tipc_sk_port(sk); 1802 struct tipc_port *tport = tipc_sk_port(sk);
@@ -1841,13 +1920,20 @@ static const struct proto_ops stream_ops = {
1841static const struct net_proto_family tipc_family_ops = { 1920static const struct net_proto_family tipc_family_ops = {
1842 .owner = THIS_MODULE, 1921 .owner = THIS_MODULE,
1843 .family = AF_TIPC, 1922 .family = AF_TIPC,
1844 .create = tipc_create 1923 .create = tipc_sk_create
1845}; 1924};
1846 1925
1847static struct proto tipc_proto = { 1926static struct proto tipc_proto = {
1848 .name = "TIPC", 1927 .name = "TIPC",
1849 .owner = THIS_MODULE, 1928 .owner = THIS_MODULE,
1850 .obj_size = sizeof(struct tipc_sock) 1929 .obj_size = sizeof(struct tipc_sock),
1930 .sysctl_rmem = sysctl_tipc_rmem
1931};
1932
1933static struct proto tipc_proto_kern = {
1934 .name = "TIPC",
1935 .obj_size = sizeof(struct tipc_sock),
1936 .sysctl_rmem = sysctl_tipc_rmem
1851}; 1937};
1852 1938
1853/** 1939/**
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 6b42d47029af..d38bb45d82e9 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -41,33 +41,42 @@
41 41
42/** 42/**
43 * struct tipc_subscriber - TIPC network topology subscriber 43 * struct tipc_subscriber - TIPC network topology subscriber
44 * @port_ref: object reference to server port connecting to subscriber 44 * @conid: connection identifier to server connecting to subscriber
45 * @lock: pointer to spinlock controlling access to subscriber's server port 45 * @lock: controll access to subscriber
46 * @subscriber_list: adjacent subscribers in top. server's list of subscribers
47 * @subscription_list: list of subscription objects for this subscriber 46 * @subscription_list: list of subscription objects for this subscriber
48 */ 47 */
49struct tipc_subscriber { 48struct tipc_subscriber {
50 u32 port_ref; 49 int conid;
51 spinlock_t *lock; 50 spinlock_t lock;
52 struct list_head subscriber_list;
53 struct list_head subscription_list; 51 struct list_head subscription_list;
54}; 52};
55 53
56/** 54static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr,
57 * struct top_srv - TIPC network topology subscription service 55 void *usr_data, void *buf, size_t len);
58 * @setup_port: reference to TIPC port that handles subscription requests 56static void *subscr_named_msg_event(int conid);
59 * @subscription_count: number of active subscriptions (not subscribers!) 57static void subscr_conn_shutdown_event(int conid, void *usr_data);
60 * @subscriber_list: list of ports subscribing to service 58
61 * @lock: spinlock govering access to subscriber list 59static atomic_t subscription_count = ATOMIC_INIT(0);
62 */ 60
63struct top_srv { 61static struct sockaddr_tipc topsrv_addr __read_mostly = {
64 u32 setup_port; 62 .family = AF_TIPC,
65 atomic_t subscription_count; 63 .addrtype = TIPC_ADDR_NAMESEQ,
66 struct list_head subscriber_list; 64 .addr.nameseq.type = TIPC_TOP_SRV,
67 spinlock_t lock; 65 .addr.nameseq.lower = TIPC_TOP_SRV,
66 .addr.nameseq.upper = TIPC_TOP_SRV,
67 .scope = TIPC_NODE_SCOPE
68}; 68};
69 69
70static struct top_srv topsrv; 70static struct tipc_server topsrv __read_mostly = {
71 .saddr = &topsrv_addr,
72 .imp = TIPC_CRITICAL_IMPORTANCE,
73 .type = SOCK_SEQPACKET,
74 .max_rcvbuf_size = sizeof(struct tipc_subscr),
75 .name = "topology_server",
76 .tipc_conn_recvmsg = subscr_conn_msg_event,
77 .tipc_conn_new = subscr_named_msg_event,
78 .tipc_conn_shutdown = subscr_conn_shutdown_event,
79};
71 80
72/** 81/**
73 * htohl - convert value to endianness used by destination 82 * htohl - convert value to endianness used by destination
@@ -81,20 +90,13 @@ static u32 htohl(u32 in, int swap)
81 return swap ? swab32(in) : in; 90 return swap ? swab32(in) : in;
82} 91}
83 92
84/** 93static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
85 * subscr_send_event - send a message containing a tipc_event to the subscriber 94 u32 found_upper, u32 event, u32 port_ref,
86 *
87 * Note: Must not hold subscriber's server port lock, since tipc_send() will
88 * try to take the lock if the message is rejected and returned!
89 */
90static void subscr_send_event(struct tipc_subscription *sub,
91 u32 found_lower,
92 u32 found_upper,
93 u32 event,
94 u32 port_ref,
95 u32 node) 95 u32 node)
96{ 96{
97 struct iovec msg_sect; 97 struct tipc_subscriber *subscriber = sub->subscriber;
98 struct kvec msg_sect;
99 int ret;
98 100
99 msg_sect.iov_base = (void *)&sub->evt; 101 msg_sect.iov_base = (void *)&sub->evt;
100 msg_sect.iov_len = sizeof(struct tipc_event); 102 msg_sect.iov_len = sizeof(struct tipc_event);
@@ -104,7 +106,10 @@ static void subscr_send_event(struct tipc_subscription *sub,
104 sub->evt.found_upper = htohl(found_upper, sub->swap); 106 sub->evt.found_upper = htohl(found_upper, sub->swap);
105 sub->evt.port.ref = htohl(port_ref, sub->swap); 107 sub->evt.port.ref = htohl(port_ref, sub->swap);
106 sub->evt.port.node = htohl(node, sub->swap); 108 sub->evt.port.node = htohl(node, sub->swap);
107 tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len); 109 ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL,
110 msg_sect.iov_base, msg_sect.iov_len);
111 if (ret < 0)
112 pr_err("Sending subscription event failed, no memory\n");
108} 113}
109 114
110/** 115/**
@@ -112,10 +117,8 @@ static void subscr_send_event(struct tipc_subscription *sub,
112 * 117 *
113 * Returns 1 if there is overlap, otherwise 0. 118 * Returns 1 if there is overlap, otherwise 0.
114 */ 119 */
115int tipc_subscr_overlap(struct tipc_subscription *sub, 120int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
116 u32 found_lower,
117 u32 found_upper) 121 u32 found_upper)
118
119{ 122{
120 if (found_lower < sub->seq.lower) 123 if (found_lower < sub->seq.lower)
121 found_lower = sub->seq.lower; 124 found_lower = sub->seq.lower;
@@ -131,13 +134,9 @@ int tipc_subscr_overlap(struct tipc_subscription *sub,
131 * 134 *
132 * Protected by nameseq.lock in name_table.c 135 * Protected by nameseq.lock in name_table.c
133 */ 136 */
134void tipc_subscr_report_overlap(struct tipc_subscription *sub, 137void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
135 u32 found_lower, 138 u32 found_upper, u32 event, u32 port_ref,
136 u32 found_upper, 139 u32 node, int must)
137 u32 event,
138 u32 port_ref,
139 u32 node,
140 int must)
141{ 140{
142 if (!tipc_subscr_overlap(sub, found_lower, found_upper)) 141 if (!tipc_subscr_overlap(sub, found_lower, found_upper))
143 return; 142 return;
@@ -147,21 +146,24 @@ void tipc_subscr_report_overlap(struct tipc_subscription *sub,
147 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); 146 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node);
148} 147}
149 148
150/**
151 * subscr_timeout - subscription timeout has occurred
152 */
153static void subscr_timeout(struct tipc_subscription *sub) 149static void subscr_timeout(struct tipc_subscription *sub)
154{ 150{
155 struct tipc_port *server_port; 151 struct tipc_subscriber *subscriber = sub->subscriber;
152
153 /* The spin lock per subscriber is used to protect its members */
154 spin_lock_bh(&subscriber->lock);
156 155
157 /* Validate server port reference (in case subscriber is terminating) */ 156 /* Validate if the connection related to the subscriber is
158 server_port = tipc_port_lock(sub->server_ref); 157 * closed (in case subscriber is terminating)
159 if (server_port == NULL) 158 */
159 if (subscriber->conid == 0) {
160 spin_unlock_bh(&subscriber->lock);
160 return; 161 return;
162 }
161 163
162 /* Validate timeout (in case subscription is being cancelled) */ 164 /* Validate timeout (in case subscription is being cancelled) */
163 if (sub->timeout == TIPC_WAIT_FOREVER) { 165 if (sub->timeout == TIPC_WAIT_FOREVER) {
164 tipc_port_unlock(server_port); 166 spin_unlock_bh(&subscriber->lock);
165 return; 167 return;
166 } 168 }
167 169
@@ -171,8 +173,7 @@ static void subscr_timeout(struct tipc_subscription *sub)
171 /* Unlink subscription from subscriber */ 173 /* Unlink subscription from subscriber */
172 list_del(&sub->subscription_list); 174 list_del(&sub->subscription_list);
173 175
174 /* Release subscriber's server port */ 176 spin_unlock_bh(&subscriber->lock);
175 tipc_port_unlock(server_port);
176 177
177 /* Notify subscriber of timeout */ 178 /* Notify subscriber of timeout */
178 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, 179 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
@@ -181,64 +182,54 @@ static void subscr_timeout(struct tipc_subscription *sub)
181 /* Now destroy subscription */ 182 /* Now destroy subscription */
182 k_term_timer(&sub->timer); 183 k_term_timer(&sub->timer);
183 kfree(sub); 184 kfree(sub);
184 atomic_dec(&topsrv.subscription_count); 185 atomic_dec(&subscription_count);
185} 186}
186 187
187/** 188/**
188 * subscr_del - delete a subscription within a subscription list 189 * subscr_del - delete a subscription within a subscription list
189 * 190 *
190 * Called with subscriber port locked. 191 * Called with subscriber lock held.
191 */ 192 */
192static void subscr_del(struct tipc_subscription *sub) 193static void subscr_del(struct tipc_subscription *sub)
193{ 194{
194 tipc_nametbl_unsubscribe(sub); 195 tipc_nametbl_unsubscribe(sub);
195 list_del(&sub->subscription_list); 196 list_del(&sub->subscription_list);
196 kfree(sub); 197 kfree(sub);
197 atomic_dec(&topsrv.subscription_count); 198 atomic_dec(&subscription_count);
198} 199}
199 200
200/** 201/**
201 * subscr_terminate - terminate communication with a subscriber 202 * subscr_terminate - terminate communication with a subscriber
202 * 203 *
203 * Called with subscriber port locked. Routine must temporarily release lock 204 * Note: Must call it in process context since it might sleep.
204 * to enable subscription timeout routine(s) to finish without deadlocking;
205 * the lock is then reclaimed to allow caller to release it upon return.
206 * (This should work even in the unlikely event some other thread creates
207 * a new object reference in the interim that uses this lock; this routine will
208 * simply wait for it to be released, then claim it.)
209 */ 205 */
210static void subscr_terminate(struct tipc_subscriber *subscriber) 206static void subscr_terminate(struct tipc_subscriber *subscriber)
211{ 207{
212 u32 port_ref; 208 tipc_conn_terminate(&topsrv, subscriber->conid);
209}
210
211static void subscr_release(struct tipc_subscriber *subscriber)
212{
213 struct tipc_subscription *sub; 213 struct tipc_subscription *sub;
214 struct tipc_subscription *sub_temp; 214 struct tipc_subscription *sub_temp;
215 215
216 /* Invalidate subscriber reference */ 216 spin_lock_bh(&subscriber->lock);
217 port_ref = subscriber->port_ref;
218 subscriber->port_ref = 0;
219 spin_unlock_bh(subscriber->lock);
220 217
221 /* Sever connection to subscriber */ 218 /* Invalidate subscriber reference */
222 tipc_shutdown(port_ref); 219 subscriber->conid = 0;
223 tipc_deleteport(port_ref);
224 220
225 /* Destroy any existing subscriptions for subscriber */ 221 /* Destroy any existing subscriptions for subscriber */
226 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 222 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
227 subscription_list) { 223 subscription_list) {
228 if (sub->timeout != TIPC_WAIT_FOREVER) { 224 if (sub->timeout != TIPC_WAIT_FOREVER) {
225 spin_unlock_bh(&subscriber->lock);
229 k_cancel_timer(&sub->timer); 226 k_cancel_timer(&sub->timer);
230 k_term_timer(&sub->timer); 227 k_term_timer(&sub->timer);
228 spin_lock_bh(&subscriber->lock);
231 } 229 }
232 subscr_del(sub); 230 subscr_del(sub);
233 } 231 }
234 232 spin_unlock_bh(&subscriber->lock);
235 /* Remove subscriber from topology server's subscriber list */
236 spin_lock_bh(&topsrv.lock);
237 list_del(&subscriber->subscriber_list);
238 spin_unlock_bh(&topsrv.lock);
239
240 /* Reclaim subscriber lock */
241 spin_lock_bh(subscriber->lock);
242 233
243 /* Now destroy subscriber */ 234 /* Now destroy subscriber */
244 kfree(subscriber); 235 kfree(subscriber);
@@ -247,7 +238,7 @@ static void subscr_terminate(struct tipc_subscriber *subscriber)
247/** 238/**
248 * subscr_cancel - handle subscription cancellation request 239 * subscr_cancel - handle subscription cancellation request
249 * 240 *
250 * Called with subscriber port locked. Routine must temporarily release lock 241 * Called with subscriber lock held. Routine must temporarily release lock
251 * to enable the subscription timeout routine to finish without deadlocking; 242 * to enable the subscription timeout routine to finish without deadlocking;
252 * the lock is then reclaimed to allow caller to release it upon return. 243 * the lock is then reclaimed to allow caller to release it upon return.
253 * 244 *
@@ -274,10 +265,10 @@ static void subscr_cancel(struct tipc_subscr *s,
274 /* Cancel subscription timer (if used), then delete subscription */ 265 /* Cancel subscription timer (if used), then delete subscription */
275 if (sub->timeout != TIPC_WAIT_FOREVER) { 266 if (sub->timeout != TIPC_WAIT_FOREVER) {
276 sub->timeout = TIPC_WAIT_FOREVER; 267 sub->timeout = TIPC_WAIT_FOREVER;
277 spin_unlock_bh(subscriber->lock); 268 spin_unlock_bh(&subscriber->lock);
278 k_cancel_timer(&sub->timer); 269 k_cancel_timer(&sub->timer);
279 k_term_timer(&sub->timer); 270 k_term_timer(&sub->timer);
280 spin_lock_bh(subscriber->lock); 271 spin_lock_bh(&subscriber->lock);
281 } 272 }
282 subscr_del(sub); 273 subscr_del(sub);
283} 274}
@@ -285,7 +276,7 @@ static void subscr_cancel(struct tipc_subscr *s,
285/** 276/**
286 * subscr_subscribe - create subscription for subscriber 277 * subscr_subscribe - create subscription for subscriber
287 * 278 *
288 * Called with subscriber port locked. 279 * Called with subscriber lock held.
289 */ 280 */
290static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, 281static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,
291 struct tipc_subscriber *subscriber) 282 struct tipc_subscriber *subscriber)
@@ -304,7 +295,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,
304 } 295 }
305 296
306 /* Refuse subscription if global limit exceeded */ 297 /* Refuse subscription if global limit exceeded */
307 if (atomic_read(&topsrv.subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { 298 if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
308 pr_warn("Subscription rejected, limit reached (%u)\n", 299 pr_warn("Subscription rejected, limit reached (%u)\n",
309 TIPC_MAX_SUBSCRIPTIONS); 300 TIPC_MAX_SUBSCRIPTIONS);
310 subscr_terminate(subscriber); 301 subscr_terminate(subscriber);
@@ -335,10 +326,10 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,
335 } 326 }
336 INIT_LIST_HEAD(&sub->nameseq_list); 327 INIT_LIST_HEAD(&sub->nameseq_list);
337 list_add(&sub->subscription_list, &subscriber->subscription_list); 328 list_add(&sub->subscription_list, &subscriber->subscription_list);
338 sub->server_ref = subscriber->port_ref; 329 sub->subscriber = subscriber;
339 sub->swap = swap; 330 sub->swap = swap;
340 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 331 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
341 atomic_inc(&topsrv.subscription_count); 332 atomic_inc(&subscription_count);
342 if (sub->timeout != TIPC_WAIT_FOREVER) { 333 if (sub->timeout != TIPC_WAIT_FOREVER) {
343 k_init_timer(&sub->timer, 334 k_init_timer(&sub->timer,
344 (Handler)subscr_timeout, (unsigned long)sub); 335 (Handler)subscr_timeout, (unsigned long)sub);
@@ -348,196 +339,51 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s,
348 return sub; 339 return sub;
349} 340}
350 341
351/** 342/* Handle one termination request for the subscriber */
352 * subscr_conn_shutdown_event - handle termination request from subscriber 343static void subscr_conn_shutdown_event(int conid, void *usr_data)
353 *
354 * Called with subscriber's server port unlocked.
355 */
356static void subscr_conn_shutdown_event(void *usr_handle,
357 u32 port_ref,
358 struct sk_buff **buf,
359 unsigned char const *data,
360 unsigned int size,
361 int reason)
362{ 344{
363 struct tipc_subscriber *subscriber = usr_handle; 345 subscr_release((struct tipc_subscriber *)usr_data);
364 spinlock_t *subscriber_lock;
365
366 if (tipc_port_lock(port_ref) == NULL)
367 return;
368
369 subscriber_lock = subscriber->lock;
370 subscr_terminate(subscriber);
371 spin_unlock_bh(subscriber_lock);
372} 346}
373 347
374/** 348/* Handle one request to create a new subscription for the subscriber */
375 * subscr_conn_msg_event - handle new subscription request from subscriber 349static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr,
376 * 350 void *usr_data, void *buf, size_t len)
377 * Called with subscriber's server port unlocked.
378 */
379static void subscr_conn_msg_event(void *usr_handle,
380 u32 port_ref,
381 struct sk_buff **buf,
382 const unchar *data,
383 u32 size)
384{ 351{
385 struct tipc_subscriber *subscriber = usr_handle; 352 struct tipc_subscriber *subscriber = usr_data;
386 spinlock_t *subscriber_lock;
387 struct tipc_subscription *sub; 353 struct tipc_subscription *sub;
388 354
389 /* 355 spin_lock_bh(&subscriber->lock);
390 * Lock subscriber's server port (& make a local copy of lock pointer, 356 sub = subscr_subscribe((struct tipc_subscr *)buf, subscriber);
391 * in case subscriber is deleted while processing subscription request) 357 if (sub)
392 */ 358 tipc_nametbl_subscribe(sub);
393 if (tipc_port_lock(port_ref) == NULL) 359 spin_unlock_bh(&subscriber->lock);
394 return;
395
396 subscriber_lock = subscriber->lock;
397
398 if (size != sizeof(struct tipc_subscr)) {
399 subscr_terminate(subscriber);
400 spin_unlock_bh(subscriber_lock);
401 } else {
402 sub = subscr_subscribe((struct tipc_subscr *)data, subscriber);
403 spin_unlock_bh(subscriber_lock);
404 if (sub != NULL) {
405
406 /*
407 * We must release the server port lock before adding a
408 * subscription to the name table since TIPC needs to be
409 * able to (re)acquire the port lock if an event message
410 * issued by the subscription process is rejected and
411 * returned. The subscription cannot be deleted while
412 * it is being added to the name table because:
413 * a) the single-threading of the native API port code
414 * ensures the subscription cannot be cancelled and
415 * the subscriber connection cannot be broken, and
416 * b) the name table lock ensures the subscription
417 * timeout code cannot delete the subscription,
418 * so the subscription object is still protected.
419 */
420 tipc_nametbl_subscribe(sub);
421 }
422 }
423} 360}
424 361
425/** 362
426 * subscr_named_msg_event - handle request to establish a new subscriber 363/* Handle one request to establish a new subscriber */
427 */ 364static void *subscr_named_msg_event(int conid)
428static void subscr_named_msg_event(void *usr_handle,
429 u32 port_ref,
430 struct sk_buff **buf,
431 const unchar *data,
432 u32 size,
433 u32 importance,
434 struct tipc_portid const *orig,
435 struct tipc_name_seq const *dest)
436{ 365{
437 struct tipc_subscriber *subscriber; 366 struct tipc_subscriber *subscriber;
438 u32 server_port_ref;
439 367
440 /* Create subscriber object */ 368 /* Create subscriber object */
441 subscriber = kzalloc(sizeof(struct tipc_subscriber), GFP_ATOMIC); 369 subscriber = kzalloc(sizeof(struct tipc_subscriber), GFP_ATOMIC);
442 if (subscriber == NULL) { 370 if (subscriber == NULL) {
443 pr_warn("Subscriber rejected, no memory\n"); 371 pr_warn("Subscriber rejected, no memory\n");
444 return; 372 return NULL;
445 } 373 }
446 INIT_LIST_HEAD(&subscriber->subscription_list); 374 INIT_LIST_HEAD(&subscriber->subscription_list);
447 INIT_LIST_HEAD(&subscriber->subscriber_list); 375 subscriber->conid = conid;
448 376 spin_lock_init(&subscriber->lock);
449 /* Create server port & establish connection to subscriber */
450 tipc_createport(subscriber,
451 importance,
452 NULL,
453 NULL,
454 subscr_conn_shutdown_event,
455 NULL,
456 NULL,
457 subscr_conn_msg_event,
458 NULL,
459 &subscriber->port_ref);
460 if (subscriber->port_ref == 0) {
461 pr_warn("Subscriber rejected, unable to create port\n");
462 kfree(subscriber);
463 return;
464 }
465 tipc_connect(subscriber->port_ref, orig);
466
467 /* Lock server port (& save lock address for future use) */
468 subscriber->lock = tipc_port_lock(subscriber->port_ref)->lock;
469
470 /* Add subscriber to topology server's subscriber list */
471 spin_lock_bh(&topsrv.lock);
472 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list);
473 spin_unlock_bh(&topsrv.lock);
474
475 /* Unlock server port */
476 server_port_ref = subscriber->port_ref;
477 spin_unlock_bh(subscriber->lock);
478
479 /* Send an ACK- to complete connection handshaking */
480 tipc_send(server_port_ref, 0, NULL, 0);
481 377
482 /* Handle optional subscription request */ 378 return (void *)subscriber;
483 if (size != 0) {
484 subscr_conn_msg_event(subscriber, server_port_ref,
485 buf, data, size);
486 }
487} 379}
488 380
489int tipc_subscr_start(void) 381int tipc_subscr_start(void)
490{ 382{
491 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; 383 return tipc_server_start(&topsrv);
492 int res;
493
494 spin_lock_init(&topsrv.lock);
495 INIT_LIST_HEAD(&topsrv.subscriber_list);
496
497 res = tipc_createport(NULL,
498 TIPC_CRITICAL_IMPORTANCE,
499 NULL,
500 NULL,
501 NULL,
502 NULL,
503 subscr_named_msg_event,
504 NULL,
505 NULL,
506 &topsrv.setup_port);
507 if (res)
508 goto failed;
509
510 res = tipc_publish(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
511 if (res) {
512 tipc_deleteport(topsrv.setup_port);
513 topsrv.setup_port = 0;
514 goto failed;
515 }
516
517 return 0;
518
519failed:
520 pr_err("Failed to create subscription service\n");
521 return res;
522} 384}
523 385
524void tipc_subscr_stop(void) 386void tipc_subscr_stop(void)
525{ 387{
526 struct tipc_subscriber *subscriber; 388 tipc_server_stop(&topsrv);
527 struct tipc_subscriber *subscriber_temp;
528 spinlock_t *subscriber_lock;
529
530 if (topsrv.setup_port) {
531 tipc_deleteport(topsrv.setup_port);
532 topsrv.setup_port = 0;
533
534 list_for_each_entry_safe(subscriber, subscriber_temp,
535 &topsrv.subscriber_list,
536 subscriber_list) {
537 subscriber_lock = subscriber->lock;
538 spin_lock_bh(subscriber_lock);
539 subscr_terminate(subscriber);
540 spin_unlock_bh(subscriber_lock);
541 }
542 }
543} 389}
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 218d2e07f0cc..393e417bee3f 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -2,7 +2,7 @@
2 * net/tipc/subscr.h: Include file for TIPC network topology service 2 * net/tipc/subscr.h: Include file for TIPC network topology service
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2012-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,10 +37,14 @@
37#ifndef _TIPC_SUBSCR_H 37#ifndef _TIPC_SUBSCR_H
38#define _TIPC_SUBSCR_H 38#define _TIPC_SUBSCR_H
39 39
40#include "server.h"
41
40struct tipc_subscription; 42struct tipc_subscription;
43struct tipc_subscriber;
41 44
42/** 45/**
43 * struct tipc_subscription - TIPC network topology subscription object 46 * struct tipc_subscription - TIPC network topology subscription object
47 * @subscriber: pointer to its subscriber
44 * @seq: name sequence associated with subscription 48 * @seq: name sequence associated with subscription
45 * @timeout: duration of subscription (in ms) 49 * @timeout: duration of subscription (in ms)
46 * @filter: event filtering to be done for subscription 50 * @filter: event filtering to be done for subscription
@@ -52,28 +56,23 @@ struct tipc_subscription;
52 * @evt: template for events generated by subscription 56 * @evt: template for events generated by subscription
53 */ 57 */
54struct tipc_subscription { 58struct tipc_subscription {
59 struct tipc_subscriber *subscriber;
55 struct tipc_name_seq seq; 60 struct tipc_name_seq seq;
56 u32 timeout; 61 u32 timeout;
57 u32 filter; 62 u32 filter;
58 struct timer_list timer; 63 struct timer_list timer;
59 struct list_head nameseq_list; 64 struct list_head nameseq_list;
60 struct list_head subscription_list; 65 struct list_head subscription_list;
61 u32 server_ref;
62 int swap; 66 int swap;
63 struct tipc_event evt; 67 struct tipc_event evt;
64}; 68};
65 69
66int tipc_subscr_overlap(struct tipc_subscription *sub, 70int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
67 u32 found_lower,
68 u32 found_upper); 71 u32 found_upper);
69 72
70void tipc_subscr_report_overlap(struct tipc_subscription *sub, 73void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
71 u32 found_lower, 74 u32 found_upper, u32 event, u32 port_ref,
72 u32 found_upper, 75 u32 node, int must);
73 u32 event,
74 u32 port_ref,
75 u32 node,
76 int must_report);
77 76
78int tipc_subscr_start(void); 77int tipc_subscr_start(void);
79 78
diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c
new file mode 100644
index 000000000000..f3fef93325a8
--- /dev/null
+++ b/net/tipc/sysctl.c
@@ -0,0 +1,64 @@
1/*
2 * net/tipc/sysctl.c: sysctl interface to TIPC subsystem
3 *
4 * Copyright (c) 2013, Wind River Systems
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "core.h"
37
38#include <linux/sysctl.h>
39
40static struct ctl_table_header *tipc_ctl_hdr;
41
42static struct ctl_table tipc_table[] = {
43 {
44 .procname = "tipc_rmem",
45 .data = &sysctl_tipc_rmem,
46 .maxlen = sizeof(sysctl_tipc_rmem),
47 .mode = 0644,
48 .proc_handler = proc_dointvec,
49 },
50 {}
51};
52
53int tipc_register_sysctl(void)
54{
55 tipc_ctl_hdr = register_net_sysctl(&init_net, "net/tipc", tipc_table);
56 if (tipc_ctl_hdr == NULL)
57 return -ENOMEM;
58 return 0;
59}
60
61void tipc_unregister_sysctl(void)
62{
63 unregister_net_sysctl_table(tipc_ctl_hdr);
64}