aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <bergwolf@gmail.com>2017-03-14 21:32:17 -0400
committerDavid S. Miller <davem@davemloft.net>2017-03-21 17:41:47 -0400
commit380feae0def7e6a115124a3219c3ec9b654dca32 (patch)
tree033d132eaa2822a9a133e571c65d4c5bfd033d1b
parent073b4f2c50fe67c7c66a059a4d6db52bb1465490 (diff)
vsock: cancel packets when failing to connect
Otherwise we'll leave the packets queued until releasing vsock device. E.g., if guest is slow to start up, resulting ETIMEDOUT on connect, guest will get the connect requests from failed host sockets. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Jorgen Hansen <jhansen@vmware.com> Signed-off-by: Peng Tao <bergwolf@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/vmw_vsock/af_vsock.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 9f770f33c100..6f7f6757ceef 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1102,10 +1102,19 @@ static const struct proto_ops vsock_dgram_ops = {
1102 .sendpage = sock_no_sendpage, 1102 .sendpage = sock_no_sendpage,
1103}; 1103};
1104 1104
1105static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
1106{
1107 if (!transport->cancel_pkt)
1108 return -EOPNOTSUPP;
1109
1110 return transport->cancel_pkt(vsk);
1111}
1112
1105static void vsock_connect_timeout(struct work_struct *work) 1113static void vsock_connect_timeout(struct work_struct *work)
1106{ 1114{
1107 struct sock *sk; 1115 struct sock *sk;
1108 struct vsock_sock *vsk; 1116 struct vsock_sock *vsk;
1117 int cancel = 0;
1109 1118
1110 vsk = container_of(work, struct vsock_sock, dwork.work); 1119 vsk = container_of(work, struct vsock_sock, dwork.work);
1111 sk = sk_vsock(vsk); 1120 sk = sk_vsock(vsk);
@@ -1116,8 +1125,11 @@ static void vsock_connect_timeout(struct work_struct *work)
1116 sk->sk_state = SS_UNCONNECTED; 1125 sk->sk_state = SS_UNCONNECTED;
1117 sk->sk_err = ETIMEDOUT; 1126 sk->sk_err = ETIMEDOUT;
1118 sk->sk_error_report(sk); 1127 sk->sk_error_report(sk);
1128 cancel = 1;
1119 } 1129 }
1120 release_sock(sk); 1130 release_sock(sk);
1131 if (cancel)
1132 vsock_transport_cancel_pkt(vsk);
1121 1133
1122 sock_put(sk); 1134 sock_put(sk);
1123} 1135}
@@ -1224,11 +1236,13 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
1224 err = sock_intr_errno(timeout); 1236 err = sock_intr_errno(timeout);
1225 sk->sk_state = SS_UNCONNECTED; 1237 sk->sk_state = SS_UNCONNECTED;
1226 sock->state = SS_UNCONNECTED; 1238 sock->state = SS_UNCONNECTED;
1239 vsock_transport_cancel_pkt(vsk);
1227 goto out_wait; 1240 goto out_wait;
1228 } else if (timeout == 0) { 1241 } else if (timeout == 0) {
1229 err = -ETIMEDOUT; 1242 err = -ETIMEDOUT;
1230 sk->sk_state = SS_UNCONNECTED; 1243 sk->sk_state = SS_UNCONNECTED;
1231 sock->state = SS_UNCONNECTED; 1244 sock->state = SS_UNCONNECTED;
1245 vsock_transport_cancel_pkt(vsk);
1232 goto out_wait; 1246 goto out_wait;
1233 } 1247 }
1234 1248