Commit 408624af authored by Stefano Garzarella's avatar Stefano Garzarella Committed by David S. Miller
Browse files

vsock: use local transport when it is loaded



Now that we have a transport that can handle the local communication,
we can use it when it is loaded.

A socket will use the local transport (loopback) when the remote
CID is:
- equal to VMADDR_CID_LOCAL
- or equal to transport_g2h->get_local_cid(), if transport_g2h
  is loaded (this allows us to keep the same behavior implemented
  by virtio and vmci transports)
- or equal to VMADDR_CID_HOST, if transport_g2h is not loaded

Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 077263fb
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -388,6 +388,21 @@ void vsock_enqueue_accept(struct sock *listener, struct sock *connected)
}
EXPORT_SYMBOL_GPL(vsock_enqueue_accept);

static bool vsock_use_local_transport(unsigned int remote_cid)
{
	if (!transport_local)
		return false;

	if (remote_cid == VMADDR_CID_LOCAL)
		return true;

	if (transport_g2h) {
		return remote_cid == transport_g2h->get_local_cid();
	} else {
		return remote_cid == VMADDR_CID_HOST;
	}
}

static void vsock_deassign_transport(struct vsock_sock *vsk)
{
	if (!vsk->transport)
@@ -404,9 +419,9 @@ static void vsock_deassign_transport(struct vsock_sock *vsk)
 * (e.g. during the connect() or when a connection request on a listener
 * socket is received).
 * The vsk->remote_addr is used to decide which transport to use:
 *  - remote CID == VMADDR_CID_LOCAL or g2h->local_cid or VMADDR_CID_HOST if
 *    g2h is not loaded, will use local transport;
 *  - remote CID <= VMADDR_CID_HOST will use guest->host transport;
 *  - remote CID == local_cid (guest->host transport) will use guest->host
 *    transport for loopback (host->guest transports don't support loopback);
 *  - remote CID > VMADDR_CID_HOST will use host->guest transport;
 */
int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
@@ -421,9 +436,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
		new_transport = transport_dgram;
		break;
	case SOCK_STREAM:
		if (remote_cid <= VMADDR_CID_HOST ||
		    (transport_g2h &&
		     remote_cid == transport_g2h->get_local_cid()))
		if (vsock_use_local_transport(remote_cid))
			new_transport = transport_local;
		else if (remote_cid <= VMADDR_CID_HOST)
			new_transport = transport_g2h;
		else
			new_transport = transport_h2g;
@@ -466,6 +481,9 @@ bool vsock_find_cid(unsigned int cid)
	if (transport_h2g && cid == VMADDR_CID_HOST)
		return true;

	if (transport_local && cid == VMADDR_CID_LOCAL)
		return true;

	return false;
}
EXPORT_SYMBOL_GPL(vsock_find_cid);