aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Makefile2
-rw-r--r--net/tipc/bcast.c20
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/tipc/config.c4
-rw-r--r--net/tipc/core.c9
-rw-r--r--net/tipc/core.h6
-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_distr.c140
-rw-r--r--net/tipc/name_distr.h1
-rw-r--r--net/tipc/name_table.c9
-rw-r--r--net/tipc/net.c3
-rw-r--r--net/tipc/node.c95
-rw-r--r--net/tipc/node.h8
-rw-r--r--net/tipc/port.c514
-rw-r--r--net/tipc/port.h187
-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
-rw-r--r--net/tipc/sysctl.c7
24 files changed, 1091 insertions, 1340 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..b8670bf262e2 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"
@@ -227,6 +226,17 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
227} 226}
228 227
229/** 228/**
229 * tipc_bclink_wakeup_users - wake up pending users
230 *
231 * Called with no locks taken
232 */
233void tipc_bclink_wakeup_users(void)
234{
235 while (skb_queue_len(&bclink->link.waiting_sks))
236 tipc_sk_rcv(skb_dequeue(&bclink->link.waiting_sks));
237}
238
239/**
230 * tipc_bclink_acknowledge - handle acknowledgement of broadcast packets 240 * tipc_bclink_acknowledge - handle acknowledgement of broadcast packets
231 * @n_ptr: node that sent acknowledgement info 241 * @n_ptr: node that sent acknowledgement info
232 * @acked: broadcast sequence # that has been acknowledged 242 * @acked: broadcast sequence # that has been acknowledged
@@ -300,8 +310,9 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
300 tipc_link_push_queue(bcl); 310 tipc_link_push_queue(bcl);
301 bclink_set_last_sent(); 311 bclink_set_last_sent();
302 } 312 }
303 if (unlikely(released && !list_empty(&bcl->waiting_ports))) 313 if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
304 tipc_link_wakeup_ports(bcl, 0); 314 n_ptr->action_flags |= TIPC_WAKEUP_BCAST_USERS;
315
305exit: 316exit:
306 tipc_bclink_unlock(); 317 tipc_bclink_unlock();
307} 318}
@@ -840,9 +851,10 @@ int tipc_bclink_init(void)
840 sprintf(bcbearer->media.name, "tipc-broadcast"); 851 sprintf(bcbearer->media.name, "tipc-broadcast");
841 852
842 spin_lock_init(&bclink->lock); 853 spin_lock_init(&bclink->lock);
843 INIT_LIST_HEAD(&bcl->waiting_ports); 854 __skb_queue_head_init(&bcl->waiting_sks);
844 bcl->next_out_no = 1; 855 bcl->next_out_no = 1;
845 spin_lock_init(&bclink->node.lock); 856 spin_lock_init(&bclink->node.lock);
857 __skb_queue_head_init(&bclink->node.waiting_sks);
846 bcl->owner = &bclink->node; 858 bcl->owner = &bclink->node;
847 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; 859 bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
848 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); 860 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 4875d9536aee..e7b0f85a82bc 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -99,5 +99,5 @@ int tipc_bclink_set_queue_limits(u32 limit);
99void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action); 99void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
100uint tipc_bclink_get_mtu(void); 100uint tipc_bclink_get_mtu(void);
101int tipc_bclink_xmit(struct sk_buff *buf); 101int tipc_bclink_xmit(struct sk_buff *buf);
102 102void tipc_bclink_wakeup_users(void);
103#endif 103#endif
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..f773b148722f 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -81,6 +81,7 @@ extern u32 tipc_own_addr __read_mostly;
81extern int tipc_max_ports __read_mostly; 81extern int tipc_max_ports __read_mostly;
82extern int tipc_net_id __read_mostly; 82extern int tipc_net_id __read_mostly;
83extern int sysctl_tipc_rmem[3] __read_mostly; 83extern int sysctl_tipc_rmem[3] __read_mostly;
84extern int sysctl_tipc_named_timeout __read_mostly;
84 85
85/* 86/*
86 * Other global variables 87 * Other global variables
@@ -187,8 +188,11 @@ static inline void k_term_timer(struct timer_list *timer)
187 188
188struct tipc_skb_cb { 189struct tipc_skb_cb {
189 void *handle; 190 void *handle;
190 bool deferred;
191 struct sk_buff *tail; 191 struct sk_buff *tail;
192 bool deferred;
193 bool wakeup_pending;
194 u16 chain_sz;
195 u16 chain_imp;
192}; 196};
193 197
194#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) 198#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_distr.c b/net/tipc/name_distr.c
index dcc15bcd5692..376d2bb51d8d 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/name_distr.c: TIPC name distribution code 2 * net/tipc/name_distr.c: TIPC name distribution code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, 2014, Ericsson AB
5 * Copyright (c) 2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -71,6 +71,21 @@ static struct publ_list *publ_lists[] = {
71}; 71};
72 72
73 73
74int sysctl_tipc_named_timeout __read_mostly = 2000;
75
76/**
77 * struct tipc_dist_queue - queue holding deferred name table updates
78 */
79static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue);
80
81struct distr_queue_item {
82 struct distr_item i;
83 u32 dtype;
84 u32 node;
85 unsigned long expires;
86 struct list_head next;
87};
88
74/** 89/**
75 * publ_to_item - add publication info to a publication message 90 * publ_to_item - add publication info to a publication message
76 */ 91 */
@@ -263,54 +278,105 @@ static void named_purge_publ(struct publication *publ)
263} 278}
264 279
265/** 280/**
281 * tipc_update_nametbl - try to process a nametable update and notify
282 * subscribers
283 *
284 * tipc_nametbl_lock must be held.
285 * Returns the publication item if successful, otherwise NULL.
286 */
287static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype)
288{
289 struct publication *publ = NULL;
290
291 if (dtype == PUBLICATION) {
292 publ = tipc_nametbl_insert_publ(ntohl(i->type), ntohl(i->lower),
293 ntohl(i->upper),
294 TIPC_CLUSTER_SCOPE, node,
295 ntohl(i->ref), ntohl(i->key));
296 if (publ) {
297 tipc_nodesub_subscribe(&publ->subscr, node, publ,
298 (net_ev_handler)
299 named_purge_publ);
300 return true;
301 }
302 } else if (dtype == WITHDRAWAL) {
303 publ = tipc_nametbl_remove_publ(ntohl(i->type), ntohl(i->lower),
304 node, ntohl(i->ref),
305 ntohl(i->key));
306 if (publ) {
307 tipc_nodesub_unsubscribe(&publ->subscr);
308 kfree(publ);
309 return true;
310 }
311 } else {
312 pr_warn("Unrecognized name table message received\n");
313 }
314 return false;
315}
316
317/**
318 * tipc_named_add_backlog - add a failed name table update to the backlog
319 *
320 */
321static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
322{
323 struct distr_queue_item *e;
324 unsigned long now = get_jiffies_64();
325
326 e = kzalloc(sizeof(*e), GFP_ATOMIC);
327 if (!e)
328 return;
329 e->dtype = type;
330 e->node = node;
331 e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout);
332 memcpy(e, i, sizeof(*i));
333 list_add_tail(&e->next, &tipc_dist_queue);
334}
335
336/**
337 * tipc_named_process_backlog - try to process any pending name table updates
338 * from the network.
339 */
340void tipc_named_process_backlog(void)
341{
342 struct distr_queue_item *e, *tmp;
343 char addr[16];
344 unsigned long now = get_jiffies_64();
345
346 list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) {
347 if (time_after(e->expires, now)) {
348 if (!tipc_update_nametbl(&e->i, e->node, e->dtype))
349 continue;
350 } else {
351 tipc_addr_string_fill(addr, e->node);
352 pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %s key=%u\n",
353 e->dtype, ntohl(e->i.type),
354 ntohl(e->i.lower),
355 ntohl(e->i.upper),
356 addr, ntohl(e->i.key));
357 }
358 list_del(&e->next);
359 kfree(e);
360 }
361}
362
363/**
266 * tipc_named_rcv - process name table update message sent by another node 364 * tipc_named_rcv - process name table update message sent by another node
267 */ 365 */
268void tipc_named_rcv(struct sk_buff *buf) 366void tipc_named_rcv(struct sk_buff *buf)
269{ 367{
270 struct publication *publ;
271 struct tipc_msg *msg = buf_msg(buf); 368 struct tipc_msg *msg = buf_msg(buf);
272 struct distr_item *item = (struct distr_item *)msg_data(msg); 369 struct distr_item *item = (struct distr_item *)msg_data(msg);
273 u32 count = msg_data_sz(msg) / ITEM_SIZE; 370 u32 count = msg_data_sz(msg) / ITEM_SIZE;
371 u32 node = msg_orignode(msg);
274 372
275 write_lock_bh(&tipc_nametbl_lock); 373 write_lock_bh(&tipc_nametbl_lock);
276 while (count--) { 374 while (count--) {
277 if (msg_type(msg) == PUBLICATION) { 375 if (!tipc_update_nametbl(item, node, msg_type(msg)))
278 publ = tipc_nametbl_insert_publ(ntohl(item->type), 376 tipc_named_add_backlog(item, msg_type(msg), node);
279 ntohl(item->lower),
280 ntohl(item->upper),
281 TIPC_CLUSTER_SCOPE,
282 msg_orignode(msg),
283 ntohl(item->ref),
284 ntohl(item->key));
285 if (publ) {
286 tipc_nodesub_subscribe(&publ->subscr,
287 msg_orignode(msg),
288 publ,
289 (net_ev_handler)
290 named_purge_publ);
291 }
292 } else if (msg_type(msg) == WITHDRAWAL) {
293 publ = tipc_nametbl_remove_publ(ntohl(item->type),
294 ntohl(item->lower),
295 msg_orignode(msg),
296 ntohl(item->ref),
297 ntohl(item->key));
298
299 if (publ) {
300 tipc_nodesub_unsubscribe(&publ->subscr);
301 kfree(publ);
302 } else {
303 pr_err("Unable to remove publication by node 0x%x\n"
304 " (type=%u, lower=%u, ref=%u, key=%u)\n",
305 msg_orignode(msg), ntohl(item->type),
306 ntohl(item->lower), ntohl(item->ref),
307 ntohl(item->key));
308 }
309 } else {
310 pr_warn("Unrecognized name table message received\n");
311 }
312 item++; 377 item++;
313 } 378 }
379 tipc_named_process_backlog();
314 write_unlock_bh(&tipc_nametbl_lock); 380 write_unlock_bh(&tipc_nametbl_lock);
315 kfree_skb(buf); 381 kfree_skb(buf);
316} 382}
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 8afe32b7fc9a..b9e75feb3434 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -73,5 +73,6 @@ void named_cluster_distribute(struct sk_buff *buf);
73void tipc_named_node_up(u32 dnode); 73void tipc_named_node_up(u32 dnode);
74void tipc_named_rcv(struct sk_buff *buf); 74void tipc_named_rcv(struct sk_buff *buf);
75void tipc_named_reinit(void); 75void tipc_named_reinit(void);
76void tipc_named_process_backlog(void);
76 77
77#endif 78#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 9d7d37d95187..3a6a0a7c0759 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
@@ -262,8 +261,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
262 261
263 /* Lower end overlaps existing entry => need an exact match */ 262 /* Lower end overlaps existing entry => need an exact match */
264 if ((sseq->lower != lower) || (sseq->upper != upper)) { 263 if ((sseq->lower != lower) || (sseq->upper != upper)) {
265 pr_warn("Cannot publish {%u,%u,%u}, overlap error\n",
266 type, lower, upper);
267 return NULL; 264 return NULL;
268 } 265 }
269 266
@@ -285,8 +282,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
285 /* Fail if upper end overlaps into an existing entry */ 282 /* Fail if upper end overlaps into an existing entry */
286 if ((inspos < nseq->first_free) && 283 if ((inspos < nseq->first_free) &&
287 (upper >= nseq->sseqs[inspos].lower)) { 284 (upper >= nseq->sseqs[inspos].lower)) {
288 pr_warn("Cannot publish {%u,%u,%u}, overlap error\n",
289 type, lower, upper);
290 return NULL; 285 return NULL;
291 } 286 }
292 287
@@ -678,6 +673,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
678 if (likely(publ)) { 673 if (likely(publ)) {
679 table.local_publ_count++; 674 table.local_publ_count++;
680 buf = tipc_named_publish(publ); 675 buf = tipc_named_publish(publ);
676 /* Any pending external events? */
677 tipc_named_process_backlog();
681 } 678 }
682 write_unlock_bh(&tipc_nametbl_lock); 679 write_unlock_bh(&tipc_nametbl_lock);
683 680
@@ -699,6 +696,8 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
699 if (likely(publ)) { 696 if (likely(publ)) {
700 table.local_publ_count--; 697 table.local_publ_count--;
701 buf = tipc_named_withdraw(publ); 698 buf = tipc_named_withdraw(publ);
699 /* Any pending external events? */
700 tipc_named_process_backlog();
702 write_unlock_bh(&tipc_nametbl_lock); 701 write_unlock_bh(&tipc_nametbl_lock);
703 list_del_init(&publ->pport_list); 702 list_del_init(&publ->pport_list);
704 kfree(publ); 703 kfree(publ);
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..90cee4a6fce4 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,25 +549,45 @@ 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;
555 unsigned int flags = node->action_flags;
478 556
479 if (likely(!node->action_flags)) { 557 if (likely(!node->action_flags)) {
480 spin_unlock_bh(&node->lock); 558 spin_unlock_bh(&node->lock);
481 return; 559 return;
482 } 560 }
483 561
562 __skb_queue_head_init(&waiting_sks);
563 if (node->action_flags & TIPC_WAKEUP_USERS) {
564 skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
565 node->action_flags &= ~TIPC_WAKEUP_USERS;
566 }
484 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) { 567 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
485 list_replace_init(&node->nsub, &nsub_list); 568 list_replace_init(&node->nsub, &nsub_list);
569 list_replace_init(&node->conn_sks, &conn_sks);
486 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; 570 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
487 } 571 }
488 if (node->action_flags & TIPC_NOTIFY_NODE_UP) { 572 if (node->action_flags & TIPC_NOTIFY_NODE_UP) {
489 node->action_flags &= ~TIPC_NOTIFY_NODE_UP; 573 node->action_flags &= ~TIPC_NOTIFY_NODE_UP;
490 addr = node->addr; 574 addr = node->addr;
491 } 575 }
576 node->action_flags &= ~TIPC_WAKEUP_BCAST_USERS;
492 spin_unlock_bh(&node->lock); 577 spin_unlock_bh(&node->lock);
493 578
579 while (!skb_queue_empty(&waiting_sks))
580 tipc_sk_rcv(__skb_dequeue(&waiting_sks));
581
582 if (!list_empty(&conn_sks))
583 tipc_node_abort_sock_conns(&conn_sks);
584
494 if (!list_empty(&nsub_list)) 585 if (!list_empty(&nsub_list))
495 tipc_nodesub_notify(&nsub_list); 586 tipc_nodesub_notify(&nsub_list);
587
588 if (flags & TIPC_WAKEUP_BCAST_USERS)
589 tipc_bclink_wakeup_users();
590
496 if (addr) 591 if (addr)
497 tipc_named_node_up(addr); 592 tipc_named_node_up(addr);
498} 593}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index b61716a8218e..67513c3c852c 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -58,7 +58,9 @@ 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),
63 TIPC_WAKEUP_BCAST_USERS = (1 << 6)
62}; 64};
63 65
64/** 66/**
@@ -115,6 +117,8 @@ struct tipc_node {
115 int working_links; 117 int working_links;
116 u32 signature; 118 u32 signature;
117 struct list_head nsub; 119 struct list_head nsub;
120 struct sk_buff_head waiting_sks;
121 struct list_head conn_sks;
118 struct rcu_head rcu; 122 struct rcu_head rcu;
119}; 123};
120 124
@@ -133,6 +137,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); 137struct 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); 138int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
135void tipc_node_unlock(struct tipc_node *node); 139void tipc_node_unlock(struct tipc_node *node);
140int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port);
141void tipc_node_remove_conn(u32 dnode, u32 port);
136 142
137static inline void tipc_node_lock(struct tipc_node *node) 143static inline void tipc_node_lock(struct tipc_node *node)
138{ 144{
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 3f93454592b6..000000000000
--- a/net/tipc/port.h
+++ /dev/null
@@ -1,187 +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 void tipc_port_set_importance(struct tipc_port *port, int imp)
183{
184 msg_set_importance(&port->phdr, (u32)imp);
185}
186
187#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 7d423ee10897..75275c5cf929 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 return;
2122
2123 sk = &tsk->sk;
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 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/**
diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c
index f3fef93325a8..1a779b1e8510 100644
--- a/net/tipc/sysctl.c
+++ b/net/tipc/sysctl.c
@@ -47,6 +47,13 @@ static struct ctl_table tipc_table[] = {
47 .mode = 0644, 47 .mode = 0644,
48 .proc_handler = proc_dointvec, 48 .proc_handler = proc_dointvec,
49 }, 49 },
50 {
51 .procname = "named_timeout",
52 .data = &sysctl_tipc_named_timeout,
53 .maxlen = sizeof(sysctl_tipc_named_timeout),
54 .mode = 0644,
55 .proc_handler = proc_dointvec,
56 },
50 {} 57 {}
51}; 58};
52 59