/*********************************************************
- * Copyright (C) 2005-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2012 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#define VMCI_RPC_PRIVILEGED 15
#define VMCI_RPC_UNPRIVILEGED 16
#define VMCI_RESOURCE_MAX 17
+/*
+ * The core VMCI device functionality only requires the resource IDs of
+ * VMCI_QUEUEPAIR_DETACH and below.
+ */
+#define VMCI_CORE_DEVICE_RESOURCE_MAX VMCI_QUEUEPAIR_DETACH
/* VMCI Ids. */
typedef uint32 VMCIId;
+typedef struct VMCIIdRange {
+ VMCIId begin;
+ VMCIId end;
+} VMCIIdRange;
+
typedef struct VMCIHandle {
VMCIId context;
VMCIId resource;
}
-#endif
+/*
+ * Defines for the VMCI traffic filter:
+ * - VMCI_FP_<name> defines the filter protocol values
+ * - VMCI_FD_<name> defines the direction values (guest or host)
+ * - VMCI_FT_<name> are the type values (allow or deny)
+ */
+
+#define VMCI_FP_INVALID -1
+#define VMCI_FP_HYPERVISOR 0
+#define VMCI_FP_QUEUEPAIR (VMCI_FP_HYPERVISOR + 1)
+#define VMCI_FP_DOORBELL (VMCI_FP_QUEUEPAIR + 1)
+#define VMCI_FP_DATAGRAM (VMCI_FP_DOORBELL + 1)
+#define VMCI_FP_STREAMSOCK (VMCI_FP_DATAGRAM + 1)
+#define VMCI_FP_SEQPACKET (VMCI_FP_STREAMSOCK + 1)
+#define VMCI_FP_MAX (VMCI_FP_SEQPACKET + 1)
+
+#define VMCI_FD_INVALID -1
+#define VMCI_FD_GUEST 0
+#define VMCI_FD_HOST (VMCI_FD_GUEST + 1)
+#define VMCI_FD_MAX (VMCI_FD_HOST + 1)
+
+#define VMCI_FT_INVALID -1
+#define VMCI_FT_ALLOW 0
+#define VMCI_FT_DENY (VMCI_FT_ALLOW + 1)
+#define VMCI_FT_MAX (VMCI_FT_DENY + 1)
+
+/*
+ * The filter list tracks VMCI Id ranges for a given filter.
+ */
+
+typedef struct {
+ uint32 len;
+ VMCIIdRange *list;
+} VMCIFilterList;
+
+/*
+ * The filter info is used to communicate the filter configuration
+ * from the VMX to the host kernel.
+ */
+
+typedef struct {
+ VA64 list; // List of VMCIIdRange
+ uint32 len; // Length of list
+ uint8 dir; // VMCI_FD_X
+ uint8 proto; // VMCI_FP_X
+ uint8 type; // VMCI_FT_X
+} VMCIFilterInfo;
+
+/*
+ * In the host kernel, the ingoing and outgoing filters are
+ * separated. The VMCIProtoFilters type captures all filters in one
+ * direction. The VMCIFilters type captures all filters.
+ */
+
+typedef VMCIFilterList VMCIProtoFilters[VMCI_FP_MAX][VMCI_FT_MAX];
+typedef VMCIProtoFilters VMCIFilters[VMCI_FD_MAX];
+
+#endif
/*********************************************************
- * Copyright (C) 2005-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2012 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#define VMCI_RPC_PRIVILEGED 15
#define VMCI_RPC_UNPRIVILEGED 16
#define VMCI_RESOURCE_MAX 17
+/*
+ * The core VMCI device functionality only requires the resource IDs of
+ * VMCI_QUEUEPAIR_DETACH and below.
+ */
+#define VMCI_CORE_DEVICE_RESOURCE_MAX VMCI_QUEUEPAIR_DETACH
/* VMCI Ids. */
typedef uint32 VMCIId;
+typedef struct VMCIIdRange {
+ VMCIId begin;
+ VMCIId end;
+} VMCIIdRange;
+
typedef struct VMCIHandle {
VMCIId context;
VMCIId resource;
}
-#endif
+/*
+ * Defines for the VMCI traffic filter:
+ * - VMCI_FP_<name> defines the filter protocol values
+ * - VMCI_FD_<name> defines the direction values (guest or host)
+ * - VMCI_FT_<name> are the type values (allow or deny)
+ */
+
+#define VMCI_FP_INVALID -1
+#define VMCI_FP_HYPERVISOR 0
+#define VMCI_FP_QUEUEPAIR (VMCI_FP_HYPERVISOR + 1)
+#define VMCI_FP_DOORBELL (VMCI_FP_QUEUEPAIR + 1)
+#define VMCI_FP_DATAGRAM (VMCI_FP_DOORBELL + 1)
+#define VMCI_FP_STREAMSOCK (VMCI_FP_DATAGRAM + 1)
+#define VMCI_FP_SEQPACKET (VMCI_FP_STREAMSOCK + 1)
+#define VMCI_FP_MAX (VMCI_FP_SEQPACKET + 1)
+
+#define VMCI_FD_INVALID -1
+#define VMCI_FD_GUEST 0
+#define VMCI_FD_HOST (VMCI_FD_GUEST + 1)
+#define VMCI_FD_MAX (VMCI_FD_HOST + 1)
+
+#define VMCI_FT_INVALID -1
+#define VMCI_FT_ALLOW 0
+#define VMCI_FT_DENY (VMCI_FT_ALLOW + 1)
+#define VMCI_FT_MAX (VMCI_FT_DENY + 1)
+
+/*
+ * The filter list tracks VMCI Id ranges for a given filter.
+ */
+
+typedef struct {
+ uint32 len;
+ VMCIIdRange *list;
+} VMCIFilterList;
+
+/*
+ * The filter info is used to communicate the filter configuration
+ * from the VMX to the host kernel.
+ */
+
+typedef struct {
+ VA64 list; // List of VMCIIdRange
+ uint32 len; // Length of list
+ uint8 dir; // VMCI_FD_X
+ uint8 proto; // VMCI_FP_X
+ uint8 type; // VMCI_FT_X
+} VMCIFilterInfo;
+
+/*
+ * In the host kernel, the ingoing and outgoing filters are
+ * separated. The VMCIProtoFilters type captures all filters in one
+ * direction. The VMCIFilters type captures all filters.
+ */
+
+typedef VMCIFilterList VMCIProtoFilters[VMCI_FP_MAX][VMCI_FT_MAX];
+typedef VMCIProtoFilters VMCIFilters[VMCI_FD_MAX];
+
+#endif
/*********************************************************
- * Copyright (C) 2006-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2012 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#define _VMCI_COMMONINT_H_
#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
#define INCLUDE_ALLOW_VMCORE
#define INCLUDE_ALLOW_VMKERNEL
#include "includeCheck.h"
#include "vmci_handle_array.h"
#include "vmci_kernel_if.h"
-
/*
* The DatagramQueueEntry is a queue header for the in-kernel VMCI
* datagram queues. It is allocated in non-paged memory, as the
} DatagramQueueEntry;
+/*
+ * The VMCIFilterState captures the state of all VMCI filters in one
+ * direction. The ranges array contains all filter list in a single
+ * memory chunk, and the filter list pointers in the VMCIProtoFilters
+ * point into the ranges array.
+ */
+
+typedef struct VMCIFilterState {
+ VMCIProtoFilters filters;
+ VMCIIdRange *ranges;
+ size_t rangesSize;
+} VMCIFilterState;
+
+
struct VMCIContext {
VMCIListItem listItem; /* For global VMCI list. */
VMCIId cid;
* this context; e.g., VMX.
*/
VMCILock lock; /*
- * Locks datagramQueue, doorbellArray,
- * pendingDoorbellArray and
- * notifierArray.
+ * Locks datagramQueue, inFilters,
+ * doorbellArray, pendingDoorbellArray
+ * and notifierArray.
*/
VMCIHandleArray *queuePairArray; /*
* QueuePairs attached to. The array of
* registration/release during FSR.
*/
VMCIGuestMemID curGuestMemID; /* ID of current registered guest mem */
+ VMCIFilterState *inFilters; /* Ingoing filters for VMCI traffic. */
#endif
#ifndef VMX86_SERVER
Bool *notify; /* Notify flag pointer - hosted only. */
/*********************************************************
- * Copyright (C) 2006-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2012 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#if defined(VMKERNEL)
static void VMCIContextReleaseGuestMemLocked(VMCIContext *context,
VMCIGuestMemID gid);
+static void VMCIContextInFilterCleanup(VMCIContext *context);
#endif
/*
goto error;
}
context->curGuestMemID = INVALID_VMCI_GUEST_MEM_ID;
+
+ context->inFilters = NULL;
#endif
/* Inititialize host-specific VMCI context. */
VMCIHandleArray_Destroy(context->pendingDoorbellArray);
VMCI_CleanupLock(&context->lock);
#if defined(VMKERNEL)
+ VMCIContextInFilterCleanup(context);
VMCIMutex_Destroy(&context->guestMemMutex);
#endif
VMCIHost_ReleaseContext(&context->hostContext);
VMCIList_InitEntry(&dqEntry->listItem);
VMCI_GrabLock(&context->lock, &flags);
+
+#if defined(VMKERNEL)
+ if (context->inFilters != NULL) {
+ if (VMCIFilterDenyDgIn(context->inFilters->filters, dg)) {
+ VMCI_ReleaseLock(&context->lock, flags);
+ VMCIContext_Release(context);
+ VMCI_FreeKernelMem(dqEntry, sizeof *dqEntry);
+ return VMCI_ERROR_NO_ACCESS;
+ }
+ }
+#endif
+
/*
* We put a higher limit on datagrams from the hypervisor. If the pending
* datagram is not from hypervisor, then we check if enqueueing it would
} else {
VMCI_GrabLock(&dstContext->lock, &flags);
+#if defined(VMKERNEL)
+ if (dstContext->inFilters != NULL &&
+ VMCIFilterProtoDeny(dstContext->inFilters->filters, handle.resource,
+ VMCI_FP_DOORBELL)) {
+ result = VMCI_ERROR_NO_ACCESS;
+ } else
+#endif // VMKERNEL
if (!VMCIHandleArray_HasEntry(dstContext->doorbellArray, handle)) {
result = VMCI_ERROR_NOT_FOUND;
} else {
VMCIMutex_Release(&context->guestMemMutex);
#endif
}
+
+#if defined(VMKERNEL)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCIContext_FilterSet --
+ *
+ * Sets an ingoing (host to guest) filter for the VMCI firewall of the
+ * given context. If a filter list already exists for the given filter
+ * entry, the old entry will be deleted. It is assumed that the list
+ * can be used as is, and that the memory backing it will be freed by the
+ * VMCI Context module once the filter is deleted.
+ *
+ * Results:
+ * VMCI_SUCCESS on success,
+ * VMCI_ERROR_NOT_FOUND if there is no active context linked to the cid,
+ * VMCI_ERROR_INVALID_ARGS if a non-VM cid is specified.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+VMCIContext_FilterSet(VMCIId cid, // IN
+ VMCIFilterState *filters) // IN
+{
+ VMCIContext *context;
+ VMCILockFlags flags;
+ VMCIFilterState *oldState;
+
+ if (!VMCI_CONTEXT_IS_VM(cid)) {
+ return VMCI_ERROR_INVALID_ARGS;
+ }
+
+ context = VMCIContext_Get(cid);
+ if (!context) {
+ return VMCI_ERROR_NOT_FOUND;
+ }
+
+ VMCI_GrabLock(&context->lock, &flags);
+
+ oldState = context->inFilters;
+ context->inFilters = filters;
+
+ VMCI_ReleaseLock(&context->lock, flags);
+ if (oldState) {
+ VMCIVMKDevFreeFilterState(oldState);
+ }
+ VMCIContext_Release(context);
+
+ return VMCI_SUCCESS;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCIContextInFilterCleanup --
+ *
+ * When a context is destroyed, all filters will be deleted.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+VMCIContextInFilterCleanup(VMCIContext *context)
+{
+ if (context->inFilters != NULL) {
+ VMCIVMKDevFreeFilterState(context->inFilters);
+ context->inFilters = NULL;
+ }
+}
+
+#endif
+
/*********************************************************
- * Copyright (C) 2006-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2012 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#include "vmci_handle_array.h"
#include "vmci_infrastructure.h"
#include "vmci_kernel_if.h"
+#include "vmciCommonInt.h"
#define MAX_QUEUED_GUESTCALLS_PER_VM 100
void VMCIContext_SignalPendingDatagrams(VMCIId contextID);
int VMCIContextID2HostVmID(VMCIId contextID, void *hostVmID, size_t hostVmIDLen);
+int VMCIContext_FilterSet(VMCIId cid, VMCIFilterState *filterState);
#endif
-
#endif // _VMCI_CONTEXT_H_
#ifndef _VMCI_VERSION_H_
#define _VMCI_VERSION_H_
-#define VMCI_DRIVER_VERSION 9.5.3.0
-#define VMCI_DRIVER_VERSION_COMMAS 9,5,3,0
-#define VMCI_DRIVER_VERSION_STRING "9.5.3.0"
+#define VMCI_DRIVER_VERSION 9.5.4.0
+#define VMCI_DRIVER_VERSION_COMMAS 9,5,4,0
+#define VMCI_DRIVER_VERSION_STRING "9.5.4.0"
#endif /* _VMCI_VERSION_H_ */