aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-08-22 18:09:11 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:34 -0400
commitdadebc00299a19dc4639ba7192db937e31b81eb2 (patch)
treee67049689659535bbe2d88f22f0a492d2a3064c3 /net/tipc
parent80e44c22255468337b891da2348cab68cb62766f (diff)
tipc: eliminate port_connect()/port_disconnect() functions
tipc_port_connect()/tipc_port_disconnect() are remnants of the obsolete native API. Their only task is to grab port_lock and call the functions __tipc_port_connect()/__tipc_port_disconnect() respectively, which will perform the actual state change. Since socket/port exection now is single-threaded the use of port_lock is not needed any more, so we can safely replace the two functions with their lock-free counterparts. In this commit, we remove the two functions. Furthermore, the contents of __tipc_port_disconnect() is so trivial that we choose to eliminate that function too, expanding its functionality into tipc_shutdown(). __tipc_port_connect() is simplified, moved to socket.c, and given the more correct name tipc_sk_finish_conn(). Finally, we eliminate the function auto_connect(), and expand its contents into filter_connect(). Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/port.c84
-rw-r--r--net/tipc/port.h10
-rw-r--r--net/tipc/socket.c75
3 files changed, 37 insertions, 132 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 3ad092b7fb7d..2f96719a3514 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -40,9 +40,6 @@
40#include "name_table.h" 40#include "name_table.h"
41#include "socket.h" 41#include "socket.h"
42 42
43/* Connection management: */
44#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
45
46#define MAX_REJECT_SIZE 1024 43#define MAX_REJECT_SIZE 1024
47 44
48DEFINE_SPINLOCK(tipc_port_list_lock); 45DEFINE_SPINLOCK(tipc_port_list_lock);
@@ -304,84 +301,3 @@ int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
304 p_ptr->published = 0; 301 p_ptr->published = 0;
305 return res; 302 return res;
306} 303}
307
308int tipc_port_connect(u32 ref, struct tipc_portid const *peer)
309{
310 struct tipc_port *p_ptr;
311 int res;
312
313 p_ptr = tipc_port_lock(ref);
314 if (!p_ptr)
315 return -EINVAL;
316 res = __tipc_port_connect(ref, p_ptr, peer);
317 tipc_port_unlock(p_ptr);
318 return res;
319}
320
321/*
322 * __tipc_port_connect - connect to a remote peer
323 *
324 * Port must be locked.
325 */
326int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
327 struct tipc_portid const *peer)
328{
329 struct tipc_msg *msg;
330 int res = -EINVAL;
331
332 if (p_ptr->published || p_ptr->connected)
333 goto exit;
334 if (!peer->ref)
335 goto exit;
336
337 msg = &p_ptr->phdr;
338 msg_set_destnode(msg, peer->node);
339 msg_set_destport(msg, peer->ref);
340 msg_set_type(msg, TIPC_CONN_MSG);
341 msg_set_lookup_scope(msg, 0);
342 msg_set_hdr_sz(msg, SHORT_H_SIZE);
343
344 p_ptr->probing_interval = PROBING_INTERVAL;
345 p_ptr->probing_state = TIPC_CONN_OK;
346 p_ptr->connected = 1;
347 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
348 res = tipc_node_add_conn(tipc_port_peernode(p_ptr), p_ptr->ref,
349 tipc_port_peerport(p_ptr));
350exit:
351 p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref);
352 return res;
353}
354
355/*
356 * __tipc_disconnect - disconnect port from peer
357 *
358 * Port must be locked.
359 */
360int __tipc_port_disconnect(struct tipc_port *tp_ptr)
361{
362 if (tp_ptr->connected) {
363 tp_ptr->connected = 0;
364 /* let timer expire on it's own to avoid deadlock! */
365 tipc_node_remove_conn(tipc_port_peernode(tp_ptr), tp_ptr->ref);
366 return 0;
367 }
368
369 return -ENOTCONN;
370}
371
372/*
373 * tipc_port_disconnect(): Disconnect port form peer.
374 * This is a node local operation.
375 */
376int tipc_port_disconnect(u32 ref)
377{
378 struct tipc_port *p_ptr;
379 int res;
380
381 p_ptr = tipc_port_lock(ref);
382 if (!p_ptr)
383 return -EINVAL;
384 res = __tipc_port_disconnect(p_ptr);
385 tipc_port_unlock(p_ptr);
386 return res;
387}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index f5762f940e33..b356cb8340d9 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -102,16 +102,6 @@ int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
102int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, 102int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
103 struct tipc_name_seq const *name_seq); 103 struct tipc_name_seq const *name_seq);
104 104
105int tipc_port_connect(u32 portref, struct tipc_portid const *port);
106
107int tipc_port_disconnect(u32 portref);
108
109/*
110 * The following routines require that the port be locked on entry
111 */
112int __tipc_port_disconnect(struct tipc_port *tp_ptr);
113int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
114 struct tipc_portid const *peer);
115int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg); 105int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
116 106
117struct sk_buff *tipc_port_get_ports(void); 107struct sk_buff *tipc_port_get_ports(void);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f202d4790ce3..a65105818fe5 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -45,6 +45,7 @@
45#define SS_READY -2 /* socket is connectionless */ 45#define SS_READY -2 /* socket is connectionless */
46 46
47#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ 47#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
48#define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */
48#define TIPC_FWD_MSG 1 49#define TIPC_FWD_MSG 1
49 50
50static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); 51static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -339,7 +340,9 @@ static int tipc_release(struct socket *sock)
339 if ((sock->state == SS_CONNECTING) || 340 if ((sock->state == SS_CONNECTING) ||
340 (sock->state == SS_CONNECTED)) { 341 (sock->state == SS_CONNECTED)) {
341 sock->state = SS_DISCONNECTING; 342 sock->state = SS_DISCONNECTING;
342 tipc_port_disconnect(port->ref); 343 port->connected = 0;
344 tipc_node_remove_conn(tipc_port_peernode(port),
345 port->ref);
343 } 346 }
344 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) 347 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
345 tipc_link_xmit(buf, dnode, 0); 348 tipc_link_xmit(buf, dnode, 0);
@@ -988,29 +991,25 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,
988 return tipc_send_stream(iocb, sock, m, dsz); 991 return tipc_send_stream(iocb, sock, m, dsz);
989} 992}
990 993
991/** 994/* tipc_sk_finish_conn - complete the setup of a connection
992 * auto_connect - complete connection setup to a remote port
993 * @tsk: tipc socket structure
994 * @msg: peer's response message
995 *
996 * Returns 0 on success, errno otherwise
997 */ 995 */
998static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg) 996static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port,
997 u32 peer_node)
999{ 998{
1000 struct tipc_port *port = &tsk->port; 999 struct tipc_msg *msg = &port->phdr;
1001 struct socket *sock = tsk->sk.sk_socket;
1002 struct tipc_portid peer;
1003
1004 peer.ref = msg_origport(msg);
1005 peer.node = msg_orignode(msg);
1006 1000
1007 __tipc_port_connect(port->ref, port, &peer); 1001 msg_set_destnode(msg, peer_node);
1002 msg_set_destport(msg, peer_port);
1003 msg_set_type(msg, TIPC_CONN_MSG);
1004 msg_set_lookup_scope(msg, 0);
1005 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1008 1006
1009 if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) 1007 port->probing_interval = CONN_PROBING_INTERVAL;
1010 return -EINVAL; 1008 port->probing_state = TIPC_CONN_OK;
1011 msg_set_importance(&port->phdr, (u32)msg_importance(msg)); 1009 port->connected = 1;
1012 sock->state = SS_CONNECTED; 1010 k_start_timer(&port->timer, port->probing_interval);
1013 return 0; 1011 tipc_node_add_conn(peer_node, port->ref, peer_port);
1012 port->max_pkt = tipc_node_get_mtu(peer_node, port->ref);
1014} 1013}
1015 1014
1016/** 1015/**
@@ -1405,7 +1404,6 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1405 struct tipc_msg *msg = buf_msg(*buf); 1404 struct tipc_msg *msg = buf_msg(*buf);
1406 1405
1407 int retval = -TIPC_ERR_NO_PORT; 1406 int retval = -TIPC_ERR_NO_PORT;
1408 int res;
1409 1407
1410 if (msg_mcast(msg)) 1408 if (msg_mcast(msg))
1411 return retval; 1409 return retval;
@@ -1416,13 +1414,20 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1416 if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { 1414 if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) {
1417 if (unlikely(msg_errcode(msg))) { 1415 if (unlikely(msg_errcode(msg))) {
1418 sock->state = SS_DISCONNECTING; 1416 sock->state = SS_DISCONNECTING;
1419 __tipc_port_disconnect(port); 1417 port->connected = 0;
1418 /* let timer expire on it's own */
1419 tipc_node_remove_conn(tipc_port_peernode(port),
1420 port->ref);
1420 } 1421 }
1421 retval = TIPC_OK; 1422 retval = TIPC_OK;
1422 } 1423 }
1423 break; 1424 break;
1424 case SS_CONNECTING: 1425 case SS_CONNECTING:
1425 /* Accept only ACK or NACK message */ 1426 /* Accept only ACK or NACK message */
1427
1428 if (unlikely(!msg_connected(msg)))
1429 break;
1430
1426 if (unlikely(msg_errcode(msg))) { 1431 if (unlikely(msg_errcode(msg))) {
1427 sock->state = SS_DISCONNECTING; 1432 sock->state = SS_DISCONNECTING;
1428 sk->sk_err = ECONNREFUSED; 1433 sk->sk_err = ECONNREFUSED;
@@ -1430,17 +1435,17 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1430 break; 1435 break;
1431 } 1436 }
1432 1437
1433 if (unlikely(!msg_connected(msg))) 1438 if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) {
1434 break;
1435
1436 res = auto_connect(tsk, msg);
1437 if (res) {
1438 sock->state = SS_DISCONNECTING; 1439 sock->state = SS_DISCONNECTING;
1439 sk->sk_err = -res; 1440 sk->sk_err = EINVAL;
1440 retval = TIPC_OK; 1441 retval = TIPC_OK;
1441 break; 1442 break;
1442 } 1443 }
1443 1444
1445 tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg));
1446 msg_set_importance(&port->phdr, msg_importance(msg));
1447 sock->state = SS_CONNECTED;
1448
1444 /* If an incoming message is an 'ACK-', it should be 1449 /* If an incoming message is an 'ACK-', it should be
1445 * discarded here because it doesn't contain useful 1450 * discarded here because it doesn't contain useful
1446 * data. In addition, we should try to wake up 1451 * data. In addition, we should try to wake up
@@ -1816,8 +1821,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1816 struct sk_buff *buf; 1821 struct sk_buff *buf;
1817 struct tipc_port *new_port; 1822 struct tipc_port *new_port;
1818 struct tipc_msg *msg; 1823 struct tipc_msg *msg;
1819 struct tipc_portid peer;
1820 u32 new_ref;
1821 long timeo; 1824 long timeo;
1822 int res; 1825 int res;
1823 1826
@@ -1840,7 +1843,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1840 1843
1841 new_sk = new_sock->sk; 1844 new_sk = new_sock->sk;
1842 new_port = &tipc_sk(new_sk)->port; 1845 new_port = &tipc_sk(new_sk)->port;
1843 new_ref = new_port->ref;
1844 msg = buf_msg(buf); 1846 msg = buf_msg(buf);
1845 1847
1846 /* we lock on new_sk; but lockdep sees the lock on sk */ 1848 /* we lock on new_sk; but lockdep sees the lock on sk */
@@ -1853,9 +1855,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
1853 reject_rx_queue(new_sk); 1855 reject_rx_queue(new_sk);
1854 1856
1855 /* Connect new socket to it's peer */ 1857 /* Connect new socket to it's peer */
1856 peer.ref = msg_origport(msg); 1858 tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));
1857 peer.node = msg_orignode(msg);
1858 tipc_port_connect(new_ref, &peer);
1859 new_sock->state = SS_CONNECTED; 1859 new_sock->state = SS_CONNECTED;
1860 1860
1861 tipc_port_set_importance(new_port, msg_importance(msg)); 1861 tipc_port_set_importance(new_port, msg_importance(msg));
@@ -1919,9 +1919,9 @@ restart:
1919 kfree_skb(buf); 1919 kfree_skb(buf);
1920 goto restart; 1920 goto restart;
1921 } 1921 }
1922 tipc_port_disconnect(port->ref);
1923 if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN)) 1922 if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
1924 tipc_link_xmit(buf, dnode, port->ref); 1923 tipc_link_xmit(buf, dnode, port->ref);
1924 tipc_node_remove_conn(dnode, port->ref);
1925 } else { 1925 } else {
1926 dnode = tipc_port_peernode(port); 1926 dnode = tipc_port_peernode(port);
1927 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, 1927 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
@@ -1930,11 +1930,10 @@ restart:
1930 tipc_port_peerport(port), 1930 tipc_port_peerport(port),
1931 port->ref, TIPC_CONN_SHUTDOWN); 1931 port->ref, TIPC_CONN_SHUTDOWN);
1932 tipc_link_xmit(buf, dnode, port->ref); 1932 tipc_link_xmit(buf, dnode, port->ref);
1933 __tipc_port_disconnect(port);
1934 } 1933 }
1935 1934 port->connected = 0;
1936 sock->state = SS_DISCONNECTING; 1935 sock->state = SS_DISCONNECTING;
1937 1936 tipc_node_remove_conn(dnode, port->ref);
1938 /* fall through */ 1937 /* fall through */
1939 1938
1940 case SS_DISCONNECTING: 1939 case SS_DISCONNECTING: