aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:41 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:41 -0400
commit5aa8dbbd5f9ae6ec6f5ab88596a29a5b5d4caf31 (patch)
treedd7368248aaf26d2476a54a345ede9f0db44eeb9 /net/tipc
parentf9474ddfaa009ead12bba44fa8fd49dc4536a124 (diff)
parent301bae56f21295a4ba71367818d80735687f11ac (diff)
Merge branch 'tipc-next'
Jon Maloy says: ==================== tipc: Merge port and socket layer code After the removal of the TIPC native interface, there is no reason to keep a distinction between a "generic" port layer and a "specific" socket layer in the code. Throughout the last months, we have posted several series that aimed at facilitating removal of the port layer, and in particular the port_lock spinlock, which in reality duplicates the role normally kept by lock_sock()/bh_lock_sock(). In this series, we finalize this work, by making a significant number of changes to the link, node, port and socket code, all with the aim of reducing dependencies between the layers. In the final commits, we then remove the port spinlock, port.c and port.h altogether. After this series, we have a socket layer that has only few dependencies to the rest of the stack, so that it should be possible to continue cleanups of its code without significantly affecting other code. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Makefile2
-rw-r--r--net/tipc/bcast.c8
-rw-r--r--net/tipc/config.c4
-rw-r--r--net/tipc/core.c9
-rw-r--r--net/tipc/core.h5
-rw-r--r--net/tipc/link.c120
-rw-r--r--net/tipc/link.h7
-rw-r--r--net/tipc/msg.c38
-rw-r--r--net/tipc/msg.h5
-rw-r--r--net/tipc/name_table.c1
-rw-r--r--net/tipc/net.c3
-rw-r--r--net/tipc/node.c90
-rw-r--r--net/tipc/node.h7
-rw-r--r--net/tipc/port.c514
-rw-r--r--net/tipc/port.h190
-rw-r--r--net/tipc/ref.c266
-rw-r--r--net/tipc/ref.h48
-rw-r--r--net/tipc/socket.c884
-rw-r--r--net/tipc/socket.h55
-rw-r--r--net/tipc/subscr.c1
20 files changed, 956 insertions, 1301 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index a080c66d819a..b8a13caad59a 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_TIPC) := tipc.o
7tipc-y += addr.o bcast.o bearer.o config.o \ 7tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o link.o discover.o msg.o \ 8 core.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 \
11 socket.o log.o eth_media.o server.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
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index dd13bfa09333..b2bbe69b2554 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -37,7 +37,6 @@
37 37
38#include "core.h" 38#include "core.h"
39#include "link.h" 39#include "link.h"
40#include "port.h"
41#include "socket.h" 40#include "socket.h"
42#include "msg.h" 41#include "msg.h"
43#include "bcast.h" 42#include "bcast.h"
@@ -300,8 +299,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
300 tipc_link_push_queue(bcl); 299 tipc_link_push_queue(bcl);
301 bclink_set_last_sent(); 300 bclink_set_last_sent();
302 } 301 }
303 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 302 if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
304 tipc_link_wakeup_ports(bcl, 0); 303 bclink->node.action_flags |= TIPC_WAKEUP_USERS;
305exit: 304exit:
306 tipc_bclink_unlock(); 305 tipc_bclink_unlock();
307} 306}
@@ -840,9 +839,10 @@ int tipc_bclink_init(void)
840 sprintf(bcbearer->media.name, "tipc-broadcast"); 839 sprintf(bcbearer->media.name, "tipc-broadcast");
841 840
842 spin_lock_init(&bclink->lock); 841 spin_lock_init(&bclink->lock);
843 INIT_LIST_HEAD(&bcl->waiting_ports); 842 __skb_queue_head_init(&bcl->waiting_sks);
844 bcl->next_out_no = 1; 843 bcl->next_out_no = 1;
845 spin_lock_init(&bclink->node.lock); 844 spin_lock_init(&bclink->node.lock);
845 __skb_queue_head_init(&bclink->node.waiting_sks);
846 bcl->owner = &bclink->node; 846 bcl->owner = &bclink->node;
847 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; 847 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
848 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); 848 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 2b42403ad33a..876f4c6a2631 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "port.h" 38#include "socket.h"
39#include "name_table.h" 39#include "name_table.h"
40#include "config.h" 40#include "config.h"
41#include "server.h" 41#include "server.h"
@@ -266,7 +266,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
266 rep_tlv_buf = tipc_media_get_names(); 266 rep_tlv_buf = tipc_media_get_names();
267 break; 267 break;
268 case TIPC_CMD_SHOW_PORTS: 268 case TIPC_CMD_SHOW_PORTS:
269 rep_tlv_buf = tipc_port_get_ports(); 269 rep_tlv_buf = tipc_sk_socks_show();
270 break; 270 break;
271 case TIPC_CMD_SHOW_STATS: 271 case TIPC_CMD_SHOW_STATS:
272 rep_tlv_buf = tipc_show_stats(); 272 rep_tlv_buf = tipc_show_stats();
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 676d18015dd8..a5737b8407dd 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -35,11 +35,10 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "ref.h"
39#include "name_table.h" 38#include "name_table.h"
40#include "subscr.h" 39#include "subscr.h"
41#include "config.h" 40#include "config.h"
42#include "port.h" 41#include "socket.h"
43 42
44#include <linux/module.h> 43#include <linux/module.h>
45 44
@@ -85,7 +84,7 @@ static void tipc_core_stop(void)
85 tipc_netlink_stop(); 84 tipc_netlink_stop();
86 tipc_subscr_stop(); 85 tipc_subscr_stop();
87 tipc_nametbl_stop(); 86 tipc_nametbl_stop();
88 tipc_ref_table_stop(); 87 tipc_sk_ref_table_stop();
89 tipc_socket_stop(); 88 tipc_socket_stop();
90 tipc_unregister_sysctl(); 89 tipc_unregister_sysctl();
91} 90}
@@ -99,7 +98,7 @@ static int tipc_core_start(void)
99 98
100 get_random_bytes(&tipc_random, sizeof(tipc_random)); 99 get_random_bytes(&tipc_random, sizeof(tipc_random));
101 100
102 err = tipc_ref_table_init(tipc_max_ports, tipc_random); 101 err = tipc_sk_ref_table_init(tipc_max_ports, tipc_random);
103 if (err) 102 if (err)
104 goto out_reftbl; 103 goto out_reftbl;
105 104
@@ -139,7 +138,7 @@ out_socket:
139out_netlink: 138out_netlink:
140 tipc_nametbl_stop(); 139 tipc_nametbl_stop();
141out_nametbl: 140out_nametbl:
142 tipc_ref_table_stop(); 141 tipc_sk_ref_table_stop();
143out_reftbl: 142out_reftbl:
144 return err; 143 return err;
145} 144}
diff --git a/net/tipc/core.h b/net/tipc/core.h
index bb26ed1ee966..d2607a8e2b80 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -187,8 +187,11 @@ static inline void k_term_timer(struct timer_list *timer)
187 187
188struct tipc_skb_cb { 188struct tipc_skb_cb {
189 void *handle; 189 void *handle;
190 bool deferred;
191 struct sk_buff *tail; 190 struct sk_buff *tail;
191 bool deferred;
192 bool wakeup_pending;
193 u16 chain_sz;
194 u16 chain_imp;
192}; 195};
193 196
194#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) 197#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
diff --git a/net/tipc/link.c b/net/tipc/link.c
index fb1485dc6736..65410e18b8a6 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -36,7 +36,6 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "link.h" 38#include "link.h"
39#include "port.h"
40#include "socket.h" 39#include "socket.h"
41#include "name_distr.h" 40#include "name_distr.h"
42#include "discover.h" 41#include "discover.h"
@@ -275,7 +274,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
275 link_init_max_pkt(l_ptr); 274 link_init_max_pkt(l_ptr);
276 275
277 l_ptr->next_out_no = 1; 276 l_ptr->next_out_no = 1;
278 INIT_LIST_HEAD(&l_ptr->waiting_ports); 277 __skb_queue_head_init(&l_ptr->waiting_sks);
279 278
280 link_reset_statistics(l_ptr); 279 link_reset_statistics(l_ptr);
281 280
@@ -322,66 +321,47 @@ void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down)
322} 321}
323 322
324/** 323/**
325 * link_schedule_port - schedule port for deferred sending 324 * link_schedule_user - schedule user for wakeup after congestion
326 * @l_ptr: pointer to link 325 * @link: congested link
327 * @origport: reference to sending port 326 * @oport: sending port
328 * @sz: amount of data to be sent 327 * @chain_sz: size of buffer chain that was attempted sent
329 * 328 * @imp: importance of message attempted sent
330 * Schedules port for renewed sending of messages after link congestion 329 * Create pseudo msg to send back to user when congestion abates
331 * has abated.
332 */ 330 */
333static int link_schedule_port(struct tipc_link *l_ptr, u32 origport, u32 sz) 331static bool link_schedule_user(struct tipc_link *link, u32 oport,
332 uint chain_sz, uint imp)
334{ 333{
335 struct tipc_port *p_ptr; 334 struct sk_buff *buf;
336 struct tipc_sock *tsk;
337 335
338 spin_lock_bh(&tipc_port_list_lock); 336 buf = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, tipc_own_addr,
339 p_ptr = tipc_port_lock(origport); 337 tipc_own_addr, oport, 0, 0);
340 if (p_ptr) { 338 if (!buf)
341 if (!list_empty(&p_ptr->wait_list)) 339 return false;
342 goto exit; 340 TIPC_SKB_CB(buf)->chain_sz = chain_sz;
343 tsk = tipc_port_to_sock(p_ptr); 341 TIPC_SKB_CB(buf)->chain_imp = imp;
344 tsk->link_cong = 1; 342 __skb_queue_tail(&link->waiting_sks, buf);
345 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); 343 link->stats.link_congs++;
346 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 344 return true;
347 l_ptr->stats.link_congs++;
348exit:
349 tipc_port_unlock(p_ptr);
350 }
351 spin_unlock_bh(&tipc_port_list_lock);
352 return -ELINKCONG;
353} 345}
354 346
355void tipc_link_wakeup_ports(struct tipc_link *l_ptr, int all) 347/**
348 * link_prepare_wakeup - prepare users for wakeup after congestion
349 * @link: congested link
350 * Move a number of waiting users, as permitted by available space in
351 * the send queue, from link wait queue to node wait queue for wakeup
352 */
353static void link_prepare_wakeup(struct tipc_link *link)
356{ 354{
357 struct tipc_port *p_ptr; 355 struct sk_buff_head *wq = &link->waiting_sks;
358 struct tipc_sock *tsk; 356 struct sk_buff *buf;
359 struct tipc_port *temp_p_ptr; 357 uint pend_qsz = link->out_queue_size;
360 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; 358
361 359 for (buf = skb_peek(wq); buf; buf = skb_peek(wq)) {
362 if (all) 360 if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(buf)->chain_imp])
363 win = 100000;
364 if (win <= 0)
365 return;
366 if (!spin_trylock_bh(&tipc_port_list_lock))
367 return;
368 if (link_congested(l_ptr))
369 goto exit;
370 list_for_each_entry_safe(p_ptr, temp_p_ptr, &l_ptr->waiting_ports,
371 wait_list) {
372 if (win <= 0)
373 break; 361 break;
374 tsk = tipc_port_to_sock(p_ptr); 362 pend_qsz += TIPC_SKB_CB(buf)->chain_sz;
375 list_del_init(&p_ptr->wait_list); 363 __skb_queue_tail(&link->owner->waiting_sks, __skb_dequeue(wq));
376 spin_lock_bh(p_ptr->lock);
377 tsk->link_cong = 0;
378 tipc_sock_wakeup(tsk);
379 win -= p_ptr->waiting_pkts;
380 spin_unlock_bh(p_ptr->lock);
381 } 364 }
382
383exit:
384 spin_unlock_bh(&tipc_port_list_lock);
385} 365}
386 366
387/** 367/**
@@ -423,6 +403,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
423 u32 prev_state = l_ptr->state; 403 u32 prev_state = l_ptr->state;
424 u32 checkpoint = l_ptr->next_in_no; 404 u32 checkpoint = l_ptr->next_in_no;
425 int was_active_link = tipc_link_is_active(l_ptr); 405 int was_active_link = tipc_link_is_active(l_ptr);
406 struct tipc_node *owner = l_ptr->owner;
426 407
427 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff)); 408 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
428 409
@@ -450,9 +431,10 @@ void tipc_link_reset(struct tipc_link *l_ptr)
450 kfree_skb(l_ptr->proto_msg_queue); 431 kfree_skb(l_ptr->proto_msg_queue);
451 l_ptr->proto_msg_queue = NULL; 432 l_ptr->proto_msg_queue = NULL;
452 kfree_skb_list(l_ptr->oldest_deferred_in); 433 kfree_skb_list(l_ptr->oldest_deferred_in);
453 if (!list_empty(&l_ptr->waiting_ports)) 434 if (!skb_queue_empty(&l_ptr->waiting_sks)) {
454 tipc_link_wakeup_ports(l_ptr, 1); 435 skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
455 436 owner->action_flags |= TIPC_WAKEUP_USERS;
437 }
456 l_ptr->retransm_queue_head = 0; 438 l_ptr->retransm_queue_head = 0;
457 l_ptr->retransm_queue_size = 0; 439 l_ptr->retransm_queue_size = 0;
458 l_ptr->last_out = NULL; 440 l_ptr->last_out = NULL;
@@ -688,19 +670,23 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
688static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf) 670static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf)
689{ 671{
690 struct tipc_msg *msg = buf_msg(buf); 672 struct tipc_msg *msg = buf_msg(buf);
691 uint psz = msg_size(msg);
692 uint imp = tipc_msg_tot_importance(msg); 673 uint imp = tipc_msg_tot_importance(msg);
693 u32 oport = msg_tot_origport(msg); 674 u32 oport = msg_tot_origport(msg);
694 675
695 if (likely(imp <= TIPC_CRITICAL_IMPORTANCE)) { 676 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
696 if (!msg_errcode(msg) && !msg_reroute_cnt(msg)) {
697 link_schedule_port(link, oport, psz);
698 return -ELINKCONG;
699 }
700 } else {
701 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name); 677 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name);
702 tipc_link_reset(link); 678 tipc_link_reset(link);
679 goto drop;
703 } 680 }
681 if (unlikely(msg_errcode(msg)))
682 goto drop;
683 if (unlikely(msg_reroute_cnt(msg)))
684 goto drop;
685 if (TIPC_SKB_CB(buf)->wakeup_pending)
686 return -ELINKCONG;
687 if (link_schedule_user(link, oport, TIPC_SKB_CB(buf)->chain_sz, imp))
688 return -ELINKCONG;
689drop:
704 kfree_skb_list(buf); 690 kfree_skb_list(buf);
705 return -EHOSTUNREACH; 691 return -EHOSTUNREACH;
706} 692}
@@ -1202,8 +1188,10 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
1202 if (unlikely(l_ptr->next_out)) 1188 if (unlikely(l_ptr->next_out))
1203 tipc_link_push_queue(l_ptr); 1189 tipc_link_push_queue(l_ptr);
1204 1190
1205 if (unlikely(!list_empty(&l_ptr->waiting_ports))) 1191 if (released && !skb_queue_empty(&l_ptr->waiting_sks)) {
1206 tipc_link_wakeup_ports(l_ptr, 0); 1192 link_prepare_wakeup(l_ptr);
1193 l_ptr->owner->action_flags |= TIPC_WAKEUP_USERS;
1194 }
1207 1195
1208 /* Process the incoming packet */ 1196 /* Process the incoming packet */
1209 if (unlikely(!link_working_working(l_ptr))) { 1197 if (unlikely(!link_working_working(l_ptr))) {
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 782983ccd323..b567a3427fda 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/link.h: Include file for TIPC link code 2 * net/tipc/link.h: Include file for TIPC link code
3 * 3 *
4 * Copyright (c) 1995-2006, 2013, Ericsson AB 4 * Copyright (c) 1995-2006, 2013-2014, Ericsson AB
5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -133,7 +133,7 @@ struct tipc_stats {
133 * @retransm_queue_size: number of messages to retransmit 133 * @retransm_queue_size: number of messages to retransmit
134 * @retransm_queue_head: sequence number of first message to retransmit 134 * @retransm_queue_head: sequence number of first message to retransmit
135 * @next_out: ptr to first unsent outbound message in queue 135 * @next_out: ptr to first unsent outbound message in queue
136 * @waiting_ports: linked list of ports waiting for link congestion to abate 136 * @waiting_sks: linked list of sockets waiting for link congestion to abate
137 * @long_msg_seq_no: next identifier to use for outbound fragmented messages 137 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
138 * @reasm_buf: head of partially reassembled inbound message fragments 138 * @reasm_buf: head of partially reassembled inbound message fragments
139 * @stats: collects statistics regarding link activity 139 * @stats: collects statistics regarding link activity
@@ -194,7 +194,7 @@ struct tipc_link {
194 u32 retransm_queue_size; 194 u32 retransm_queue_size;
195 u32 retransm_queue_head; 195 u32 retransm_queue_head;
196 struct sk_buff *next_out; 196 struct sk_buff *next_out;
197 struct list_head waiting_ports; 197 struct sk_buff_head waiting_sks;
198 198
199 /* Fragmentation/reassembly */ 199 /* Fragmentation/reassembly */
200 u32 long_msg_seq_no; 200 u32 long_msg_seq_no;
@@ -235,7 +235,6 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
235void tipc_link_push_queue(struct tipc_link *l_ptr); 235void tipc_link_push_queue(struct tipc_link *l_ptr);
236u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, 236u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
237 struct sk_buff *buf); 237 struct sk_buff *buf);
238void tipc_link_wakeup_ports(struct tipc_link *l_ptr, int all);
239void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); 238void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
240void tipc_link_retransmit(struct tipc_link *l_ptr, 239void tipc_link_retransmit(struct tipc_link *l_ptr,
241 struct sk_buff *start, u32 retransmits); 240 struct sk_buff *start, u32 retransmits);
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 9680be6d388a..74745a47d72a 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -56,8 +56,35 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
56 msg_set_size(m, hsize); 56 msg_set_size(m, hsize);
57 msg_set_prevnode(m, tipc_own_addr); 57 msg_set_prevnode(m, tipc_own_addr);
58 msg_set_type(m, type); 58 msg_set_type(m, type);
59 msg_set_orignode(m, tipc_own_addr); 59 if (hsize > SHORT_H_SIZE) {
60 msg_set_destnode(m, destnode); 60 msg_set_orignode(m, tipc_own_addr);
61 msg_set_destnode(m, destnode);
62 }
63}
64
65struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
66 uint data_sz, u32 dnode, u32 onode,
67 u32 dport, u32 oport, int errcode)
68{
69 struct tipc_msg *msg;
70 struct sk_buff *buf;
71
72 buf = tipc_buf_acquire(hdr_sz + data_sz);
73 if (unlikely(!buf))
74 return NULL;
75
76 msg = buf_msg(buf);
77 tipc_msg_init(msg, user, type, hdr_sz, dnode);
78 msg_set_size(msg, hdr_sz + data_sz);
79 msg_set_prevnode(msg, onode);
80 msg_set_origport(msg, oport);
81 msg_set_destport(msg, dport);
82 msg_set_errcode(msg, errcode);
83 if (hdr_sz > SHORT_H_SIZE) {
84 msg_set_orignode(msg, onode);
85 msg_set_destnode(msg, dnode);
86 }
87 return buf;
61} 88}
62 89
63/* tipc_buf_append(): Append a buffer to the fragment list of another buffer 90/* tipc_buf_append(): Append a buffer to the fragment list of another buffer
@@ -155,7 +182,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
155 struct sk_buff *buf, *prev; 182 struct sk_buff *buf, *prev;
156 char *pktpos; 183 char *pktpos;
157 int rc; 184 int rc;
158 185 uint chain_sz = 0;
159 msg_set_size(mhdr, msz); 186 msg_set_size(mhdr, msz);
160 187
161 /* No fragmentation needed? */ 188 /* No fragmentation needed? */
@@ -166,6 +193,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
166 return -ENOMEM; 193 return -ENOMEM;
167 skb_copy_to_linear_data(buf, mhdr, mhsz); 194 skb_copy_to_linear_data(buf, mhdr, mhsz);
168 pktpos = buf->data + mhsz; 195 pktpos = buf->data + mhsz;
196 TIPC_SKB_CB(buf)->chain_sz = 1;
169 if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz)) 197 if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
170 return dsz; 198 return dsz;
171 rc = -EFAULT; 199 rc = -EFAULT;
@@ -182,6 +210,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
182 *chain = buf = tipc_buf_acquire(pktmax); 210 *chain = buf = tipc_buf_acquire(pktmax);
183 if (!buf) 211 if (!buf)
184 return -ENOMEM; 212 return -ENOMEM;
213 chain_sz = 1;
185 pktpos = buf->data; 214 pktpos = buf->data;
186 skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); 215 skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
187 pktpos += INT_H_SIZE; 216 pktpos += INT_H_SIZE;
@@ -215,6 +244,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
215 rc = -ENOMEM; 244 rc = -ENOMEM;
216 goto error; 245 goto error;
217 } 246 }
247 chain_sz++;
218 prev->next = buf; 248 prev->next = buf;
219 msg_set_type(&pkthdr, FRAGMENT); 249 msg_set_type(&pkthdr, FRAGMENT);
220 msg_set_size(&pkthdr, pktsz); 250 msg_set_size(&pkthdr, pktsz);
@@ -224,7 +254,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
224 pktrem = pktsz - INT_H_SIZE; 254 pktrem = pktsz - INT_H_SIZE;
225 255
226 } while (1); 256 } while (1);
227 257 TIPC_SKB_CB(*chain)->chain_sz = chain_sz;
228 msg_set_type(buf_msg(buf), LAST_FRAGMENT); 258 msg_set_type(buf_msg(buf), LAST_FRAGMENT);
229 return dsz; 259 return dsz;
230error: 260error:
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 462fa194a6af..0ea7b695ac4d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -442,6 +442,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
442#define NAME_DISTRIBUTOR 11 442#define NAME_DISTRIBUTOR 11
443#define MSG_FRAGMENTER 12 443#define MSG_FRAGMENTER 12
444#define LINK_CONFIG 13 444#define LINK_CONFIG 13
445#define SOCK_WAKEUP 14 /* pseudo user */
445 446
446/* 447/*
447 * Connection management protocol message types 448 * Connection management protocol message types
@@ -732,6 +733,10 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode);
732void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, 733void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
733 u32 destnode); 734 u32 destnode);
734 735
736struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
737 uint data_sz, u32 dnode, u32 onode,
738 u32 dport, u32 oport, int errcode);
739
735int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf); 740int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
736 741
737bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu); 742bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 9d7d37d95187..c058e30f84aa 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -39,7 +39,6 @@
39#include "name_table.h" 39#include "name_table.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "subscr.h" 41#include "subscr.h"
42#include "port.h"
43 42
44#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ 43#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
45 44
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 7fcc94998fea..93b9944a6a8b 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -38,7 +38,6 @@
38#include "net.h" 38#include "net.h"
39#include "name_distr.h" 39#include "name_distr.h"
40#include "subscr.h" 40#include "subscr.h"
41#include "port.h"
42#include "socket.h" 41#include "socket.h"
43#include "node.h" 42#include "node.h"
44#include "config.h" 43#include "config.h"
@@ -111,7 +110,7 @@ int tipc_net_start(u32 addr)
111 110
112 tipc_own_addr = addr; 111 tipc_own_addr = addr;
113 tipc_named_reinit(); 112 tipc_named_reinit();
114 tipc_port_reinit(); 113 tipc_sk_reinit();
115 res = tipc_bclink_init(); 114 res = tipc_bclink_init();
116 if (res) 115 if (res)
117 return res; 116 return res;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index f7069299943f..17e6378c4dfe 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -38,6 +38,7 @@
38#include "config.h" 38#include "config.h"
39#include "node.h" 39#include "node.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "socket.h"
41 42
42#define NODE_HTABLE_SIZE 512 43#define NODE_HTABLE_SIZE 512
43 44
@@ -50,6 +51,13 @@ static u32 tipc_num_nodes;
50static u32 tipc_num_links; 51static u32 tipc_num_links;
51static DEFINE_SPINLOCK(node_list_lock); 52static DEFINE_SPINLOCK(node_list_lock);
52 53
54struct tipc_sock_conn {
55 u32 port;
56 u32 peer_port;
57 u32 peer_node;
58 struct list_head list;
59};
60
53/* 61/*
54 * A trivial power-of-two bitmask technique is used for speed, since this 62 * A trivial power-of-two bitmask technique is used for speed, since this
55 * operation is done for every incoming TIPC packet. The number of hash table 63 * operation is done for every incoming TIPC packet. The number of hash table
@@ -100,6 +108,8 @@ struct tipc_node *tipc_node_create(u32 addr)
100 INIT_HLIST_NODE(&n_ptr->hash); 108 INIT_HLIST_NODE(&n_ptr->hash);
101 INIT_LIST_HEAD(&n_ptr->list); 109 INIT_LIST_HEAD(&n_ptr->list);
102 INIT_LIST_HEAD(&n_ptr->nsub); 110 INIT_LIST_HEAD(&n_ptr->nsub);
111 INIT_LIST_HEAD(&n_ptr->conn_sks);
112 __skb_queue_head_init(&n_ptr->waiting_sks);
103 113
104 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); 114 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
105 115
@@ -136,6 +146,71 @@ void tipc_node_stop(void)
136 spin_unlock_bh(&node_list_lock); 146 spin_unlock_bh(&node_list_lock);
137} 147}
138 148
149int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port)
150{
151 struct tipc_node *node;
152 struct tipc_sock_conn *conn;
153
154 if (in_own_node(dnode))
155 return 0;
156
157 node = tipc_node_find(dnode);
158 if (!node) {
159 pr_warn("Connecting sock to node 0x%x failed\n", dnode);
160 return -EHOSTUNREACH;
161 }
162 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
163 if (!conn)
164 return -EHOSTUNREACH;
165 conn->peer_node = dnode;
166 conn->port = port;
167 conn->peer_port = peer_port;
168
169 tipc_node_lock(node);
170 list_add_tail(&conn->list, &node->conn_sks);
171 tipc_node_unlock(node);
172 return 0;
173}
174
175void tipc_node_remove_conn(u32 dnode, u32 port)
176{
177 struct tipc_node *node;
178 struct tipc_sock_conn *conn, *safe;
179
180 if (in_own_node(dnode))
181 return;
182
183 node = tipc_node_find(dnode);
184 if (!node)
185 return;
186
187 tipc_node_lock(node);
188 list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
189 if (port != conn->port)
190 continue;
191 list_del(&conn->list);
192 kfree(conn);
193 }
194 tipc_node_unlock(node);
195}
196
197void tipc_node_abort_sock_conns(struct list_head *conns)
198{
199 struct tipc_sock_conn *conn, *safe;
200 struct sk_buff *buf;
201
202 list_for_each_entry_safe(conn, safe, conns, list) {
203 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
204 SHORT_H_SIZE, 0, tipc_own_addr,
205 conn->peer_node, conn->port,
206 conn->peer_port, TIPC_ERR_NO_NODE);
207 if (likely(buf))
208 tipc_sk_rcv(buf);
209 list_del(&conn->list);
210 kfree(conn);
211 }
212}
213
139/** 214/**
140 * tipc_node_link_up - handle addition of link 215 * tipc_node_link_up - handle addition of link
141 * 216 *
@@ -474,6 +549,8 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
474void tipc_node_unlock(struct tipc_node *node) 549void tipc_node_unlock(struct tipc_node *node)
475{ 550{
476 LIST_HEAD(nsub_list); 551 LIST_HEAD(nsub_list);
552 LIST_HEAD(conn_sks);
553 struct sk_buff_head waiting_sks;
477 u32 addr = 0; 554 u32 addr = 0;
478 555
479 if (likely(!node->action_flags)) { 556 if (likely(!node->action_flags)) {
@@ -481,8 +558,14 @@ void tipc_node_unlock(struct tipc_node *node)
481 return; 558 return;
482 } 559 }
483 560
561 __skb_queue_head_init(&waiting_sks);
562 if (node->action_flags & TIPC_WAKEUP_USERS) {
563 skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
564 node->action_flags &= ~TIPC_WAKEUP_USERS;
565 }
484 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) { 566 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
485 list_replace_init(&node->nsub, &nsub_list); 567 list_replace_init(&node->nsub, &nsub_list);
568 list_replace_init(&node->conn_sks, &conn_sks);
486 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; 569 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
487 } 570 }
488 if (node->action_flags & TIPC_NOTIFY_NODE_UP) { 571 if (node->action_flags & TIPC_NOTIFY_NODE_UP) {
@@ -491,8 +574,15 @@ void tipc_node_unlock(struct tipc_node *node)
491 } 574 }
492 spin_unlock_bh(&node->lock); 575 spin_unlock_bh(&node->lock);
493 576
577 while (!skb_queue_empty(&waiting_sks))
578 tipc_sk_rcv(__skb_dequeue(&waiting_sks));
579
580 if (!list_empty(&conn_sks))
581 tipc_node_abort_sock_conns(&conn_sks);
582
494 if (!list_empty(&nsub_list)) 583 if (!list_empty(&nsub_list))
495 tipc_nodesub_notify(&nsub_list); 584 tipc_nodesub_notify(&nsub_list);
585
496 if (addr) 586 if (addr)
497 tipc_named_node_up(addr); 587 tipc_named_node_up(addr);
498} 588}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index b61716a8218e..522d6f3157b3 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -58,7 +58,8 @@ enum {
58 TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1), 58 TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1),
59 TIPC_WAIT_OWN_LINKS_DOWN = (1 << 2), 59 TIPC_WAIT_OWN_LINKS_DOWN = (1 << 2),
60 TIPC_NOTIFY_NODE_DOWN = (1 << 3), 60 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
61 TIPC_NOTIFY_NODE_UP = (1 << 4) 61 TIPC_NOTIFY_NODE_UP = (1 << 4),
62 TIPC_WAKEUP_USERS = (1 << 5)
62}; 63};
63 64
64/** 65/**
@@ -115,6 +116,8 @@ struct tipc_node {
115 int working_links; 116 int working_links;
116 u32 signature; 117 u32 signature;
117 struct list_head nsub; 118 struct list_head nsub;
119 struct sk_buff_head waiting_sks;
120 struct list_head conn_sks;
118 struct rcu_head rcu; 121 struct rcu_head rcu;
119}; 122};
120 123
@@ -133,6 +136,8 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
133struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 136struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
134int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len); 137int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
135void tipc_node_unlock(struct tipc_node *node); 138void tipc_node_unlock(struct tipc_node *node);
139int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port);
140void tipc_node_remove_conn(u32 dnode, u32 port);
136 141
137static inline void tipc_node_lock(struct tipc_node *node) 142static inline void tipc_node_lock(struct tipc_node *node)
138{ 143{
diff --git a/net/tipc/port.c b/net/tipc/port.c
deleted file mode 100644
index 7e096a5e7701..000000000000
--- a/net/tipc/port.c
+++ /dev/null
@@ -1,514 +0,0 @@
1/*
2 * net/tipc/port.c: TIPC port code
3 *
4 * Copyright (c) 1992-2007, 2014, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
38#include "config.h"
39#include "port.h"
40#include "name_table.h"
41#include "socket.h"
42
43/* Connection management: */
44#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
45
46#define MAX_REJECT_SIZE 1024
47
48DEFINE_SPINLOCK(tipc_port_list_lock);
49
50static LIST_HEAD(ports);
51static void port_handle_node_down(unsigned long ref);
52static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
53static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
54static void port_timeout(unsigned long ref);
55
56/**
57 * tipc_port_peer_msg - verify message was sent by connected port's peer
58 *
59 * Handles cases where the node's network address has changed from
60 * the default of <0.0.0> to its configured setting.
61 */
62int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
63{
64 u32 peernode;
65 u32 orignode;
66
67 if (msg_origport(msg) != tipc_port_peerport(p_ptr))
68 return 0;
69
70 orignode = msg_orignode(msg);
71 peernode = tipc_port_peernode(p_ptr);
72 return (orignode == peernode) ||
73 (!orignode && (peernode == tipc_own_addr)) ||
74 (!peernode && (orignode == tipc_own_addr));
75}
76
77/* tipc_port_init - intiate TIPC port and lock it
78 *
79 * Returns obtained reference if initialization is successful, zero otherwise
80 */
81u32 tipc_port_init(struct tipc_port *p_ptr,
82 const unsigned int importance)
83{
84 struct tipc_msg *msg;
85 u32 ref;
86
87 ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
88 if (!ref) {
89 pr_warn("Port registration failed, ref. table exhausted\n");
90 return 0;
91 }
92
93 p_ptr->max_pkt = MAX_PKT_DEFAULT;
94 p_ptr->ref = ref;
95 INIT_LIST_HEAD(&p_ptr->wait_list);
96 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
97 k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
98 INIT_LIST_HEAD(&p_ptr->publications);
99 INIT_LIST_HEAD(&p_ptr->port_list);
100
101 /*
102 * Must hold port list lock while initializing message header template
103 * to ensure a change to node's own network address doesn't result
104 * in template containing out-dated network address information
105 */
106 spin_lock_bh(&tipc_port_list_lock);
107 msg = &p_ptr->phdr;
108 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, NAMED_H_SIZE, 0);
109 msg_set_origport(msg, ref);
110 list_add_tail(&p_ptr->port_list, &ports);
111 spin_unlock_bh(&tipc_port_list_lock);
112 return ref;
113}
114
115void tipc_port_destroy(struct tipc_port *p_ptr)
116{
117 struct sk_buff *buf = NULL;
118 struct tipc_msg *msg = NULL;
119 u32 peer;
120
121 tipc_withdraw(p_ptr, 0, NULL);
122
123 spin_lock_bh(p_ptr->lock);
124 tipc_ref_discard(p_ptr->ref);
125 spin_unlock_bh(p_ptr->lock);
126
127 k_cancel_timer(&p_ptr->timer);
128 if (p_ptr->connected) {
129 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
130 tipc_nodesub_unsubscribe(&p_ptr->subscription);
131 msg = buf_msg(buf);
132 peer = msg_destnode(msg);
133 tipc_link_xmit(buf, peer, msg_link_selector(msg));
134 }
135 spin_lock_bh(&tipc_port_list_lock);
136 list_del(&p_ptr->port_list);
137 list_del(&p_ptr->wait_list);
138 spin_unlock_bh(&tipc_port_list_lock);
139 k_term_timer(&p_ptr->timer);
140}
141
142/*
143 * port_build_proto_msg(): create connection protocol message for port
144 *
145 * On entry the port must be locked and connected.
146 */
147static struct sk_buff *port_build_proto_msg(struct tipc_port *p_ptr,
148 u32 type, u32 ack)
149{
150 struct sk_buff *buf;
151 struct tipc_msg *msg;
152
153 buf = tipc_buf_acquire(INT_H_SIZE);
154 if (buf) {
155 msg = buf_msg(buf);
156 tipc_msg_init(msg, CONN_MANAGER, type, INT_H_SIZE,
157 tipc_port_peernode(p_ptr));
158 msg_set_destport(msg, tipc_port_peerport(p_ptr));
159 msg_set_origport(msg, p_ptr->ref);
160 msg_set_msgcnt(msg, ack);
161 buf->next = NULL;
162 }
163 return buf;
164}
165
166static void port_timeout(unsigned long ref)
167{
168 struct tipc_port *p_ptr = tipc_port_lock(ref);
169 struct sk_buff *buf = NULL;
170 struct tipc_msg *msg = NULL;
171
172 if (!p_ptr)
173 return;
174
175 if (!p_ptr->connected) {
176 tipc_port_unlock(p_ptr);
177 return;
178 }
179
180 /* Last probe answered ? */
181 if (p_ptr->probing_state == TIPC_CONN_PROBING) {
182 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
183 } else {
184 buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0);
185 p_ptr->probing_state = TIPC_CONN_PROBING;
186 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
187 }
188 tipc_port_unlock(p_ptr);
189 msg = buf_msg(buf);
190 tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
191}
192
193
194static void port_handle_node_down(unsigned long ref)
195{
196 struct tipc_port *p_ptr = tipc_port_lock(ref);
197 struct sk_buff *buf = NULL;
198 struct tipc_msg *msg = NULL;
199
200 if (!p_ptr)
201 return;
202 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE);
203 tipc_port_unlock(p_ptr);
204 msg = buf_msg(buf);
205 tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
206}
207
208
209static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
210{
211 struct sk_buff *buf = port_build_peer_abort_msg(p_ptr, err);
212
213 if (buf) {
214 struct tipc_msg *msg = buf_msg(buf);
215 msg_swap_words(msg, 4, 5);
216 msg_swap_words(msg, 6, 7);
217 buf->next = NULL;
218 }
219 return buf;
220}
221
222
223static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
224{
225 struct sk_buff *buf;
226 struct tipc_msg *msg;
227 u32 imp;
228
229 if (!p_ptr->connected)
230 return NULL;
231
232 buf = tipc_buf_acquire(BASIC_H_SIZE);
233 if (buf) {
234 msg = buf_msg(buf);
235 memcpy(msg, &p_ptr->phdr, BASIC_H_SIZE);
236 msg_set_hdr_sz(msg, BASIC_H_SIZE);
237 msg_set_size(msg, BASIC_H_SIZE);
238 imp = msg_importance(msg);
239 if (imp < TIPC_CRITICAL_IMPORTANCE)
240 msg_set_importance(msg, ++imp);
241 msg_set_errcode(msg, err);
242 buf->next = NULL;
243 }
244 return buf;
245}
246
247static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
248{
249 struct publication *publ;
250 int ret;
251
252 if (full_id)
253 ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
254 tipc_zone(tipc_own_addr),
255 tipc_cluster(tipc_own_addr),
256 tipc_node(tipc_own_addr), p_ptr->ref);
257 else
258 ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref);
259
260 if (p_ptr->connected) {
261 u32 dport = tipc_port_peerport(p_ptr);
262 u32 destnode = tipc_port_peernode(p_ptr);
263
264 ret += tipc_snprintf(buf + ret, len - ret,
265 " connected to <%u.%u.%u:%u>",
266 tipc_zone(destnode),
267 tipc_cluster(destnode),
268 tipc_node(destnode), dport);
269 if (p_ptr->conn_type != 0)
270 ret += tipc_snprintf(buf + ret, len - ret,
271 " via {%u,%u}", p_ptr->conn_type,
272 p_ptr->conn_instance);
273 } else if (p_ptr->published) {
274 ret += tipc_snprintf(buf + ret, len - ret, " bound to");
275 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
276 if (publ->lower == publ->upper)
277 ret += tipc_snprintf(buf + ret, len - ret,
278 " {%u,%u}", publ->type,
279 publ->lower);
280 else
281 ret += tipc_snprintf(buf + ret, len - ret,
282 " {%u,%u,%u}", publ->type,
283 publ->lower, publ->upper);
284 }
285 }
286 ret += tipc_snprintf(buf + ret, len - ret, "\n");
287 return ret;
288}
289
290struct sk_buff *tipc_port_get_ports(void)
291{
292 struct sk_buff *buf;
293 struct tlv_desc *rep_tlv;
294 char *pb;
295 int pb_len;
296 struct tipc_port *p_ptr;
297 int str_len = 0;
298
299 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
300 if (!buf)
301 return NULL;
302 rep_tlv = (struct tlv_desc *)buf->data;
303 pb = TLV_DATA(rep_tlv);
304 pb_len = ULTRA_STRING_MAX_LEN;
305
306 spin_lock_bh(&tipc_port_list_lock);
307 list_for_each_entry(p_ptr, &ports, port_list) {
308 spin_lock_bh(p_ptr->lock);
309 str_len += port_print(p_ptr, pb, pb_len, 0);
310 spin_unlock_bh(p_ptr->lock);
311 }
312 spin_unlock_bh(&tipc_port_list_lock);
313 str_len += 1; /* for "\0" */
314 skb_put(buf, TLV_SPACE(str_len));
315 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
316
317 return buf;
318}
319
320void tipc_port_reinit(void)
321{
322 struct tipc_port *p_ptr;
323 struct tipc_msg *msg;
324
325 spin_lock_bh(&tipc_port_list_lock);
326 list_for_each_entry(p_ptr, &ports, port_list) {
327 msg = &p_ptr->phdr;
328 msg_set_prevnode(msg, tipc_own_addr);
329 msg_set_orignode(msg, tipc_own_addr);
330 }
331 spin_unlock_bh(&tipc_port_list_lock);
332}
333
334void tipc_acknowledge(u32 ref, u32 ack)
335{
336 struct tipc_port *p_ptr;
337 struct sk_buff *buf = NULL;
338 struct tipc_msg *msg;
339
340 p_ptr = tipc_port_lock(ref);
341 if (!p_ptr)
342 return;
343 if (p_ptr->connected)
344 buf = port_build_proto_msg(p_ptr, CONN_ACK, ack);
345
346 tipc_port_unlock(p_ptr);
347 if (!buf)
348 return;
349 msg = buf_msg(buf);
350 tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
351}
352
353int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
354 struct tipc_name_seq const *seq)
355{
356 struct publication *publ;
357 u32 key;
358
359 if (p_ptr->connected)
360 return -EINVAL;
361 key = p_ptr->ref + p_ptr->pub_count + 1;
362 if (key == p_ptr->ref)
363 return -EADDRINUSE;
364
365 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
366 scope, p_ptr->ref, key);
367 if (publ) {
368 list_add(&publ->pport_list, &p_ptr->publications);
369 p_ptr->pub_count++;
370 p_ptr->published = 1;
371 return 0;
372 }
373 return -EINVAL;
374}
375
376int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
377 struct tipc_name_seq const *seq)
378{
379 struct publication *publ;
380 struct publication *tpubl;
381 int res = -EINVAL;
382
383 if (!seq) {
384 list_for_each_entry_safe(publ, tpubl,
385 &p_ptr->publications, pport_list) {
386 tipc_nametbl_withdraw(publ->type, publ->lower,
387 publ->ref, publ->key);
388 }
389 res = 0;
390 } else {
391 list_for_each_entry_safe(publ, tpubl,
392 &p_ptr->publications, pport_list) {
393 if (publ->scope != scope)
394 continue;
395 if (publ->type != seq->type)
396 continue;
397 if (publ->lower != seq->lower)
398 continue;
399 if (publ->upper != seq->upper)
400 break;
401 tipc_nametbl_withdraw(publ->type, publ->lower,
402 publ->ref, publ->key);
403 res = 0;
404 break;
405 }
406 }
407 if (list_empty(&p_ptr->publications))
408 p_ptr->published = 0;
409 return res;
410}
411
412int tipc_port_connect(u32 ref, struct tipc_portid const *peer)
413{
414 struct tipc_port *p_ptr;
415 int res;
416
417 p_ptr = tipc_port_lock(ref);
418 if (!p_ptr)
419 return -EINVAL;
420 res = __tipc_port_connect(ref, p_ptr, peer);
421 tipc_port_unlock(p_ptr);
422 return res;
423}
424
425/*
426 * __tipc_port_connect - connect to a remote peer
427 *
428 * Port must be locked.
429 */
430int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
431 struct tipc_portid const *peer)
432{
433 struct tipc_msg *msg;
434 int res = -EINVAL;
435
436 if (p_ptr->published || p_ptr->connected)
437 goto exit;
438 if (!peer->ref)
439 goto exit;
440
441 msg = &p_ptr->phdr;
442 msg_set_destnode(msg, peer->node);
443 msg_set_destport(msg, peer->ref);
444 msg_set_type(msg, TIPC_CONN_MSG);
445 msg_set_lookup_scope(msg, 0);
446 msg_set_hdr_sz(msg, SHORT_H_SIZE);
447
448 p_ptr->probing_interval = PROBING_INTERVAL;
449 p_ptr->probing_state = TIPC_CONN_OK;
450 p_ptr->connected = 1;
451 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
452
453 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
454 (void *)(unsigned long)ref,
455 (net_ev_handler)port_handle_node_down);
456 res = 0;
457exit:
458 p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref);
459 return res;
460}
461
462/*
463 * __tipc_disconnect - disconnect port from peer
464 *
465 * Port must be locked.
466 */
467int __tipc_port_disconnect(struct tipc_port *tp_ptr)
468{
469 if (tp_ptr->connected) {
470 tp_ptr->connected = 0;
471 /* let timer expire on it's own to avoid deadlock! */
472 tipc_nodesub_unsubscribe(&tp_ptr->subscription);
473 return 0;
474 }
475
476 return -ENOTCONN;
477}
478
479/*
480 * tipc_port_disconnect(): Disconnect port form peer.
481 * This is a node local operation.
482 */
483int tipc_port_disconnect(u32 ref)
484{
485 struct tipc_port *p_ptr;
486 int res;
487
488 p_ptr = tipc_port_lock(ref);
489 if (!p_ptr)
490 return -EINVAL;
491 res = __tipc_port_disconnect(p_ptr);
492 tipc_port_unlock(p_ptr);
493 return res;
494}
495
496/*
497 * tipc_port_shutdown(): Send a SHUTDOWN msg to peer and disconnect
498 */
499int tipc_port_shutdown(u32 ref)
500{
501 struct tipc_msg *msg;
502 struct tipc_port *p_ptr;
503 struct sk_buff *buf = NULL;
504
505 p_ptr = tipc_port_lock(ref);
506 if (!p_ptr)
507 return -EINVAL;
508
509 buf = port_build_peer_abort_msg(p_ptr, TIPC_CONN_SHUTDOWN);
510 tipc_port_unlock(p_ptr);
511 msg = buf_msg(buf);
512 tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
513 return tipc_port_disconnect(ref);
514}
diff --git a/net/tipc/port.h b/net/tipc/port.h
deleted file mode 100644
index 3087da39ee47..000000000000
--- a/net/tipc/port.h
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 * net/tipc/port.h: Include file for TIPC port code
3 *
4 * Copyright (c) 1994-2007, 2014, Ericsson AB
5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _TIPC_PORT_H
38#define _TIPC_PORT_H
39
40#include "ref.h"
41#include "net.h"
42#include "msg.h"
43#include "node_subscr.h"
44
45#define TIPC_CONNACK_INTV 256
46#define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2)
47#define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
48 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
49
50/**
51 * struct tipc_port - TIPC port structure
52 * @lock: pointer to spinlock for controlling access to port
53 * @connected: non-zero if port is currently connected to a peer port
54 * @conn_type: TIPC type used when connection was established
55 * @conn_instance: TIPC instance used when connection was established
56 * @published: non-zero if port has one or more associated names
57 * @max_pkt: maximum packet size "hint" used when building messages sent by port
58 * @ref: unique reference to port in TIPC object registry
59 * @phdr: preformatted message header used when sending messages
60 * @port_list: adjacent ports in TIPC's global list of ports
61 * @wait_list: adjacent ports in list of ports waiting on link congestion
62 * @waiting_pkts:
63 * @publications: list of publications for port
64 * @pub_count: total # of publications port has made during its lifetime
65 * @probing_state:
66 * @probing_interval:
67 * @timer_ref:
68 * @subscription: "node down" subscription used to terminate failed connections
69 */
70struct tipc_port {
71 spinlock_t *lock;
72 int connected;
73 u32 conn_type;
74 u32 conn_instance;
75 int published;
76 u32 max_pkt;
77 u32 ref;
78 struct tipc_msg phdr;
79 struct list_head port_list;
80 struct list_head wait_list;
81 u32 waiting_pkts;
82 struct list_head publications;
83 u32 pub_count;
84 u32 probing_state;
85 u32 probing_interval;
86 struct timer_list timer;
87 struct tipc_node_subscr subscription;
88};
89
90extern spinlock_t tipc_port_list_lock;
91struct tipc_port_list;
92
93/*
94 * TIPC port manipulation routines
95 */
96u32 tipc_port_init(struct tipc_port *p_ptr,
97 const unsigned int importance);
98
99void tipc_acknowledge(u32 port_ref, u32 ack);
100
101void tipc_port_destroy(struct tipc_port *p_ptr);
102
103int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
104 struct tipc_name_seq const *name_seq);
105
106int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
107 struct tipc_name_seq const *name_seq);
108
109int tipc_port_connect(u32 portref, struct tipc_portid const *port);
110
111int tipc_port_disconnect(u32 portref);
112
113int tipc_port_shutdown(u32 ref);
114
115/*
116 * The following routines require that the port be locked on entry
117 */
118int __tipc_port_disconnect(struct tipc_port *tp_ptr);
119int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
120 struct tipc_portid const *peer);
121int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
122
123struct sk_buff *tipc_port_get_ports(void);
124void tipc_port_reinit(void);
125
126/**
127 * tipc_port_lock - lock port instance referred to and return its pointer
128 */
129static inline struct tipc_port *tipc_port_lock(u32 ref)
130{
131 return (struct tipc_port *)tipc_ref_lock(ref);
132}
133
134/**
135 * tipc_port_unlock - unlock a port instance
136 *
137 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
138 */
139static inline void tipc_port_unlock(struct tipc_port *p_ptr)
140{
141 spin_unlock_bh(p_ptr->lock);
142}
143
144static inline u32 tipc_port_peernode(struct tipc_port *p_ptr)
145{
146 return msg_destnode(&p_ptr->phdr);
147}
148
149static inline u32 tipc_port_peerport(struct tipc_port *p_ptr)
150{
151 return msg_destport(&p_ptr->phdr);
152}
153
154static inline bool tipc_port_unreliable(struct tipc_port *port)
155{
156 return msg_src_droppable(&port->phdr) != 0;
157}
158
159static inline void tipc_port_set_unreliable(struct tipc_port *port,
160 bool unreliable)
161{
162 msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0);
163}
164
165static inline bool tipc_port_unreturnable(struct tipc_port *port)
166{
167 return msg_dest_droppable(&port->phdr) != 0;
168}
169
170static inline void tipc_port_set_unreturnable(struct tipc_port *port,
171 bool unreturnable)
172{
173 msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0);
174}
175
176
177static inline int tipc_port_importance(struct tipc_port *port)
178{
179 return msg_importance(&port->phdr);
180}
181
182static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
183{
184 if (imp > TIPC_CRITICAL_IMPORTANCE)
185 return -EINVAL;
186 msg_set_importance(&port->phdr, (u32)imp);
187 return 0;
188}
189
190#endif
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
deleted file mode 100644
index 3d4ecd754eee..000000000000
--- a/net/tipc/ref.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * net/tipc/ref.c: TIPC object registry code
3 *
4 * Copyright (c) 1991-2006, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
38#include "ref.h"
39
40/**
41 * struct reference - TIPC object reference entry
42 * @object: pointer to object associated with reference entry
43 * @lock: spinlock controlling access to object
44 * @ref: reference value for object (combines instance & array index info)
45 */
46struct reference {
47 void *object;
48 spinlock_t lock;
49 u32 ref;
50};
51
52/**
53 * struct tipc_ref_table - table of TIPC object reference entries
54 * @entries: pointer to array of reference entries
55 * @capacity: array index of first unusable entry
56 * @init_point: array index of first uninitialized entry
57 * @first_free: array index of first unused object reference entry
58 * @last_free: array index of last unused object reference entry
59 * @index_mask: bitmask for array index portion of reference values
60 * @start_mask: initial value for instance value portion of reference values
61 */
62struct ref_table {
63 struct reference *entries;
64 u32 capacity;
65 u32 init_point;
66 u32 first_free;
67 u32 last_free;
68 u32 index_mask;
69 u32 start_mask;
70};
71
72/*
73 * Object reference table consists of 2**N entries.
74 *
75 * State Object ptr Reference
76 * ----- ---------- ---------
77 * In use non-NULL XXXX|own index
78 * (XXXX changes each time entry is acquired)
79 * Free NULL YYYY|next free index
80 * (YYYY is one more than last used XXXX)
81 * Uninitialized NULL 0
82 *
83 * Entry 0 is not used; this allows index 0 to denote the end of the free list.
84 *
85 * Note that a reference value of 0 does not necessarily indicate that an
86 * entry is uninitialized, since the last entry in the free list could also
87 * have a reference value of 0 (although this is unlikely).
88 */
89
90static struct ref_table tipc_ref_table;
91
92static DEFINE_SPINLOCK(ref_table_lock);
93
94/**
95 * tipc_ref_table_init - create reference table for objects
96 */
97int tipc_ref_table_init(u32 requested_size, u32 start)
98{
99 struct reference *table;
100 u32 actual_size;
101
102 /* account for unused entry, then round up size to a power of 2 */
103
104 requested_size++;
105 for (actual_size = 16; actual_size < requested_size; actual_size <<= 1)
106 /* do nothing */ ;
107
108 /* allocate table & mark all entries as uninitialized */
109 table = vzalloc(actual_size * sizeof(struct reference));
110 if (table == NULL)
111 return -ENOMEM;
112
113 tipc_ref_table.entries = table;
114 tipc_ref_table.capacity = requested_size;
115 tipc_ref_table.init_point = 1;
116 tipc_ref_table.first_free = 0;
117 tipc_ref_table.last_free = 0;
118 tipc_ref_table.index_mask = actual_size - 1;
119 tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
120
121 return 0;
122}
123
124/**
125 * tipc_ref_table_stop - destroy reference table for objects
126 */
127void tipc_ref_table_stop(void)
128{
129 vfree(tipc_ref_table.entries);
130 tipc_ref_table.entries = NULL;
131}
132
133/**
134 * tipc_ref_acquire - create reference to an object
135 *
136 * Register an object pointer in reference table and lock the object.
137 * Returns a unique reference value that is used from then on to retrieve the
138 * object pointer, or to determine that the object has been deregistered.
139 *
140 * Note: The object is returned in the locked state so that the caller can
141 * register a partially initialized object, without running the risk that
142 * the object will be accessed before initialization is complete.
143 */
144u32 tipc_ref_acquire(void *object, spinlock_t **lock)
145{
146 u32 index;
147 u32 index_mask;
148 u32 next_plus_upper;
149 u32 ref;
150 struct reference *entry = NULL;
151
152 if (!object) {
153 pr_err("Attempt to acquire ref. to non-existent obj\n");
154 return 0;
155 }
156 if (!tipc_ref_table.entries) {
157 pr_err("Ref. table not found in acquisition attempt\n");
158 return 0;
159 }
160
161 /* take a free entry, if available; otherwise initialize a new entry */
162 spin_lock_bh(&ref_table_lock);
163 if (tipc_ref_table.first_free) {
164 index = tipc_ref_table.first_free;
165 entry = &(tipc_ref_table.entries[index]);
166 index_mask = tipc_ref_table.index_mask;
167 next_plus_upper = entry->ref;
168 tipc_ref_table.first_free = next_plus_upper & index_mask;
169 ref = (next_plus_upper & ~index_mask) + index;
170 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
171 index = tipc_ref_table.init_point++;
172 entry = &(tipc_ref_table.entries[index]);
173 spin_lock_init(&entry->lock);
174 ref = tipc_ref_table.start_mask + index;
175 } else {
176 ref = 0;
177 }
178 spin_unlock_bh(&ref_table_lock);
179
180 /*
181 * Grab the lock so no one else can modify this entry
182 * While we assign its ref value & object pointer
183 */
184 if (entry) {
185 spin_lock_bh(&entry->lock);
186 entry->ref = ref;
187 entry->object = object;
188 *lock = &entry->lock;
189 /*
190 * keep it locked, the caller is responsible
191 * for unlocking this when they're done with it
192 */
193 }
194
195 return ref;
196}
197
198/**
199 * tipc_ref_discard - invalidate references to an object
200 *
201 * Disallow future references to an object and free up the entry for re-use.
202 * Note: The entry's spin_lock may still be busy after discard
203 */
204void tipc_ref_discard(u32 ref)
205{
206 struct reference *entry;
207 u32 index;
208 u32 index_mask;
209
210 if (!tipc_ref_table.entries) {
211 pr_err("Ref. table not found during discard attempt\n");
212 return;
213 }
214
215 index_mask = tipc_ref_table.index_mask;
216 index = ref & index_mask;
217 entry = &(tipc_ref_table.entries[index]);
218
219 spin_lock_bh(&ref_table_lock);
220
221 if (!entry->object) {
222 pr_err("Attempt to discard ref. to non-existent obj\n");
223 goto exit;
224 }
225 if (entry->ref != ref) {
226 pr_err("Attempt to discard non-existent reference\n");
227 goto exit;
228 }
229
230 /*
231 * mark entry as unused; increment instance part of entry's reference
232 * to invalidate any subsequent references
233 */
234 entry->object = NULL;
235 entry->ref = (ref & ~index_mask) + (index_mask + 1);
236
237 /* append entry to free entry list */
238 if (tipc_ref_table.first_free == 0)
239 tipc_ref_table.first_free = index;
240 else
241 tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
242 tipc_ref_table.last_free = index;
243
244exit:
245 spin_unlock_bh(&ref_table_lock);
246}
247
248/**
249 * tipc_ref_lock - lock referenced object and return pointer to it
250 */
251void *tipc_ref_lock(u32 ref)
252{
253 if (likely(tipc_ref_table.entries)) {
254 struct reference *entry;
255
256 entry = &tipc_ref_table.entries[ref &
257 tipc_ref_table.index_mask];
258 if (likely(entry->ref != 0)) {
259 spin_lock_bh(&entry->lock);
260 if (likely((entry->ref == ref) && (entry->object)))
261 return entry->object;
262 spin_unlock_bh(&entry->lock);
263 }
264 }
265 return NULL;
266}
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
deleted file mode 100644
index d01aa1df63b8..000000000000
--- a/net/tipc/ref.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * net/tipc/ref.h: Include file for TIPC object registry code
3 *
4 * Copyright (c) 1991-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _TIPC_REF_H
38#define _TIPC_REF_H
39
40int tipc_ref_table_init(u32 requested_size, u32 start);
41void tipc_ref_table_stop(void);
42
43u32 tipc_ref_acquire(void *object, spinlock_t **lock);
44void tipc_ref_discard(u32 ref);
45
46void *tipc_ref_lock(u32 ref);
47
48#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ff8c8118d56e..d416e83ce069 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -35,17 +35,67 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "port.h"
39#include "name_table.h" 38#include "name_table.h"
40#include "node.h" 39#include "node.h"
41#include "link.h" 40#include "link.h"
42#include <linux/export.h> 41#include <linux/export.h>
42#include "config.h"
43#include "socket.h"
43 44
44#define SS_LISTENING -1 /* socket is listening */ 45#define SS_LISTENING -1 /* socket is listening */
45#define SS_READY -2 /* socket is connectionless */ 46#define SS_READY -2 /* socket is connectionless */
46 47
47#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 48#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
48#define TIPC_FWD_MSG 1 49#define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */
50#define TIPC_FWD_MSG 1
51#define TIPC_CONN_OK 0
52#define TIPC_CONN_PROBING 1
53
54/**
55 * struct tipc_sock - TIPC socket structure
56 * @sk: socket - interacts with 'port' and with user via the socket API
57 * @connected: non-zero if port is currently connected to a peer port
58 * @conn_type: TIPC type used when connection was established
59 * @conn_instance: TIPC instance used when connection was established
60 * @published: non-zero if port has one or more associated names
61 * @max_pkt: maximum packet size "hint" used when building messages sent by port
62 * @ref: unique reference to port in TIPC object registry
63 * @phdr: preformatted message header used when sending messages
64 * @port_list: adjacent ports in TIPC's global list of ports
65 * @publications: list of publications for port
66 * @pub_count: total # of publications port has made during its lifetime
67 * @probing_state:
68 * @probing_interval:
69 * @timer:
70 * @port: port - interacts with 'sk' and with the rest of the TIPC stack
71 * @peer_name: the peer of the connection, if any
72 * @conn_timeout: the time we can wait for an unresponded setup request
73 * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
74 * @link_cong: non-zero if owner must sleep because of link congestion
75 * @sent_unacked: # messages sent by socket, and not yet acked by peer
76 * @rcv_unacked: # messages read by user, but not yet acked back to peer
77 */
78struct tipc_sock {
79 struct sock sk;
80 int connected;
81 u32 conn_type;
82 u32 conn_instance;
83 int published;
84 u32 max_pkt;
85 u32 ref;
86 struct tipc_msg phdr;
87 struct list_head sock_list;
88 struct list_head publications;
89 u32 pub_count;
90 u32 probing_state;
91 u32 probing_interval;
92 struct timer_list timer;
93 uint conn_timeout;
94 atomic_t dupl_rcvcnt;
95 bool link_cong;
96 uint sent_unacked;
97 uint rcv_unacked;
98};
49 99
50static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); 100static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
51static void tipc_data_ready(struct sock *sk); 101static void tipc_data_ready(struct sock *sk);
@@ -53,6 +103,16 @@ static void tipc_write_space(struct sock *sk);
53static int tipc_release(struct socket *sock); 103static int tipc_release(struct socket *sock);
54static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); 104static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
55static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); 105static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
106static void tipc_sk_timeout(unsigned long ref);
107static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
108 struct tipc_name_seq const *seq);
109static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
110 struct tipc_name_seq const *seq);
111static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk);
112static void tipc_sk_ref_discard(u32 ref);
113static struct tipc_sock *tipc_sk_get(u32 ref);
114static struct tipc_sock *tipc_sk_get_next(u32 *ref);
115static void tipc_sk_put(struct tipc_sock *tsk);
56 116
57static const struct proto_ops packet_ops; 117static const struct proto_ops packet_ops;
58static const struct proto_ops stream_ops; 118static const struct proto_ops stream_ops;
@@ -106,24 +166,75 @@ static struct proto tipc_proto_kern;
106 * - port reference 166 * - port reference
107 */ 167 */
108 168
109#include "socket.h" 169static u32 tsk_peer_node(struct tipc_sock *tsk)
170{
171 return msg_destnode(&tsk->phdr);
172}
173
174static u32 tsk_peer_port(struct tipc_sock *tsk)
175{
176 return msg_destport(&tsk->phdr);
177}
178
179static bool tsk_unreliable(struct tipc_sock *tsk)
180{
181 return msg_src_droppable(&tsk->phdr) != 0;
182}
183
184static void tsk_set_unreliable(struct tipc_sock *tsk, bool unreliable)
185{
186 msg_set_src_droppable(&tsk->phdr, unreliable ? 1 : 0);
187}
188
189static bool tsk_unreturnable(struct tipc_sock *tsk)
190{
191 return msg_dest_droppable(&tsk->phdr) != 0;
192}
193
194static void tsk_set_unreturnable(struct tipc_sock *tsk, bool unreturnable)
195{
196 msg_set_dest_droppable(&tsk->phdr, unreturnable ? 1 : 0);
197}
198
199static int tsk_importance(struct tipc_sock *tsk)
200{
201 return msg_importance(&tsk->phdr);
202}
203
204static int tsk_set_importance(struct tipc_sock *tsk, int imp)
205{
206 if (imp > TIPC_CRITICAL_IMPORTANCE)
207 return -EINVAL;
208 msg_set_importance(&tsk->phdr, (u32)imp);
209 return 0;
210}
211
212static struct tipc_sock *tipc_sk(const struct sock *sk)
213{
214 return container_of(sk, struct tipc_sock, sk);
215}
216
217static int tsk_conn_cong(struct tipc_sock *tsk)
218{
219 return tsk->sent_unacked >= TIPC_FLOWCTRL_WIN;
220}
110 221
111/** 222/**
112 * advance_rx_queue - discard first buffer in socket receive queue 223 * tsk_advance_rx_queue - discard first buffer in socket receive queue
113 * 224 *
114 * Caller must hold socket lock 225 * Caller must hold socket lock
115 */ 226 */
116static void advance_rx_queue(struct sock *sk) 227static void tsk_advance_rx_queue(struct sock *sk)
117{ 228{
118 kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); 229 kfree_skb(__skb_dequeue(&sk->sk_receive_queue));
119} 230}
120 231
121/** 232/**
122 * reject_rx_queue - reject all buffers in socket receive queue 233 * tsk_rej_rx_queue - reject all buffers in socket receive queue
123 * 234 *
124 * Caller must hold socket lock 235 * Caller must hold socket lock
125 */ 236 */
126static void reject_rx_queue(struct sock *sk) 237static void tsk_rej_rx_queue(struct sock *sk)
127{ 238{
128 struct sk_buff *buf; 239 struct sk_buff *buf;
129 u32 dnode; 240 u32 dnode;
@@ -134,6 +245,38 @@ static void reject_rx_queue(struct sock *sk)
134 } 245 }
135} 246}
136 247
248/* tsk_peer_msg - verify if message was sent by connected port's peer
249 *
250 * Handles cases where the node's network address has changed from
251 * the default of <0.0.0> to its configured setting.
252 */
253static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
254{
255 u32 peer_port = tsk_peer_port(tsk);
256 u32 orig_node;
257 u32 peer_node;
258
259 if (unlikely(!tsk->connected))
260 return false;
261
262 if (unlikely(msg_origport(msg) != peer_port))
263 return false;
264
265 orig_node = msg_orignode(msg);
266 peer_node = tsk_peer_node(tsk);
267
268 if (likely(orig_node == peer_node))
269 return true;
270
271 if (!orig_node && (peer_node == tipc_own_addr))
272 return true;
273
274 if (!peer_node && (orig_node == tipc_own_addr))
275 return true;
276
277 return false;
278}
279
137/** 280/**
138 * tipc_sk_create - create a TIPC socket 281 * tipc_sk_create - create a TIPC socket
139 * @net: network namespace (must be default network) 282 * @net: network namespace (must be default network)
@@ -153,7 +296,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
153 socket_state state; 296 socket_state state;
154 struct sock *sk; 297 struct sock *sk;
155 struct tipc_sock *tsk; 298 struct tipc_sock *tsk;
156 struct tipc_port *port; 299 struct tipc_msg *msg;
157 u32 ref; 300 u32 ref;
158 301
159 /* Validate arguments */ 302 /* Validate arguments */
@@ -188,20 +331,24 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
188 return -ENOMEM; 331 return -ENOMEM;
189 332
190 tsk = tipc_sk(sk); 333 tsk = tipc_sk(sk);
191 port = &tsk->port; 334 ref = tipc_sk_ref_acquire(tsk);
192
193 ref = tipc_port_init(port, TIPC_LOW_IMPORTANCE);
194 if (!ref) { 335 if (!ref) {
195 pr_warn("Socket registration failed, ref. table exhausted\n"); 336 pr_warn("Socket create failed; reference table exhausted\n");
196 sk_free(sk);
197 return -ENOMEM; 337 return -ENOMEM;
198 } 338 }
339 tsk->max_pkt = MAX_PKT_DEFAULT;
340 tsk->ref = ref;
341 INIT_LIST_HEAD(&tsk->publications);
342 msg = &tsk->phdr;
343 tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
344 NAMED_H_SIZE, 0);
345 msg_set_origport(msg, ref);
199 346
200 /* Finish initializing socket data structures */ 347 /* Finish initializing socket data structures */
201 sock->ops = ops; 348 sock->ops = ops;
202 sock->state = state; 349 sock->state = state;
203
204 sock_init_data(sock, sk); 350 sock_init_data(sock, sk);
351 k_init_timer(&tsk->timer, (Handler)tipc_sk_timeout, ref);
205 sk->sk_backlog_rcv = tipc_backlog_rcv; 352 sk->sk_backlog_rcv = tipc_backlog_rcv;
206 sk->sk_rcvbuf = sysctl_tipc_rmem[1]; 353 sk->sk_rcvbuf = sysctl_tipc_rmem[1];
207 sk->sk_data_ready = tipc_data_ready; 354 sk->sk_data_ready = tipc_data_ready;
@@ -209,12 +356,11 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
209 tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; 356 tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
210 tsk->sent_unacked = 0; 357 tsk->sent_unacked = 0;
211 atomic_set(&tsk->dupl_rcvcnt, 0); 358 atomic_set(&tsk->dupl_rcvcnt, 0);
212 tipc_port_unlock(port);
213 359
214 if (sock->state == SS_READY) { 360 if (sock->state == SS_READY) {
215 tipc_port_set_unreturnable(port, true); 361 tsk_set_unreturnable(tsk, true);
216 if (sock->type == SOCK_DGRAM) 362 if (sock->type == SOCK_DGRAM)
217 tipc_port_set_unreliable(port, true); 363 tsk_set_unreliable(tsk, true);
218 } 364 }
219 return 0; 365 return 0;
220} 366}
@@ -308,7 +454,6 @@ static int tipc_release(struct socket *sock)
308{ 454{
309 struct sock *sk = sock->sk; 455 struct sock *sk = sock->sk;
310 struct tipc_sock *tsk; 456 struct tipc_sock *tsk;
311 struct tipc_port *port;
312 struct sk_buff *buf; 457 struct sk_buff *buf;
313 u32 dnode; 458 u32 dnode;
314 459
@@ -320,13 +465,13 @@ static int tipc_release(struct socket *sock)
320 return 0; 465 return 0;
321 466
322 tsk = tipc_sk(sk); 467 tsk = tipc_sk(sk);
323 port = &tsk->port;
324 lock_sock(sk); 468 lock_sock(sk);
325 469
326 /* 470 /*
327 * Reject all unreceived messages, except on an active connection 471 * Reject all unreceived messages, except on an active connection
328 * (which disconnects locally & sends a 'FIN+' to peer) 472 * (which disconnects locally & sends a 'FIN+' to peer)
329 */ 473 */
474 dnode = tsk_peer_node(tsk);
330 while (sock->state != SS_DISCONNECTING) { 475 while (sock->state != SS_DISCONNECTING) {
331 buf = __skb_dequeue(&sk->sk_receive_queue); 476 buf = __skb_dequeue(&sk->sk_receive_queue);
332 if (buf == NULL) 477 if (buf == NULL)
@@ -337,17 +482,27 @@ static int tipc_release(struct socket *sock)
337 if ((sock->state == SS_CONNECTING) || 482 if ((sock->state == SS_CONNECTING) ||
338 (sock->state == SS_CONNECTED)) { 483 (sock->state == SS_CONNECTED)) {
339 sock->state = SS_DISCONNECTING; 484 sock->state = SS_DISCONNECTING;
340 tipc_port_disconnect(port->ref); 485 tsk->connected = 0;
486 tipc_node_remove_conn(dnode, tsk->ref);
341 } 487 }
342 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) 488 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
343 tipc_link_xmit(buf, dnode, 0); 489 tipc_link_xmit(buf, dnode, 0);
344 } 490 }
345 } 491 }
346 492
347 /* Destroy TIPC port; also disconnects an active connection and 493 tipc_sk_withdraw(tsk, 0, NULL);
348 * sends a 'FIN-' to peer. 494 tipc_sk_ref_discard(tsk->ref);
349 */ 495 k_cancel_timer(&tsk->timer);
350 tipc_port_destroy(port); 496 if (tsk->connected) {
497 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
498 SHORT_H_SIZE, 0, dnode, tipc_own_addr,
499 tsk_peer_port(tsk),
500 tsk->ref, TIPC_ERR_NO_PORT);
501 if (buf)
502 tipc_link_xmit(buf, dnode, tsk->ref);
503 tipc_node_remove_conn(dnode, tsk->ref);
504 }
505 k_term_timer(&tsk->timer);
351 506
352 /* Discard any remaining (connection-based) messages in receive queue */ 507 /* Discard any remaining (connection-based) messages in receive queue */
353 __skb_queue_purge(&sk->sk_receive_queue); 508 __skb_queue_purge(&sk->sk_receive_queue);
@@ -355,7 +510,6 @@ static int tipc_release(struct socket *sock)
355 /* Reject any messages that accumulated in backlog queue */ 510 /* Reject any messages that accumulated in backlog queue */
356 sock->state = SS_DISCONNECTING; 511 sock->state = SS_DISCONNECTING;
357 release_sock(sk); 512 release_sock(sk);
358
359 sock_put(sk); 513 sock_put(sk);
360 sock->sk = NULL; 514 sock->sk = NULL;
361 515
@@ -387,7 +541,7 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
387 541
388 lock_sock(sk); 542 lock_sock(sk);
389 if (unlikely(!uaddr_len)) { 543 if (unlikely(!uaddr_len)) {
390 res = tipc_withdraw(&tsk->port, 0, NULL); 544 res = tipc_sk_withdraw(tsk, 0, NULL);
391 goto exit; 545 goto exit;
392 } 546 }
393 547
@@ -415,8 +569,8 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
415 } 569 }
416 570
417 res = (addr->scope > 0) ? 571 res = (addr->scope > 0) ?
418 tipc_publish(&tsk->port, addr->scope, &addr->addr.nameseq) : 572 tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) :
419 tipc_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq); 573 tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
420exit: 574exit:
421 release_sock(sk); 575 release_sock(sk);
422 return res; 576 return res;
@@ -446,10 +600,10 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
446 if ((sock->state != SS_CONNECTED) && 600 if ((sock->state != SS_CONNECTED) &&
447 ((peer != 2) || (sock->state != SS_DISCONNECTING))) 601 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
448 return -ENOTCONN; 602 return -ENOTCONN;
449 addr->addr.id.ref = tipc_port_peerport(&tsk->port); 603 addr->addr.id.ref = tsk_peer_port(tsk);
450 addr->addr.id.node = tipc_port_peernode(&tsk->port); 604 addr->addr.id.node = tsk_peer_node(tsk);
451 } else { 605 } else {
452 addr->addr.id.ref = tsk->port.ref; 606 addr->addr.id.ref = tsk->ref;
453 addr->addr.id.node = tipc_own_addr; 607 addr->addr.id.node = tipc_own_addr;
454 } 608 }
455 609
@@ -518,7 +672,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
518 break; 672 break;
519 case SS_READY: 673 case SS_READY:
520 case SS_CONNECTED: 674 case SS_CONNECTED:
521 if (!tsk->link_cong && !tipc_sk_conn_cong(tsk)) 675 if (!tsk->link_cong && !tsk_conn_cong(tsk))
522 mask |= POLLOUT; 676 mask |= POLLOUT;
523 /* fall thru' */ 677 /* fall thru' */
524 case SS_CONNECTING: 678 case SS_CONNECTING:
@@ -549,7 +703,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
549 struct iovec *iov, size_t dsz, long timeo) 703 struct iovec *iov, size_t dsz, long timeo)
550{ 704{
551 struct sock *sk = sock->sk; 705 struct sock *sk = sock->sk;
552 struct tipc_msg *mhdr = &tipc_sk(sk)->port.phdr; 706 struct tipc_msg *mhdr = &tipc_sk(sk)->phdr;
553 struct sk_buff *buf; 707 struct sk_buff *buf;
554 uint mtu; 708 uint mtu;
555 int rc; 709 int rc;
@@ -579,6 +733,7 @@ new_mtu:
579 goto new_mtu; 733 goto new_mtu;
580 if (rc != -ELINKCONG) 734 if (rc != -ELINKCONG)
581 break; 735 break;
736 tipc_sk(sk)->link_cong = 1;
582 rc = tipc_wait_for_sndmsg(sock, &timeo); 737 rc = tipc_wait_for_sndmsg(sock, &timeo);
583 if (rc) 738 if (rc)
584 kfree_skb_list(buf); 739 kfree_skb_list(buf);
@@ -638,20 +793,19 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
638 struct sk_buff *buf) 793 struct sk_buff *buf)
639{ 794{
640 struct tipc_msg *msg = buf_msg(buf); 795 struct tipc_msg *msg = buf_msg(buf);
641 struct tipc_port *port = &tsk->port;
642 int conn_cong; 796 int conn_cong;
643 797
644 /* Ignore if connection cannot be validated: */ 798 /* Ignore if connection cannot be validated: */
645 if (!port->connected || !tipc_port_peer_msg(port, msg)) 799 if (!tsk_peer_msg(tsk, msg))
646 goto exit; 800 goto exit;
647 801
648 port->probing_state = TIPC_CONN_OK; 802 tsk->probing_state = TIPC_CONN_OK;
649 803
650 if (msg_type(msg) == CONN_ACK) { 804 if (msg_type(msg) == CONN_ACK) {
651 conn_cong = tipc_sk_conn_cong(tsk); 805 conn_cong = tsk_conn_cong(tsk);
652 tsk->sent_unacked -= msg_msgcnt(msg); 806 tsk->sent_unacked -= msg_msgcnt(msg);
653 if (conn_cong) 807 if (conn_cong)
654 tipc_sock_wakeup(tsk); 808 tsk->sk.sk_write_space(&tsk->sk);
655 } else if (msg_type(msg) == CONN_PROBE) { 809 } else if (msg_type(msg) == CONN_PROBE) {
656 if (!tipc_msg_reverse(buf, dnode, TIPC_OK)) 810 if (!tipc_msg_reverse(buf, dnode, TIPC_OK))
657 return TIPC_OK; 811 return TIPC_OK;
@@ -742,8 +896,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
742 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); 896 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
743 struct sock *sk = sock->sk; 897 struct sock *sk = sock->sk;
744 struct tipc_sock *tsk = tipc_sk(sk); 898 struct tipc_sock *tsk = tipc_sk(sk);
745 struct tipc_port *port = &tsk->port; 899 struct tipc_msg *mhdr = &tsk->phdr;
746 struct tipc_msg *mhdr = &port->phdr;
747 struct iovec *iov = m->msg_iov; 900 struct iovec *iov = m->msg_iov;
748 u32 dnode, dport; 901 u32 dnode, dport;
749 struct sk_buff *buf; 902 struct sk_buff *buf;
@@ -774,13 +927,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
774 rc = -EISCONN; 927 rc = -EISCONN;
775 goto exit; 928 goto exit;
776 } 929 }
777 if (tsk->port.published) { 930 if (tsk->published) {
778 rc = -EOPNOTSUPP; 931 rc = -EOPNOTSUPP;
779 goto exit; 932 goto exit;
780 } 933 }
781 if (dest->addrtype == TIPC_ADDR_NAME) { 934 if (dest->addrtype == TIPC_ADDR_NAME) {
782 tsk->port.conn_type = dest->addr.name.name.type; 935 tsk->conn_type = dest->addr.name.name.type;
783 tsk->port.conn_instance = dest->addr.name.name.instance; 936 tsk->conn_instance = dest->addr.name.name.instance;
784 } 937 }
785 } 938 }
786 rc = dest_name_check(dest, m); 939 rc = dest_name_check(dest, m);
@@ -820,13 +973,14 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
820 } 973 }
821 974
822new_mtu: 975new_mtu:
823 mtu = tipc_node_get_mtu(dnode, tsk->port.ref); 976 mtu = tipc_node_get_mtu(dnode, tsk->ref);
824 rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); 977 rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
825 if (rc < 0) 978 if (rc < 0)
826 goto exit; 979 goto exit;
827 980
828 do { 981 do {
829 rc = tipc_link_xmit(buf, dnode, tsk->port.ref); 982 TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong;
983 rc = tipc_link_xmit(buf, dnode, tsk->ref);
830 if (likely(rc >= 0)) { 984 if (likely(rc >= 0)) {
831 if (sock->state != SS_READY) 985 if (sock->state != SS_READY)
832 sock->state = SS_CONNECTING; 986 sock->state = SS_CONNECTING;
@@ -835,10 +989,9 @@ new_mtu:
835 } 989 }
836 if (rc == -EMSGSIZE) 990 if (rc == -EMSGSIZE)
837 goto new_mtu; 991 goto new_mtu;
838
839 if (rc != -ELINKCONG) 992 if (rc != -ELINKCONG)
840 break; 993 break;
841 994 tsk->link_cong = 1;
842 rc = tipc_wait_for_sndmsg(sock, &timeo); 995 rc = tipc_wait_for_sndmsg(sock, &timeo);
843 if (rc) 996 if (rc)
844 kfree_skb_list(buf); 997 kfree_skb_list(buf);
@@ -873,8 +1026,8 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
873 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1026 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
874 done = sk_wait_event(sk, timeo_p, 1027 done = sk_wait_event(sk, timeo_p,
875 (!tsk->link_cong && 1028 (!tsk->link_cong &&
876 !tipc_sk_conn_cong(tsk)) || 1029 !tsk_conn_cong(tsk)) ||
877 !tsk->port.connected); 1030 !tsk->connected);
878 finish_wait(sk_sleep(sk), &wait); 1031 finish_wait(sk_sleep(sk), &wait);
879 } while (!done); 1032 } while (!done);
880 return 0; 1033 return 0;
@@ -897,11 +1050,10 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
897{ 1050{
898 struct sock *sk = sock->sk; 1051 struct sock *sk = sock->sk;
899 struct tipc_sock *tsk = tipc_sk(sk); 1052 struct tipc_sock *tsk = tipc_sk(sk);
900 struct tipc_port *port = &tsk->port; 1053 struct tipc_msg *mhdr = &tsk->phdr;
901 struct tipc_msg *mhdr = &port->phdr;
902 struct sk_buff *buf; 1054 struct sk_buff *buf;
903 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); 1055 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
904 u32 ref = port->ref; 1056 u32 ref = tsk->ref;
905 int rc = -EINVAL; 1057 int rc = -EINVAL;
906 long timeo; 1058 long timeo;
907 u32 dnode; 1059 u32 dnode;
@@ -929,16 +1081,16 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
929 } 1081 }
930 1082
931 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 1083 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
932 dnode = tipc_port_peernode(port); 1084 dnode = tsk_peer_node(tsk);
933 1085
934next: 1086next:
935 mtu = port->max_pkt; 1087 mtu = tsk->max_pkt;
936 send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); 1088 send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
937 rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf); 1089 rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf);
938 if (unlikely(rc < 0)) 1090 if (unlikely(rc < 0))
939 goto exit; 1091 goto exit;
940 do { 1092 do {
941 if (likely(!tipc_sk_conn_cong(tsk))) { 1093 if (likely(!tsk_conn_cong(tsk))) {
942 rc = tipc_link_xmit(buf, dnode, ref); 1094 rc = tipc_link_xmit(buf, dnode, ref);
943 if (likely(!rc)) { 1095 if (likely(!rc)) {
944 tsk->sent_unacked++; 1096 tsk->sent_unacked++;
@@ -948,11 +1100,12 @@ next:
948 goto next; 1100 goto next;
949 } 1101 }
950 if (rc == -EMSGSIZE) { 1102 if (rc == -EMSGSIZE) {
951 port->max_pkt = tipc_node_get_mtu(dnode, ref); 1103 tsk->max_pkt = tipc_node_get_mtu(dnode, ref);
952 goto next; 1104 goto next;
953 } 1105 }
954 if (rc != -ELINKCONG) 1106 if (rc != -ELINKCONG)
955 break; 1107 break;
1108 tsk->link_cong = 1;
956 } 1109 }
957 rc = tipc_wait_for_sndpkt(sock, &timeo); 1110 rc = tipc_wait_for_sndpkt(sock, &timeo);
958 if (rc) 1111 if (rc)
@@ -984,29 +1137,25 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,
984 return tipc_send_stream(iocb, sock, m, dsz); 1137 return tipc_send_stream(iocb, sock, m, dsz);
985} 1138}
986 1139
987/** 1140/* tipc_sk_finish_conn - complete the setup of a connection
988 * auto_connect - complete connection setup to a remote port
989 * @tsk: tipc socket structure
990 * @msg: peer's response message
991 *
992 * Returns 0 on success, errno otherwise
993 */ 1141 */
994static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg) 1142static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
1143 u32 peer_node)
995{ 1144{
996 struct tipc_port *port = &tsk->port; 1145 struct tipc_msg *msg = &tsk->phdr;
997 struct socket *sock = tsk->sk.sk_socket; 1146
998 struct tipc_portid peer; 1147 msg_set_destnode(msg, peer_node);
999 1148 msg_set_destport(msg, peer_port);
1000 peer.ref = msg_origport(msg); 1149 msg_set_type(msg, TIPC_CONN_MSG);
1001 peer.node = msg_orignode(msg); 1150 msg_set_lookup_scope(msg, 0);
1002 1151 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1003 __tipc_port_connect(port->ref, port, &peer); 1152
1004 1153 tsk->probing_interval = CONN_PROBING_INTERVAL;
1005 if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) 1154 tsk->probing_state = TIPC_CONN_OK;
1006 return -EINVAL; 1155 tsk->connected = 1;
1007 msg_set_importance(&port->phdr, (u32)msg_importance(msg)); 1156 k_start_timer(&tsk->timer, tsk->probing_interval);
1008 sock->state = SS_CONNECTED; 1157 tipc_node_add_conn(peer_node, tsk->ref, peer_port);
1009 return 0; 1158 tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->ref);
1010} 1159}
1011 1160
1012/** 1161/**
@@ -1033,17 +1182,17 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
1033} 1182}
1034 1183
1035/** 1184/**
1036 * anc_data_recv - optionally capture ancillary data for received message 1185 * tipc_sk_anc_data_recv - optionally capture ancillary data for received message
1037 * @m: descriptor for message info 1186 * @m: descriptor for message info
1038 * @msg: received message header 1187 * @msg: received message header
1039 * @tport: TIPC port associated with message 1188 * @tsk: TIPC port associated with message
1040 * 1189 *
1041 * Note: Ancillary data is not captured if not requested by receiver. 1190 * Note: Ancillary data is not captured if not requested by receiver.
1042 * 1191 *
1043 * Returns 0 if successful, otherwise errno 1192 * Returns 0 if successful, otherwise errno
1044 */ 1193 */
1045static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, 1194static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
1046 struct tipc_port *tport) 1195 struct tipc_sock *tsk)
1047{ 1196{
1048 u32 anc_data[3]; 1197 u32 anc_data[3];
1049 u32 err; 1198 u32 err;
@@ -1086,10 +1235,10 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
1086 anc_data[2] = msg_nameupper(msg); 1235 anc_data[2] = msg_nameupper(msg);
1087 break; 1236 break;
1088 case TIPC_CONN_MSG: 1237 case TIPC_CONN_MSG:
1089 has_name = (tport->conn_type != 0); 1238 has_name = (tsk->conn_type != 0);
1090 anc_data[0] = tport->conn_type; 1239 anc_data[0] = tsk->conn_type;
1091 anc_data[1] = tport->conn_instance; 1240 anc_data[1] = tsk->conn_instance;
1092 anc_data[2] = tport->conn_instance; 1241 anc_data[2] = tsk->conn_instance;
1093 break; 1242 break;
1094 default: 1243 default:
1095 has_name = 0; 1244 has_name = 0;
@@ -1103,6 +1252,24 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
1103 return 0; 1252 return 0;
1104} 1253}
1105 1254
1255static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack)
1256{
1257 struct sk_buff *buf = NULL;
1258 struct tipc_msg *msg;
1259 u32 peer_port = tsk_peer_port(tsk);
1260 u32 dnode = tsk_peer_node(tsk);
1261
1262 if (!tsk->connected)
1263 return;
1264 buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
1265 tipc_own_addr, peer_port, tsk->ref, TIPC_OK);
1266 if (!buf)
1267 return;
1268 msg = buf_msg(buf);
1269 msg_set_msgcnt(msg, ack);
1270 tipc_link_xmit(buf, dnode, msg_link_selector(msg));
1271}
1272
1106static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) 1273static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
1107{ 1274{
1108 struct sock *sk = sock->sk; 1275 struct sock *sk = sock->sk;
@@ -1153,7 +1320,6 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock,
1153{ 1320{
1154 struct sock *sk = sock->sk; 1321 struct sock *sk = sock->sk;
1155 struct tipc_sock *tsk = tipc_sk(sk); 1322 struct tipc_sock *tsk = tipc_sk(sk);
1156 struct tipc_port *port = &tsk->port;
1157 struct sk_buff *buf; 1323 struct sk_buff *buf;
1158 struct tipc_msg *msg; 1324 struct tipc_msg *msg;
1159 long timeo; 1325 long timeo;
@@ -1188,7 +1354,7 @@ restart:
1188 1354
1189 /* Discard an empty non-errored message & try again */ 1355 /* Discard an empty non-errored message & try again */
1190 if ((!sz) && (!err)) { 1356 if ((!sz) && (!err)) {
1191 advance_rx_queue(sk); 1357 tsk_advance_rx_queue(sk);
1192 goto restart; 1358 goto restart;
1193 } 1359 }
1194 1360
@@ -1196,7 +1362,7 @@ restart:
1196 set_orig_addr(m, msg); 1362 set_orig_addr(m, msg);
1197 1363
1198 /* Capture ancillary data (optional) */ 1364 /* Capture ancillary data (optional) */
1199 res = anc_data_recv(m, msg, port); 1365 res = tipc_sk_anc_data_recv(m, msg, tsk);
1200 if (res) 1366 if (res)
1201 goto exit; 1367 goto exit;
1202 1368
@@ -1223,10 +1389,10 @@ restart:
1223 if (likely(!(flags & MSG_PEEK))) { 1389 if (likely(!(flags & MSG_PEEK))) {
1224 if ((sock->state != SS_READY) && 1390 if ((sock->state != SS_READY) &&
1225 (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) { 1391 (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
1226 tipc_acknowledge(port->ref, tsk->rcv_unacked); 1392 tipc_sk_send_ack(tsk, tsk->rcv_unacked);
1227 tsk->rcv_unacked = 0; 1393 tsk->rcv_unacked = 0;
1228 } 1394 }
1229 advance_rx_queue(sk); 1395 tsk_advance_rx_queue(sk);
1230 } 1396 }
1231exit: 1397exit:
1232 release_sock(sk); 1398 release_sock(sk);
@@ -1250,7 +1416,6 @@ static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock,
1250{ 1416{
1251 struct sock *sk = sock->sk; 1417 struct sock *sk = sock->sk;
1252 struct tipc_sock *tsk = tipc_sk(sk); 1418 struct tipc_sock *tsk = tipc_sk(sk);
1253 struct tipc_port *port = &tsk->port;
1254 struct sk_buff *buf; 1419 struct sk_buff *buf;
1255 struct tipc_msg *msg; 1420 struct tipc_msg *msg;
1256 long timeo; 1421 long timeo;
@@ -1288,14 +1453,14 @@ restart:
1288 1453
1289 /* Discard an empty non-errored message & try again */ 1454 /* Discard an empty non-errored message & try again */
1290 if ((!sz) && (!err)) { 1455 if ((!sz) && (!err)) {
1291 advance_rx_queue(sk); 1456 tsk_advance_rx_queue(sk);
1292 goto restart; 1457 goto restart;
1293 } 1458 }
1294 1459
1295 /* Optionally capture sender's address & ancillary data of first msg */ 1460 /* Optionally capture sender's address & ancillary data of first msg */
1296 if (sz_copied == 0) { 1461 if (sz_copied == 0) {
1297 set_orig_addr(m, msg); 1462 set_orig_addr(m, msg);
1298 res = anc_data_recv(m, msg, port); 1463 res = tipc_sk_anc_data_recv(m, msg, tsk);
1299 if (res) 1464 if (res)
1300 goto exit; 1465 goto exit;
1301 } 1466 }
@@ -1334,10 +1499,10 @@ restart:
1334 /* Consume received message (optional) */ 1499 /* Consume received message (optional) */
1335 if (likely(!(flags & MSG_PEEK))) { 1500 if (likely(!(flags & MSG_PEEK))) {
1336 if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) { 1501 if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
1337 tipc_acknowledge(port->ref, tsk->rcv_unacked); 1502 tipc_sk_send_ack(tsk, tsk->rcv_unacked);
1338 tsk->rcv_unacked = 0; 1503 tsk->rcv_unacked = 0;
1339 } 1504 }
1340 advance_rx_queue(sk); 1505 tsk_advance_rx_queue(sk);
1341 } 1506 }
1342 1507
1343 /* Loop around if more data is required */ 1508 /* Loop around if more data is required */
@@ -1396,12 +1561,9 @@ static void tipc_data_ready(struct sock *sk)
1396static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) 1561static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1397{ 1562{
1398 struct sock *sk = &tsk->sk; 1563 struct sock *sk = &tsk->sk;
1399 struct tipc_port *port = &tsk->port;
1400 struct socket *sock = sk->sk_socket; 1564 struct socket *sock = sk->sk_socket;
1401 struct tipc_msg *msg = buf_msg(*buf); 1565 struct tipc_msg *msg = buf_msg(*buf);
1402
1403 int retval = -TIPC_ERR_NO_PORT; 1566 int retval = -TIPC_ERR_NO_PORT;
1404 int res;
1405 1567
1406 if (msg_mcast(msg)) 1568 if (msg_mcast(msg))
1407 return retval; 1569 return retval;
@@ -1409,16 +1571,23 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1409 switch ((int)sock->state) { 1571 switch ((int)sock->state) {
1410 case SS_CONNECTED: 1572 case SS_CONNECTED:
1411 /* Accept only connection-based messages sent by peer */ 1573 /* Accept only connection-based messages sent by peer */
1412 if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { 1574 if (tsk_peer_msg(tsk, msg)) {
1413 if (unlikely(msg_errcode(msg))) { 1575 if (unlikely(msg_errcode(msg))) {
1414 sock->state = SS_DISCONNECTING; 1576 sock->state = SS_DISCONNECTING;
1415 __tipc_port_disconnect(port); 1577 tsk->connected = 0;
1578 /* let timer expire on it's own */
1579 tipc_node_remove_conn(tsk_peer_node(tsk),
1580 tsk->ref);
1416 } 1581 }
1417 retval = TIPC_OK; 1582 retval = TIPC_OK;
1418 } 1583 }
1419 break; 1584 break;
1420 case SS_CONNECTING: 1585 case SS_CONNECTING:
1421 /* Accept only ACK or NACK message */ 1586 /* Accept only ACK or NACK message */
1587
1588 if (unlikely(!msg_connected(msg)))
1589 break;
1590
1422 if (unlikely(msg_errcode(msg))) { 1591 if (unlikely(msg_errcode(msg))) {
1423 sock->state = SS_DISCONNECTING; 1592 sock->state = SS_DISCONNECTING;
1424 sk->sk_err = ECONNREFUSED; 1593 sk->sk_err = ECONNREFUSED;
@@ -1426,17 +1595,17 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1426 break; 1595 break;
1427 } 1596 }
1428 1597
1429 if (unlikely(!msg_connected(msg))) 1598 if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) {
1430 break;
1431
1432 res = auto_connect(tsk, msg);
1433 if (res) {
1434 sock->state = SS_DISCONNECTING; 1599 sock->state = SS_DISCONNECTING;
1435 sk->sk_err = -res; 1600 sk->sk_err = EINVAL;
1436 retval = TIPC_OK; 1601 retval = TIPC_OK;
1437 break; 1602 break;
1438 } 1603 }
1439 1604
1605 tipc_sk_finish_conn(tsk, msg_origport(msg), msg_orignode(msg));
1606 msg_set_importance(&tsk->phdr, msg_importance(msg));
1607 sock->state = SS_CONNECTED;
1608
1440 /* If an incoming message is an 'ACK-', it should be 1609 /* If an incoming message is an 'ACK-', it should be
1441 * discarded here because it doesn't contain useful 1610 * discarded here because it doesn't contain useful
1442 * data. In addition, we should try to wake up 1611 * data. In addition, we should try to wake up
@@ -1518,6 +1687,13 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
1518 if (unlikely(msg_user(msg) == CONN_MANAGER)) 1687 if (unlikely(msg_user(msg) == CONN_MANAGER))
1519 return tipc_sk_proto_rcv(tsk, &onode, buf); 1688 return tipc_sk_proto_rcv(tsk, &onode, buf);
1520 1689
1690 if (unlikely(msg_user(msg) == SOCK_WAKEUP)) {
1691 kfree_skb(buf);
1692 tsk->link_cong = 0;
1693 sk->sk_write_space(sk);
1694 return TIPC_OK;
1695 }
1696
1521 /* Reject message if it is wrong sort of message for socket */ 1697 /* Reject message if it is wrong sort of message for socket */
1522 if (msg_type(msg) > TIPC_DIRECT_MSG) 1698 if (msg_type(msg) > TIPC_DIRECT_MSG)
1523 return -TIPC_ERR_NO_PORT; 1699 return -TIPC_ERR_NO_PORT;
@@ -1585,7 +1761,6 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
1585int tipc_sk_rcv(struct sk_buff *buf) 1761int tipc_sk_rcv(struct sk_buff *buf)
1586{ 1762{
1587 struct tipc_sock *tsk; 1763 struct tipc_sock *tsk;
1588 struct tipc_port *port;
1589 struct sock *sk; 1764 struct sock *sk;
1590 u32 dport = msg_destport(buf_msg(buf)); 1765 u32 dport = msg_destport(buf_msg(buf));
1591 int rc = TIPC_OK; 1766 int rc = TIPC_OK;
@@ -1593,13 +1768,11 @@ int tipc_sk_rcv(struct sk_buff *buf)
1593 u32 dnode; 1768 u32 dnode;
1594 1769
1595 /* Validate destination and message */ 1770 /* Validate destination and message */
1596 port = tipc_port_lock(dport); 1771 tsk = tipc_sk_get(dport);
1597 if (unlikely(!port)) { 1772 if (unlikely(!tsk)) {
1598 rc = tipc_msg_eval(buf, &dnode); 1773 rc = tipc_msg_eval(buf, &dnode);
1599 goto exit; 1774 goto exit;
1600 } 1775 }
1601
1602 tsk = tipc_port_to_sock(port);
1603 sk = &tsk->sk; 1776 sk = &tsk->sk;
1604 1777
1605 /* Queue message */ 1778 /* Queue message */
@@ -1615,8 +1788,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
1615 rc = -TIPC_ERR_OVERLOAD; 1788 rc = -TIPC_ERR_OVERLOAD;
1616 } 1789 }
1617 bh_unlock_sock(sk); 1790 bh_unlock_sock(sk);
1618 tipc_port_unlock(port); 1791 tipc_sk_put(tsk);
1619
1620 if (likely(!rc)) 1792 if (likely(!rc))
1621 return 0; 1793 return 0;
1622exit: 1794exit:
@@ -1803,10 +1975,8 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1803{ 1975{
1804 struct sock *new_sk, *sk = sock->sk; 1976 struct sock *new_sk, *sk = sock->sk;
1805 struct sk_buff *buf; 1977 struct sk_buff *buf;
1806 struct tipc_port *new_port; 1978 struct tipc_sock *new_tsock;
1807 struct tipc_msg *msg; 1979 struct tipc_msg *msg;
1808 struct tipc_portid peer;
1809 u32 new_ref;
1810 long timeo; 1980 long timeo;
1811 int res; 1981 int res;
1812 1982
@@ -1828,8 +1998,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1828 goto exit; 1998 goto exit;
1829 1999
1830 new_sk = new_sock->sk; 2000 new_sk = new_sock->sk;
1831 new_port = &tipc_sk(new_sk)->port; 2001 new_tsock = tipc_sk(new_sk);
1832 new_ref = new_port->ref;
1833 msg = buf_msg(buf); 2002 msg = buf_msg(buf);
1834 2003
1835 /* we lock on new_sk; but lockdep sees the lock on sk */ 2004 /* we lock on new_sk; but lockdep sees the lock on sk */
@@ -1839,18 +2008,16 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1839 * Reject any stray messages received by new socket 2008 * Reject any stray messages received by new socket
1840 * before the socket lock was taken (very, very unlikely) 2009 * before the socket lock was taken (very, very unlikely)
1841 */ 2010 */
1842 reject_rx_queue(new_sk); 2011 tsk_rej_rx_queue(new_sk);
1843 2012
1844 /* Connect new socket to it's peer */ 2013 /* Connect new socket to it's peer */
1845 peer.ref = msg_origport(msg); 2014 tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));
1846 peer.node = msg_orignode(msg);
1847 tipc_port_connect(new_ref, &peer);
1848 new_sock->state = SS_CONNECTED; 2015 new_sock->state = SS_CONNECTED;
1849 2016
1850 tipc_port_set_importance(new_port, msg_importance(msg)); 2017 tsk_set_importance(new_tsock, msg_importance(msg));
1851 if (msg_named(msg)) { 2018 if (msg_named(msg)) {
1852 new_port->conn_type = msg_nametype(msg); 2019 new_tsock->conn_type = msg_nametype(msg);
1853 new_port->conn_instance = msg_nameinst(msg); 2020 new_tsock->conn_instance = msg_nameinst(msg);
1854 } 2021 }
1855 2022
1856 /* 2023 /*
@@ -1860,7 +2027,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1860 if (!msg_data_sz(msg)) { 2027 if (!msg_data_sz(msg)) {
1861 struct msghdr m = {NULL,}; 2028 struct msghdr m = {NULL,};
1862 2029
1863 advance_rx_queue(sk); 2030 tsk_advance_rx_queue(sk);
1864 tipc_send_packet(NULL, new_sock, &m, 0); 2031 tipc_send_packet(NULL, new_sock, &m, 0);
1865 } else { 2032 } else {
1866 __skb_dequeue(&sk->sk_receive_queue); 2033 __skb_dequeue(&sk->sk_receive_queue);
@@ -1886,9 +2053,8 @@ static int tipc_shutdown(struct socket *sock, int how)
1886{ 2053{
1887 struct sock *sk = sock->sk; 2054 struct sock *sk = sock->sk;
1888 struct tipc_sock *tsk = tipc_sk(sk); 2055 struct tipc_sock *tsk = tipc_sk(sk);
1889 struct tipc_port *port = &tsk->port;
1890 struct sk_buff *buf; 2056 struct sk_buff *buf;
1891 u32 peer; 2057 u32 dnode;
1892 int res; 2058 int res;
1893 2059
1894 if (how != SHUT_RDWR) 2060 if (how != SHUT_RDWR)
@@ -1908,15 +2074,21 @@ restart:
1908 kfree_skb(buf); 2074 kfree_skb(buf);
1909 goto restart; 2075 goto restart;
1910 } 2076 }
1911 tipc_port_disconnect(port->ref); 2077 if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
1912 if (tipc_msg_reverse(buf, &peer, TIPC_CONN_SHUTDOWN)) 2078 tipc_link_xmit(buf, dnode, tsk->ref);
1913 tipc_link_xmit(buf, peer, 0); 2079 tipc_node_remove_conn(dnode, tsk->ref);
1914 } else { 2080 } else {
1915 tipc_port_shutdown(port->ref); 2081 dnode = tsk_peer_node(tsk);
2082 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
2083 TIPC_CONN_MSG, SHORT_H_SIZE,
2084 0, dnode, tipc_own_addr,
2085 tsk_peer_port(tsk),
2086 tsk->ref, TIPC_CONN_SHUTDOWN);
2087 tipc_link_xmit(buf, dnode, tsk->ref);
1916 } 2088 }
1917 2089 tsk->connected = 0;
1918 sock->state = SS_DISCONNECTING; 2090 sock->state = SS_DISCONNECTING;
1919 2091 tipc_node_remove_conn(dnode, tsk->ref);
1920 /* fall through */ 2092 /* fall through */
1921 2093
1922 case SS_DISCONNECTING: 2094 case SS_DISCONNECTING:
@@ -1937,6 +2109,432 @@ restart:
1937 return res; 2109 return res;
1938} 2110}
1939 2111
2112static void tipc_sk_timeout(unsigned long ref)
2113{
2114 struct tipc_sock *tsk;
2115 struct sock *sk;
2116 struct sk_buff *buf = NULL;
2117 u32 peer_port, peer_node;
2118
2119 tsk = tipc_sk_get(ref);
2120 if (!tsk)
2121 goto exit;
2122 sk = &tsk->sk;
2123
2124 bh_lock_sock(sk);
2125 if (!tsk->connected) {
2126 bh_unlock_sock(sk);
2127 goto exit;
2128 }
2129 peer_port = tsk_peer_port(tsk);
2130 peer_node = tsk_peer_node(tsk);
2131
2132 if (tsk->probing_state == TIPC_CONN_PROBING) {
2133 /* Previous probe not answered -> self abort */
2134 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
2135 SHORT_H_SIZE, 0, tipc_own_addr,
2136 peer_node, ref, peer_port,
2137 TIPC_ERR_NO_PORT);
2138 } else {
2139 buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
2140 0, peer_node, tipc_own_addr,
2141 peer_port, ref, TIPC_OK);
2142 tsk->probing_state = TIPC_CONN_PROBING;
2143 k_start_timer(&tsk->timer, tsk->probing_interval);
2144 }
2145 bh_unlock_sock(sk);
2146 if (buf)
2147 tipc_link_xmit(buf, peer_node, ref);
2148exit:
2149 tipc_sk_put(tsk);
2150}
2151
2152static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
2153 struct tipc_name_seq const *seq)
2154{
2155 struct publication *publ;
2156 u32 key;
2157
2158 if (tsk->connected)
2159 return -EINVAL;
2160 key = tsk->ref + tsk->pub_count + 1;
2161 if (key == tsk->ref)
2162 return -EADDRINUSE;
2163
2164 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
2165 scope, tsk->ref, key);
2166 if (unlikely(!publ))
2167 return -EINVAL;
2168
2169 list_add(&publ->pport_list, &tsk->publications);
2170 tsk->pub_count++;
2171 tsk->published = 1;
2172 return 0;
2173}
2174
2175static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
2176 struct tipc_name_seq const *seq)
2177{
2178 struct publication *publ;
2179 struct publication *safe;
2180 int rc = -EINVAL;
2181
2182 list_for_each_entry_safe(publ, safe, &tsk->publications, pport_list) {
2183 if (seq) {
2184 if (publ->scope != scope)
2185 continue;
2186 if (publ->type != seq->type)
2187 continue;
2188 if (publ->lower != seq->lower)
2189 continue;
2190 if (publ->upper != seq->upper)
2191 break;
2192 tipc_nametbl_withdraw(publ->type, publ->lower,
2193 publ->ref, publ->key);
2194 rc = 0;
2195 break;
2196 }
2197 tipc_nametbl_withdraw(publ->type, publ->lower,
2198 publ->ref, publ->key);
2199 rc = 0;
2200 }
2201 if (list_empty(&tsk->publications))
2202 tsk->published = 0;
2203 return rc;
2204}
2205
2206static int tipc_sk_show(struct tipc_sock *tsk, char *buf,
2207 int len, int full_id)
2208{
2209 struct publication *publ;
2210 int ret;
2211
2212 if (full_id)
2213 ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
2214 tipc_zone(tipc_own_addr),
2215 tipc_cluster(tipc_own_addr),
2216 tipc_node(tipc_own_addr), tsk->ref);
2217 else
2218 ret = tipc_snprintf(buf, len, "%-10u:", tsk->ref);
2219
2220 if (tsk->connected) {
2221 u32 dport = tsk_peer_port(tsk);
2222 u32 destnode = tsk_peer_node(tsk);
2223
2224 ret += tipc_snprintf(buf + ret, len - ret,
2225 " connected to <%u.%u.%u:%u>",
2226 tipc_zone(destnode),
2227 tipc_cluster(destnode),
2228 tipc_node(destnode), dport);
2229 if (tsk->conn_type != 0)
2230 ret += tipc_snprintf(buf + ret, len - ret,
2231 " via {%u,%u}", tsk->conn_type,
2232 tsk->conn_instance);
2233 } else if (tsk->published) {
2234 ret += tipc_snprintf(buf + ret, len - ret, " bound to");
2235 list_for_each_entry(publ, &tsk->publications, pport_list) {
2236 if (publ->lower == publ->upper)
2237 ret += tipc_snprintf(buf + ret, len - ret,
2238 " {%u,%u}", publ->type,
2239 publ->lower);
2240 else
2241 ret += tipc_snprintf(buf + ret, len - ret,
2242 " {%u,%u,%u}", publ->type,
2243 publ->lower, publ->upper);
2244 }
2245 }
2246 ret += tipc_snprintf(buf + ret, len - ret, "\n");
2247 return ret;
2248}
2249
2250struct sk_buff *tipc_sk_socks_show(void)
2251{
2252 struct sk_buff *buf;
2253 struct tlv_desc *rep_tlv;
2254 char *pb;
2255 int pb_len;
2256 struct tipc_sock *tsk;
2257 int str_len = 0;
2258 u32 ref = 0;
2259
2260 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
2261 if (!buf)
2262 return NULL;
2263 rep_tlv = (struct tlv_desc *)buf->data;
2264 pb = TLV_DATA(rep_tlv);
2265 pb_len = ULTRA_STRING_MAX_LEN;
2266
2267 tsk = tipc_sk_get_next(&ref);
2268 for (; tsk; tsk = tipc_sk_get_next(&ref)) {
2269 lock_sock(&tsk->sk);
2270 str_len += tipc_sk_show(tsk, pb + str_len,
2271 pb_len - str_len, 0);
2272 release_sock(&tsk->sk);
2273 tipc_sk_put(tsk);
2274 }
2275 str_len += 1; /* for "\0" */
2276 skb_put(buf, TLV_SPACE(str_len));
2277 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
2278
2279 return buf;
2280}
2281
2282/* tipc_sk_reinit: set non-zero address in all existing sockets
2283 * when we go from standalone to network mode.
2284 */
2285void tipc_sk_reinit(void)
2286{
2287 struct tipc_msg *msg;
2288 u32 ref = 0;
2289 struct tipc_sock *tsk = tipc_sk_get_next(&ref);
2290
2291 for (; tsk; tsk = tipc_sk_get_next(&ref)) {
2292 lock_sock(&tsk->sk);
2293 msg = &tsk->phdr;
2294 msg_set_prevnode(msg, tipc_own_addr);
2295 msg_set_orignode(msg, tipc_own_addr);
2296 release_sock(&tsk->sk);
2297 tipc_sk_put(tsk);
2298 }
2299}
2300
2301/**
2302 * struct reference - TIPC socket reference entry
2303 * @tsk: pointer to socket associated with reference entry
2304 * @ref: reference value for socket (combines instance & array index info)
2305 */
2306struct reference {
2307 struct tipc_sock *tsk;
2308 u32 ref;
2309};
2310
2311/**
2312 * struct tipc_ref_table - table of TIPC socket reference entries
2313 * @entries: pointer to array of reference entries
2314 * @capacity: array index of first unusable entry
2315 * @init_point: array index of first uninitialized entry
2316 * @first_free: array index of first unused socket reference entry
2317 * @last_free: array index of last unused socket reference entry
2318 * @index_mask: bitmask for array index portion of reference values
2319 * @start_mask: initial value for instance value portion of reference values
2320 */
2321struct ref_table {
2322 struct reference *entries;
2323 u32 capacity;
2324 u32 init_point;
2325 u32 first_free;
2326 u32 last_free;
2327 u32 index_mask;
2328 u32 start_mask;
2329};
2330
2331/* Socket reference table consists of 2**N entries.
2332 *
2333 * State Socket ptr Reference
2334 * ----- ---------- ---------
2335 * In use non-NULL XXXX|own index
2336 * (XXXX changes each time entry is acquired)
2337 * Free NULL YYYY|next free index
2338 * (YYYY is one more than last used XXXX)
2339 * Uninitialized NULL 0
2340 *
2341 * Entry 0 is not used; this allows index 0 to denote the end of the free list.
2342 *
2343 * Note that a reference value of 0 does not necessarily indicate that an
2344 * entry is uninitialized, since the last entry in the free list could also
2345 * have a reference value of 0 (although this is unlikely).
2346 */
2347
2348static struct ref_table tipc_ref_table;
2349
2350static DEFINE_RWLOCK(ref_table_lock);
2351
2352/**
2353 * tipc_ref_table_init - create reference table for sockets
2354 */
2355int tipc_sk_ref_table_init(u32 req_sz, u32 start)
2356{
2357 struct reference *table;
2358 u32 actual_sz;
2359
2360 /* account for unused entry, then round up size to a power of 2 */
2361
2362 req_sz++;
2363 for (actual_sz = 16; actual_sz < req_sz; actual_sz <<= 1) {
2364 /* do nothing */
2365 };
2366
2367 /* allocate table & mark all entries as uninitialized */
2368 table = vzalloc(actual_sz * sizeof(struct reference));
2369 if (table == NULL)
2370 return -ENOMEM;
2371
2372 tipc_ref_table.entries = table;
2373 tipc_ref_table.capacity = req_sz;
2374 tipc_ref_table.init_point = 1;
2375 tipc_ref_table.first_free = 0;
2376 tipc_ref_table.last_free = 0;
2377 tipc_ref_table.index_mask = actual_sz - 1;
2378 tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
2379
2380 return 0;
2381}
2382
2383/**
2384 * tipc_ref_table_stop - destroy reference table for sockets
2385 */
2386void tipc_sk_ref_table_stop(void)
2387{
2388 if (!tipc_ref_table.entries)
2389 return;
2390 vfree(tipc_ref_table.entries);
2391 tipc_ref_table.entries = NULL;
2392}
2393
2394/* tipc_ref_acquire - create reference to a socket
2395 *
2396 * Register an socket pointer in the reference table.
2397 * Returns a unique reference value that is used from then on to retrieve the
2398 * socket pointer, or to determine if the socket has been deregistered.
2399 */
2400u32 tipc_sk_ref_acquire(struct tipc_sock *tsk)
2401{
2402 u32 index;
2403 u32 index_mask;
2404 u32 next_plus_upper;
2405 u32 ref = 0;
2406 struct reference *entry;
2407
2408 if (unlikely(!tsk)) {
2409 pr_err("Attempt to acquire ref. to non-existent obj\n");
2410 return 0;
2411 }
2412 if (unlikely(!tipc_ref_table.entries)) {
2413 pr_err("Ref. table not found in acquisition attempt\n");
2414 return 0;
2415 }
2416
2417 /* Take a free entry, if available; otherwise initialize a new one */
2418 write_lock_bh(&ref_table_lock);
2419 index = tipc_ref_table.first_free;
2420 entry = &tipc_ref_table.entries[index];
2421
2422 if (likely(index)) {
2423 index = tipc_ref_table.first_free;
2424 entry = &tipc_ref_table.entries[index];
2425 index_mask = tipc_ref_table.index_mask;
2426 next_plus_upper = entry->ref;
2427 tipc_ref_table.first_free = next_plus_upper & index_mask;
2428 ref = (next_plus_upper & ~index_mask) + index;
2429 entry->tsk = tsk;
2430 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
2431 index = tipc_ref_table.init_point++;
2432 entry = &tipc_ref_table.entries[index];
2433 ref = tipc_ref_table.start_mask + index;
2434 }
2435
2436 if (ref) {
2437 entry->ref = ref;
2438 entry->tsk = tsk;
2439 }
2440 write_unlock_bh(&ref_table_lock);
2441 return ref;
2442}
2443
2444/* tipc_sk_ref_discard - invalidate reference to an socket
2445 *
2446 * Disallow future references to an socket and free up the entry for re-use.
2447 */
2448void tipc_sk_ref_discard(u32 ref)
2449{
2450 struct reference *entry;
2451 u32 index;
2452 u32 index_mask;
2453
2454 if (unlikely(!tipc_ref_table.entries)) {
2455 pr_err("Ref. table not found during discard attempt\n");
2456 return;
2457 }
2458
2459 index_mask = tipc_ref_table.index_mask;
2460 index = ref & index_mask;
2461 entry = &tipc_ref_table.entries[index];
2462
2463 write_lock_bh(&ref_table_lock);
2464
2465 if (unlikely(!entry->tsk)) {
2466 pr_err("Attempt to discard ref. to non-existent socket\n");
2467 goto exit;
2468 }
2469 if (unlikely(entry->ref != ref)) {
2470 pr_err("Attempt to discard non-existent reference\n");
2471 goto exit;
2472 }
2473
2474 /* Mark entry as unused; increment instance part of entry's
2475 * reference to invalidate any subsequent references
2476 */
2477
2478 entry->tsk = NULL;
2479 entry->ref = (ref & ~index_mask) + (index_mask + 1);
2480
2481 /* Append entry to free entry list */
2482 if (unlikely(tipc_ref_table.first_free == 0))
2483 tipc_ref_table.first_free = index;
2484 else
2485 tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
2486 tipc_ref_table.last_free = index;
2487exit:
2488 write_unlock_bh(&ref_table_lock);
2489}
2490
2491/* tipc_sk_get - find referenced socket and return pointer to it
2492 */
2493struct tipc_sock *tipc_sk_get(u32 ref)
2494{
2495 struct reference *entry;
2496 struct tipc_sock *tsk;
2497
2498 if (unlikely(!tipc_ref_table.entries))
2499 return NULL;
2500 read_lock_bh(&ref_table_lock);
2501 entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
2502 tsk = entry->tsk;
2503 if (likely(tsk && (entry->ref == ref)))
2504 sock_hold(&tsk->sk);
2505 else
2506 tsk = NULL;
2507 read_unlock_bh(&ref_table_lock);
2508 return tsk;
2509}
2510
2511/* tipc_sk_get_next - lock & return next socket after referenced one
2512*/
2513struct tipc_sock *tipc_sk_get_next(u32 *ref)
2514{
2515 struct reference *entry;
2516 struct tipc_sock *tsk = NULL;
2517 uint index = *ref & tipc_ref_table.index_mask;
2518
2519 read_lock_bh(&ref_table_lock);
2520 while (++index < tipc_ref_table.capacity) {
2521 entry = &tipc_ref_table.entries[index];
2522 if (!entry->tsk)
2523 continue;
2524 tsk = entry->tsk;
2525 sock_hold(&tsk->sk);
2526 *ref = entry->ref;
2527 break;
2528 }
2529 read_unlock_bh(&ref_table_lock);
2530 return tsk;
2531}
2532
2533static void tipc_sk_put(struct tipc_sock *tsk)
2534{
2535 sock_put(&tsk->sk);
2536}
2537
1940/** 2538/**
1941 * tipc_setsockopt - set socket option 2539 * tipc_setsockopt - set socket option
1942 * @sock: socket structure 2540 * @sock: socket structure
@@ -1955,7 +2553,6 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
1955{ 2553{
1956 struct sock *sk = sock->sk; 2554 struct sock *sk = sock->sk;
1957 struct tipc_sock *tsk = tipc_sk(sk); 2555 struct tipc_sock *tsk = tipc_sk(sk);
1958 struct tipc_port *port = &tsk->port;
1959 u32 value; 2556 u32 value;
1960 int res; 2557 int res;
1961 2558
@@ -1973,16 +2570,16 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
1973 2570
1974 switch (opt) { 2571 switch (opt) {
1975 case TIPC_IMPORTANCE: 2572 case TIPC_IMPORTANCE:
1976 res = tipc_port_set_importance(port, value); 2573 res = tsk_set_importance(tsk, value);
1977 break; 2574 break;
1978 case TIPC_SRC_DROPPABLE: 2575 case TIPC_SRC_DROPPABLE:
1979 if (sock->type != SOCK_STREAM) 2576 if (sock->type != SOCK_STREAM)
1980 tipc_port_set_unreliable(port, value); 2577 tsk_set_unreliable(tsk, value);
1981 else 2578 else
1982 res = -ENOPROTOOPT; 2579 res = -ENOPROTOOPT;
1983 break; 2580 break;
1984 case TIPC_DEST_DROPPABLE: 2581 case TIPC_DEST_DROPPABLE:
1985 tipc_port_set_unreturnable(port, value); 2582 tsk_set_unreturnable(tsk, value);
1986 break; 2583 break;
1987 case TIPC_CONN_TIMEOUT: 2584 case TIPC_CONN_TIMEOUT:
1988 tipc_sk(sk)->conn_timeout = value; 2585 tipc_sk(sk)->conn_timeout = value;
@@ -2015,7 +2612,6 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
2015{ 2612{
2016 struct sock *sk = sock->sk; 2613 struct sock *sk = sock->sk;
2017 struct tipc_sock *tsk = tipc_sk(sk); 2614 struct tipc_sock *tsk = tipc_sk(sk);
2018 struct tipc_port *port = &tsk->port;
2019 int len; 2615 int len;
2020 u32 value; 2616 u32 value;
2021 int res; 2617 int res;
@@ -2032,16 +2628,16 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
2032 2628
2033 switch (opt) { 2629 switch (opt) {
2034 case TIPC_IMPORTANCE: 2630 case TIPC_IMPORTANCE:
2035 value = tipc_port_importance(port); 2631 value = tsk_importance(tsk);
2036 break; 2632 break;
2037 case TIPC_SRC_DROPPABLE: 2633 case TIPC_SRC_DROPPABLE:
2038 value = tipc_port_unreliable(port); 2634 value = tsk_unreliable(tsk);
2039 break; 2635 break;
2040 case TIPC_DEST_DROPPABLE: 2636 case TIPC_DEST_DROPPABLE:
2041 value = tipc_port_unreturnable(port); 2637 value = tsk_unreturnable(tsk);
2042 break; 2638 break;
2043 case TIPC_CONN_TIMEOUT: 2639 case TIPC_CONN_TIMEOUT:
2044 value = tipc_sk(sk)->conn_timeout; 2640 value = tsk->conn_timeout;
2045 /* no need to set "res", since already 0 at this point */ 2641 /* no need to set "res", since already 0 at this point */
2046 break; 2642 break;
2047 case TIPC_NODE_RECVQ_DEPTH: 2643 case TIPC_NODE_RECVQ_DEPTH:
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 43b75b3ceced..baa43d03901e 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -35,56 +35,17 @@
35#ifndef _TIPC_SOCK_H 35#ifndef _TIPC_SOCK_H
36#define _TIPC_SOCK_H 36#define _TIPC_SOCK_H
37 37
38#include "port.h"
39#include <net/sock.h> 38#include <net/sock.h>
40 39
41#define TIPC_CONN_OK 0 40#define TIPC_CONNACK_INTV 256
42#define TIPC_CONN_PROBING 1 41#define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2)
43 42#define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
44/** 43 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
45 * struct tipc_sock - TIPC socket structure
46 * @sk: socket - interacts with 'port' and with user via the socket API
47 * @port: port - interacts with 'sk' and with the rest of the TIPC stack
48 * @peer_name: the peer of the connection, if any
49 * @conn_timeout: the time we can wait for an unresponded setup request
50 * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
51 * @link_cong: non-zero if owner must sleep because of link congestion
52 * @sent_unacked: # messages sent by socket, and not yet acked by peer
53 * @rcv_unacked: # messages read by user, but not yet acked back to peer
54 */
55
56struct tipc_sock {
57 struct sock sk;
58 struct tipc_port port;
59 unsigned int conn_timeout;
60 atomic_t dupl_rcvcnt;
61 int link_cong;
62 uint sent_unacked;
63 uint rcv_unacked;
64};
65
66static inline struct tipc_sock *tipc_sk(const struct sock *sk)
67{
68 return container_of(sk, struct tipc_sock, sk);
69}
70
71static inline struct tipc_sock *tipc_port_to_sock(const struct tipc_port *port)
72{
73 return container_of(port, struct tipc_sock, port);
74}
75
76static inline void tipc_sock_wakeup(struct tipc_sock *tsk)
77{
78 tsk->sk.sk_write_space(&tsk->sk);
79}
80
81static inline int tipc_sk_conn_cong(struct tipc_sock *tsk)
82{
83 return tsk->sent_unacked >= TIPC_FLOWCTRL_WIN;
84}
85
86int tipc_sk_rcv(struct sk_buff *buf); 44int tipc_sk_rcv(struct sk_buff *buf);
87 45struct sk_buff *tipc_sk_socks_show(void);
88void tipc_sk_mcast_rcv(struct sk_buff *buf); 46void tipc_sk_mcast_rcv(struct sk_buff *buf);
47void tipc_sk_reinit(void);
48int tipc_sk_ref_table_init(u32 requested_size, u32 start);
49void tipc_sk_ref_table_stop(void);
89 50
90#endif 51#endif
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 642437231ad5..31b5cb232a43 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -36,7 +36,6 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "name_table.h" 38#include "name_table.h"
39#include "port.h"
40#include "subscr.h" 39#include "subscr.h"
41 40
42/** 41/**