597
568
* Check that source handle matches sending context.
599
570
if (dg->src.context != contextID) {
600
if (dg->src.context == VMCI_WELL_KNOWN_CONTEXT_ID) {
601
/* Determine mapping. */
602
DatagramWKMapping *wkMap = DatagramGetWellKnownMap(dg->src.resource);
604
VMCI_DEBUG_LOG(4, (LGPFX"Sending from invalid well-known resource "
605
"(handle=0x%x:0x%x).\n",
606
dg->src.context, dg->src.resource));
607
return VMCI_ERROR_INVALID_RESOURCE;
609
if (wkMap->contextID != contextID) {
610
VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of "
611
"well-known src datagram entry "
612
"(handle=0x%x:0x%x).\n",
613
contextID, dg->src.context, dg->src.resource));
614
DatagramReleaseWellKnownMap(wkMap);
615
return VMCI_ERROR_NO_ACCESS;
617
DatagramReleaseWellKnownMap(wkMap);
619
VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of src "
620
"datagram entry (handle=0x%x:0x%x).\n",
621
contextID, dg->src.context, dg->src.resource));
622
return VMCI_ERROR_NO_ACCESS;
626
if (dg->dst.context == VMCI_WELL_KNOWN_CONTEXT_ID) {
627
/* Determine mapping. */
628
DatagramWKMapping *wkMap = DatagramGetWellKnownMap(dg->dst.resource);
630
VMCI_DEBUG_LOG(4, (LGPFX"Sending to invalid wellknown destination "
631
"(handle=0x%x:0x%x).\n",
632
dg->dst.context, dg->dst.resource));
633
return VMCI_ERROR_DST_UNREACHABLE;
635
dstContext = wkMap->contextID;
636
DatagramReleaseWellKnownMap(wkMap);
638
dstContext = dg->dst.context;
571
VMCI_DEBUG_LOG(4, (LGPFX"Sender context (ID=0x%x) is not owner of src "
572
"datagram entry (handle=0x%x:0x%x).\n",
573
contextID, dg->src.context, dg->src.resource));
574
return VMCI_ERROR_NO_ACCESS;
654
* In the vmkernel, all communicating contexts except the
655
* hypervisor context must belong to the same domain. If the
656
* hypervisor is the source, the domain doesn't matter.
659
if (contextID != VMCI_HYPERVISOR_CONTEXT_ID) {
660
retval = VMCIContext_GetDomainName(contextID, srcDomain,
662
if (retval < VMCI_SUCCESS) {
663
VMCI_WARNING((LGPFX"Failed to get domain name for context (ID=0x%x).\n",
670
588
/* Determine if we should route to host or guest destination. */
671
if (dstContext == VMCI_HOST_CONTEXT_ID) {
589
if (dg->dst.context == VMCI_HOST_CONTEXT_ID) {
672
590
/* Route to host datagram entry. */
673
591
DatagramEntry *dstEntry;
674
592
VMCIResource *resource;
686
604
return VMCI_ERROR_INVALID_RESOURCE;
688
606
dstEntry = RESOURCE_CONTAINER(resource, DatagramEntry, resource);
690
retval = VMCIContext_GetDomainName(VMCI_HOST_CONTEXT_ID, dstDomain,
692
if (retval < VMCI_SUCCESS) {
693
VMCI_WARNING((LGPFX"Failed to get domain name for context (ID=0x%x).\n",
694
VMCI_HOST_CONTEXT_ID));
695
VMCIResource_Release(resource);
699
if (VMCIDenyInteraction(srcPrivFlags, dstEntry->privFlags, srcDomain,
607
if (VMCIDenyInteraction(srcPrivFlags, dstEntry->privFlags)) {
701
608
VMCIResource_Release(resource);
702
609
return VMCI_ERROR_NO_ACCESS;
754
/* Route to destination VM context. */
662
* Route to destination VM context.
755
665
VMCIDatagram *newDG;
758
retval = VMCIContext_GetDomainName(dstContext, dstDomain,
760
if (retval < VMCI_SUCCESS) {
761
VMCI_DEBUG_LOG(4, (LGPFX"Failed to get domain name for context "
762
"(ID=0x%x).\n", dstContext));
766
if (contextID != dstContext &&
767
VMCIDenyInteraction(srcPrivFlags, VMCIContext_GetPrivFlags(dstContext),
768
srcDomain, dstDomain)) {
769
return VMCI_ERROR_NO_ACCESS;
667
if (contextID != dg->dst.context) {
668
if (VMCIDenyInteraction(srcPrivFlags,
669
VMCIContext_GetPrivFlags(dg->dst.context))) {
670
return VMCI_ERROR_NO_ACCESS;
671
} else if (VMCI_CONTEXT_IS_VM(contextID)) {
673
* If the sending context is a VM, it cannot reach another VM.
676
VMCI_DEBUG_LOG(4, (LGPFX"Datagram communication between VMs not"
677
"supported (src=0x%x, dst=0x%x).\n",
678
contextID, dg->dst.context));
679
return VMCI_ERROR_DST_UNREACHABLE;
772
683
/* We make a copy to enqueue. */
999
*------------------------------------------------------------------------------
1001
* DatagramGetWellKnownMap --
1003
* Gets a mapping between handle and wellknown resource.
1006
* DatagramWKMapping * if found, NULL if not.
1011
*------------------------------------------------------------------------------
1014
static DatagramWKMapping *
1015
DatagramGetWellKnownMap(VMCIId wellKnownID) // IN:
1017
VMCIHashEntry *entry;
1018
DatagramWKMapping *wkMap = NULL;
1019
VMCIHandle wkHandle = VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID,
1021
entry = VMCIHashTable_GetEntry(wellKnownTable, wkHandle);
1022
if (entry != NULL) {
1023
wkMap = RESOURCE_CONTAINER(entry, DatagramWKMapping, entry);
1030
*------------------------------------------------------------------------------
1032
* DatagramReleaseWellKnownMap --
1034
* Releases a wellknown mapping.
1042
*------------------------------------------------------------------------------
1046
DatagramReleaseWellKnownMap(DatagramWKMapping *wkMap) // IN:
1048
if (VMCIHashTable_ReleaseEntry(wellKnownTable, &wkMap->entry) ==
1049
VMCI_SUCCESS_ENTRY_DEAD) {
1050
VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1056
*------------------------------------------------------------------------------
1058
* VMCIDatagramRequestWellKnownMap --
1060
* Creates a mapping between handle and wellknown resource. If resource
1061
* is already used we fail the request.
1064
* VMCI_SUCCESS if created, negative errno value otherwise.
1069
*------------------------------------------------------------------------------
1073
VMCIDatagramRequestWellKnownMap(VMCIId wellKnownID, // IN:
1074
VMCIId contextID, // IN:
1075
VMCIPrivilegeFlags privFlags) // IN:
1078
DatagramWKMapping *wkMap;
1079
VMCIHandle wkHandle = VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID,
1082
if (privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED ||
1083
!VMCIWellKnownID_AllowMap(wellKnownID, privFlags)) {
1084
return VMCI_ERROR_NO_ACCESS;
1087
wkMap = VMCI_AllocKernelMem(sizeof *wkMap, VMCI_MEMORY_NONPAGED);
1088
if (wkMap == NULL) {
1089
return VMCI_ERROR_NO_MEM;
1092
VMCIHashTable_InitEntry(&wkMap->entry, wkHandle);
1093
wkMap->contextID = contextID;
1095
/* Fails if wkHandle (wellKnownID) already exists. */
1096
result = VMCIHashTable_AddEntry(wellKnownTable, &wkMap->entry);
1097
if (result != VMCI_SUCCESS) {
1098
VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1101
result = VMCIContext_AddWellKnown(contextID, wellKnownID);
1102
if (UNLIKELY(result < VMCI_SUCCESS)) {
1103
VMCIHashTable_RemoveEntry(wellKnownTable, &wkMap->entry);
1104
VMCI_FreeKernelMem(wkMap, sizeof *wkMap);
1111
*------------------------------------------------------------------------------
1113
* VMCIDatagramRemoveWellKnownMap --
1115
* Removes a mapping between handle and wellknown resource. Checks if
1116
* mapping belongs to calling context.
1119
* VMCI_SUCCESS if removed, negative errno value otherwise.
1124
*------------------------------------------------------------------------------
1128
VMCIDatagramRemoveWellKnownMap(VMCIId wellKnownID, // IN:
1129
VMCIId contextID) // IN:
1131
int result = VMCI_ERROR_NO_ACCESS;
1132
DatagramWKMapping *wkMap = DatagramGetWellKnownMap(wellKnownID);
1133
if (wkMap == NULL) {
1134
VMCI_DEBUG_LOG(4, (LGPFX"Failed to remove well-known mapping between "
1135
"resource (ID=0x%x) and context (ID=0x%x).\n",
1136
wellKnownID, contextID));
1137
return VMCI_ERROR_NOT_FOUND;
1140
if (contextID == wkMap->contextID) {
1141
VMCIHashTable_RemoveEntry(wellKnownTable, &wkMap->entry);
1142
VMCIContext_RemoveWellKnown(contextID, wellKnownID);
1143
result = VMCI_SUCCESS;
1145
DatagramReleaseWellKnownMap(wkMap);
1151
913
*-----------------------------------------------------------------------------
1153
915
* VMCIDatagram_Sync --