diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 36 | 
1 files changed, 27 insertions, 9 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index ab7a2a7178f7..49810fdff4c5 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -576,6 +576,7 @@ static int tipc_release(struct socket *sock)  	sk_stop_timer(sk, &sk->sk_timer);  	tipc_sk_remove(tsk); +	sock_orphan(sk);  	/* Reject any messages that accumulated in backlog queue */  	release_sock(sk);  	tipc_dest_list_purge(&tsk->cong_links); @@ -1195,6 +1196,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,   * @skb: pointer to message buffer.   */  static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb, +				   struct sk_buff_head *inputq,  				   struct sk_buff_head *xmitq)  {  	struct tipc_msg *hdr = buf_msg(skb); @@ -1212,7 +1214,16 @@ static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,  		tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),  				      tsk_peer_port(tsk));  		sk->sk_state_change(sk); -		goto exit; + +		/* State change is ignored if socket already awake, +		 * - convert msg to abort msg and add to inqueue +		 */ +		msg_set_user(hdr, TIPC_CRITICAL_IMPORTANCE); +		msg_set_type(hdr, TIPC_CONN_MSG); +		msg_set_size(hdr, BASIC_H_SIZE); +		msg_set_hdr_sz(hdr, BASIC_H_SIZE); +		__skb_queue_tail(inputq, skb); +		return;  	}  	tsk->probe_unacked = false; @@ -1418,8 +1429,10 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen)  	/* Handle implicit connection setup */  	if (unlikely(dest)) {  		rc = __tipc_sendmsg(sock, m, dlen); -		if (dlen && (dlen == rc)) +		if (dlen && dlen == rc) { +			tsk->peer_caps = tipc_node_get_capabilities(net, dnode);  			tsk->snt_unacked = tsk_inc(tsk, dlen + msg_hdr_sz(hdr)); +		}  		return rc;  	} @@ -1933,7 +1946,7 @@ static void tipc_sk_proto_rcv(struct sock *sk,  	switch (msg_user(hdr)) {  	case CONN_MANAGER: -		tipc_sk_conn_proto_rcv(tsk, skb, xmitq); +		tipc_sk_conn_proto_rcv(tsk, skb, inputq, xmitq);  		return;  	case SOCK_WAKEUP:  		tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0); @@ -3229,7 +3242,7 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,  				       struct netlink_callback *cb,  				       struct tipc_sock *tsk))  { -	struct rhashtable_iter *iter = (void *)cb->args[0]; +	struct rhashtable_iter *iter = (void *)cb->args[4];  	struct tipc_sock *tsk;  	int err; @@ -3265,8 +3278,14 @@ EXPORT_SYMBOL(tipc_nl_sk_walk);  int tipc_dump_start(struct netlink_callback *cb)  { -	struct rhashtable_iter *iter = (void *)cb->args[0]; -	struct net *net = sock_net(cb->skb->sk); +	return __tipc_dump_start(cb, sock_net(cb->skb->sk)); +} +EXPORT_SYMBOL(tipc_dump_start); + +int __tipc_dump_start(struct netlink_callback *cb, struct net *net) +{ +	/* tipc_nl_name_table_dump() uses cb->args[0...3]. */ +	struct rhashtable_iter *iter = (void *)cb->args[4];  	struct tipc_net *tn = tipc_net(net);  	if (!iter) { @@ -3274,17 +3293,16 @@ int tipc_dump_start(struct netlink_callback *cb)  		if (!iter)  			return -ENOMEM; -		cb->args[0] = (long)iter; +		cb->args[4] = (long)iter;  	}  	rhashtable_walk_enter(&tn->sk_rht, iter);  	return 0;  } -EXPORT_SYMBOL(tipc_dump_start);  int tipc_dump_done(struct netlink_callback *cb)  { -	struct rhashtable_iter *hti = (void *)cb->args[0]; +	struct rhashtable_iter *hti = (void *)cb->args[4];  	rhashtable_walk_exit(hti);  	kfree(hti);  |