From: VMware, Inc <> Date: Wed, 26 Dec 2012 21:14:49 +0000 (-0800) Subject: VSOCK: Remove SOCK_SEQPACKET from Linux X-Git-Tag: 2012.12.26-958366~48 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6d2f9852b8d987820bf95465ce5903e62013a0fb;p=thirdparty%2Fopen-vm-tools.git VSOCK: Remove SOCK_SEQPACKET from Linux This was a poor implementation of SOCK_SEQPACKET, let's rip it out. This mirrors the work done for the upstream Linux driver. A follow-up change will remove it from the other platforms. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c index 94b28dfc0..7477e7051 100644 --- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c +++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c @@ -106,11 +106,6 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -# include -#else -# include -#endif #include #if defined(__x86_64__) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) # include @@ -174,7 +169,6 @@ static Bool VSockVmciProtoToNotifyStruct(struct sock *sk, Bool oldPktProto); static int VSockVmciGetAFValue(void); static int VSockVmciRecvDgramCB(void *data, VMCIDatagram *dg); -static int VSockVmciRecvSeqCB(void *data, VMCIDatagram *dg); static int VSockVmciRecvStreamCB(void *data, VMCIDatagram *dg); static void VSockVmciPeerAttachCB(VMCIId subId, VMCI_EventData *ed, void *clientData); @@ -216,8 +210,6 @@ static int VSockVmciBind(struct socket *sock, struct sockaddr *addr, int addrLen); static int VSockVmciDgramConnect(struct socket *sock, struct sockaddr *addr, int addrLen, int flags); -static int VSockVmciSeqConnect(struct socket *sock, - struct sockaddr *addr, int addrLen, int flags); static int VSockVmciStreamConnect(struct socket *sock, struct sockaddr *addr, int addrLen, int flags); static int VSockVmciAccept(struct socket *sock, struct socket *newsock, int flags); @@ -244,10 +236,6 @@ static int VSockVmciDgramSendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len); static int VSockVmciDgramRecvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); -static int VSockVmciSeqSendmsg(struct kiocb *kiocb, - struct socket *sock, struct msghdr *msg, size_t len); -static int VSockVmciSeqRecvmsg(struct kiocb *kiocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags); static int VSockVmciStreamSendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len); static int VSockVmciStreamRecvmsg(struct kiocb *kiocb, struct socket *sock, @@ -309,7 +297,7 @@ static struct net_proto_family vsockVmciFamilyOps = { .owner = THIS_MODULE, }; -/* Socket operations, split for DGRAM, STREAM and SEQPACKET sockets. */ +/* Socket operations, split for DGRAM and STREAM sockets. */ static struct proto_ops vsockVmciDgramOps = { .family = VSOCK_INVALID_FAMILY, .owner = THIS_MODULE, @@ -331,27 +319,6 @@ static struct proto_ops vsockVmciDgramOps = { .sendpage = sock_no_sendpage, }; -static struct proto_ops vsockVmciSeqOps = { - .family = VSOCK_INVALID_FAMILY, - .owner = THIS_MODULE, - .release = VSockVmciRelease, - .bind = VSockVmciBind, - .connect = VSockVmciSeqConnect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = VSockVmciGetname, - .poll = VSockVmciPoll, - .ioctl = sock_no_ioctl, - .listen = sock_no_listen, - .shutdown = VSockVmciShutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = VSockVmciSeqSendmsg, - .recvmsg = VSockVmciSeqRecvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -}; - static struct proto_ops vsockVmciStreamOps = { .family = VSOCK_INVALID_FAMILY, .owner = THIS_MODULE, @@ -425,11 +392,6 @@ static int PROTOCOL_OVERRIDE = -1; */ #define VSOCK_DEFAULT_CONNECT_TIMEOUT (2 * HZ) -#define VSOCK_SEND_SEQ_CLOSE(_vsk, _err) \ - VSockVmciSendSeqPacket((_vsk), VSOCK_SEQ_PACKET_TYPE_CLOSE, (_err)) -#define VSOCK_SEND_SEQ_SHUTDOWN(_vsk, _mode) \ - VSockVmciSendSeqPacket((_vsk), VSOCK_SEQ_PACKET_TYPE_SHUTDOWN, (_mode)) - #ifdef VMX86_DEVEL # define LOG_PACKET(_pkt) VSockVmciLogPkt(__FUNCTION__, __LINE__, _pkt) #else @@ -1039,193 +1001,6 @@ VSockVmciRecvDgramCB(void *data, // IN } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciSendSeqPacket -- - * - * Send a sequential packet. This uses a stack-allocated packet, i.e., - * it isn't meant for DATA packets, but it works fine for the other packet - * types. - * - * Results: - * Zero on success, negative error code on failure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -static int -VSockVmciSendSeqPacket(VSockVmciSock *vsk, // IN - VSockSeqPacketType type, // IN - uint32 mode) // IN -{ - int err; - VSockSeqPacket pkt; - - ASSERT(vsk); - - VSockSeqPacket_Init(&pkt, &vsk->localAddr, &vsk->remoteAddr, type, mode); - - err = VMCIDatagram_Send(&pkt.hdr.dg); - if (err < 0) { - err = VSockVmci_ErrorToVSockError(err); - } - - return err; -} - - -/* - *---------------------------------------------------------------------------- - * - * VSockVmciRecvSeqCB -- - * - * VMCI Datagram receive callback. This function is used specifically for - * SOCK_SEQPACKET sockets. - * - * This is invoked as part of a tasklet that's scheduled when the VMCI - * interrupt fires. This is run in bottom-half context and if it ever needs - * to sleep it should defer that work to a work queue. - * - * Results: - * Zero on success, negative error code on failure. - * - * Side effects: - * An sk_buff is created and queued with this socket. - * - *---------------------------------------------------------------------------- - */ - -static int -VSockVmciRecvSeqCB(void *data, // IN - VMCIDatagram *dg) // IN -{ - struct sock *sk; - size_t size; - VSockVmciSock *vsk; - VSockSeqPacket *pkt; - - ASSERT(dg); - ASSERT(dg->payloadSize <= VMCI_MAX_DG_PAYLOAD_SIZE); - - sk = (struct sock *)data; - - ASSERT(sk); - - /* XXX, figure out why sk->sk_socket can be NULL. */ - if (!sk->sk_socket) { - return EINVAL; - } - - ASSERT(sk->sk_socket->type == SOCK_SEQPACKET); - - if (VMCI_HYPERVISOR_CONTEXT_ID != dg->src.context) { - return VMCI_ERROR_NO_ACCESS; - } - - if (VMCI_RPC_PRIVILEGED != dg->src.resource && - VMCI_RPC_UNPRIVILEGED != dg->src.resource) { - return VMCI_ERROR_NO_ACCESS; - } - - size = VMCI_DG_SIZE(dg); - if (size < sizeof *pkt) { - return VMCI_ERROR_INVALID_ARGS; - } - - vsk = vsock_sk(sk); - pkt = (VSockSeqPacket *)dg; - - /* - * After this point, if we fail to handle the packet, we need to send a - * close to the peer with an error. Otherwise it might hang, waiting for a - * response to a packet that we discarded. - */ - - if (VSOCK_SEQ_PACKET_VERSION_1 != pkt->hdr.version) { - VSOCK_SEND_SEQ_CLOSE(vsk, EINVAL); - return VMCI_ERROR_INVALID_ARGS; - } - - if (SS_CONNECTED != sk->sk_socket->state) { - VSOCK_SEND_SEQ_CLOSE(vsk, ENOTCONN); - return VMCI_ERROR_DST_UNREACHABLE; - } - - switch (pkt->hdr.type) { - case VSOCK_SEQ_PACKET_TYPE_DATA: { - struct sk_buff *skb; - /* - * Attach the packet to the socket's receive queue as an sk_buff. - */ - - size -= sizeof *pkt; - skb = alloc_skb(size, GFP_ATOMIC); - if (!skb) { - VSOCK_SEND_SEQ_CLOSE(vsk, ENOMEM); - return VMCI_ERROR_NO_MEM; - } - - /* compat_sk_receive_skb() will do a sock_put(), so hold here. */ - sock_hold(sk); - skb_put(skb, size); - memcpy(skb->data, VSOCK_SEQ_PACKET_PAYLOAD(pkt), size); - - /* - * XXX, this can drop the skb. We need to find an alternative that - * will return an error if that happens, so that we can send a reset - * to the peer, i.e., - * - * if (!receive_skb(sk, skb)) { - * VSOCK_SEND_SEQ_CLOSE(vsk, ENOMEM); - * return VMCI_ERROR_NO_MEM; - * } - */ - - compat_sk_receive_skb(sk, skb, 0); - break; - } - case VSOCK_SEQ_PACKET_TYPE_CLOSE: - bh_lock_sock(sk); - - sock_set_flag(sk, SOCK_DONE); - vsk->peerShutdown = SHUTDOWN_MASK; - sk->sk_state = TCP_CLOSE; - - /* - * A close packet with an error code means a forceful reset, whereas - * no error means a graceful close. - */ - if (pkt->hdr.val) { - sk->sk_socket->state = SS_UNCONNECTED; - sk->sk_err = pkt->hdr.val; - sk->sk_error_report(sk); - } else { - if (skb_queue_empty(&sk->sk_receive_queue)) { - sk->sk_socket->state = SS_DISCONNECTING; - } - sk->sk_state_change(sk); - } - - bh_unlock_sock(sk); - break; - /* - * There's no reason for us to receive a shutdown packet in this direction, - * or any other packet for that matter. Inform the peer that the packet - * is invalid. - */ - default: - VSOCK_SEND_SEQ_CLOSE(vsk, EINVAL); - return VMCI_ERROR_INVALID_ARGS; - } - - return VMCI_SUCCESS; -} - - /* *---------------------------------------------------------------------------- * @@ -1623,55 +1398,6 @@ VSockVmciQPResumedCB(VMCIId subId, // IN } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciContextUpdatedCB -- - * - * Invoked when a VM is resumed (technically when the context ID changes, - * but the event is actually sent even when it does not, so this works - * well for catching resumes). We must mark all connected sequential - * sockets as detached. - * - * Results: - * None. - * - * Side effects: - * May modify socket state and signal socket. - * - *---------------------------------------------------------------------------- - */ - -static void -VSockVmciContextUpdatedCB(VMCIId subId, // IN - VMCI_EventData *eData, // IN - void *clientData) // IN -{ - uint32 i; - - spin_lock_bh(&vsockSeqTableLock); - - for (i = 0; i < ARRAYSIZE(vsockSeqTable); i++) { - VSockVmciSock *vsk; - - list_for_each_entry(vsk, &vsockSeqTable[i], seqTable) { - struct sock *sk = sk_vsock(vsk); - - sock_set_flag(sk, SOCK_DONE); - vsk->peerShutdown = SHUTDOWN_MASK; - sk->sk_state = TCP_CLOSE; - - if (skb_queue_empty(&sk->sk_receive_queue)) { - sk->sk_socket->state = SS_DISCONNECTING; - } - sk->sk_state_change(sk); - } - } - - spin_unlock_bh(&vsockSeqTableLock); -} - - /* *---------------------------------------------------------------------------- * @@ -2969,8 +2695,7 @@ __VSockVmciBind(struct sock *sk, // IN/OUT } break; } - case SOCK_DGRAM: - case SOCK_SEQPACKET: { + case SOCK_DGRAM: { uint32 flags = 0; /* VMCI will select a resource ID for us if we provide VMCI_INVALID_ID. */ @@ -2989,9 +2714,7 @@ __VSockVmciBind(struct sock *sk, // IN/OUT } err = VSockVmciDatagramCreateHnd(newAddr.svm_port, flags, - sk->sk_socket->type == SOCK_DGRAM ? - VSockVmciRecvDgramCB : - VSockVmciRecvSeqCB, + VSockVmciRecvDgramCB, sk, &vsk->dgHandle); if (err < VMCI_SUCCESS) { err = VSockVmci_ErrorToVSockError(err); @@ -3135,7 +2858,6 @@ __VSockVmciCreate(struct net *net, // IN: Network namespace INIT_LIST_HEAD(&vsk->boundTable); INIT_LIST_HEAD(&vsk->connectedTable); - INIT_LIST_HEAD(&vsk->seqTable); vsk->dgHandle = VMCI_INVALID_HANDLE; vsk->qpHandle = VMCI_INVALID_HANDLE; vsk->qpair = NULL; @@ -3211,14 +2933,7 @@ __VSockVmciRelease(struct sock *sk) // IN VSockVmciRemoveConnected(sk); } - if (VSockVmciInSeqTable(sk)) { - VSockVmciRemoveSeq(sk); - } - if (!VMCI_HANDLE_INVALID(vsk->dgHandle)) { - if (SOCK_SEQPACKET == sk->sk_type && TCP_ESTABLISHED == sk->sk_state) { - VSOCK_SEND_SEQ_CLOSE(vsk, 0); - } VMCIDatagram_DestroyHnd(vsk->dgHandle); vsk->dgHandle = VMCI_INVALID_HANDLE; } @@ -3467,7 +3182,6 @@ VSockVmciRegisterAddressFamily(void) } else { vsockVmciDgramOps.family = i; vsockVmciStreamOps.family = i; - vsockVmciSeqOps.family = i; err = i; break; } @@ -3508,7 +3222,6 @@ VSockVmciUnregisterAddressFamily(void) vsockVmciDgramOps.family = vsockVmciFamilyOps.family = VSOCK_INVALID_FAMILY; vsockVmciStreamOps.family = vsockVmciFamilyOps.family; - vsockVmciSeqOps.family = vsockVmciFamilyOps.family; } @@ -3574,18 +3287,6 @@ VSockVmciRegisterWithVmci(void) goto out; } - err = VMCIEvent_Subscribe(VMCI_EVENT_CTX_ID_UPDATE, - VMCI_FLAG_EVENT_NONE, - VSockVmciContextUpdatedCB, - NULL, - &ctxUpdatedSubId); - if (err < VMCI_SUCCESS) { - Warning("Unable to subscribe to context updated event. (%d)\n", err); - err = VSockVmci_ErrorToVSockError(err); - ctxUpdatedSubId = VMCI_INVALID_ID; - goto out; - } - out: if (err != 0) { VSockVmciUnregisterWithVmci(); @@ -3838,123 +3539,6 @@ out: } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciSeqConnect -- - * - * Connects a sequential socket. - * - * Results: - * Zero on success, negative error code on failure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -static int -VSockVmciSeqConnect(struct socket *sock, // IN - struct sockaddr *addr, // IN - int addrLen, // IN - int flags) // IN -{ - int err; - struct sock *sk; - VSockVmciSock *vsk; - VSockSeqPacket pkt; - struct sockaddr_vm *remoteAddr; - - sk = sock->sk; - vsk = vsock_sk(sk); - - lock_sock(sk); - - if (SS_CONNECTED == sock->state) { - err = -EISCONN; - goto out; - } else if (SS_CONNECTING == sock->state || - SS_DISCONNECTING == sock->state) { - err = -EINVAL; - goto out; - } - - if (VSockAddr_Cast(addr, addrLen, &remoteAddr) != 0) { - err = -EINVAL; - goto out; - } - - if (!VSockAddr_Bound(&vsk->localAddr)) { - struct sockaddr_vm localAddr; - - VSockAddr_Init(&localAddr, VMADDR_CID_ANY, VMADDR_PORT_ANY); - if ((err = __VSockVmciBind(sk, &localAddr))) { - goto out; - } - } - - if (VMCI_HYPERVISOR_CONTEXT_ID != remoteAddr->svm_cid) { - err = -EINVAL; - goto out; - } - - if (VMCI_RPC_PRIVILEGED != remoteAddr->svm_port && - VMCI_RPC_UNPRIVILEGED != remoteAddr->svm_port) { - err = -EINVAL; - goto out; - } - - /* - * No need to call SocketContextDgram() here, we already do specific checks - * on the context and port above. All we have to do here is ensure that - * only the superuser gets access to the privileged RPC handler. - */ - - if (VMCI_RPC_PRIVILEGED == remoteAddr->svm_port && - !capable(CAP_SYS_ADMIN)) { - err = -EACCES; - goto out; - } - - VSockSeqPacket_Init(&pkt, &vsk->localAddr, remoteAddr, - VSOCK_SEQ_PACKET_TYPE_CONNECT, 0); - - err = VMCIDatagram_Send(&pkt.hdr.dg); - if (err < 0) { - err = VSockVmci_ErrorToVSockError(err); - goto out; - } - - /* - * It's not necessary to get an acknowledgement. We're sending to the - * hypervisor, which means the result of the call tells us whether the - * endpoint accepted it or not. So as long as it returns success, - * we are connected. - */ - - memcpy(&vsk->remoteAddr, remoteAddr, sizeof vsk->remoteAddr); - - /* - * The skb routines actually check if this is a sequential socket, and if - * so, they require that the socket be in the TCP established state. So - * we need to use the TCP states for sk_state rather than the SS states - * (our STREAM sockets cheat and get away with it, we should fix that). - */ - - sock->state = SS_CONNECTED; - sk->sk_state = TCP_ESTABLISHED; - VSockVmciInsertSeq(vsockSeqSocketsVsk(vsk), sk); - sk->sk_state_change(sk); - - err = 0; - -out: - release_sock(sk); - return err; -} - - /* *---------------------------------------------------------------------------- * @@ -4470,36 +4054,6 @@ VSockVmciPoll(struct file *file, // IN } } - release_sock(sk); - } else if (sock->type == SOCK_SEQPACKET) { - lock_sock(sk); - - /* - * If there is something in the queue then we can read. - */ - if (!skb_queue_empty(&sk->sk_receive_queue) && - !(sk->sk_shutdown & RCV_SHUTDOWN)) { - mask |= POLLIN | POLLRDNORM; - } - - /* - * Sockets whose connections have beed closed, reset or terminated - * should also be considered readable, and we check the shutdown flag - * for that. - */ - if (sk->sk_shutdown & RCV_SHUTDOWN || - vsk->peerShutdown & SEND_SHUTDOWN) { - mask |= POLLIN | POLLRDNORM; - } - - /* - * Connected sockets that can produce data can be written. - */ - if (sk->sk_state == TCP_ESTABLISHED && - !(sk->sk_shutdown & SEND_SHUTDOWN)) { - mask |= POLLOUT | POLLWRNORM; - } - release_sock(sk); } @@ -4600,16 +4154,16 @@ VSockVmciShutdown(struct socket *sock, // IN } /* - * If this is a STREAM/SEQPACKET socket and it is not connected then bail - * out immediately. If it is a DGRAM socket then we must first kick the - * socket so that it wakes up from any sleeping calls, for example recv(), - * and then afterwards return the error. + * If this is a STREAM socket and it is not connected then bail out + * immediately. If it is a DGRAM socket then we must first kick the socket + * so that it wakes up from any sleeping calls, for example recv(), and then + * afterwards return the error. */ sk = sock->sk; if (sock->state == SS_UNCONNECTED) { err = -ENOTCONN; - if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { + if (sk->sk_type == SOCK_STREAM) { return err; } } else { @@ -4617,33 +4171,17 @@ VSockVmciShutdown(struct socket *sock, // IN err = 0; } - /* - * It doesn't make any sense to try and shutdown a sequential socket to - * the hypervisor in the recv direction, only for send or for both. - */ - - if (sk->sk_type == SOCK_SEQPACKET && mode == RCV_SHUTDOWN) { - err = -EINVAL; - return err; - } - /* Receive and send shutdowns are treated alike. */ mode = mode & (RCV_SHUTDOWN | SEND_SHUTDOWN); if (mode) { lock_sock(sk); sk->sk_shutdown |= mode; - if (sk->sk_type == SOCK_SEQPACKET) { - sk->sk_state = TCP_CLOSE; - } sk->sk_state_change(sk); release_sock(sk); if (sk->sk_type == SOCK_STREAM) { sock_reset_flag(sk, SOCK_DONE); VSOCK_SEND_SHUTDOWN(sk, mode); - } else if (sk->sk_type == SOCK_SEQPACKET) { - sock_reset_flag(sk, SOCK_DONE); - err = VSOCK_SEND_SEQ_SHUTDOWN(vsock_sk(sk), mode); } } @@ -4782,103 +4320,6 @@ out: } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciSeqSendmsg -- - * - * Sends a datagram. - * - * Results: - * Number of bytes sent on success, negative error code on failure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -static int -VSockVmciSeqSendmsg(struct kiocb *kiocb, // UNUSED - struct socket *sock, // IN: socket to send on - struct msghdr *msg, // IN: message to send - size_t len) // IN: length of message -{ - int err; - struct sock *sk; - VSockVmciSock *vsk; - VSockSeqPacket *pkt; - - sk = sock->sk; - vsk = vsock_sk(sk); - - if (msg->msg_flags & MSG_OOB) { - return -EOPNOTSUPP; - } - - if (len > VMCI_MAX_DG_PAYLOAD_SIZE) { - return -EMSGSIZE; - } - - lock_sock(sk); - - /* Callers should not provide a destination with sequential sockets. */ - if (msg->msg_namelen) { - err = sock->state == SS_CONNECTED ? -EISCONN : -EOPNOTSUPP; - goto out; - } - - /* Send data only if we're not shutdown in that direction. */ - if (sk->sk_shutdown & SEND_SHUTDOWN) { - err = -EPIPE; - goto out; - } - - if (sock->state != SS_CONNECTED) { - err = -ENOTCONN; - goto out; - } - - /* - * We already managed to connect, which means we must already have the - * right privs to send to our peer. So no need for the usual datagram - * checks here, they were done by connect(). - */ - - /* - * Allocate a buffer for the user's message and our packet header. - */ - pkt = kmalloc(len + sizeof *pkt, GFP_KERNEL); - if (!pkt) { - err = -ENOMEM; - goto out; - } - - VSockSeqPacket_Init(pkt, &vsk->localAddr, &vsk->remoteAddr, - VSOCK_SEQ_PACKET_TYPE_DATA, 0); - pkt->hdr.dg.payloadSize += len; - - err = memcpy_fromiovec(VSOCK_SEQ_PACKET_PAYLOAD(pkt), msg->msg_iov, len); - if (0 != err) { - kfree(pkt); - goto out; - } - - err = VMCIDatagram_Send(&pkt->hdr.dg); - kfree(pkt); - if (err < 0) { - err = VSockVmci_ErrorToVSockError(err); - goto out; - } - - err = len; - -out: - release_sock(sk); - return err; -} - - /* *---------------------------------------------------------------------------- * @@ -5338,99 +4779,6 @@ out: } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciSeqRecvmsg -- - * - * Receives a datagram and places it in the caller's msg. - * - * Results: - * The size of the payload on success, negative value on failure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -static int -VSockVmciSeqRecvmsg(struct kiocb *kiocb, // UNUSED - struct socket *sock, // IN: socket to receive from - struct msghdr *msg, // IN/OUT: message to receive into - size_t len, // IN: length of receive buffer - int flags) // IN: receive flags -{ - int err; - int noblock; - size_t payloadLen; - struct sock *sk; - struct sk_buff *skb; - - if (flags & MSG_OOB || flags & MSG_ERRQUEUE) { - return -EOPNOTSUPP; - } - - sk = sock->sk; - noblock = flags & MSG_DONTWAIT; - - /* Retrieve the head sk_buff from the socket's receive queue. */ - err = 0; - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (err) { - return err; - } - - if (!skb) { - return -EAGAIN; - } - - if (!skb->data) { - /* err is 0, meaning we read zero bytes. */ - goto out; - } - - payloadLen = skb->len; - if (payloadLen > len) { - payloadLen = len; - msg->msg_flags |= MSG_TRUNC; - /* - * XXX, we're supposed to be a reliable protocol, so while it's fine to - * return a partial packet here, we shouldn't drop the remainder. We - * should keep it around so that a subsequent recv() can read it and - * then get the end of record marker (see below). - */ - } else { - /* We managed to read the whole payload, so mark the end of record. */ - msg->msg_flags |= MSG_EOR; - } - - /* Place the datagram payload in the user's iovec. */ - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, payloadLen); - if (err) { - goto out; - } - - msg->msg_namelen = 0; - if (msg->msg_name) { - VSockVmciSock *vsk; - struct sockaddr_vm *vmciAddr; - - /* Provide the address of the sender. */ - vsk = vsock_sk(sk); - vmciAddr = (struct sockaddr_vm *)msg->msg_name; - VSockAddr_Init(vmciAddr, - vsk->remoteAddr.svm_cid, vsk->remoteAddr.svm_port); - msg->msg_namelen = sizeof *vmciAddr; - } - err = payloadLen; - -out: - skb_free_datagram(sk, skb); - return err; -} - - /* *---------------------------------------------------------------------------- * @@ -5694,9 +5042,6 @@ VSockVmciCreate( case SOCK_STREAM: sock->ops = &vsockVmciStreamOps; break; - case SOCK_SEQPACKET: - sock->ops = &vsockVmciSeqOps; - break; default: return -ESOCKTNOSUPPORT; } diff --git a/open-vm-tools/modules/linux/vsock/linux/af_vsock.h b/open-vm-tools/modules/linux/vsock/linux/af_vsock.h index 1f584a430..30600ae52 100644 --- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.h +++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.h @@ -50,10 +50,9 @@ typedef struct VSockVmciSock { struct sock sk; struct sockaddr_vm localAddr; struct sockaddr_vm remoteAddr; - /* Links for the global tables of bound, connected and sequential sockets. */ + /* Links for the global tables of bound and connected sockets. */ struct list_head boundTable; struct list_head connectedTable; - struct list_head seqTable; /* * Accessed without the socket lock held. This means it can never be * modified outsided of socket create or destruct. diff --git a/open-vm-tools/modules/linux/vsock/linux/util.c b/open-vm-tools/modules/linux/vsock/linux/util.c index 24a28402d..61f79597b 100644 --- a/open-vm-tools/modules/linux/vsock/linux/util.c +++ b/open-vm-tools/modules/linux/vsock/linux/util.c @@ -33,10 +33,8 @@ struct list_head vsockBindTable[VSOCK_HASH_SIZE + 1]; struct list_head vsockConnectedTable[VSOCK_HASH_SIZE]; -struct list_head vsockSeqTable[VSOCK_HASH_SIZE]; DEFINE_SPINLOCK(vsockTableLock); -DEFINE_SPINLOCK(vsockSeqTableLock); /* @@ -194,10 +192,6 @@ VSockVmciInitTables(void) for (i = 0; i < ARRAYSIZE(vsockConnectedTable); i++) { INIT_LIST_HEAD(&vsockConnectedTable[i]); } - - for (i = 0; i < ARRAYSIZE(vsockSeqTable); i++) { - INIT_LIST_HEAD(&vsockSeqTable[i]); - } } @@ -269,40 +263,6 @@ __VSockVmciInsertConnected(struct list_head *list, // IN } -/* - *---------------------------------------------------------------------------- - * - * __VSockVmciInsertSeq -- - * - * Inserts socket into the sequential table. - * - * Note that this assumes any necessary locks are held. - * - * Results: - * None. - * - * Side effects: - * The reference count for sk is incremented. - * - *---------------------------------------------------------------------------- - */ - -void -__VSockVmciInsertSeq(struct list_head *list, // IN - struct sock *sk) // IN -{ - VSockVmciSock *vsk; - - ASSERT(list); - ASSERT(sk); - - vsk = vsock_sk(sk); - - sock_hold(sk); - list_add(&vsk->seqTable, list); -} - - /* *---------------------------------------------------------------------------- * @@ -369,39 +329,6 @@ __VSockVmciRemoveConnected(struct sock *sk) // IN } -/* - *---------------------------------------------------------------------------- - * - * __VSockVmciRemoveSeq -- - * - * Removes socket from the sequential table. - * - * Note that this assumes any necessary locks are held. - * - * Results: - * None. - * - * Side effects: - * The reference count for sk is decremented. - * - *---------------------------------------------------------------------------- - */ - -void -__VSockVmciRemoveSeq(struct sock *sk) // IN -{ - VSockVmciSock *vsk; - - ASSERT(sk); - ASSERT(__VSockVmciInSeqTable(sk)); - - vsk = vsock_sk(sk); - - list_del_init(&vsk->seqTable); - sock_put(sk); -} - - /* *---------------------------------------------------------------------------- * @@ -549,35 +476,6 @@ __VSockVmciInConnectedTable(struct sock *sk) // IN } -/* - *---------------------------------------------------------------------------- - * - * __VSockVmciInSeqTable -- - * - * Determines whether the provided socket is in the sequential table. - * - * Results: - * TRUE is socket is in sequential table, FALSE otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------------- - */ - -Bool -__VSockVmciInSeqTable(struct sock *sk) // IN -{ - VSockVmciSock *vsk; - - ASSERT(sk); - - vsk = vsock_sk(sk); - - return !list_empty(&vsk->seqTable); -} - - /* *---------------------------------------------------------------------------- * diff --git a/open-vm-tools/modules/linux/vsock/linux/util.h b/open-vm-tools/modules/linux/vsock/linux/util.h index 1c8184b6b..9f806059d 100644 --- a/open-vm-tools/modules/linux/vsock/linux/util.h +++ b/open-vm-tools/modules/linux/vsock/linux/util.h @@ -47,8 +47,6 @@ * vsockBindTable[VSOCK_HASH_SIZE - 1] are for bound sockets and * vsockBindTable[VSOCK_HASH_SIZE] is for unbound sockets. The hash function * mods with VSOCK_HASH_SIZE - 1 to ensure this. - * - * Connected sequential sockets are put in the seq table. */ #define VSOCK_HASH_SIZE 251 #define LAST_RESERVED_PORT 1023 @@ -56,10 +54,8 @@ extern struct list_head vsockBindTable[VSOCK_HASH_SIZE + 1]; extern struct list_head vsockConnectedTable[VSOCK_HASH_SIZE]; -extern struct list_head vsockSeqTable[VSOCK_HASH_SIZE]; extern spinlock_t vsockTableLock; -extern spinlock_t vsockSeqTableLock; #define VSOCK_HASH(addr) ((addr)->svm_port % (VSOCK_HASH_SIZE - 1)) #define vsockBoundSockets(addr) (&vsockBindTable[VSOCK_HASH(addr)]) @@ -72,11 +68,6 @@ extern spinlock_t vsockSeqTableLock; (&vsockConnectedTable[VSOCK_CONN_HASH(src, dst)]) #define vsockConnectedSocketsVsk(vsk) \ vsockConnectedSockets(&(vsk)->remoteAddr, &(vsk)->localAddr) -#define VSOCK_SEQ_HASH(src, dst) VSOCK_CONN_HASH(src, dst) -#define vsockSeqSockets(src, dst) \ - (&vsockSeqTable[VSOCK_SEQ_HASH(src, dst)]) -#define vsockSeqSocketsVsk(vsk) \ - vsockSeqSockets(&(vsk)->remoteAddr, &(vsk)->localAddr) /* * Prototypes. @@ -87,16 +78,13 @@ void VSockVmciLogPkt(char const *function, uint32 line, VSockPacket *pkt); void VSockVmciInitTables(void); void __VSockVmciInsertBound(struct list_head *list, struct sock *sk); void __VSockVmciInsertConnected(struct list_head *list, struct sock *sk); -void __VSockVmciInsertSeq(struct list_head *list, struct sock *sk); void __VSockVmciRemoveBound(struct sock *sk); void __VSockVmciRemoveConnected(struct sock *sk); -void __VSockVmciRemoveSeq(struct sock *sk); struct sock *__VSockVmciFindBoundSocket(struct sockaddr_vm *addr); struct sock *__VSockVmciFindConnectedSocket(struct sockaddr_vm *src, struct sockaddr_vm *dst); Bool __VSockVmciInBoundTable(struct sock *sk); Bool __VSockVmciInConnectedTable(struct sock *sk); -Bool __VSockVmciInSeqTable(struct sock *sk); struct sock *VSockVmciGetPending(struct sock *listener, VSockPacket *pkt); void VSockVmciReleasePending(struct sock *pending); @@ -111,16 +99,13 @@ Bool VSockVmciIsPending(struct sock *sk); static INLINE void VSockVmciInsertBound(struct list_head *list, struct sock *sk); static INLINE void VSockVmciInsertConnected(struct list_head *list, struct sock *sk); -static INLINE void VSockVmciInsertSeq(struct list_head *list, struct sock *sk); static INLINE void VSockVmciRemoveBound(struct sock *sk); static INLINE void VSockVmciRemoveConnected(struct sock *sk); -static INLINE void VSockVmciRemoveSeq(struct sock *sk); static INLINE struct sock *VSockVmciFindBoundSocket(struct sockaddr_vm *addr); static INLINE struct sock *VSockVmciFindConnectedSocket(struct sockaddr_vm *src, struct sockaddr_vm *dst); static INLINE Bool VSockVmciInBoundTable(struct sock *sk); static INLINE Bool VSockVmciInConnectedTable(struct sock *sk); -static INLINE Bool VSockVmciInSeqTable(struct sock *sk); /* @@ -187,38 +172,6 @@ VSockVmciInsertConnected(struct list_head *list, // IN } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciInsertSeq -- - * - * Inserts socket into the sequential table. - * - * Note that it is important to invoke the bottom-half versions of the - * spinlock functions since these may be called from tasklets. - * - * Results: - * None. - * - * Side effects: - * vsockSeqTableLock is acquired and released. - * - *---------------------------------------------------------------------------- - */ - -static INLINE void -VSockVmciInsertSeq(struct list_head *list, // IN - struct sock *sk) // IN -{ - ASSERT(list); - ASSERT(sk); - - spin_lock_bh(&vsockSeqTableLock); - __VSockVmciInsertSeq(list, sk); - spin_unlock_bh(&vsockSeqTableLock); -} - - /* *---------------------------------------------------------------------------- * @@ -279,36 +232,6 @@ VSockVmciRemoveConnected(struct sock *sk) // IN } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciRemoveSeq -- - * - * Removes socket from the sequential list. - * - * Note that it is important to invoke the bottom-half versions of the - * spinlock functions since these may be called from tasklets. - * - * Results: - * None. - * - * Side effects: - * vsockSeqTableLock is acquired and released. - * - *---------------------------------------------------------------------------- - */ - -static INLINE void -VSockVmciRemoveSeq(struct sock *sk) // IN -{ - ASSERT(sk); - - spin_lock_bh(&vsockSeqTableLock); - __VSockVmciRemoveSeq(sk); - spin_unlock_bh(&vsockSeqTableLock); -} - - /* *---------------------------------------------------------------------------- * @@ -457,38 +380,4 @@ VSockVmciInConnectedTable(struct sock *sk) // IN } -/* - *---------------------------------------------------------------------------- - * - * VSockVmciInSeqTable -- - * - * Determines whether the provided socket is in the sequential table. - * - * Note that it is important to invoke the bottom-half versions of the - * spinlock functions since these may be called from tasklets. - * - * Results: - * TRUE is socket is in sequential table, FALSE otherwise. - * - * Side effects: - * vsockSeqTableLock is acquired and released. - * - *---------------------------------------------------------------------------- - */ - -static INLINE Bool -VSockVmciInSeqTable(struct sock *sk) // IN -{ - Bool ret; - - ASSERT(sk); - - spin_lock_bh(&vsockSeqTableLock); - ret = __VSockVmciInSeqTable(sk); - spin_unlock_bh(&vsockSeqTableLock); - - return ret; -} - - #endif /* __UTIL_H__ */ diff --git a/open-vm-tools/modules/linux/vsock/linux/vsockPacket.h b/open-vm-tools/modules/linux/vsock/linux/vsockPacket.h index 34ca4e6af..c3f61ba1e 100644 --- a/open-vm-tools/modules/linux/vsock/linux/vsockPacket.h +++ b/open-vm-tools/modules/linux/vsock/linux/vsockPacket.h @@ -238,51 +238,4 @@ VSockPacket_GetAddresses(VSockPacket *pkt, // IN pkt->srcPort); } - -/* - * SEQPACKET packets. - */ - - -/* - *----------------------------------------------------------------------------- - * - * VSockSeqPacket_Init - * - * Initialize the given packet. This will use the current version and - * set the offset to point after the current (combined) structure. The - * length will be set to include the combined structure. To add data - * after calling this function, do "pkt->hdr.dg.payloadSize += dataLen". - * - * Results: - * None. - * - * Side effects: - * None. - * - *----------------------------------------------------------------------------- - */ - -static INLINE void -VSockSeqPacket_Init(VSockSeqPacket *pkt, // IN/OUT - struct sockaddr_vm *src, // IN - struct sockaddr_vm *dst, // IN - uint8 type, // IN - int32 val) // IN -{ - ASSERT(pkt); - VSOCK_ADDR_NOFAMILY_ASSERT(src); - VSOCK_ADDR_NOFAMILY_ASSERT(dst); - - pkt->hdr.dg.src = VMCI_MAKE_HANDLE(src->svm_cid, src->svm_port); - pkt->hdr.dg.dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, - dst->svm_port); - pkt->hdr.dg.payloadSize = sizeof *pkt - sizeof pkt->hdr.dg; - pkt->hdr.version = VSOCK_SEQ_PACKET_VERSION; - pkt->hdr.type = type; - pkt->hdr.offset = sizeof *pkt; - pkt->hdr.val = val; -} - - #endif // _VSOCK_PACKET_H_ diff --git a/open-vm-tools/modules/linux/vsock/linux/vsock_version.h b/open-vm-tools/modules/linux/vsock/linux/vsock_version.h index 61c809d1c..e1ed4950f 100644 --- a/open-vm-tools/modules/linux/vsock/linux/vsock_version.h +++ b/open-vm-tools/modules/linux/vsock/linux/vsock_version.h @@ -25,8 +25,8 @@ #ifndef _VSOCK_VERSION_H_ #define _VSOCK_VERSION_H_ -#define VSOCK_DRIVER_VERSION 9.5.5.0 -#define VSOCK_DRIVER_VERSION_COMMAS 9,5.5,0 -#define VSOCK_DRIVER_VERSION_STRING "9.5.5.0" +#define VSOCK_DRIVER_VERSION 9.5.6.0 +#define VSOCK_DRIVER_VERSION_COMMAS 9,5,6,0 +#define VSOCK_DRIVER_VERSION_STRING "9.5.6.0" #endif /* _VSOCK_VERSION_H_ */