diff mbox series

[net-next,5/6] vsock: use local transport when it is loaded

Message ID 20191119110121.14480-6-sgarzare@redhat.com (mailing list archive)
State New, archived
Headers show
Series vsock: add local transport support | expand

Commit Message

Stefano Garzarella Nov. 19, 2019, 11:01 a.m. UTC
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: Stefano Garzarella <sgarzare@redhat.com>
---
 net/vmw_vsock/af_vsock.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

Comments

Stefan Hajnoczi Nov. 21, 2019, 9:46 a.m. UTC | #1
On Tue, Nov 19, 2019 at 12:01:20PM +0100, Stefano Garzarella wrote:
> @@ -420,9 +436,10 @@ 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 ||
> +			 remote_cid == VMADDR_CID_HYPERVISOR)
>  			new_transport = transport_g2h;
>  		else
>  			new_transport = transport_h2g;

We used to send VMADDR_CID_RESERVED to the host.  Now we send
VMADDR_CID_RESERVED (LOCAL) to the guest when there is no
transport_local loaded?

If this is correct, is there a justification for this change?  It seems
safest to retain existing behavior.
Stefano Garzarella Nov. 21, 2019, 10:01 a.m. UTC | #2
On Thu, Nov 21, 2019 at 09:46:14AM +0000, Stefan Hajnoczi wrote:
> On Tue, Nov 19, 2019 at 12:01:20PM +0100, Stefano Garzarella wrote:
> > @@ -420,9 +436,10 @@ 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 ||
> > +			 remote_cid == VMADDR_CID_HYPERVISOR)
> >  			new_transport = transport_g2h;
> >  		else
> >  			new_transport = transport_h2g;
> 
> We used to send VMADDR_CID_RESERVED to the host.  Now we send
> VMADDR_CID_RESERVED (LOCAL) to the guest when there is no
> transport_local loaded?
> 
> If this is correct, is there a justification for this change?  It seems
> safest to retain existing behavior.

You're right, I'll revert this change in v2.

Thanks,
Stefano
diff mbox series

Patch

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index c9e5bad59dc1..40bbb2a17e3d 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -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,10 @@  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_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_LOCAL or g2h->local_cid or VMADDR_CID_HOST if
+ *    g2h is not loaded, will use local transport;
+ *  - remote CID == VMADDR_CID_HOST or VMADDR_CID_HYPERVISOR, will use
+ *    guest->host transport;
  *  - remote CID > VMADDR_CID_HOST will use host->guest transport;
  */
 int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
@@ -420,9 +436,10 @@  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 ||
+			 remote_cid == VMADDR_CID_HYPERVISOR)
 			new_transport = transport_g2h;
 		else
 			new_transport = transport_h2g;
@@ -459,6 +476,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);