All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 00/16] tipc: socket layer improvements
@ 2016-11-01 13:02 Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 01/16] tipc: return early for non-blocking sockets at link congestion Parthasarathy Bhuvaragan
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

The following issues with the current socket layer hinders socket diagnostics
implementation, which led to this patch series.

1. tipc socket state is derived from multiple variables like
   sock->state, tsk->probing_state and tsk->connected. This style forces
   us to export multiple attributes to the user space, which has to be
   backward compatible.

2. Abuse of sock->state cannot be exported to user-space without
   requiring tipc specific hacks in the user-space.
   - For connection less (CL) sockets sock->state is overloaded to
     tipc state SS_READY.
   - For connection oriented (CO) listening socket sock->state is
     overloaded to tipc state SS_LISTEN.

This series is split into four:
1. Bug fixes in patch #1,2,3.
2. Minor cleanups in patch#4-5.
3. Express all tipc states using a single variable in patch#6-8.
4. Migrate the new tipc states to sk->sk_state in patch#9-16.

The figures below represents the FSM after this series:

Stream Server Listening Socket:
+-----------+       +-------------+
| TIPC_OPEN |------>| TIPC_LISTEN |
+-----------+       +-------------+

Stream Server Data Socket:
+-----------+       +------------------+
| TIPC_OPEN |------>| TIPC_ESTABLISHED |
+-----------+       +------------------+
                          ^   |
                          |   |
                          |   v
                    +--------------------+
                    | TIPC_DISCONNECTING |
                    +--------------------+

Stream Socket Client:
+-----------+       +-----------------+
| TIPC_OPEN |------>| TIPC_CONNECTING |------+
+-----------+       +-----------------+      |
                            |                |
                            |                |
                            v                |
                    +------------------+     |
                    | TIPC_ESTABLISHED |     |
                    +------------------+     |
                          ^   |              |
                          |   |              |
                          |   v              |
                    +--------------------+   |
                    | TIPC_DISCONNECTING |<--+
                    +--------------------+

NOTE:
This is just a base refractoring required for socket diagnostics.
TIPC socket diagnostics support will be introduced in a later series.

v2: - remove extra cast and parenthesis as suggested by David S. Miller in #4.
    - map new tipc state values to tcp states to address Eric Dumazet's concern,
      thus allow the usage of generic sk_* helpers. This is done in patch#10-15.
    - remove TIPC_PROBING state and replace it with probe_unacked flag in #11.
    - replace the TIPC_CLOSING state in v1 with sk_shutdown flag in #14.
    - introduce __tipc_shutdown() to avoid code duplication in #14.

Parthasarathy Bhuvaragan (16):
  tipc: return early for non-blocking sockets at link congestion
  tipc: wakeup sleeping users at disconnect
  tipc: set kern=0 in sk_alloc() during tipc_accept()
  tipc: rename struct tipc_skb_cb member handle to bytes_read
  tipc: rename tsk->remote to tsk->peer for consistent naming
  tipc: remove tsk->connected for connectionless sockets
  tipc: remove tsk->connected from tipc_sock
  tipc: remove probing_intv from tipc_sock
  tipc: remove socket state SS_READY
  tipc: create TIPC_LISTEN as a new sk_state
  tipc: create TIPC_ESTABLISHED as a new sk_state
  tipc: create TIPC_OPEN as a new sk_state
  tipc: create TIPC_DISCONNECTING as a new sk_state
  tipc: remove SS_DISCONNECTING state
  tipc: create TIPC_CONNECTING as a new sk_state
  tipc: remove SS_CONNECTED sock state

 net/tipc/msg.h    |   2 +-
 net/tipc/socket.c | 478 +++++++++++++++++++++++++++---------------------------
 2 files changed, 242 insertions(+), 238 deletions(-)

-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 01/16] tipc: return early for non-blocking sockets at link congestion
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 02/16] tipc: wakeup sleeping users at disconnect Parthasarathy Bhuvaragan
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, in stream/mcast send() we pass the message to the link
layer even when the link is congested and add the socket to the
link's wakeup queue. This is unnecessary for non-blocking sockets.
If a socket is set to non-blocking and sends multicast with zero
back off time while receiving EAGAIN, we exhaust the memory.

In this commit, we return immediately at stream/mcast send() for
non-blocking sockets.

Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f9f5f3c3dab5..adf3e6ecf61e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -697,6 +697,9 @@ static int tipc_sendmcast(struct  socket *sock, struct tipc_name_seq *seq,
 	uint mtu;
 	int rc;
 
+	if (!timeo && tsk->link_cong)
+		return -ELINKCONG;
+
 	msg_set_type(mhdr, TIPC_MCAST_MSG);
 	msg_set_lookup_scope(mhdr, TIPC_CLUSTER_SCOPE);
 	msg_set_destport(mhdr, 0);
@@ -1072,6 +1075,9 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
 	}
 
 	timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+	if (!timeo && tsk->link_cong)
+		return -ELINKCONG;
+
 	dnode = tsk_peer_node(tsk);
 	skb_queue_head_init(&pktchain);
 
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 02/16] tipc: wakeup sleeping users at disconnect
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 01/16] tipc: return early for non-blocking sockets at link congestion Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 03/16] tipc: set kern=0 in sk_alloc() during tipc_accept() Parthasarathy Bhuvaragan
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

Until now, in filter_connect() when we terminate a connection due to
an error message from peer, we set the socket state to DISCONNECTING.

The socket is notified about this broken connection using EPIPE when
a user tries to send a message. However if a socket was waiting on a
poll() while the connection is being terminated, we fail to wakeup
that socket.

In this commit, we wakeup sleeping sockets at connection termination.

Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index adf3e6ecf61e..cd01deb1da9c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1599,6 +1599,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 			/* Let timer expire on it's own */
 			tipc_node_remove_conn(net, tsk_peer_node(tsk),
 					      tsk->portid);
+			sk->sk_state_change(sk);
 		}
 		return true;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 03/16] tipc: set kern=0 in sk_alloc() during tipc_accept()
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 01/16] tipc: return early for non-blocking sockets at link congestion Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 02/16] tipc: wakeup sleeping users at disconnect Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 04/16] tipc: rename struct tipc_skb_cb member handle to bytes_read Parthasarathy Bhuvaragan
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, tipc_accept() calls sk_alloc() with kern=1. This is
incorrect as the data socket's owner is the user application.
Thus for these accepted data sockets the network namespace
refcount is skipped.

In this commit, we fix this by setting kern=0.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index cd01deb1da9c..82aec2eb8497 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2093,7 +2093,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 
 	buf = skb_peek(&sk->sk_receive_queue);
 
-	res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1);
+	res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 0);
 	if (res)
 		goto exit;
 	security_sk_clone(sock->sk, new_sock->sk);
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 04/16] tipc: rename struct tipc_skb_cb member handle to bytes_read
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (2 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 03/16] tipc: set kern=0 in sk_alloc() during tipc_accept() Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 05/16] tipc: rename tsk->remote to tsk->peer for consistent naming Parthasarathy Bhuvaragan
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

In this commit, we rename handle to bytes_read indicating the
purpose of the member.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: Remove unnecessary cast and parenthesis as suggested by David S. Miller.
---
 net/tipc/msg.h    |  2 +-
 net/tipc/socket.c | 18 ++++++++++--------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 50a739860d37..8d408612ffa4 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -95,7 +95,7 @@ struct plist;
 #define TIPC_MEDIA_INFO_OFFSET	5
 
 struct tipc_skb_cb {
-	void *handle;
+	u32 bytes_read;
 	struct sk_buff *tail;
 	bool validated;
 	bool wakeup_pending;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 82aec2eb8497..c543ae6cbf65 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -465,7 +465,7 @@ static int tipc_release(struct socket *sock)
 		skb = __skb_dequeue(&sk->sk_receive_queue);
 		if (skb == NULL)
 			break;
-		if (TIPC_SKB_CB(skb)->handle != NULL)
+		if (TIPC_SKB_CB(skb)->bytes_read)
 			kfree_skb(skb);
 		else {
 			if ((sock->state == SS_CONNECTING) ||
@@ -1435,7 +1435,7 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
 	struct tipc_msg *msg;
 	long timeo;
 	unsigned int sz;
-	int sz_to_copy, target, needed;
+	int target;
 	int sz_copied = 0;
 	u32 err;
 	int res = 0, hlen;
@@ -1483,11 +1483,13 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
 
 	/* Capture message data (if valid) & compute return value (always) */
 	if (!err) {
-		u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
+		u32 offset = TIPC_SKB_CB(buf)->bytes_read;
+		u32 needed;
+		int sz_to_copy;
 
 		sz -= offset;
 		needed = (buf_len - sz_copied);
-		sz_to_copy = (sz <= needed) ? sz : needed;
+		sz_to_copy = min(sz, needed);
 
 		res = skb_copy_datagram_msg(buf, hlen + offset, m, sz_to_copy);
 		if (res)
@@ -1497,8 +1499,8 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
 
 		if (sz_to_copy < sz) {
 			if (!(flags & MSG_PEEK))
-				TIPC_SKB_CB(buf)->handle =
-				(void *)(unsigned long)(offset + sz_to_copy);
+				TIPC_SKB_CB(buf)->bytes_read =
+					offset + sz_to_copy;
 			goto exit;
 		}
 	} else {
@@ -1742,7 +1744,7 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
 	}
 
 	/* Enqueue message */
-	TIPC_SKB_CB(skb)->handle = NULL;
+	TIPC_SKB_CB(skb)->bytes_read = 0;
 	__skb_queue_tail(&sk->sk_receive_queue, skb);
 	skb_set_owner_r(skb, sk);
 
@@ -2177,7 +2179,7 @@ static int tipc_shutdown(struct socket *sock, int how)
 		/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
 		skb = __skb_dequeue(&sk->sk_receive_queue);
 		if (skb) {
-			if (TIPC_SKB_CB(skb)->handle != NULL) {
+			if (TIPC_SKB_CB(skb)->bytes_read) {
 				kfree_skb(skb);
 				goto restart;
 			}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 05/16] tipc: rename tsk->remote to tsk->peer for consistent naming
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (3 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 04/16] tipc: rename struct tipc_skb_cb member handle to bytes_read Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 06/16] tipc: remove tsk->connected for connectionless sockets Parthasarathy Bhuvaragan
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

Until now, the peer information for connect is stored in tsk->remote
but the rest of code uses the name peer for peer/remote.

In this commit, we rename tsk->remote to tsk->peer to align with
naming convention followed in the rest of the code.

There is no functional change in this commit.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index c543ae6cbf65..0546556d3517 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -65,7 +65,6 @@
  * @max_pkt: maximum packet size "hint" used when building messages sent by port
  * @portid: unique port identity in TIPC socket hash table
  * @phdr: preformatted message header used when sending messages
- * @port_list: adjacent ports in TIPC's global list of ports
  * @publications: list of publications for port
  * @pub_count: total # of publications port has made during its lifetime
  * @probing_state:
@@ -75,7 +74,7 @@
  * @link_cong: non-zero if owner must sleep because of link congestion
  * @sent_unacked: # messages sent by socket, and not yet acked by peer
  * @rcv_unacked: # messages read by user, but not yet acked back to peer
- * @remote: 'connected' peer for dgram/rdm
+ * @peer: 'connected' peer for dgram/rdm
  * @node: hash table node
  * @rcu: rcu struct for tipc_sock
  */
@@ -101,7 +100,7 @@ struct tipc_sock {
 	u16 peer_caps;
 	u16 rcv_unacked;
 	u16 rcv_win;
-	struct sockaddr_tipc remote;
+	struct sockaddr_tipc peer;
 	struct rhash_head node;
 	struct rcu_head rcu;
 };
@@ -904,7 +903,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 		return -EMSGSIZE;
 	if (unlikely(!dest)) {
 		if (tsk->connected && sock->state == SS_READY)
-			dest = &tsk->remote;
+			dest = &tsk->peer;
 		else
 			return -EDESTADDRREQ;
 	} else if (unlikely(m->msg_namelen < sizeof(*dest)) ||
@@ -1939,12 +1938,12 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 	/* DGRAM/RDM connect(), just save the destaddr */
 	if (sock->state == SS_READY) {
 		if (dst->family == AF_UNSPEC) {
-			memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc));
+			memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
 			tsk->connected = 0;
 		} else if (destlen != sizeof(struct sockaddr_tipc)) {
 			res = -EINVAL;
 		} else {
-			memcpy(&tsk->remote, dest, destlen);
+			memcpy(&tsk->peer, dest, destlen);
 			tsk->connected = 1;
 		}
 		goto exit;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 06/16] tipc: remove tsk->connected for connectionless sockets
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (4 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 05/16] tipc: rename tsk->remote to tsk->peer for consistent naming Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 07/16] tipc: remove tsk->connected from tipc_sock Parthasarathy Bhuvaragan
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, for connectionless sockets the peer information during
connect is stored in tsk->peer and a connection state is set in
tsk->connected. This is redundant.

In this commit, for connectionless sockets we update:
- __tipc_sendmsg(), when the destination is NULL the peer existence
  is determined by tsk->peer.family, instead of tsk->connected.
- tipc_connect(), remove set/unset of tsk->connected.
Hence tsk->connected is no longer used for connectionless sockets.

There is no functional change in this commit.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 0546556d3517..524abe47560d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -902,7 +902,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 	if (dsz > TIPC_MAX_USER_MSG_SIZE)
 		return -EMSGSIZE;
 	if (unlikely(!dest)) {
-		if (tsk->connected && sock->state == SS_READY)
+		if (sock->state == SS_READY && tsk->peer.family == AF_TIPC)
 			dest = &tsk->peer;
 		else
 			return -EDESTADDRREQ;
@@ -1939,12 +1939,10 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 	if (sock->state == SS_READY) {
 		if (dst->family == AF_UNSPEC) {
 			memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
-			tsk->connected = 0;
 		} else if (destlen != sizeof(struct sockaddr_tipc)) {
 			res = -EINVAL;
 		} else {
 			memcpy(&tsk->peer, dest, destlen);
-			tsk->connected = 1;
 		}
 		goto exit;
 	}
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 07/16] tipc: remove tsk->connected from tipc_sock
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (5 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 06/16] tipc: remove tsk->connected for connectionless sockets Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 08/16] tipc: remove probing_intv " Parthasarathy Bhuvaragan
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, we determine if a socket is connected or not based on
tsk->connected, which is set once when the probing state is set
to TIPC_CONN_OK. It is unset when the sock->state is updated from
SS_CONNECTED to any other state.

In this commit, we remove connected variable from tipc_sock and
derive socket connection status from the following condition:
sock->state == SS_CONNECTED => tsk->connected

There is no functional change in this commit.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 524abe47560d..7b6a1847cf8a 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -58,7 +58,6 @@
 /**
  * struct tipc_sock - TIPC socket structure
  * @sk: socket - interacts with 'port' and with user via the socket API
- * @connected: non-zero if port is currently connected to a peer port
  * @conn_type: TIPC type used when connection was established
  * @conn_instance: TIPC instance used when connection was established
  * @published: non-zero if port has one or more associated names
@@ -80,7 +79,6 @@
  */
 struct tipc_sock {
 	struct sock sk;
-	int connected;
 	u32 conn_type;
 	u32 conn_instance;
 	int published;
@@ -293,6 +291,11 @@ static void tsk_rej_rx_queue(struct sock *sk)
 		tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
 }
 
+static bool tipc_sk_connected(struct sock *sk)
+{
+	return sk->sk_socket->state == SS_CONNECTED;
+}
+
 /* tsk_peer_msg - verify if message was sent by connected port's peer
  *
  * Handles cases where the node's network address has changed from
@@ -300,12 +303,13 @@ static void tsk_rej_rx_queue(struct sock *sk)
  */
 static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 {
-	struct tipc_net *tn = net_generic(sock_net(&tsk->sk), tipc_net_id);
+	struct sock *sk = &tsk->sk;
+	struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id);
 	u32 peer_port = tsk_peer_port(tsk);
 	u32 orig_node;
 	u32 peer_node;
 
-	if (unlikely(!tsk->connected))
+	if (unlikely(!tipc_sk_connected(sk)))
 		return false;
 
 	if (unlikely(msg_origport(msg) != peer_port))
@@ -470,7 +474,6 @@ static int tipc_release(struct socket *sock)
 			if ((sock->state == SS_CONNECTING) ||
 			    (sock->state == SS_CONNECTED)) {
 				sock->state = SS_DISCONNECTING;
-				tsk->connected = 0;
 				tipc_node_remove_conn(net, dnode, tsk->portid);
 			}
 			tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
@@ -480,7 +483,7 @@ static int tipc_release(struct socket *sock)
 	tipc_sk_withdraw(tsk, 0, NULL);
 	sk_stop_timer(sk, &sk->sk_timer);
 	tipc_sk_remove(tsk);
-	if (tsk->connected) {
+	if (tipc_sk_connected(sk)) {
 		skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
 				      TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
 				      tsk_own_node(tsk), tsk_peer_port(tsk),
@@ -1010,7 +1013,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
 		done = sk_wait_event(sk, timeo_p,
 				     (!tsk->link_cong &&
 				      !tsk_conn_cong(tsk)) ||
-				     !tsk->connected);
+				      !tipc_sk_connected(sk));
 		finish_wait(sk_sleep(sk), &wait);
 	} while (!done);
 	return 0;
@@ -1152,7 +1155,6 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
 
 	tsk->probing_intv = CONN_PROBING_INTERVAL;
 	tsk->probing_state = TIPC_CONN_OK;
-	tsk->connected = 1;
 	sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
 	tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
 	tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
@@ -1261,13 +1263,14 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
 
 static void tipc_sk_send_ack(struct tipc_sock *tsk)
 {
-	struct net *net = sock_net(&tsk->sk);
+	struct sock *sk = &tsk->sk;
+	struct net *net = sock_net(sk);
 	struct sk_buff *skb = NULL;
 	struct tipc_msg *msg;
 	u32 peer_port = tsk_peer_port(tsk);
 	u32 dnode = tsk_peer_node(tsk);
 
-	if (!tsk->connected)
+	if (!tipc_sk_connected(sk))
 		return;
 	skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0,
 			      dnode, tsk_own_node(tsk), peer_port,
@@ -1596,7 +1599,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 
 		if (unlikely(msg_errcode(hdr))) {
 			sock->state = SS_DISCONNECTING;
-			tsk->connected = 0;
 			/* Let timer expire on it's own */
 			tipc_node_remove_conn(net, tsk_peer_node(tsk),
 					      tsk->portid);
@@ -2189,7 +2191,6 @@ static int tipc_shutdown(struct socket *sock, int how)
 			if (skb)
 				tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
 		}
-		tsk->connected = 0;
 		sock->state = SS_DISCONNECTING;
 		tipc_node_remove_conn(net, dnode, tsk->portid);
 		/* fall through */
@@ -2221,7 +2222,7 @@ static void tipc_sk_timeout(unsigned long data)
 	u32 own_node = tsk_own_node(tsk);
 
 	bh_lock_sock(sk);
-	if (!tsk->connected) {
+	if (!tipc_sk_connected(sk)) {
 		bh_unlock_sock(sk);
 		goto exit;
 	}
@@ -2231,7 +2232,6 @@ static void tipc_sk_timeout(unsigned long data)
 	if (tsk->probing_state == TIPC_CONN_PROBING) {
 		if (!sock_owned_by_user(sk)) {
 			sk->sk_socket->state = SS_DISCONNECTING;
-			tsk->connected = 0;
 			tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
 					      tsk_peer_port(tsk));
 			sk->sk_state_change(sk);
@@ -2257,11 +2257,12 @@ static void tipc_sk_timeout(unsigned long data)
 static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
 			   struct tipc_name_seq const *seq)
 {
-	struct net *net = sock_net(&tsk->sk);
+	struct sock *sk = &tsk->sk;
+	struct net *net = sock_net(sk);
 	struct publication *publ;
 	u32 key;
 
-	if (tsk->connected)
+	if (tipc_sk_connected(sk))
 		return -EINVAL;
 	key = tsk->portid + tsk->pub_count + 1;
 	if (key == tsk->portid)
@@ -2719,6 +2720,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
 	struct nlattr *attrs;
 	struct net *net = sock_net(skb->sk);
 	struct tipc_net *tn = net_generic(net, tipc_net_id);
+	struct sock *sk = &tsk->sk;
 
 	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
 			  &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
@@ -2733,7 +2735,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
 	if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr))
 		goto attr_msg_cancel;
 
-	if (tsk->connected) {
+	if (tipc_sk_connected(sk)) {
 		err = __tipc_nl_add_sk_con(skb, tsk);
 		if (err)
 			goto attr_msg_cancel;
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 08/16] tipc: remove probing_intv from tipc_sock
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (6 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 07/16] tipc: remove tsk->connected from tipc_sock Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 09/16] tipc: remove socket state SS_READY Parthasarathy Bhuvaragan
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

Until now, probing_intv is a variable in struct tipc_sock but is
always set to a constant CONN_PROBING_INTERVAL. The socket
connection is probed based on this value.

In this commit, we remove this variable and setup the socket
timer based on the constant CONN_PROBING_INTERVAL.

There is no functional change in this commit.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7b6a1847cf8a..1b1aa941cd06 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -67,7 +67,6 @@
  * @publications: list of publications for port
  * @pub_count: total # of publications port has made during its lifetime
  * @probing_state:
- * @probing_intv:
  * @conn_timeout: the time we can wait for an unresponded setup request
  * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
  * @link_cong: non-zero if owner must sleep because of link congestion
@@ -89,7 +88,6 @@ struct tipc_sock {
 	struct list_head publications;
 	u32 pub_count;
 	u32 probing_state;
-	unsigned long probing_intv;
 	uint conn_timeout;
 	atomic_t dupl_rcvcnt;
 	bool link_cong;
@@ -1153,9 +1151,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
 	msg_set_lookup_scope(msg, 0);
 	msg_set_hdr_sz(msg, SHORT_H_SIZE);
 
-	tsk->probing_intv = CONN_PROBING_INTERVAL;
 	tsk->probing_state = TIPC_CONN_OK;
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
 	tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
 	tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
 	tsk->peer_caps = tipc_node_get_capabilities(net, peer_node);
@@ -2240,13 +2237,15 @@ static void tipc_sk_timeout(unsigned long data)
 			sk_reset_timer(sk, &sk->sk_timer, (HZ / 20));
 		}
 
-	} else {
-		skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
-				      INT_H_SIZE, 0, peer_node, own_node,
-				      peer_port, tsk->portid, TIPC_OK);
-		tsk->probing_state = TIPC_CONN_PROBING;
-		sk_reset_timer(sk, &sk->sk_timer, jiffies + tsk->probing_intv);
+		bh_unlock_sock(sk);
+		goto exit;
 	}
+
+	skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
+			      INT_H_SIZE, 0, peer_node, own_node,
+			      peer_port, tsk->portid, TIPC_OK);
+	tsk->probing_state = TIPC_CONN_PROBING;
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
 	bh_unlock_sock(sk);
 	if (skb)
 		tipc_node_xmit_skb(sock_net(sk), skb, peer_node, tsk->portid);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 09/16] tipc: remove socket state SS_READY
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (7 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 08/16] tipc: remove probing_intv " Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 10/16] tipc: create TIPC_LISTEN as a new sk_state Parthasarathy Bhuvaragan
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, tipc socket state SS_READY declares that the socket is a
connectionless socket.

In this commit, we remove the state SS_READY and replace it with a
condition which returns true for datagram / connectionless sockets.

Acked-by: Ying Xue <ying.xue@windriver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/socket.c | 49 +++++++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1b1aa941cd06..a8c10764f2f6 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -45,7 +45,6 @@
 #include "netlink.h"
 
 #define SS_LISTENING		-1	/* socket is listening */
-#define SS_READY		-2	/* socket is connectionless */
 
 #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
 #define CONN_PROBING_INTERVAL	msecs_to_jiffies(3600000)  /* [ms] => 1 h */
@@ -294,6 +293,16 @@ static bool tipc_sk_connected(struct sock *sk)
 	return sk->sk_socket->state == SS_CONNECTED;
 }
 
+/* tipc_sk_type_connectionless - check if the socket is datagram socket
+ * @sk: socket
+ *
+ * Returns true if connection less, false otherwise
+ */
+static bool tipc_sk_type_connectionless(struct sock *sk)
+{
+	return sk->sk_type == SOCK_RDM || sk->sk_type == SOCK_DGRAM;
+}
+
 /* tsk_peer_msg - verify if message was sent by connected port's peer
  *
  * Handles cases where the node's network address has changed from
@@ -345,7 +354,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 {
 	struct tipc_net *tn;
 	const struct proto_ops *ops;
-	socket_state state;
 	struct sock *sk;
 	struct tipc_sock *tsk;
 	struct tipc_msg *msg;
@@ -357,16 +365,13 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	switch (sock->type) {
 	case SOCK_STREAM:
 		ops = &stream_ops;
-		state = SS_UNCONNECTED;
 		break;
 	case SOCK_SEQPACKET:
 		ops = &packet_ops;
-		state = SS_UNCONNECTED;
 		break;
 	case SOCK_DGRAM:
 	case SOCK_RDM:
 		ops = &msg_ops;
-		state = SS_READY;
 		break;
 	default:
 		return -EPROTOTYPE;
@@ -387,7 +392,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	/* Finish initializing socket data structures */
 	sock->ops = ops;
-	sock->state = state;
+	sock->state = SS_UNCONNECTED;
 	sock_init_data(sock, sk);
 	if (tipc_sk_insert(tsk)) {
 		pr_warn("Socket create failed; port number exhausted\n");
@@ -407,7 +412,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	tsk->snd_win = tsk_adv_blocks(RCVBUF_MIN);
 	tsk->rcv_win = tsk->snd_win;
 
-	if (sock->state == SS_READY) {
+	if (tipc_sk_type_connectionless(sk)) {
 		tsk_set_unreturnable(tsk, true);
 		if (sock->type == SOCK_DGRAM)
 			tsk_set_unreliable(tsk, true);
@@ -651,12 +656,19 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 
 	sock_poll_wait(file, sk_sleep(sk), wait);
 
+	if (tipc_sk_type_connectionless(sk)) {
+		if (!tsk->link_cong)
+			mask |= POLLOUT;
+		if (!skb_queue_empty(&sk->sk_receive_queue))
+			mask |= (POLLIN | POLLRDNORM);
+		return mask;
+	}
+
 	switch ((int)sock->state) {
 	case SS_UNCONNECTED:
 		if (!tsk->link_cong)
 			mask |= POLLOUT;
 		break;
-	case SS_READY:
 	case SS_CONNECTED:
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
@@ -893,6 +905,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 	struct tipc_msg *mhdr = &tsk->phdr;
 	u32 dnode, dport;
 	struct sk_buff_head pktchain;
+	bool is_connectionless = tipc_sk_type_connectionless(sk);
 	struct sk_buff *skb;
 	struct tipc_name_seq *seq;
 	struct iov_iter save;
@@ -903,7 +916,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 	if (dsz > TIPC_MAX_USER_MSG_SIZE)
 		return -EMSGSIZE;
 	if (unlikely(!dest)) {
-		if (sock->state == SS_READY && tsk->peer.family == AF_TIPC)
+		if (is_connectionless && tsk->peer.family == AF_TIPC)
 			dest = &tsk->peer;
 		else
 			return -EDESTADDRREQ;
@@ -911,7 +924,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 		   dest->family != AF_TIPC) {
 		return -EINVAL;
 	}
-	if (unlikely(sock->state != SS_READY)) {
+	if (!is_connectionless) {
 		if (sock->state == SS_LISTENING)
 			return -EPIPE;
 		if (sock->state != SS_UNCONNECTED)
@@ -966,7 +979,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 		TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
 		rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
 		if (likely(!rc)) {
-			if (sock->state != SS_READY)
+			if (!is_connectionless)
 				sock->state = SS_CONNECTING;
 			return dsz;
 		}
@@ -1337,6 +1350,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
 	struct tipc_sock *tsk = tipc_sk(sk);
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
+	bool is_connectionless = tipc_sk_type_connectionless(sk);
 	long timeo;
 	unsigned int sz;
 	u32 err;
@@ -1348,7 +1362,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
 
 	lock_sock(sk);
 
-	if (unlikely(sock->state == SS_UNCONNECTED)) {
+	if (!is_connectionless && unlikely(sock->state == SS_UNCONNECTED)) {
 		res = -ENOTCONN;
 		goto exit;
 	}
@@ -1393,8 +1407,8 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
 			goto exit;
 		res = sz;
 	} else {
-		if ((sock->state == SS_READY) ||
-		    ((err == TIPC_CONN_SHUTDOWN) || m->msg_control))
+		if (is_connectionless || err == TIPC_CONN_SHUTDOWN ||
+		    m->msg_control)
 			res = 0;
 		else
 			res = -ECONNRESET;
@@ -1403,7 +1417,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
 	if (unlikely(flags & MSG_PEEK))
 		goto exit;
 
-	if (likely(sock->state != SS_READY)) {
+	if (likely(!is_connectionless)) {
 		tsk->rcv_unacked += tsk_inc(tsk, hlen + sz);
 		if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4)))
 			tipc_sk_send_ack(tsk);
@@ -1699,7 +1713,6 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *skb)
 static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
 		       struct sk_buff_head *xmitq)
 {
-	struct socket *sock = sk->sk_socket;
 	struct tipc_sock *tsk = tipc_sk(sk);
 	struct tipc_msg *hdr = buf_msg(skb);
 	unsigned int limit = rcvbuf_limit(sk, skb);
@@ -1725,7 +1738,7 @@ static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
 	}
 
 	/* Reject if wrong message type for current socket state */
-	if (unlikely(sock->state == SS_READY)) {
+	if (tipc_sk_type_connectionless(sk)) {
 		if (msg_connected(hdr)) {
 			err = TIPC_ERR_NO_PORT;
 			goto reject;
@@ -1935,7 +1948,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 	lock_sock(sk);
 
 	/* DGRAM/RDM connect(), just save the destaddr */
-	if (sock->state == SS_READY) {
+	if (tipc_sk_type_connectionless(sk)) {
 		if (dst->family == AF_UNSPEC) {
 			memset(&tsk->peer, 0, sizeof(struct sockaddr_tipc));
 		} else if (destlen != sizeof(struct sockaddr_tipc)) {
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 10/16] tipc: create TIPC_LISTEN as a new sk_state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (8 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 09/16] tipc: remove socket state SS_READY Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 11/16] tipc: create TIPC_ESTABLISHED " Parthasarathy Bhuvaragan
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

Until now, tipc maintains the socket state in sock->state variable.
This is used to maintain generic socket states, but in tipc
we overload it and save tipc socket states like TIPC_LISTEN.
Other protocols like TCP, UDP store protocol specific states
in sk->sk_state instead.

In this commit, we :
- declare a new tipc state TIPC_LISTEN, that replaces SS_LISTEN
- Create a new function tipc_set_state(), to update sk->sk_state.
- TIPC_LISTEN state is maintained in sk->sk_state.
- replace references to SS_LISTEN with TIPC_LISTEN.

There is no functional change in this commit.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: set TIPC_LISTEN value to TCP_LISTEN to permit the usage of generic
    sk_* helpers as suggested by Eric Dumazet.
---
 net/tipc/socket.c | 62 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 19 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index a8c10764f2f6..ce7d9be8833c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -44,8 +44,6 @@
 #include "bcast.h"
 #include "netlink.h"
 
-#define SS_LISTENING		-1	/* socket is listening */
-
 #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
 #define CONN_PROBING_INTERVAL	msecs_to_jiffies(3600000)  /* [ms] => 1 h */
 #define TIPC_FWD_MSG		1
@@ -54,6 +52,10 @@
 #define TIPC_MAX_PORT		0xffffffff
 #define TIPC_MIN_PORT		1
 
+enum {
+	TIPC_LISTEN = TCP_LISTEN,
+};
+
 /**
  * struct tipc_sock - TIPC socket structure
  * @sk: socket - interacts with 'port' and with user via the socket API
@@ -337,6 +339,31 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 	return false;
 }
 
+/* tipc_set_sk_state - set the sk_state of the socket
+ * @sk: socket
+ *
+ * Caller must hold socket lock
+ *
+ * Returns 0 on success, errno otherwise
+ */
+static int tipc_set_sk_state(struct sock *sk, int state)
+{
+	int oldstate = sk->sk_socket->state;
+	int res = -EINVAL;
+
+	switch (state) {
+	case TIPC_LISTEN:
+		if (oldstate == SS_UNCONNECTED)
+			res = 0;
+		break;
+	}
+
+	if (!res)
+		sk->sk_state = state;
+
+	return res;
+}
+
 /**
  * tipc_sk_create - create a TIPC socket
  * @net: network namespace (must be default network)
@@ -666,15 +693,22 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 
 	switch ((int)sock->state) {
 	case SS_UNCONNECTED:
-		if (!tsk->link_cong)
-			mask |= POLLOUT;
+		switch (sk->sk_state) {
+		case TIPC_LISTEN:
+			if (!skb_queue_empty(&sk->sk_receive_queue))
+				mask |= (POLLIN | POLLRDNORM);
+			break;
+		default:
+			if (!tsk->link_cong)
+				mask |= POLLOUT;
+			break;
+		}
 		break;
 	case SS_CONNECTED:
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
 		/* fall thru' */
 	case SS_CONNECTING:
-	case SS_LISTENING:
 		if (!skb_queue_empty(&sk->sk_receive_queue))
 			mask |= (POLLIN | POLLRDNORM);
 		break;
@@ -925,7 +959,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 		return -EINVAL;
 	}
 	if (!is_connectionless) {
-		if (sock->state == SS_LISTENING)
+		if (sk->sk_state == TIPC_LISTEN)
 			return -EPIPE;
 		if (sock->state != SS_UNCONNECTED)
 			return -EISCONN;
@@ -1651,7 +1685,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 		msg_set_dest_droppable(hdr, 1);
 		return false;
 
-	case SS_LISTENING:
 	case SS_UNCONNECTED:
 
 		/* Accept only SYN message */
@@ -2026,15 +2059,9 @@ static int tipc_listen(struct socket *sock, int len)
 	int res;
 
 	lock_sock(sk);
-
-	if (sock->state != SS_UNCONNECTED)
-		res = -EINVAL;
-	else {
-		sock->state = SS_LISTENING;
-		res = 0;
-	}
-
+	res = tipc_set_sk_state(sk, TIPC_LISTEN);
 	release_sock(sk);
+
 	return res;
 }
 
@@ -2060,9 +2087,6 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
 		err = 0;
 		if (!skb_queue_empty(&sk->sk_receive_queue))
 			break;
-		err = -EINVAL;
-		if (sock->state != SS_LISTENING)
-			break;
 		err = -EAGAIN;
 		if (!timeo)
 			break;
@@ -2093,7 +2117,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 
 	lock_sock(sk);
 
-	if (sock->state != SS_LISTENING) {
+	if (sk->sk_state != TIPC_LISTEN) {
 		res = -EINVAL;
 		goto exit;
 	}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 11/16] tipc: create TIPC_ESTABLISHED as a new sk_state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (9 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 10/16] tipc: create TIPC_LISTEN as a new sk_state Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 12/16] tipc: create TIPC_OPEN " Parthasarathy Bhuvaragan
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

Until now, tipc maintains probing state for connected sockets in
tsk->probing_state variable.

In this commit, we express this information as socket states and
this remove the variable. We set probe_unacked flag when a probe
is sent out and reset it if we receive a reply. Instead of the
probing state TIPC_CONN_OK, we create a new state TIPC_ESTABLISHED.

There is no functional change in this commit.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: remove TIPC_PROBING state and replace it with probe_unacked flag.
---
 net/tipc/socket.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ce7d9be8833c..9215e2144b6a 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -47,13 +47,12 @@
 #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
 #define CONN_PROBING_INTERVAL	msecs_to_jiffies(3600000)  /* [ms] => 1 h */
 #define TIPC_FWD_MSG		1
-#define TIPC_CONN_OK		0
-#define TIPC_CONN_PROBING	1
 #define TIPC_MAX_PORT		0xffffffff
 #define TIPC_MIN_PORT		1
 
 enum {
 	TIPC_LISTEN = TCP_LISTEN,
+	TIPC_ESTABLISHED = TCP_ESTABLISHED,
 };
 
 /**
@@ -88,9 +87,9 @@ struct tipc_sock {
 	struct list_head sock_list;
 	struct list_head publications;
 	u32 pub_count;
-	u32 probing_state;
 	uint conn_timeout;
 	atomic_t dupl_rcvcnt;
+	bool probe_unacked;
 	bool link_cong;
 	u16 snt_unacked;
 	u16 snd_win;
@@ -356,6 +355,11 @@ static int tipc_set_sk_state(struct sock *sk, int state)
 		if (oldstate == SS_UNCONNECTED)
 			res = 0;
 		break;
+	case TIPC_ESTABLISHED:
+		if (oldstate == SS_CONNECTING ||
+		    oldstate == SS_UNCONNECTED)
+			res = 0;
+		break;
 	}
 
 	if (!res)
@@ -858,7 +862,7 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
 	if (!tsk_peer_msg(tsk, hdr))
 		goto exit;
 
-	tsk->probing_state = TIPC_CONN_OK;
+	tsk->probe_unacked = false;
 
 	if (mtyp == CONN_PROBE) {
 		msg_set_type(hdr, CONN_PROBE_REPLY);
@@ -1198,8 +1202,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
 	msg_set_lookup_scope(msg, 0);
 	msg_set_hdr_sz(msg, SHORT_H_SIZE);
 
-	tsk->probing_state = TIPC_CONN_OK;
 	sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
+	tipc_set_sk_state(sk, TIPC_ESTABLISHED);
 	tipc_node_add_conn(net, peer_node, tsk->portid, peer_port);
 	tsk->max_pkt = tipc_node_get_mtu(net, peer_node, tsk->portid);
 	tsk->peer_caps = tipc_node_get_capabilities(net, peer_node);
@@ -2263,7 +2267,7 @@ static void tipc_sk_timeout(unsigned long data)
 	peer_port = tsk_peer_port(tsk);
 	peer_node = tsk_peer_node(tsk);
 
-	if (tsk->probing_state == TIPC_CONN_PROBING) {
+	if (tsk->probe_unacked) {
 		if (!sock_owned_by_user(sk)) {
 			sk->sk_socket->state = SS_DISCONNECTING;
 			tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
@@ -2281,7 +2285,7 @@ static void tipc_sk_timeout(unsigned long data)
 	skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
 			      INT_H_SIZE, 0, peer_node, own_node,
 			      peer_port, tsk->portid, TIPC_OK);
-	tsk->probing_state = TIPC_CONN_PROBING;
+	tsk->probe_unacked = true;
 	sk_reset_timer(sk, &sk->sk_timer, jiffies + CONN_PROBING_INTERVAL);
 	bh_unlock_sock(sk);
 	if (skb)
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 12/16] tipc: create TIPC_OPEN as a new sk_state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (10 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 11/16] tipc: create TIPC_ESTABLISHED " Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 13/16] tipc: create TIPC_DISCONNECTING " Parthasarathy Bhuvaragan
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

In this commit, we create a new tipc socket state TIPC_OPEN in
sk_state. We primarily replace the SS_UNCONNECTED sock->state with
TIPC_OPEN.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: TIPC_OPEN is set to the default sk_state TCP_CLOSE.
---
 net/tipc/socket.c | 97 ++++++++++++++++++++++++-------------------------------
 1 file changed, 43 insertions(+), 54 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 9215e2144b6a..b14dd2549980 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -53,6 +53,7 @@
 enum {
 	TIPC_LISTEN = TCP_LISTEN,
 	TIPC_ESTABLISHED = TCP_ESTABLISHED,
+	TIPC_OPEN = TCP_CLOSE,
 };
 
 /**
@@ -348,16 +349,21 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 static int tipc_set_sk_state(struct sock *sk, int state)
 {
 	int oldstate = sk->sk_socket->state;
+	int oldsk_state = sk->sk_state;
 	int res = -EINVAL;
 
 	switch (state) {
+	case TIPC_OPEN:
+		res = 0;
+		break;
 	case TIPC_LISTEN:
-		if (oldstate == SS_UNCONNECTED)
+		if (oldsk_state == TIPC_OPEN)
 			res = 0;
 		break;
 	case TIPC_ESTABLISHED:
 		if (oldstate == SS_CONNECTING ||
-		    oldstate == SS_UNCONNECTED)
+		    oldstate == SS_UNCONNECTED ||
+		    oldsk_state == TIPC_OPEN)
 			res = 0;
 		break;
 	}
@@ -423,8 +429,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	/* Finish initializing socket data structures */
 	sock->ops = ops;
-	sock->state = SS_UNCONNECTED;
 	sock_init_data(sock, sk);
+	tipc_set_sk_state(sk, TIPC_OPEN);
 	if (tipc_sk_insert(tsk)) {
 		pr_warn("Socket create failed; port number exhausted\n");
 		return -EINVAL;
@@ -448,6 +454,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 		if (sock->type == SOCK_DGRAM)
 			tsk_set_unreliable(tsk, true);
 	}
+
 	return 0;
 }
 
@@ -652,28 +659,6 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
  * exits.  TCP and other protocols seem to rely on higher level poll routines
  * to handle any preventable race conditions, so TIPC will do the same ...
  *
- * TIPC sets the returned events as follows:
- *
- * socket state		flags set
- * ------------		---------
- * unconnected		no read flags
- *			POLLOUT if port is not congested
- *
- * connecting		POLLIN/POLLRDNORM if ACK/NACK in rx queue
- *			no write flags
- *
- * connected		POLLIN/POLLRDNORM if data in rx queue
- *			POLLOUT if port is not congested
- *
- * disconnecting	POLLIN/POLLRDNORM/POLLHUP
- *			no write flags
- *
- * listening		POLLIN if SYN in rx queue
- *			no write flags
- *
- * ready		POLLIN/POLLRDNORM if data in rx queue
- * [connectionless]	POLLOUT (since port cannot be congested)
- *
  * IMPORTANT: The fact that a read or write operation is indicated does NOT
  * imply that the operation will succeed, merely that it should be performed
  * and will not block.
@@ -687,27 +672,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 
 	sock_poll_wait(file, sk_sleep(sk), wait);
 
-	if (tipc_sk_type_connectionless(sk)) {
-		if (!tsk->link_cong)
-			mask |= POLLOUT;
-		if (!skb_queue_empty(&sk->sk_receive_queue))
-			mask |= (POLLIN | POLLRDNORM);
-		return mask;
-	}
-
 	switch ((int)sock->state) {
-	case SS_UNCONNECTED:
-		switch (sk->sk_state) {
-		case TIPC_LISTEN:
-			if (!skb_queue_empty(&sk->sk_receive_queue))
-				mask |= (POLLIN | POLLRDNORM);
-			break;
-		default:
-			if (!tsk->link_cong)
-				mask |= POLLOUT;
-			break;
-		}
-		break;
 	case SS_CONNECTED:
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
@@ -719,6 +684,20 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 	case SS_DISCONNECTING:
 		mask = (POLLIN | POLLRDNORM | POLLHUP);
 		break;
+	default:
+		switch (sk->sk_state) {
+		case TIPC_OPEN:
+			if (!tsk->link_cong)
+				mask |= POLLOUT;
+			if (tipc_sk_type_connectionless(sk) &&
+			    (!skb_queue_empty(&sk->sk_receive_queue)))
+				mask |= (POLLIN | POLLRDNORM);
+			break;
+		case TIPC_LISTEN:
+			if (!skb_queue_empty(&sk->sk_receive_queue))
+				mask |= (POLLIN | POLLRDNORM);
+			break;
+		}
 	}
 
 	return mask;
@@ -965,7 +944,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 	if (!is_connectionless) {
 		if (sk->sk_state == TIPC_LISTEN)
 			return -EPIPE;
-		if (sock->state != SS_UNCONNECTED)
+		if (sk->sk_state != TIPC_OPEN)
 			return -EISCONN;
 		if (tsk->published)
 			return -EOPNOTSUPP;
@@ -1400,7 +1379,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len,
 
 	lock_sock(sk);
 
-	if (!is_connectionless && unlikely(sock->state == SS_UNCONNECTED)) {
+	if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) {
 		res = -ENOTCONN;
 		goto exit;
 	}
@@ -1497,7 +1476,7 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m,
 
 	lock_sock(sk);
 
-	if (unlikely(sock->state == SS_UNCONNECTED)) {
+	if (unlikely(sk->sk_state == TIPC_OPEN)) {
 		res = -ENOTCONN;
 		goto exit;
 	}
@@ -1689,17 +1668,22 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 		msg_set_dest_droppable(hdr, 1);
 		return false;
 
-	case SS_UNCONNECTED:
+	case SS_DISCONNECTING:
+		break;
+	}
 
+	switch (sk->sk_state) {
+	case TIPC_OPEN:
+		break;
+	case TIPC_LISTEN:
 		/* Accept only SYN message */
 		if (!msg_connected(hdr) && !(msg_errcode(hdr)))
 			return true;
 		break;
-	case SS_DISCONNECTING:
-		break;
 	default:
-		pr_err("Unknown socket state %u\n", sock->state);
+		pr_err("Unknown sk_state %u\n", sk->sk_state);
 	}
+
 	return false;
 }
 
@@ -2008,8 +1992,9 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 	}
 
 	previous = sock->state;
-	switch (sock->state) {
-	case SS_UNCONNECTED:
+
+	switch (sk->sk_state) {
+	case TIPC_OPEN:
 		/* Send a 'SYN-' to destination */
 		m.msg_name = dest;
 		m.msg_namelen = destlen;
@@ -2029,6 +2014,10 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 		 * case is EINPROGRESS, rather than EALREADY.
 		 */
 		res = -EINPROGRESS;
+		break;
+	}
+
+	switch (sock->state) {
 	case SS_CONNECTING:
 		if (previous == SS_CONNECTING)
 			res = -EALREADY;
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 13/16] tipc: create TIPC_DISCONNECTING as a new sk_state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (11 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 12/16] tipc: create TIPC_OPEN " Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 14/16] tipc: remove SS_DISCONNECTING state Parthasarathy Bhuvaragan
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

In this commit, we create a new tipc socket state TIPC_DISCONNECTING in
sk_state. TIPC_DISCONNECTING is replacing the socket connection status
update using SS_DISCONNECTING.
TIPC_DISCONNECTING is set for connection oriented sockets at:
- tipc_shutdown()
- connection probe timeout
- when we receive an error message on the connection.

There is no functional change in this commit.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: set TIPC_DISCONNECTING to TCP_CLOSE_WAIT.
---
 net/tipc/socket.c | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b14dd2549980..a48c0c0676cf 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -54,6 +54,7 @@ enum {
 	TIPC_LISTEN = TCP_LISTEN,
 	TIPC_ESTABLISHED = TCP_ESTABLISHED,
 	TIPC_OPEN = TCP_CLOSE,
+	TIPC_DISCONNECTING = TCP_CLOSE_WAIT,
 };
 
 /**
@@ -362,10 +363,14 @@ static int tipc_set_sk_state(struct sock *sk, int state)
 		break;
 	case TIPC_ESTABLISHED:
 		if (oldstate == SS_CONNECTING ||
-		    oldstate == SS_UNCONNECTED ||
 		    oldsk_state == TIPC_OPEN)
 			res = 0;
 		break;
+	case TIPC_DISCONNECTING:
+		if (oldstate == SS_CONNECTING ||
+		    oldsk_state == TIPC_ESTABLISHED)
+			res = 0;
+		break;
 	}
 
 	if (!res)
@@ -621,13 +626,14 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
 			int *uaddr_len, int peer)
 {
 	struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
-	struct tipc_sock *tsk = tipc_sk(sock->sk);
+	struct sock *sk = sock->sk;
+	struct tipc_sock *tsk = tipc_sk(sk);
 	struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id);
 
 	memset(addr, 0, sizeof(*addr));
 	if (peer) {
 		if ((sock->state != SS_CONNECTED) &&
-			((peer != 2) || (sock->state != SS_DISCONNECTING)))
+		    ((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING)))
 			return -ENOTCONN;
 		addr->addr.id.ref = tsk_peer_port(tsk);
 		addr->addr.id.node = tsk_peer_node(tsk);
@@ -693,6 +699,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 			    (!skb_queue_empty(&sk->sk_receive_queue)))
 				mask |= (POLLIN | POLLRDNORM);
 			break;
+		case TIPC_DISCONNECTING:
+			mask = (POLLIN | POLLRDNORM | POLLHUP);
+			break;
 		case TIPC_LISTEN:
 			if (!skb_queue_empty(&sk->sk_receive_queue))
 				mask |= (POLLIN | POLLRDNORM);
@@ -1028,7 +1037,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
 		int err = sock_error(sk);
 		if (err)
 			return err;
-		if (sock->state == SS_DISCONNECTING)
+		if (sk->sk_state == TIPC_DISCONNECTING)
 			return -EPIPE;
 		else if (sock->state != SS_CONNECTED)
 			return -ENOTCONN;
@@ -1098,7 +1107,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
 		return -EMSGSIZE;
 
 	if (unlikely(sock->state != SS_CONNECTED)) {
-		if (sock->state == SS_DISCONNECTING)
+		if (sk->sk_state == TIPC_DISCONNECTING)
 			return -EPIPE;
 		else
 			return -ENOTCONN;
@@ -1626,7 +1635,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 			return false;
 
 		if (unlikely(msg_errcode(hdr))) {
-			sock->state = SS_DISCONNECTING;
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
 			/* Let timer expire on it's own */
 			tipc_node_remove_conn(net, tsk_peer_node(tsk),
 					      tsk->portid);
@@ -1641,13 +1650,13 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 			return false;
 
 		if (unlikely(msg_errcode(hdr))) {
-			sock->state = SS_DISCONNECTING;
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
 			sk->sk_err = ECONNREFUSED;
 			return true;
 		}
 
 		if (unlikely(!msg_isdata(hdr))) {
-			sock->state = SS_DISCONNECTING;
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
 			sk->sk_err = EINVAL;
 			return true;
 		}
@@ -1674,6 +1683,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 
 	switch (sk->sk_state) {
 	case TIPC_OPEN:
+	case TIPC_DISCONNECTING:
 		break;
 	case TIPC_LISTEN:
 		/* Accept only SYN message */
@@ -2195,9 +2205,7 @@ static int tipc_shutdown(struct socket *sock, int how)
 
 	lock_sock(sk);
 
-	switch (sock->state) {
-	case SS_CONNECTING:
-	case SS_CONNECTED:
+	if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) {
 
 restart:
 		dnode = tsk_peer_node(tsk);
@@ -2218,11 +2226,12 @@ static int tipc_shutdown(struct socket *sock, int how)
 			if (skb)
 				tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
 		}
-		sock->state = SS_DISCONNECTING;
+		tipc_set_sk_state(sk, TIPC_DISCONNECTING);
 		tipc_node_remove_conn(net, dnode, tsk->portid);
-		/* fall through */
+	}
 
-	case SS_DISCONNECTING:
+	switch (sk->sk_state) {
+	case TIPC_DISCONNECTING:
 
 		/* Discard any unreceived messages */
 		__skb_queue_purge(&sk->sk_receive_queue);
@@ -2258,7 +2267,7 @@ static void tipc_sk_timeout(unsigned long data)
 
 	if (tsk->probe_unacked) {
 		if (!sock_owned_by_user(sk)) {
-			sk->sk_socket->state = SS_DISCONNECTING;
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
 			tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
 					      tsk_peer_port(tsk));
 			sk->sk_state_change(sk);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 14/16] tipc: remove SS_DISCONNECTING state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (12 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 13/16] tipc: create TIPC_DISCONNECTING " Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 15/16] tipc: create TIPC_CONNECTING as a new sk_state Parthasarathy Bhuvaragan
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

In this commit, we replace the references to SS_DISCONNECTING with
the combination of sk_state TIPC_DISCONNECTING and flags set in
sk_shutdown.
We introduce a new function _tipc_shutdown(), which provides
the common code required by tipc_release() and tipc_shutdown().

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: introduce __tipc_shutdown() to avoid code duplication.
    replace the TIPC_CLOSING state in v1 with sk_shutdown flag.
---
 net/tipc/socket.c | 132 +++++++++++++++++++++---------------------------------
 1 file changed, 52 insertions(+), 80 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index a48c0c0676cf..e732b1fe7eab 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -442,6 +442,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	}
 	msg_set_origport(msg, tsk->portid);
 	setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk);
+	sk->sk_shutdown = 0;
 	sk->sk_backlog_rcv = tipc_backlog_rcv;
 	sk->sk_rcvbuf = sysctl_tipc_rmem[1];
 	sk->sk_data_ready = tipc_data_ready;
@@ -470,6 +471,44 @@ static void tipc_sk_callback(struct rcu_head *head)
 	sock_put(&tsk->sk);
 }
 
+/* Caller should hold socket lock for the socket. */
+static void __tipc_shutdown(struct socket *sock, int error)
+{
+	struct sock *sk = sock->sk;
+	struct tipc_sock *tsk = tipc_sk(sk);
+	struct net *net = sock_net(sk);
+	u32 dnode = tsk_peer_node(tsk);
+	struct sk_buff *skb;
+
+	/* Reject all unreceived messages, except on an active connection
+	 * (which disconnects locally & sends a 'FIN+' to peer).
+	 */
+	while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+		if (TIPC_SKB_CB(skb)->bytes_read) {
+			kfree_skb(skb);
+		} else {
+			if (!tipc_sk_type_connectionless(sk) &&
+			    sk->sk_state != TIPC_DISCONNECTING) {
+				tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+				tipc_node_remove_conn(net, dnode, tsk->portid);
+			}
+			tipc_sk_respond(sk, skb, error);
+		}
+	}
+	if (sk->sk_state != TIPC_DISCONNECTING) {
+		skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
+				      TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
+				      tsk_own_node(tsk), tsk_peer_port(tsk),
+				      tsk->portid, error);
+		if (skb)
+			tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
+		if (!tipc_sk_type_connectionless(sk)) {
+			tipc_node_remove_conn(net, dnode, tsk->portid);
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+		}
+	}
+}
+
 /**
  * tipc_release - destroy a TIPC socket
  * @sock: socket to destroy
@@ -489,10 +528,7 @@ static void tipc_sk_callback(struct rcu_head *head)
 static int tipc_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
-	struct net *net;
 	struct tipc_sock *tsk;
-	struct sk_buff *skb;
-	u32 dnode;
 
 	/*
 	 * Exit if socket isn't fully initialized (occurs when a failed accept()
@@ -501,46 +537,16 @@ static int tipc_release(struct socket *sock)
 	if (sk == NULL)
 		return 0;
 
-	net = sock_net(sk);
 	tsk = tipc_sk(sk);
 	lock_sock(sk);
 
-	/*
-	 * Reject all unreceived messages, except on an active connection
-	 * (which disconnects locally & sends a 'FIN+' to peer)
-	 */
-	dnode = tsk_peer_node(tsk);
-	while (sock->state != SS_DISCONNECTING) {
-		skb = __skb_dequeue(&sk->sk_receive_queue);
-		if (skb == NULL)
-			break;
-		if (TIPC_SKB_CB(skb)->bytes_read)
-			kfree_skb(skb);
-		else {
-			if ((sock->state == SS_CONNECTING) ||
-			    (sock->state == SS_CONNECTED)) {
-				sock->state = SS_DISCONNECTING;
-				tipc_node_remove_conn(net, dnode, tsk->portid);
-			}
-			tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
-		}
-	}
-
+	__tipc_shutdown(sock, TIPC_ERR_NO_PORT);
+	sk->sk_shutdown = SHUTDOWN_MASK;
 	tipc_sk_withdraw(tsk, 0, NULL);
 	sk_stop_timer(sk, &sk->sk_timer);
 	tipc_sk_remove(tsk);
-	if (tipc_sk_connected(sk)) {
-		skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
-				      TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
-				      tsk_own_node(tsk), tsk_peer_port(tsk),
-				      tsk->portid, TIPC_ERR_NO_PORT);
-		if (skb)
-			tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
-		tipc_node_remove_conn(net, dnode, tsk->portid);
-	}
 
 	/* Reject any messages that accumulated in backlog queue */
-	sock->state = SS_DISCONNECTING;
 	release_sock(sk);
 
 	call_rcu(&tsk->rcu, tipc_sk_callback);
@@ -678,6 +684,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 
 	sock_poll_wait(file, sk_sleep(sk), wait);
 
+	if (sk->sk_shutdown & RCV_SHUTDOWN)
+		mask |= POLLRDHUP | POLLIN | POLLRDNORM;
+	if (sk->sk_shutdown == SHUTDOWN_MASK)
+		mask |= POLLHUP;
+
 	switch ((int)sock->state) {
 	case SS_CONNECTED:
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
@@ -687,9 +698,6 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 		if (!skb_queue_empty(&sk->sk_receive_queue))
 			mask |= (POLLIN | POLLRDNORM);
 		break;
-	case SS_DISCONNECTING:
-		mask = (POLLIN | POLLRDNORM | POLLHUP);
-		break;
 	default:
 		switch (sk->sk_state) {
 		case TIPC_OPEN:
@@ -882,7 +890,7 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
 		int err = sock_error(sk);
 		if (err)
 			return err;
-		if (sock->state == SS_DISCONNECTING)
+		if (sk->sk_shutdown & SEND_SHUTDOWN)
 			return -EPIPE;
 		if (!*timeo_p)
 			return -EAGAIN;
@@ -1335,7 +1343,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
 	for (;;) {
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 		if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
-			if (sock->state == SS_DISCONNECTING) {
+			if (sk->sk_shutdown & RCV_SHUTDOWN) {
 				err = -ENOTCONN;
 				break;
 			}
@@ -1676,9 +1684,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 		/* 'ACK-' message is neither accepted nor rejected: */
 		msg_set_dest_droppable(hdr, 1);
 		return false;
-
-	case SS_DISCONNECTING:
-		break;
 	}
 
 	switch (sk->sk_state) {
@@ -2191,13 +2196,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 static int tipc_shutdown(struct socket *sock, int how)
 {
 	struct sock *sk = sock->sk;
-	struct net *net = sock_net(sk);
-	struct tipc_sock *tsk = tipc_sk(sk);
-	struct sk_buff *skb;
-	u32 dnode = tsk_peer_node(tsk);
-	u32 dport = tsk_peer_port(tsk);
-	u32 onode = tipc_own_addr(net);
-	u32 oport = tsk->portid;
 	int res;
 
 	if (how != SHUT_RDWR)
@@ -2205,43 +2203,17 @@ static int tipc_shutdown(struct socket *sock, int how)
 
 	lock_sock(sk);
 
-	if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) {
-
-restart:
-		dnode = tsk_peer_node(tsk);
-
-		/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
-		skb = __skb_dequeue(&sk->sk_receive_queue);
-		if (skb) {
-			if (TIPC_SKB_CB(skb)->bytes_read) {
-				kfree_skb(skb);
-				goto restart;
-			}
-			tipc_sk_respond(sk, skb, TIPC_CONN_SHUTDOWN);
-		} else {
-			skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
-					      TIPC_CONN_MSG, SHORT_H_SIZE,
-					      0, dnode, onode, dport, oport,
-					      TIPC_CONN_SHUTDOWN);
-			if (skb)
-				tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
-		}
-		tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-		tipc_node_remove_conn(net, dnode, tsk->portid);
-	}
-
-	switch (sk->sk_state) {
-	case TIPC_DISCONNECTING:
+	__tipc_shutdown(sock, TIPC_CONN_SHUTDOWN);
+	sk->sk_shutdown = SEND_SHUTDOWN;
 
+	if (sk->sk_state == TIPC_DISCONNECTING) {
 		/* Discard any unreceived messages */
 		__skb_queue_purge(&sk->sk_receive_queue);
 
 		/* Wake up anyone sleeping in poll */
 		sk->sk_state_change(sk);
 		res = 0;
-		break;
-
-	default:
+	} else {
 		res = -ENOTCONN;
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 15/16] tipc: create TIPC_CONNECTING as a new sk_state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (13 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 14/16] tipc: remove SS_DISCONNECTING state Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 13:02 ` [PATCH net-next v2 16/16] tipc: remove SS_CONNECTED sock state Parthasarathy Bhuvaragan
  2016-11-01 15:53 ` [PATCH net-next v2 00/16] tipc: socket layer improvements David Miller
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: tipc-discussion, jon.maloy, maloy, ying.xue

In this commit, we create a new tipc socket state TIPC_CONNECTING
by primarily replacing the SS_CONNECTING with TIPC_CONNECTING.

There is no functional change in this commit.

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: set TIPC_CONNECTING to TCP_SYN_SENT.
---
 net/tipc/socket.c | 60 ++++++++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e732b1fe7eab..074f4d546828 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -55,6 +55,7 @@ enum {
 	TIPC_ESTABLISHED = TCP_ESTABLISHED,
 	TIPC_OPEN = TCP_CLOSE,
 	TIPC_DISCONNECTING = TCP_CLOSE_WAIT,
+	TIPC_CONNECTING = TCP_SYN_SENT,
 };
 
 /**
@@ -349,7 +350,6 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
  */
 static int tipc_set_sk_state(struct sock *sk, int state)
 {
-	int oldstate = sk->sk_socket->state;
 	int oldsk_state = sk->sk_state;
 	int res = -EINVAL;
 
@@ -358,16 +358,17 @@ static int tipc_set_sk_state(struct sock *sk, int state)
 		res = 0;
 		break;
 	case TIPC_LISTEN:
+	case TIPC_CONNECTING:
 		if (oldsk_state == TIPC_OPEN)
 			res = 0;
 		break;
 	case TIPC_ESTABLISHED:
-		if (oldstate == SS_CONNECTING ||
+		if (oldsk_state == TIPC_CONNECTING ||
 		    oldsk_state == TIPC_OPEN)
 			res = 0;
 		break;
 	case TIPC_DISCONNECTING:
-		if (oldstate == SS_CONNECTING ||
+		if (oldsk_state == TIPC_CONNECTING ||
 		    oldsk_state == TIPC_ESTABLISHED)
 			res = 0;
 		break;
@@ -689,16 +690,12 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 	if (sk->sk_shutdown == SHUTDOWN_MASK)
 		mask |= POLLHUP;
 
-	switch ((int)sock->state) {
-	case SS_CONNECTED:
+	if ((int)sock->state == SS_CONNECTED) {
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
-		/* fall thru' */
-	case SS_CONNECTING:
 		if (!skb_queue_empty(&sk->sk_receive_queue))
 			mask |= (POLLIN | POLLRDNORM);
-		break;
-	default:
+	} else {
 		switch (sk->sk_state) {
 		case TIPC_OPEN:
 			if (!tsk->link_cong)
@@ -711,6 +708,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 			mask = (POLLIN | POLLRDNORM | POLLHUP);
 			break;
 		case TIPC_LISTEN:
+		case TIPC_CONNECTING:
 			if (!skb_queue_empty(&sk->sk_receive_queue))
 				mask |= (POLLIN | POLLRDNORM);
 			break;
@@ -1014,7 +1012,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
 		rc = tipc_node_xmit(net, &pktchain, dnode, tsk->portid);
 		if (likely(!rc)) {
 			if (!is_connectionless)
-				sock->state = SS_CONNECTING;
+				tipc_set_sk_state(sk, TIPC_CONNECTING);
 			return dsz;
 		}
 		if (rc == -ELINKCONG) {
@@ -1650,9 +1648,10 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 			sk->sk_state_change(sk);
 		}
 		return true;
+	}
 
-	case SS_CONNECTING:
-
+	switch (sk->sk_state) {
+	case TIPC_CONNECTING:
 		/* Accept only ACK or NACK message */
 		if (unlikely(!msg_connected(hdr)))
 			return false;
@@ -1684,9 +1683,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 		/* 'ACK-' message is neither accepted nor rejected: */
 		msg_set_dest_droppable(hdr, 1);
 		return false;
-	}
 
-	switch (sk->sk_state) {
 	case TIPC_OPEN:
 	case TIPC_DISCONNECTING:
 		break;
@@ -1955,7 +1952,8 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)
 			return sock_intr_errno(*timeo_p);
 
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-		done = sk_wait_event(sk, timeo_p, sock->state != SS_CONNECTING);
+		done = sk_wait_event(sk, timeo_p,
+				     sk->sk_state != TIPC_CONNECTING);
 		finish_wait(sk_sleep(sk), &wait);
 	} while (!done);
 	return 0;
@@ -1978,7 +1976,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 	struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
 	struct msghdr m = {NULL,};
 	long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout;
-	socket_state previous;
+	int previous;
 	int res = 0;
 
 	lock_sock(sk);
@@ -2006,7 +2004,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 		goto exit;
 	}
 
-	previous = sock->state;
+	previous = sk->sk_state;
 
 	switch (sk->sk_state) {
 	case TIPC_OPEN:
@@ -2024,31 +2022,29 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 		if ((res < 0) && (res != -EWOULDBLOCK))
 			goto exit;
 
-		/* Just entered SS_CONNECTING state; the only
+		/* Just entered TIPC_CONNECTING state; the only
 		 * difference is that return value in non-blocking
 		 * case is EINPROGRESS, rather than EALREADY.
 		 */
 		res = -EINPROGRESS;
-		break;
-	}
-
-	switch (sock->state) {
-	case SS_CONNECTING:
-		if (previous == SS_CONNECTING)
-			res = -EALREADY;
-		if (!timeout)
+		/* fall thru' */
+	case TIPC_CONNECTING:
+		if (!timeout) {
+			if (previous == TIPC_CONNECTING)
+				res = -EALREADY;
 			goto exit;
+		}
 		timeout = msecs_to_jiffies(timeout);
 		/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
 		res = tipc_wait_for_connect(sock, &timeout);
-		break;
-	case SS_CONNECTED:
+		goto exit;
+	}
+
+	if (sock->state == SS_CONNECTED)
 		res = -EISCONN;
-		break;
-	default:
+	else
 		res = -EINVAL;
-		break;
-	}
+
 exit:
 	release_sock(sk);
 	return res;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next v2 16/16] tipc: remove SS_CONNECTED sock state
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (14 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 15/16] tipc: create TIPC_CONNECTING as a new sk_state Parthasarathy Bhuvaragan
@ 2016-11-01 13:02 ` Parthasarathy Bhuvaragan
  2016-11-01 15:53 ` [PATCH net-next v2 00/16] tipc: socket layer improvements David Miller
  16 siblings, 0 replies; 18+ messages in thread
From: Parthasarathy Bhuvaragan @ 2016-11-01 13:02 UTC (permalink / raw)
  To: netdev; +Cc: jon.maloy, tipc-discussion

In this commit, we replace references to sock->state SS_CONNECTE
with sk_state TIPC_ESTABLISHED.

Finally, the sock->state is no longer explicitly used by tipc.
The FSM below is for various types of connection oriented sockets.

Stream Server Listening Socket:
+-----------+       +-------------+
| TIPC_OPEN |------>| TIPC_LISTEN |
+-----------+       +-------------+

Stream Server Data Socket:
+-----------+       +------------------+
| TIPC_OPEN |------>| TIPC_ESTABLISHED |
+-----------+       +------------------+
                          ^   |
                          |   |
                          |   v
                    +--------------------+
                    | TIPC_DISCONNECTING |
                    +--------------------+

Stream Socket Client:
+-----------+       +-----------------+
| TIPC_OPEN |------>| TIPC_CONNECTING |------+
+-----------+       +-----------------+      |
                            |                |
                            |                |
                            v                |
                    +------------------+     |
                    | TIPC_ESTABLISHED |     |
                    +------------------+     |
                          ^   |              |
                          |   |              |
                          |   v              |
                    +--------------------+   |
                    | TIPC_DISCONNECTING |<--+
                    +--------------------+

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
v2: adapt to the v2 versions of earlier patches.
---
 net/tipc/socket.c | 86 ++++++++++++++++++++++++-------------------------------
 1 file changed, 38 insertions(+), 48 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 074f4d546828..149396366e80 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -294,7 +294,7 @@ static void tsk_rej_rx_queue(struct sock *sk)
 
 static bool tipc_sk_connected(struct sock *sk)
 {
-	return sk->sk_socket->state == SS_CONNECTED;
+	return sk->sk_state == TIPC_ESTABLISHED;
 }
 
 /* tipc_sk_type_connectionless - check if the socket is datagram socket
@@ -639,7 +639,7 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
 
 	memset(addr, 0, sizeof(*addr));
 	if (peer) {
-		if ((sock->state != SS_CONNECTED) &&
+		if ((!tipc_sk_connected(sk)) &&
 		    ((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING)))
 			return -ENOTCONN;
 		addr->addr.id.ref = tsk_peer_port(tsk);
@@ -690,29 +690,26 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 	if (sk->sk_shutdown == SHUTDOWN_MASK)
 		mask |= POLLHUP;
 
-	if ((int)sock->state == SS_CONNECTED) {
+	switch (sk->sk_state) {
+	case TIPC_ESTABLISHED:
 		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
+		/* fall thru' */
+	case TIPC_LISTEN:
+	case TIPC_CONNECTING:
 		if (!skb_queue_empty(&sk->sk_receive_queue))
 			mask |= (POLLIN | POLLRDNORM);
-	} else {
-		switch (sk->sk_state) {
-		case TIPC_OPEN:
-			if (!tsk->link_cong)
-				mask |= POLLOUT;
-			if (tipc_sk_type_connectionless(sk) &&
-			    (!skb_queue_empty(&sk->sk_receive_queue)))
-				mask |= (POLLIN | POLLRDNORM);
-			break;
-		case TIPC_DISCONNECTING:
-			mask = (POLLIN | POLLRDNORM | POLLHUP);
-			break;
-		case TIPC_LISTEN:
-		case TIPC_CONNECTING:
-			if (!skb_queue_empty(&sk->sk_receive_queue))
-				mask |= (POLLIN | POLLRDNORM);
-			break;
-		}
+		break;
+	case TIPC_OPEN:
+		if (!tsk->link_cong)
+			mask |= POLLOUT;
+		if (tipc_sk_type_connectionless(sk) &&
+		    (!skb_queue_empty(&sk->sk_receive_queue)))
+			mask |= (POLLIN | POLLRDNORM);
+		break;
+	case TIPC_DISCONNECTING:
+		mask = (POLLIN | POLLRDNORM | POLLHUP);
+		break;
 	}
 
 	return mask;
@@ -1045,7 +1042,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
 			return err;
 		if (sk->sk_state == TIPC_DISCONNECTING)
 			return -EPIPE;
-		else if (sock->state != SS_CONNECTED)
+		else if (!tipc_sk_connected(sk))
 			return -ENOTCONN;
 		if (!*timeo_p)
 			return -EAGAIN;
@@ -1112,7 +1109,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
 	if (dsz > (uint)INT_MAX)
 		return -EMSGSIZE;
 
-	if (unlikely(sock->state != SS_CONNECTED)) {
+	if (unlikely(!tipc_sk_connected(sk))) {
 		if (sk->sk_state == TIPC_DISCONNECTING)
 			return -EPIPE;
 		else
@@ -1627,29 +1624,11 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 {
 	struct sock *sk = &tsk->sk;
 	struct net *net = sock_net(sk);
-	struct socket *sock = sk->sk_socket;
 	struct tipc_msg *hdr = buf_msg(skb);
 
 	if (unlikely(msg_mcast(hdr)))
 		return false;
 
-	switch ((int)sock->state) {
-	case SS_CONNECTED:
-
-		/* Accept only connection-based messages sent by peer */
-		if (unlikely(!tsk_peer_msg(tsk, hdr)))
-			return false;
-
-		if (unlikely(msg_errcode(hdr))) {
-			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-			/* Let timer expire on it's own */
-			tipc_node_remove_conn(net, tsk_peer_node(tsk),
-					      tsk->portid);
-			sk->sk_state_change(sk);
-		}
-		return true;
-	}
-
 	switch (sk->sk_state) {
 	case TIPC_CONNECTING:
 		/* Accept only ACK or NACK message */
@@ -1670,7 +1649,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 
 		tipc_sk_finish_conn(tsk, msg_origport(hdr), msg_orignode(hdr));
 		msg_set_importance(&tsk->phdr, msg_importance(hdr));
-		sock->state = SS_CONNECTED;
 
 		/* If 'ACK+' message, add to socket receive queue */
 		if (msg_data_sz(hdr))
@@ -1692,6 +1670,19 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 		if (!msg_connected(hdr) && !(msg_errcode(hdr)))
 			return true;
 		break;
+	case TIPC_ESTABLISHED:
+		/* Accept only connection-based messages sent by peer */
+		if (unlikely(!tsk_peer_msg(tsk, hdr)))
+			return false;
+
+		if (unlikely(msg_errcode(hdr))) {
+			tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+			/* Let timer expire on it's own */
+			tipc_node_remove_conn(net, tsk_peer_node(tsk),
+					      tsk->portid);
+			sk->sk_state_change(sk);
+		}
+		return true;
 	default:
 		pr_err("Unknown sk_state %u\n", sk->sk_state);
 	}
@@ -2037,13 +2028,13 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
 		timeout = msecs_to_jiffies(timeout);
 		/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
 		res = tipc_wait_for_connect(sock, &timeout);
-		goto exit;
-	}
-
-	if (sock->state == SS_CONNECTED)
+		break;
+	case TIPC_ESTABLISHED:
 		res = -EISCONN;
-	else
+		break;
+	default:
 		res = -EINVAL;
+	}
 
 exit:
 	release_sock(sk);
@@ -2152,7 +2143,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 
 	/* Connect new socket to it's peer */
 	tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));
-	new_sock->state = SS_CONNECTED;
 
 	tsk_set_importance(new_tsock, msg_importance(msg));
 	if (msg_named(msg)) {
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH net-next v2 00/16] tipc: socket layer improvements
  2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
                   ` (15 preceding siblings ...)
  2016-11-01 13:02 ` [PATCH net-next v2 16/16] tipc: remove SS_CONNECTED sock state Parthasarathy Bhuvaragan
@ 2016-11-01 15:53 ` David Miller
  16 siblings, 0 replies; 18+ messages in thread
From: David Miller @ 2016-11-01 15:53 UTC (permalink / raw)
  To: parthasarathy.bhuvaragan; +Cc: jon.maloy, netdev, tipc-discussion

From: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Date: Tue, 1 Nov 2016 14:02:33 +0100

> The following issues with the current socket layer hinders socket
> diagnostics implementation, which led to this patch series.

Series applied, thank you.

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-11-01 15:53 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-01 13:02 [PATCH net-next v2 00/16] tipc: socket layer improvements Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 01/16] tipc: return early for non-blocking sockets at link congestion Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 02/16] tipc: wakeup sleeping users at disconnect Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 03/16] tipc: set kern=0 in sk_alloc() during tipc_accept() Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 04/16] tipc: rename struct tipc_skb_cb member handle to bytes_read Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 05/16] tipc: rename tsk->remote to tsk->peer for consistent naming Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 06/16] tipc: remove tsk->connected for connectionless sockets Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 07/16] tipc: remove tsk->connected from tipc_sock Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 08/16] tipc: remove probing_intv " Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 09/16] tipc: remove socket state SS_READY Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 10/16] tipc: create TIPC_LISTEN as a new sk_state Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 11/16] tipc: create TIPC_ESTABLISHED " Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 12/16] tipc: create TIPC_OPEN " Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 13/16] tipc: create TIPC_DISCONNECTING " Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 14/16] tipc: remove SS_DISCONNECTING state Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 15/16] tipc: create TIPC_CONNECTING as a new sk_state Parthasarathy Bhuvaragan
2016-11-01 13:02 ` [PATCH net-next v2 16/16] tipc: remove SS_CONNECTED sock state Parthasarathy Bhuvaragan
2016-11-01 15:53 ` [PATCH net-next v2 00/16] tipc: socket layer improvements David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.