From: VMware, Inc <> Date: Tue, 29 Mar 2011 20:13:01 +0000 (-0700) Subject: Make VMCI Stream Sockets use control packet destination for binding. X-Git-Tag: 2011.03.28-387002~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7fec13b3bc117ccd06b57afe3d9af46adb3d6f7;p=thirdparty%2Fopen-vm-tools.git Make VMCI Stream Sockets use control packet destination for binding. When creating a VMCI stream socket connection, the protocol calls VMCI_GetContextID() to set the local CID of a connection. However, in the nested VM case, this may no longer be correct, since a given connection can either be a host CID endpoint or a guest CID endpoint. Instead, we can use an incoming control packet to determine what destination CID the peer is using when sending to us, and use that as our local CID. For server side sockets, the change is simple - instead of calling VMCI_GetContextID() to set the local CID when receiving a request packet, we use the dst cid of the packet. For the client side, we delay the assignment of the local CID until we receive the negotiate packet from the server side. Until then, a connecting socket will continue to have the local CID of any - just like a listening socket. Since all sockets share the same port range regardless of their CID, no additional port conflicts will arise from this. Signed-off-by: Marcelo Vanzin --- 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 35cc262d2..da640b4eb 100644 --- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c +++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c @@ -1651,7 +1651,7 @@ VSockVmciRecvListen(struct sock *sk, // IN ASSERT(vsk->localAddr.svm_port == pkt->dstPort); VSockAddr_Init(&vpending->localAddr, - VMCI_GetContextID(), + VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst), pkt->dstPort); VSockAddr_Init(&vpending->remoteAddr, VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src), @@ -2139,6 +2139,14 @@ VSockVmciRecvConnectingClientNegotiate(struct sock *sk, // IN: socket goto destroy; } + /* + * At this point we know the CID the peer is using to talk to us. + */ + + if (vsk->localAddr.svm_cid == VMADDR_CID_ANY) { + vsk->localAddr.svm_cid = VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst); + } + /* * Setup the notify ops to be the highest supported version that both the * server and the client support. @@ -3642,14 +3650,6 @@ VSockVmciStreamConnect(struct socket *sock, // IN } } - /* - * For the client stream sockets, we always want to make sure that - * we have a specific context id. - */ - if (vsk->localAddr.svm_cid == VMADDR_CID_ANY) { - vsk->localAddr.svm_cid = VMCI_GetContextID(); - } - sk->sk_state = SS_CONNECTING; if (VSockVmciOldProtoOverride(&oldPktProto) && oldPktProto) {