From: "jiang.wang" <jiang.w...@bytedance.com>

Currently, only VMCI supports dgram sockets. To supported
nested VM use case, this patch removes transport_dgram and
uses transport_g2h and transport_h2g for dgram too.

The transport is assgined when sending every packet and
receiving every packet on dgram sockets.

Signed-off-by: Jiang Wang <jiang.w...@bytedance.com>
---
This patch is not tested. I don't have a VMWare testing
environment. Could someone help me to test it? 

 include/net/af_vsock.h         |  2 --
 net/vmw_vsock/af_vsock.c       | 63 +++++++++++++++++++++---------------------
 net/vmw_vsock/vmci_transport.c | 20 +++++++++-----
 3 files changed, 45 insertions(+), 40 deletions(-)

diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index b1c717286993..aba241e0d202 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -96,8 +96,6 @@ struct vsock_transport_send_notify_data {
 #define VSOCK_TRANSPORT_F_H2G          0x00000001
 /* Transport provides guest->host communication */
 #define VSOCK_TRANSPORT_F_G2H          0x00000002
-/* Transport provides DGRAM communication */
-#define VSOCK_TRANSPORT_F_DGRAM                0x00000004
 /* Transport provides local (loopback) communication */
 #define VSOCK_TRANSPORT_F_LOCAL                0x00000008
 
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 92a72f0e0d94..7739ab2521a1 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -449,8 +449,6 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct 
vsock_sock *psk)
 
        switch (sk->sk_type) {
        case SOCK_DGRAM:
-               new_transport = transport_dgram;
-               break;
        case SOCK_STREAM:
                if (vsock_use_local_transport(remote_cid))
                        new_transport = transport_local;
@@ -1096,7 +1094,6 @@ static int vsock_dgram_sendmsg(struct socket *sock, 
struct msghdr *msg,
        struct sock *sk;
        struct vsock_sock *vsk;
        struct sockaddr_vm *remote_addr;
-       const struct vsock_transport *transport;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
@@ -1108,25 +1105,30 @@ static int vsock_dgram_sendmsg(struct socket *sock, 
struct msghdr *msg,
 
        lock_sock(sk);
 
-       transport = vsk->transport;
-
        err = vsock_auto_bind(vsk);
        if (err)
                goto out;
 
-
        /* If the provided message contains an address, use that.  Otherwise
         * fall back on the socket's remote handle (if it has been connected).
         */
        if (msg->msg_name &&
            vsock_addr_cast(msg->msg_name, msg->msg_namelen,
                            &remote_addr) == 0) {
+               vsock_addr_init(&vsk->remote_addr, remote_addr->svm_cid,
+                       remote_addr->svm_port);
+
+               err = vsock_assign_transport(vsk, NULL);
+               if (err) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
                /* Ensure this address is of the right type and is a valid
                 * destination.
                 */
-
                if (remote_addr->svm_cid == VMADDR_CID_ANY)
-                       remote_addr->svm_cid = transport->get_local_cid();
+                       remote_addr->svm_cid = vsk->transport->get_local_cid();
 
                if (!vsock_addr_bound(remote_addr)) {
                        err = -EINVAL;
@@ -1136,7 +1138,7 @@ static int vsock_dgram_sendmsg(struct socket *sock, 
struct msghdr *msg,
                remote_addr = &vsk->remote_addr;
 
                if (remote_addr->svm_cid == VMADDR_CID_ANY)
-                       remote_addr->svm_cid = transport->get_local_cid();
+                       remote_addr->svm_cid = vsk->transport->get_local_cid();
 
                /* XXX Should connect() or this function ensure remote_addr is
                 * bound?
@@ -1150,13 +1152,13 @@ static int vsock_dgram_sendmsg(struct socket *sock, 
struct msghdr *msg,
                goto out;
        }
 
-       if (!transport->dgram_allow(remote_addr->svm_cid,
+       if (!vsk->transport->dgram_allow(remote_addr->svm_cid,
                                    remote_addr->svm_port)) {
                err = -EINVAL;
                goto out;
        }
 
-       err = transport->dgram_enqueue(vsk, remote_addr, msg, len);
+       err = vsk->transport->dgram_enqueue(vsk, remote_addr, msg, len);
 
 out:
        release_sock(sk);
@@ -1191,13 +1193,20 @@ static int vsock_dgram_connect(struct socket *sock,
        if (err)
                goto out;
 
+       memcpy(&vsk->remote_addr, remote_addr, sizeof(vsk->remote_addr));
+
+       err = vsock_assign_transport(vsk, NULL);
+       if (err) {
+               err = -EINVAL;
+               goto out;
+       }
+
        if (!vsk->transport->dgram_allow(remote_addr->svm_cid,
                                         remote_addr->svm_port)) {
                err = -EINVAL;
                goto out;
        }
 
-       memcpy(&vsk->remote_addr, remote_addr, sizeof(vsk->remote_addr));
        sock->state = SS_CONNECTED;
 
 out:
@@ -1209,6 +1218,16 @@ static int vsock_dgram_recvmsg(struct socket *sock, 
struct msghdr *msg,
                               size_t len, int flags)
 {
        struct vsock_sock *vsk = vsock_sk(sock->sk);
+       long timeo;
+
+       timeo = sock_rcvtimeo(sock->sk, flags & MSG_DONTWAIT);
+       do {
+               if (vsk->transport)
+                       break;
+       } while (timeo && !vsk->transport);
+
+       if (!vsk->transport)
+               return -EAGAIN;
 
        return vsk->transport->dgram_dequeue(vsk, msg, len, flags);
 }
@@ -2055,14 +2074,6 @@ static int vsock_create(struct net *net, struct socket 
*sock,
 
        vsk = vsock_sk(sk);
 
-       if (sock->type == SOCK_DGRAM) {
-               ret = vsock_assign_transport(vsk, NULL);
-               if (ret < 0) {
-                       sock_put(sk);
-                       return ret;
-               }
-       }
-
        vsock_insert_unbound(vsk);
 
        return 0;
@@ -2182,7 +2193,7 @@ EXPORT_SYMBOL_GPL(vsock_core_get_transport);
 
 int vsock_core_register(const struct vsock_transport *t, int features)
 {
-       const struct vsock_transport *t_h2g, *t_g2h, *t_dgram, *t_local;
+       const struct vsock_transport *t_h2g, *t_g2h, *t_local;
        int err = mutex_lock_interruptible(&vsock_register_mutex);
 
        if (err)
@@ -2190,7 +2201,6 @@ int vsock_core_register(const struct vsock_transport *t, 
int features)
 
        t_h2g = transport_h2g;
        t_g2h = transport_g2h;
-       t_dgram = transport_dgram;
        t_local = transport_local;
 
        if (features & VSOCK_TRANSPORT_F_H2G) {
@@ -2209,14 +2219,6 @@ int vsock_core_register(const struct vsock_transport *t, 
int features)
                t_g2h = t;
        }
 
-       if (features & VSOCK_TRANSPORT_F_DGRAM) {
-               if (t_dgram) {
-                       err = -EBUSY;
-                       goto err_busy;
-               }
-               t_dgram = t;
-       }
-
        if (features & VSOCK_TRANSPORT_F_LOCAL) {
                if (t_local) {
                        err = -EBUSY;
@@ -2227,7 +2229,6 @@ int vsock_core_register(const struct vsock_transport *t, 
int features)
 
        transport_h2g = t_h2g;
        transport_g2h = t_g2h;
-       transport_dgram = t_dgram;
        transport_local = t_local;
 
 err_busy:
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 8b65323207db..42ea2a1c92ce 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -613,6 +613,7 @@ static int vmci_transport_recv_dgram_cb(void *data, struct 
vmci_datagram *dg)
        size_t size;
        struct sk_buff *skb;
        struct vsock_sock *vsk;
+       int err;
 
        sk = (struct sock *)data;
 
@@ -629,6 +630,17 @@ static int vmci_transport_recv_dgram_cb(void *data, struct 
vmci_datagram *dg)
        if (!vmci_transport_allow_dgram(vsk, dg->src.context))
                return VMCI_ERROR_NO_ACCESS;
 
+       vsock_addr_init(&vsk->remote_addr, dg->src.context,
+                               dg->src.resource);
+
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk)) {
+               err = vsock_assign_transport(vsk, NULL);
+               if (err)
+                       return err;
+       }
+       bh_unlock_sock(sk);
+
        size = VMCI_DG_SIZE(dg);
 
        /* Attach the packet to the socket's receive queue as an sk_buff. */
@@ -2093,13 +2105,7 @@ static int __init vmci_transport_init(void)
                goto err_destroy_stream_handle;
        }
 
-       /* Register only with dgram feature, other features (H2G, G2H) will be
-        * registered when the first host or guest becomes active.
-        */
-       err = vsock_core_register(&vmci_transport, VSOCK_TRANSPORT_F_DGRAM);
-       if (err < 0)
-               goto err_unsubscribe;
-
+       /* H2G, G2H will be registered when the first host or guest becomes 
active. */
        err = vmci_register_vsock_callback(vmci_vsock_transport_cb);
        if (err < 0)
                goto err_unregister;
-- 
2.11.0

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to