mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-21 11:44:01 +08:00
tipc: queue socket protocol error messages into socket receive buffer
In tipc_sk_filter_rcv(), when we detect protocol messages with error we call tipc_sk_conn_proto_rcv() and let it reset the connection and notify the socket by calling sk->sk_state_change(). However, tipc_sk_filter_rcv() may have been called from the function tipc_backlog_rcv(), in which case the socket lock is held and the socket already awake. This means that the sk_state_change() call is ignored and the error notification lost. Now the receive queue will remain empty and the socket sleeps forever. In this commit, we convert the protocol message into a connection abort message and enqueue it into the socket's receive queue. By this addition to the above state change we cover all conditions. Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
047491ea33
commit
e7eb058238
@ -1196,6 +1196,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
|
|||||||
* @skb: pointer to message buffer.
|
* @skb: pointer to message buffer.
|
||||||
*/
|
*/
|
||||||
static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
|
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 sk_buff_head *xmitq)
|
||||||
{
|
{
|
||||||
struct tipc_msg *hdr = buf_msg(skb);
|
struct tipc_msg *hdr = buf_msg(skb);
|
||||||
@ -1213,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),
|
tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
|
||||||
tsk_peer_port(tsk));
|
tsk_peer_port(tsk));
|
||||||
sk->sk_state_change(sk);
|
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;
|
tsk->probe_unacked = false;
|
||||||
@ -1936,7 +1946,7 @@ static void tipc_sk_proto_rcv(struct sock *sk,
|
|||||||
|
|
||||||
switch (msg_user(hdr)) {
|
switch (msg_user(hdr)) {
|
||||||
case CONN_MANAGER:
|
case CONN_MANAGER:
|
||||||
tipc_sk_conn_proto_rcv(tsk, skb, xmitq);
|
tipc_sk_conn_proto_rcv(tsk, skb, inputq, xmitq);
|
||||||
return;
|
return;
|
||||||
case SOCK_WAKEUP:
|
case SOCK_WAKEUP:
|
||||||
tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0);
|
tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user