summaryrefslogtreecommitdiff
path: root/src/VBox/HostDrivers/VBoxNetFlt
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostDrivers/VBoxNetFlt')
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk41
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c402
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h94
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp147
-rwxr-xr-xsrc/VBox/HostDrivers/VBoxNetFlt/darwin/loadnetflt.sh6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c81
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt15
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/Makefile8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c1186
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt20
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c280
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c1063
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h199
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h156
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h498
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp22
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c419
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h106
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc12
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltA-win.asm33
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h20
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c87
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c161
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp233
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl15
38 files changed, 4122 insertions, 1272 deletions
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
index 0d1dfdd70..b1d4b028d 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk
@@ -1,10 +1,10 @@
-# $Id: Makefile.kmk $
+# $Id: Makefile.kmk 29108 2010-05-05 20:17:42Z vboxsync $
## @file
# Sub-Makefile for the Network Filter Driver (VBoxNetFlt).
#
#
-# Copyright (C) 2008 Sun Microsystems, Inc.
+# Copyright (C) 2008 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -14,10 +14,6 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
@@ -48,6 +44,9 @@ ifdef VBOX_NETFLT_ONDEMAND_BIND
VBoxNetFlt_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND
else
VBoxNetFlt_DEFS.win += VBOXNETFLT_STATIC_CONFIG
+ VBoxNetFlt_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE
+ VBoxNetFlt_DEFS.win += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0
+ VBoxNetFlt_DEFS.win += NDIS50_MINIPORT=1 NDIS50=1
VBoxNetFlt_SOURCES.win += win/VBoxNetFltMp-win.c
endif
ifdef VBOX_LOOPBACK_USEFLAGS
@@ -57,8 +56,6 @@ VBoxNetFlt_SOURCES = VBoxNetFlt.c
#VBoxNetFlt_LDFLAGS.darwin = -v -Wl,-whyload -Wl,-v -Wl,-whatsloaded
VBoxNetFlt_LDFLAGS.win.x86 = -Entry:DriverEntry@8
VBoxNetFlt_LDFLAGS.win.amd64 = -Entry:DriverEntry
-VBoxNetFlt_SOURCES.win.amd64 += win/VBoxNetFltA-win.asm
-VBoxNetFlt_DEFS.win.amd64 += RT_WITH_W64_UNWIND_HACK
VBoxNetFlt_LIBS.win = \
$(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
$(PATH_SDK_W2K3DDK_LIB)/hal.lib \
@@ -201,6 +198,9 @@ NetAdpUninstall_LIBS = $(TARGET_WinNetConfig) \
# VBoxNetFltNotify
#
DLLS.win += VBoxNetFltNotify
+if defined(VBOX_SIGNING_MODE)
+VBoxNetFltNotify_NOINST = true
+endif
VBoxNetFltNotify_TEMPLATE = VBOXR3STATIC
VBoxNetFltNotify_SDKS = WINPSDK W2K3DDK VBOX_NTDLL
VBoxNetFltNotify_DEFS = _WIN32_WINNT=0x0500 WIN32 _ATL_STATIC_REGISTRY
@@ -258,10 +258,11 @@ VBoxNetAdp_SOURCES = \
win/VBoxNetFltMp-win.c \
win/VBoxNetFlt-win.rc
VBoxNetAdp_DEFS += VBOXNETFLT_STATIC_CONFIG VBOXNETADP
+VBoxNetAdp_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE
+VBoxNetAdp_DEFS += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0
+VBoxNetAdp_DEFS += NDIS50_MINIPORT=1 NDIS50=1
VBoxNetAdp_LDFLAGS.win.x86 = -Entry:DriverEntry@8
VBoxNetAdp_LDFLAGS.win.amd64 = -Entry:DriverEntry
-VBoxNetAdp_SOURCES.win.amd64 += win/VBoxNetFltA-win.asm
-VBoxNetAdp_DEFS.win.amd64 += RT_WITH_W64_UNWIND_HACK
VBoxNetAdp_LIBS.win = \
$(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \
$(PATH_SDK_W2K3DDK_LIB)/hal.lib \
@@ -332,9 +333,22 @@ vboxnetflt_SOURCES.linux = linux/VBoxNetFlt-linux.c
vboxnetflt_SOURCES.solaris = solaris/VBoxNetFlt-solaris.c
vboxnetflt_SOURCES.freebsd = freebsd/VBoxNetFlt-freebsd.c
vboxnetflt_SOURCES = VBoxNetFlt.c
- endif
-
solaris/VBoxNetFlt-solaris.c_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV)
+ ifdef VBOX_WITH_NETFLT_CROSSBOW
+SYSMODS += vboxnetbow
+vboxnetbow_TEMPLATE = VBOXR0DRV
+vboxnetbow_NAME = vboxbow
+vboxnetbow_DEFS = vboxnetflt_DEFS VBOX_WITH_NETFLT_CROSSBOW
+vboxnetbow_DEPS += $(VBOX_SVN_REV_KMK)
+vboxnetbow_INCS := $(PATH_SUB_CURRENT)
+vboxnetbow_LDFLAGS += -N drv/vboxdrv -N drv/vnic -N misc/mac -N misc/dls
+vboxnetbow_LIBS = \
+ $(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB)
+vboxnetbow_SOURCES.solaris = solaris/VBoxNetFltBow-solaris.c
+vboxnetbow_SOURCES = VBoxNetFlt.c
+solaris/VBoxNetFltBow-solaris.c_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV)
+ endif # VBOX_WITH_NETFLT_CROSSBOW
+ endif # VBOX_WITH_VBOXDRV
endif # to be removed.
@@ -384,7 +398,7 @@ ifeq ($(KBUILD_TARGET),linux)
$(VBOX_VERSION_STAMP) \
| $$(dir $$@)
$(call MSG_TOOL,Creating,,$@)
- $(QUIET)$(SED) -e "s;_VERSION_;${VBOX_VERSION_STRING};g; s;_MODULE_;vboxnetflt;g" --output $@ $<
+ $(QUIET)$(SED) -e "s;_VERSION_;${VBOX_VERSION_STRING};g; s;_MODULE_;vboxnetflt;g; s;_BUILDTYPE_;${KBUILD_TYPE};g" --output $@ $<
$(QUIET)chmod 0755 $@
# Script needed for building the kernel module
@@ -431,4 +445,3 @@ endif # freebsd
include $(KBUILD_PATH)/subfooter.kmk
-
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
index 2a2fc9c93..e49e64b47 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt.c $ */
+/* $Id: VBoxNetFlt.c 29150 2010-05-06 13:13:03Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Common Code.
*/
/*
- * Copyright (C) 2008-2009 Sun Microsystems, Inc.
+ * Copyright (C) 2008-2009 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,32 +13,65 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/** @page pg_netflt VBoxNetFlt - Network Interface Filter
*
- * This is a kernel module that attaches to a real interface on the host
- * and filters and injects packets.
+ * This is a kernel module that attaches to a real interface on the host and
+ * filters and injects packets.
*
* In the big picture we're one of the three trunk interface on the internal
* network, the one named "NIC Filter Driver": @image html Networking_Overview.gif
*
*
- * @section sec_netflt_msc Locking / Sequence Diagrams
+ * @section sec_netflt_locking Locking and Potential Races
+ *
+ * The main challenge here is to make sure the netfilter and internal network
+ * instances won't be destroyed while someone is calling into them.
+ *
+ * The main calls into or out of of the filter driver are:
+ * - Send.
+ * - Async send completion (not implemented yet)
+ * - Release by the internal network.
+ * - Receive.
+ * - Disappearance of the host networking interface.
+ * - Reappearance of the host networking interface.
+ *
+ * The latter two calls are can be caused by driver unloading/loading or the
+ * device being physical unplugged (e.g. a USB network device). Actually, the
+ * unload scenario must fervently be prevent as it will cause panics because the
+ * internal network will assume the trunk is around until it releases it.
+ * @todo Need to figure which host allow unloading and block/fix it.
+ *
+ * Currently the netfilter instance lives until the internal network releases
+ * it. So, it is the internal networks responsibility to make sure there are no
+ * active calls when it releases the trunk and destroys the network. The
+ * netfilter assists in this by providing INTNETTRUNKIFPORT::pfnSetState and
+ * INTNETTRUNKIFPORT::pfnWaitForIdle. The trunk state is used to enable/disable
+ * promiscuous mode on the hardware NIC (or similar activation) as well
+ * indicating that disconnect is imminent and no further calls shall be made
+ * into the internal network. After changing the state to disconnecting and
+ * prior to invoking INTNETTRUNKIFPORT::pfnDisconnectAndRelease, the internal
+ * network will use INTNETTRUNKIFPORT::pfnWaitForIdle to wait for any still
+ * active calls to complete.
+ *
+ * The netfilter employs a busy counter and an internal state in addition to the
+ * public trunk state. All these variables are protected using a spinlock.
+ *
+ *
+ * @section sec_netflt_msc Locking / Sequence Diagrams - OBSOLETE
+ *
+ * !OBSOLETE! - THIS WAS THE OLD APPROACH!
*
* This secion contains a few sequence diagrams describing the problematic
* transitions of a host interface filter instance.
*
* The thing that makes it all a bit problematic is that multiple events may
* happen at the same time, and that we have to be very careful to avoid
- * deadlocks caused by mixing our locks with the ones in the host kernel.
- * The main events are receive, send, async send completion, disappearance of
- * the host networking interface and it's reappearance. The latter two events
- * are can be caused by driver unloading/loading or the device being physical
+ * deadlocks caused by mixing our locks with the ones in the host kernel. The
+ * main events are receive, send, async send completion, disappearance of the
+ * host networking interface and its reappearance. The latter two events are
+ * can be caused by driver unloading/loading or the device being physical
* unplugged (e.g. a USB network device).
*
* The strategy for dealing with these issues are:
@@ -52,7 +85,7 @@
* using a spinlock.
*
*
- * @subsection subsec_netflt_msc_dis_rel Disconnect from the network and release
+ * @subsection subsec_netflt_msc_dis_rel Disconnect from the network and release - OBSOLETE
*
* @msc
* VM, IntNet, NetFlt, Kernel, Wire;
@@ -117,7 +150,7 @@
*
*
*
- * @subsection subsec_netflt_msc_hif_rm Host Interface Removal
+ * @subsection subsec_netflt_msc_hif_rm Host Interface Removal - OBSOLETE
*
* The ifnet_t (pIf) is a tricky customer as any reference to it can potentially
* race the filter detaching. The simple way of solving it on Darwin is to guard
@@ -157,7 +190,7 @@
*
*
*
- * @subsection subsec_netflt_msc_hif_rm Host Interface Rediscovery
+ * @subsection subsec_netflt_msc_hif_rm Host Interface Rediscovery - OBSOLETE
*
* The rediscovery is performed when we receive a send request and a certain
* period have elapsed since the last attempt, i.e. we're polling it. We
@@ -341,15 +374,28 @@ static void vboxNetFltUnlinkLocked(PVBOXNETFLTGLOBALS pGlobals, PVBOXNETFLTINS p
*/
static bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
{
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- uint64_t Now = RTTimeNanoTS();
- bool fRediscovered;
- bool fDoIt;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ uint64_t Now;
+ bool fRediscovered;
+ bool fDoIt;
+
+ /*
+ * Don't do rediscovery if we're called with preemption disabled.
+ *
+ * Note! This may cause trouble if we're always called with preemptioni
+ * disabled and vboxNetFltOsMaybeRediscovered actually does some real
+ * work. For the time being though, only Darwin and FreeBSD depends
+ * on these call outs and neither supports sending with preemption
+ * disabled.
+ */
+ if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+ return false;
/*
* Rediscovered already? Time to try again?
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ Now = RTTimeNanoTS();
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
fRediscovered = !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
fDoIt = !fRediscovered
@@ -358,7 +404,7 @@ static bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
if (fDoIt)
ASMAtomicWriteBool(&pThis->fRediscoveryPending, true);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
/*
* Call the OS specific code to do the job.
@@ -375,39 +421,18 @@ static bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
ASMAtomicWriteBool(&pThis->fRediscoveryPending, false);
if (fRediscovered)
- vboxNetFltPortOsSetActive(pThis, pThis->fActive);
+ /** @todo this isn't 100% serialized. */
+ vboxNetFltPortOsSetActive(pThis, pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
}
return fRediscovered;
}
-#ifdef RT_WITH_W64_UNWIND_HACK
-# if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
-# define NETFLT_DECL_CALLBACK(type) DECLASM(DECLHIDDEN(type))
-# define NETFLT_CALLBACK(_n) netfltNtWrap##_n
-
-NETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortXmit)(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst);
-NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous)(PINTNETTRUNKIFPORT pIfPort);
-NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortGetMacAddress)(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac);
-NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsHostMac)(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac);
-NETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortWaitForIdle)(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies);
-NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortSetActive)(PINTNETTRUNKIFPORT pIfPort, bool fActive);
-NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease)(PINTNETTRUNKIFPORT pIfPort);
-NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRetain)(PINTNETTRUNKIFPORT pIfPort);
-NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRelease)(PINTNETTRUNKIFPORT pIfPort);
-
-# else
-# error "UNSUPPORTED (RT_WITH_W64_UNWIND_HACK)"
-# endif
-#else
-# define NETFLT_DECL_CALLBACK(type) static DECLCALLBACK(type)
-# define NETFLT_CALLBACK(_n) _n
-#endif
/**
* @copydoc INTNETTRUNKIFPORT::pfnXmit
*/
-NETFLT_DECL_CALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
+static DECLCALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
{
PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
int rc = VINF_SUCCESS;
@@ -419,92 +444,27 @@ NETFLT_DECL_CALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNET
AssertPtr(pSG);
Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
- Assert(pThis->fActive);
/*
* Do a busy retain and then make sure we're connected to the interface
* before invoking the OS specific code.
*/
- vboxNetFltRetain(pThis, true /* fBusy */);
- if ( !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost)
- || vboxNetFltMaybeRediscovered(pThis))
- rc = vboxNetFltPortOsXmit(pThis, pSG, fDst);
- vboxNetFltRelease(pThis, true /* fBusy */);
+ if (RT_LIKELY(vboxNetFltTryRetainBusyActive(pThis)))
+ {
+ if ( !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost)
+ || vboxNetFltMaybeRediscovered(pThis))
+ rc = vboxNetFltPortOsXmit(pThis, pSG, fDst);
+ vboxNetFltRelease(pThis, true /* fBusy */);
+ }
return rc;
}
/**
- * @copydoc INTNETTRUNKIFPORT::pfnIsPromiscuous
- */
-NETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsPromiscuous(PINTNETTRUNKIFPORT pIfPort)
-{
- PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
-
- /*
- * Input validation.
- */
- AssertPtr(pThis);
- Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
- Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
- Assert(pThis->fActive);
-
- /*
- * Ask the OS specific code.
- */
- return vboxNetFltPortOsIsPromiscuous(pThis);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnGetMacAddress
- */
-NETFLT_DECL_CALLBACK(void) vboxNetFltPortGetMacAddress(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac)
-{
- PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
-
- /*
- * Input validation.
- */
- AssertPtr(pThis);
- Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
- Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
- Assert(pThis->fActive);
-
- /*
- * Forward the question to the OS specific code.
- */
- vboxNetFltPortOsGetMacAddress(pThis, pMac);
-}
-
-
-/**
- * @copydoc INTNETTRUNKIFPORT::pfnIsHostMac
- */
-NETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsHostMac(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac)
-{
- PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
-
- /*
- * Input validation.
- */
- AssertPtr(pThis);
- Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
- Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
- Assert(pThis->fActive);
-
- /*
- * Ask the OS specific code.
- */
- return vboxNetFltPortOsIsHostMac(pThis, pMac);
-}
-
-
-/**
* @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle
*/
-NETFLT_DECL_CALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
+static DECLCALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
{
PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
int rc;
@@ -515,7 +475,7 @@ NETFLT_DECL_CALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort,
AssertPtr(pThis);
Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
- AssertReturn(!pThis->fActive, VERR_INVALID_STATE);
+ AssertReturn(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING, VERR_INVALID_STATE);
/*
* Go to sleep on the semaphore after checking the busy count.
@@ -533,11 +493,13 @@ NETFLT_DECL_CALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort,
/**
- * @copydoc INTNETTRUNKIFPORT::pfnSetActive
+ * @copydoc INTNETTRUNKIFPORT::pfnSetState
*/
-NETFLT_DECL_CALLBACK(bool) vboxNetFltPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive)
+static DECLCALLBACK(INTNETTRUNKIFSTATE) vboxNetFltPortSetState(PINTNETTRUNKIFPORT pIfPort, INTNETTRUNKIFSTATE enmState)
{
- PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
+ PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ INTNETTRUNKIFSTATE enmOldTrunkState;
/*
* Input validation.
@@ -545,35 +507,39 @@ NETFLT_DECL_CALLBACK(bool) vboxNetFltPortSetActive(PINTNETTRUNKIFPORT pIfPort, b
AssertPtr(pThis);
AssertPtr(pThis->pGlobals);
Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
- AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, false);
+ AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, INTNETTRUNKIFSTATE_INVALID);
+ AssertReturn(enmState > INTNETTRUNKIFSTATE_INVALID && enmState < INTNETTRUNKIFSTATE_END,
+ INTNETTRUNKIFSTATE_INVALID);
/*
- * We're assuming that the caller is serializing the calls, so we don't
- * have to be extremely careful here. Just update first and then call
- * the OS specific code, the update must be serialized for various reasons.
+ * Take the lock and change the state.
*/
- if (ASMAtomicReadBool(&pThis->fActive) != fActive)
- {
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
- ASMAtomicWriteBool(&pThis->fActive, fActive);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ enmOldTrunkState = pThis->enmTrunkState;
+ if (enmOldTrunkState != enmState)
+ ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmTrunkState, enmState);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
- vboxNetFltPortOsSetActive(pThis, fActive);
- }
- else
- fActive = !fActive;
- return !fActive;
+ /*
+ * If the state change indicates that the trunk has become active or
+ * inactive, call the OS specific part so they can work the promiscuous
+ * settings and such.
+ * Note! The caller makes sure there are no concurrent pfnSetState calls.
+ */
+ if ((enmOldTrunkState == INTNETTRUNKIFSTATE_ACTIVE) != (enmState == INTNETTRUNKIFSTATE_ACTIVE))
+ vboxNetFltPortOsSetActive(pThis, (enmState == INTNETTRUNKIFSTATE_ACTIVE));
+
+ return enmOldTrunkState;
}
/**
* @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease
*/
-NETFLT_DECL_CALLBACK(void) vboxNetFltPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
+static DECLCALLBACK(void) vboxNetFltPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
{
PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
/*
* Serious paranoia.
@@ -587,24 +553,24 @@ NETFLT_DECL_CALLBACK(void) vboxNetFltPortDisconnectAndRelease(PINTNETTRUNKIFPORT
Assert(pThis->szName[0]);
Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
- Assert(!pThis->fActive);
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING);
Assert(!pThis->fRediscoveryPending);
Assert(!pThis->cBusy);
/*
* Disconnect and release it.
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
vboxNetFltSetState(pThis, kVBoxNetFltInsState_Disconnecting);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
vboxNetFltOsDisconnectIt(pThis);
pThis->pSwitchPort = NULL;
#ifdef VBOXNETFLT_STATIC_CONFIG
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
vboxNetFltSetState(pThis, kVBoxNetFltInsState_Unconnected);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
#endif
vboxNetFltRelease(pThis, false /* fBusy */);
@@ -634,7 +600,7 @@ static bool vboxNetFltDestroyInstance(PVBOXNETFLTINS pThis)
#else
Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Disconnecting);
#endif
- Assert(!pThis->fActive);
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING);
Assert(!pThis->fRediscoveryPending);
Assert(!pThis->cRefs);
Assert(!pThis->cBusy);
@@ -725,7 +691,7 @@ DECLHIDDEN(void) vboxNetFltRelease(PVBOXNETFLTINS pThis, bool fBusy)
/**
* @copydoc INTNETTRUNKIFPORT::pfnRetain
*/
-NETFLT_DECL_CALLBACK(void) vboxNetFltPortRelease(PINTNETTRUNKIFPORT pIfPort)
+static DECLCALLBACK(void) vboxNetFltPortRelease(PINTNETTRUNKIFPORT pIfPort)
{
PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
vboxNetFltRelease(pThis, false /* fBusy */);
@@ -775,9 +741,104 @@ DECLHIDDEN(void) vboxNetFltRetain(PVBOXNETFLTINS pThis, bool fBusy)
/**
+ * Tries to retain the device as busy if the trunk is active.
+ *
+ * This is used before calling pfnRecv or pfnPreRecv.
+ *
+ * @returns true if we succeeded in retaining a busy reference to the active
+ * device. false if we failed.
+ * @param pThis The instance.
+ */
+DECLHIDDEN(bool) vboxNetFltTryRetainBusyActive(PVBOXNETFLTINS pThis)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ uint32_t cRefs;
+ bool fRc;
+
+ /*
+ * Paranoid Android.
+ */
+ AssertPtr(pThis);
+ Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
+ Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
+ Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
+ && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
+ AssertPtr(pThis->pGlobals);
+ Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
+ Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
+ Assert(pThis->szName[0]);
+
+ /*
+ * Do the retaining and checking behind the spinlock.
+ */
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ fRc = pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE;
+ if (fRc)
+ {
+ cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ AssertMsg(cRefs > 1 && cRefs < UINT32_MAX / 2, ("%d\n", cRefs)); NOREF(cRefs);
+
+ cRefs = ASMAtomicIncU32(&pThis->cBusy);
+ AssertMsg(cRefs >= 1 && cRefs < UINT32_MAX / 2, ("%d\n", cRefs)); NOREF(cRefs);
+ }
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
+ return fRc;
+}
+
+
+/**
+ * Tries to retain the device as busy if the trunk is not disconnecting.
+ *
+ * This is used before reporting stuff to the internal network.
+ *
+ * @returns true if we succeeded in retaining a busy reference to the active
+ * device. false if we failed.
+ * @param pThis The instance.
+ */
+DECLHIDDEN(bool) vboxNetFltTryRetainBusyNotDisconnected(PVBOXNETFLTINS pThis)
+{
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ uint32_t cRefs;
+ bool fRc;
+
+ /*
+ * Paranoid Android.
+ */
+ AssertPtr(pThis);
+ Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
+ Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
+ Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
+ && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
+ AssertPtr(pThis->pGlobals);
+ Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
+ Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
+ Assert(pThis->szName[0]);
+
+ /*
+ * Do the retaining and checking behind the spinlock.
+ */
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ fRc = pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE
+ || pThis->enmTrunkState == INTNETTRUNKIFSTATE_INACTIVE;
+ if (fRc)
+ {
+ cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ AssertMsg(cRefs > 1 && cRefs < UINT32_MAX / 2, ("%d\n", cRefs)); NOREF(cRefs);
+
+ cRefs = ASMAtomicIncU32(&pThis->cBusy);
+ AssertMsg(cRefs >= 1 && cRefs < UINT32_MAX / 2, ("%d\n", cRefs)); NOREF(cRefs);
+ }
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
+ return fRc;
+}
+
+
+/**
* @copydoc INTNETTRUNKIFPORT::pfnRetain
*/
-NETFLT_DECL_CALLBACK(void) vboxNetFltPortRetain(PINTNETTRUNKIFPORT pIfPort)
+static DECLCALLBACK(void) vboxNetFltPortRetain(PINTNETTRUNKIFPORT pIfPort)
{
PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
vboxNetFltRetain(pThis, false /* fBusy */);
@@ -804,13 +865,19 @@ static int vboxNetFltConnectIt(PVBOXNETFLTINS pThis, PINTNETTRUNKSWPORT pSwitchP
/*
* Validate state.
*/
- Assert(!pThis->fActive);
Assert(!pThis->fRediscoveryPending);
Assert(!pThis->cBusy);
#ifdef VBOXNETFLT_STATIC_CONFIG
Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Unconnected);
+ /* INTNETTRUNKIFSTATE_DISCONNECTING means "not connected" here
+ * we use the INTNETTRUNKIFSTATE_DISCONNECTING state for consistency of cases when trunk
+ * was never connected and was connected and disconnected.
+ * In the latter case we end up with INTNETTRUNKIFSTATE_DICONNECTING,
+ * so use the same state for the former */
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING);
#else
Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Initializing);
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_INACTIVE);
#endif
/*
@@ -827,7 +894,16 @@ static int vboxNetFltConnectIt(PVBOXNETFLTINS pThis, PINTNETTRUNKSWPORT pSwitchP
else
pThis->pSwitchPort = NULL;
- Assert(!pThis->fActive);
+#ifdef VBOXNETFLT_STATIC_CONFIG
+ /* INTNETTRUNKIFSTATE_DISCONNECTING means "not connected" here
+ * we use the INTNETTRUNKIFSTATE_DISCONNECTING state for consistency of cases when trunk
+ * was never connected and was connected and disconnected.
+ * In the latter case we end up with INTNETTRUNKIFSTATE_DISCONNECTING,
+ * so use the same state for the former */
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING);
+#else
+ Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_INACTIVE);
+#endif
return rc;
}
@@ -861,21 +937,25 @@ static int vboxNetFltNewInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszNam
return VERR_INTNET_FLT_IF_FAILED;
pNew->pNext = NULL;
pNew->MyPort.u32Version = INTNETTRUNKIFPORT_VERSION;
- pNew->MyPort.pfnRetain = NETFLT_CALLBACK(vboxNetFltPortRetain);
- pNew->MyPort.pfnRelease = NETFLT_CALLBACK(vboxNetFltPortRelease);
- pNew->MyPort.pfnDisconnectAndRelease= NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease);
- pNew->MyPort.pfnSetActive = NETFLT_CALLBACK(vboxNetFltPortSetActive);
- pNew->MyPort.pfnWaitForIdle = NETFLT_CALLBACK(vboxNetFltPortWaitForIdle);
- pNew->MyPort.pfnGetMacAddress = NETFLT_CALLBACK(vboxNetFltPortGetMacAddress);
- pNew->MyPort.pfnIsHostMac = NETFLT_CALLBACK(vboxNetFltPortIsHostMac);
- pNew->MyPort.pfnIsPromiscuous = NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous);
- pNew->MyPort.pfnXmit = NETFLT_CALLBACK(vboxNetFltPortXmit);
+ pNew->MyPort.pfnRetain = vboxNetFltPortRetain;
+ pNew->MyPort.pfnRelease = vboxNetFltPortRelease;
+ pNew->MyPort.pfnDisconnectAndRelease= vboxNetFltPortDisconnectAndRelease;
+ pNew->MyPort.pfnSetState = vboxNetFltPortSetState;
+ pNew->MyPort.pfnWaitForIdle = vboxNetFltPortWaitForIdle;
+ pNew->MyPort.pfnXmit = vboxNetFltPortXmit;
pNew->MyPort.u32VersionEnd = INTNETTRUNKIFPORT_VERSION;
- pNew->pSwitchPort = NULL;
+ pNew->pSwitchPort = pSwitchPort;
pNew->pGlobals = pGlobals;
pNew->hSpinlock = NIL_RTSPINLOCK;
pNew->enmState = kVBoxNetFltInsState_Initializing;
- pNew->fActive = false;
+#ifdef VBOXNETFLT_STATIC_CONFIG
+ /* for consistency of cases when trunk was never connected and was connected and disconnected.
+ * In the latter case we end up with INTNETTRUNKIFSTATE_DISCONNECTING,
+ * so use the same state for the former */
+ pNew->enmTrunkState = INTNETTRUNKIFSTATE_DISCONNECTING;
+#else
+ pNew->enmTrunkState = INTNETTRUNKIFSTATE_INACTIVE;
+#endif
pNew->fDisconnectedFromHost = false;
pNew->fRediscoveryPending = false;
pNew->fDisablePromiscuous = fNoPromisc;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
index 68b86383c..2bb676377 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltInternal.h $ */
+/* $Id: VBoxNetFltInternal.h 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Internal Header.
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#ifndef ___VBoxNetFltInternal_h___
@@ -107,7 +103,8 @@ typedef struct VBOXNETFLTINS
RTSPINLOCK hSpinlock;
/** The current interface state. */
VBOXNETFTLINSSTATE volatile enmState;
- /** Active / Suspended indicator. */
+ /** The trunk state. */
+ INTNETTRUNKIFSTATE volatile enmTrunkState;
bool volatile fActive;
/** Disconnected from the host network interface. */
bool volatile fDisconnectedFromHost;
@@ -130,6 +127,7 @@ typedef struct VBOXNETFLTINS
/** The event that is signaled when we go idle and that pfnWaitForIdle blocks on. */
RTSEMEVENT hEventIdle;
+ /** @todo move MacAddr out of this structure! */
union
{
#ifdef VBOXNETFLT_OS_SPECFIC
@@ -152,7 +150,7 @@ typedef struct VBOXNETFLTINS
* This is for dealing with the ENETDOWN case. */
bool volatile fSetPromiscuous;
/** The MAC address of the interface. */
- RTMAC Mac;
+ RTMAC MacAddr;
/** @} */
# elif defined(RT_OS_LINUX)
/** @name Linux instance data
@@ -165,15 +163,35 @@ typedef struct VBOXNETFLTINS
/** Whether device exists and physically attached. */
bool volatile fRegistered;
/** The MAC address of the interface. */
- RTMAC Mac;
+ RTMAC MacAddr;
struct notifier_block Notifier;
struct packet_type PacketType;
+# ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
struct sk_buff_head XmitQueue;
struct work_struct XmitTask;
+# endif
/** @} */
# elif defined(RT_OS_SOLARIS)
/** @name Solaris instance data.
* @{ */
+# ifdef VBOX_WITH_NETFLT_CROSSBOW
+ /** The link Id of the VNIC */
+ datalink_id_t VNICLinkId;
+ /** Instance number of VNIC */
+ uint16_t uInstance;
+ /** Whether we created the VNIC or not */
+ bool fCreatedVNIC;
+ /** The lower MAC handle */
+ mac_handle_t hInterface;
+ /** The client MAC handle */
+ mac_client_handle_t hClient;
+ /** The unicast address handle */
+ mac_unicast_handle_t hUnicast;
+ /** The promiscuous handle */
+ mac_promisc_handle_t hPromiscuous;
+ /** The MAC address of the interface */
+ RTMAC MacAddr;
+# else
/** Pointer to the bound IPv4 stream. */
void volatile *pvIp4Stream;
/** Pointer to the bound IPv6 stream. */
@@ -189,11 +207,12 @@ typedef struct VBOXNETFLTINS
/** Layered device handle to the interface. */
ldi_handle_t hIface;
/** The MAC address of the interface. */
- RTMAC Mac;
+ RTMAC MacAddr;
/** Mutex protection used for loopback. */
RTSEMFASTMUTEX hFastMtx;
/** Mutex protection used for dynamic IPv6 attaches. */
RTSEMFASTMUTEX hPollMtx;
+# endif
/** @} */
# elif defined(RT_OS_FREEBSD)
/** @name FreeBSD instance data.
@@ -217,7 +236,7 @@ typedef struct VBOXNETFLTINS
/** Output task */
struct task tskout;
/** The MAC address of the interface. */
- RTMAC Mac;
+ RTMAC MacAddr;
/** @} */
# elif defined(RT_OS_WINDOWS)
/** @name Windows instance data.
@@ -227,11 +246,12 @@ typedef struct VBOXNETFLTINS
volatile uint32_t cModeNetFltRefs;
volatile uint32_t cModePassThruRefs;
-
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/** Packet worker thread info */
PACKET_QUEUE_WORKER PacketQueueWorker;
+#endif
/** The MAC address of the interface. Caching MAC for performance reasons. */
- RTMAC Mac;
+ RTMAC MacAddr;
/** mutex used to synchronize ADAPT init/deinit */
RTSEMMUTEX hAdaptMutex;
/** @} */
@@ -308,6 +328,8 @@ DECLHIDDEN(bool) vboxNetFltCanUnload(PVBOXNETFLTGLOBALS pGlobals);
DECLHIDDEN(PVBOXNETFLTINS) vboxNetFltFindInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName);
DECLHIDDEN(void) vboxNetFltRetain(PVBOXNETFLTINS pThis, bool fBusy);
+DECLHIDDEN(bool) vboxNetFltTryRetainBusyActive(PVBOXNETFLTINS pThis);
+DECLHIDDEN(bool) vboxNetFltTryRetainBusyNotDisconnected(PVBOXNETFLTINS pThis);
DECLHIDDEN(void) vboxNetFltRelease(PVBOXNETFLTINS pThis, bool fBusy);
#ifdef VBOXNETFLT_STATIC_CONFIG
@@ -343,49 +365,6 @@ DECLHIDDEN(bool) vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis);
DECLHIDDEN(int) vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst);
/**
- * Checks if the interface is in promiscuous mode from the host perspective.
- *
- * If it is, then the internal networking switch will send frames
- * heading for the wire to the host as well.
- *
- * @see INTNETTRUNKIFPORT::pfnIsPromiscuous for more details.
- *
- * @returns true / false accordingly.
- * @param pThis The instance.
- *
- * @remarks Owns the network lock and the out-bound trunk port semaphores.
- */
-DECLHIDDEN(bool) vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis);
-
-/**
- * Get the MAC address of the interface we're attached to.
- *
- * Used by the internal networking switch for implementing the
- * shared-MAC-on-the-wire mode.
- *
- * @param pThis The instance.
- * @param pMac Where to store the MAC address.
- * If you don't know, set all the bits except the first (the multicast one).
- *
- * @remarks Owns the network lock and the out-bound trunk port semaphores.
- */
-DECLHIDDEN(void) vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac);
-
-/**
- * Checks if the specified MAC address is for any of the host interfaces.
- *
- * Used by the internal networking switch to decide the destination(s)
- * of a frame.
- *
- * @returns true / false accordingly.
- * @param pThis The instance.
- * @param pMac The MAC address.
- *
- * @remarks Owns the network lock and the out-bound trunk port semaphores.
- */
-DECLHIDDEN(bool) vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac);
-
-/**
* This is called when activating or suspending the instance.
*
* Use this method to enable and disable promiscuous mode on
@@ -433,6 +412,9 @@ DECLHIDDEN(void) vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis);
* This is called to attach to the actual host interface
* after linking the instance into the list.
*
+ * The MAC address as well promiscuousness and GSO capabilities should be
+ * reported by this function.
+ *
* @return IPRT status code.
* @param pThis The new instance.
* @param pvContext The user supplied context in the static config only.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
index fecb5d249..3e7d035ea 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-darwin.cpp $ */
+/* $Id: VBoxNetFlt-darwin.cpp 28830 2010-04-27 14:05:25Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Darwin Specific Code.
*/
/*
- * Copyright (C) 2006-2008 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*******************************************************************************
@@ -36,6 +32,7 @@
#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
#include <VBox/log.h>
#include <VBox/err.h>
+#include <VBox/intnetinline.h>
#include <VBox/version.h>
#include <iprt/initterm.h>
#include <iprt/assert.h>
@@ -235,14 +232,14 @@ DECLINLINE(ifnet_t) vboxNetFltDarwinRetainIfNet(PVBOXNETFLTINS pThis)
/*
* Be careful here to avoid problems racing the detached callback.
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
if (!ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost))
{
pIfNet = (ifnet_t)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pIfNet);
if (pIfNet)
ifnet_reference(pIfNet);
}
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
return pIfNet;
}
@@ -384,26 +381,27 @@ static mbuf_t vboxNetFltDarwinMBufFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG)
&& mbuf_maxlen(pCur) >= pSG->cbTotal)
{
mbuf_setlen(pCur, pSG->cbTotal);
- memcpy(mbuf_data(pCur), pSG->aSegs[0].pv, pSG->cbTotal);
+ IntNetSgRead(pSG, mbuf_data(pCur));
}
else
{
/* Multi buffer copying. */
- size_t cbSrc = pSG->cbTotal;
- uint8_t const *pbSrc = (uint8_t const *)pSG->aSegs[0].pv;
- while (cbSrc > 0 && pCur)
+ size_t cbLeft = pSG->cbTotal;
+ size_t offSrc = 0;
+ while (cbLeft > 0 && pCur)
{
size_t cb = mbuf_maxlen(pCur);
- if (cbSrc < cb)
- cb = cbSrc;
+ if (cb > cbLeft)
+ cb = cbLeft;
mbuf_setlen(pCur, cb);
- memcpy(mbuf_data(pCur), pbSrc, cb);
+ IntNetSgReadEx(pSG, offSrc, cb, mbuf_data(pCur));
/* advance */
- pbSrc += cb;
- cbSrc -= cb;
+ offSrc += cb;
+ cbLeft -= cb;
pCur = mbuf_next(pCur);
}
+ Assert(cbLeft == 0);
}
if (!err)
{
@@ -492,18 +490,11 @@ DECLINLINE(void) vboxNetFltDarwinMBufToSG(PVBOXNETFLTINS pThis, mbuf_t pMBuf, vo
{
NOREF(pThis);
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsAlloc = cSegs;
-
/*
- * Walk the chain and convert the buffers to segments.
+ * Walk the chain and convert the buffers to segments. Works INTNETSG::cbTotal.
*/
unsigned iSeg = 0;
- pSG->cbTotal = 0;
+ IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
for (mbuf_t pCur = pMBuf; pCur; pCur = mbuf_next(pCur))
{
size_t cbSeg = mbuf_len(pCur);
@@ -622,6 +613,31 @@ DECLINLINE(void) vboxNetFltDarwinMBufToSG(PVBOXNETFLTINS pThis, mbuf_t pMBuf, vo
/**
+ * Helper for determining whether the host wants the interface to be
+ * promiscuous.
+ */
+static bool vboxNetFltDarwinIsPromiscuous(PVBOXNETFLTINS pThis)
+{
+ bool fRc = false;
+ ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis);
+ if (pIfNet)
+ {
+ /* gather the data */
+ uint16_t fIf = ifnet_flags(pIfNet);
+ unsigned cPromisc = VBOX_GET_PCOUNT(pIfNet);
+ bool fSetPromiscuous = ASMAtomicUoReadBool(&pThis->u.s.fSetPromiscuous);
+ vboxNetFltDarwinReleaseIfNet(pThis, pIfNet);
+
+ /* calc the return. */
+ fRc = (fIf & IFF_PROMISC)
+ && cPromisc > fSetPromiscuous;
+ }
+ return fRc;
+}
+
+
+
+/**
*
* @see iff_detached_func in the darwin kpi.
*/
@@ -647,7 +663,7 @@ static void vboxNetFltDarwinIffDetached(void *pvThis, ifnet_t pIfNet)
* We carefully take the spinlock and increase the interface reference
* behind it in order to avoid problematic races with the detached callback.
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
pIfNet = (ifnet_t)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pIfNet);
int cPromisc = VALID_PTR(pIfNet) ? VBOX_GET_PCOUNT(pIfNet) : - 1;
@@ -660,7 +676,7 @@ static void vboxNetFltDarwinIffDetached(void *pvThis, ifnet_t pIfNet)
ASMAtomicUoWriteBool(&pThis->fRediscoveryPending, false);
ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
if (pIfNet)
ifnet_release(pIfNet);
@@ -755,6 +771,8 @@ static void vboxNetFltDarwinIffEvent(void *pvThis, ifnet_t pIfNet, protocol_fami
}
else if (pEvMsg->event_code == KEV_DL_LINK_OFF)
Log(("vboxNetFltDarwinIffEvent: %s goes down (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pIfNet)));
+/** @todo KEV_DL_LINK_ADDRESS_CHANGED -> pfnReportMacAddress */
+/** @todo KEV_DL_SIFFLAGS -> pfnReportPromiscuousMode */
}
else
Log(("vboxNetFltDarwinIffEvent: pThis->u.s.pIfNet=%p pIfNet=%p (%d)\n", pThis->u.s.pIfNet, pIfNet, VALID_PTR(pIfNet) ? VBOX_GET_PCOUNT(pIfNet) : -1));
@@ -798,13 +816,7 @@ static errno_t vboxNetFltDarwinIffInputOutputWorker(PVBOXNETFLTINS pThis, mbuf_t
/*
* Active? Retain the instance and increment the busy counter.
*/
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
- const bool fActive = ASMAtomicUoReadBool(&pThis->fActive);
- if (fActive)
- vboxNetFltRetain(pThis, true /* fBusy */);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
- if (!fActive)
+ if (!vboxNetFltTryRetainBusyActive(pThis))
return 0;
/*
@@ -900,14 +912,14 @@ static int vboxNetFltDarwinAttachToInterface(PVBOXNETFLTINS pThis, bool fRedisco
}
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pIfNet, pIfNet);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
/*
* Get the mac address while we still have a valid ifnet reference.
*/
- err = ifnet_lladdr_copy_bytes(pIfNet, &pThis->u.s.Mac, sizeof(pThis->u.s.Mac));
+ err = ifnet_lladdr_copy_bytes(pIfNet, &pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
if (!err)
{
/*
@@ -926,7 +938,7 @@ static int vboxNetFltDarwinAttachToInterface(PVBOXNETFLTINS pThis, bool fRedisco
err = iflt_attach(pIfNet, &RegRec, &pIfFilter);
Assert(err || pIfFilter);
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
pIfNet = (ifnet_t)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pIfNet);
if (pIfNet && !err)
{
@@ -934,7 +946,19 @@ static int vboxNetFltDarwinAttachToInterface(PVBOXNETFLTINS pThis, bool fRedisco
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pIfFilter, pIfFilter);
pIfNet = NULL; /* don't dereference it */
}
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
+ /* Report capabilities. */
+ if ( !pIfNet
+ && vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ Assert(pThis->pSwitchPort);
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, vboxNetFltDarwinIsPromiscuous(pThis));
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
}
/* Release the interface on failure. */
@@ -943,7 +967,7 @@ static int vboxNetFltDarwinAttachToInterface(PVBOXNETFLTINS pThis, bool fRedisco
int rc = RTErrConvertFromErrno(err);
if (RT_SUCCESS(rc))
- LogRel(("VBoxFltDrv: attached to '%s' / %.*Rhxs\n", pThis->szName, sizeof(pThis->u.s.Mac), &pThis->u.s.Mac));
+ LogRel(("VBoxFltDrv: attached to '%s' / %.*Rhxs\n", pThis->szName, sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
else
LogRel(("VBoxFltDrv: failed to attach to ifnet '%s' (err=%d)\n", pThis->szName, err));
return rc;
@@ -1009,41 +1033,6 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
}
-bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
-{
- bool fRc = false;
- ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis);
- if (pIfNet)
- {
- /* gather the data */
- uint16_t fIf = ifnet_flags(pIfNet);
- unsigned cPromisc = VBOX_GET_PCOUNT(pIfNet);
- bool fSetPromiscuous = ASMAtomicUoReadBool(&pThis->u.s.fSetPromiscuous);
- vboxNetFltDarwinReleaseIfNet(pThis, pIfNet);
-
- /* calc the return. */
- fRc = (fIf & IFF_PROMISC)
- && cPromisc > fSetPromiscuous;
- }
- return fRc;
-}
-
-
-void vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
-{
- *pMac = pThis->u.s.Mac;
-}
-
-
-bool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
-{
- /* ASSUMES that the MAC address never changes. */
- return pThis->u.s.Mac.au16[0] == pMac->au16[0]
- && pThis->u.s.Mac.au16[1] == pMac->au16[1]
- && pThis->u.s.Mac.au16[2] == pMac->au16[2];
-}
-
-
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
{
ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis);
@@ -1169,11 +1158,11 @@ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
/*
* Carefully obtain the interface filter reference and detach it.
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
pIfFilter = (interface_filter_t)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pIfFilter);
if (pIfFilter)
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pIfFilter, NULL);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
if (pIfFilter)
iflt_detach(pIfFilter);
@@ -1196,7 +1185,7 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
pThis->u.s.pIfFilter = NULL;
pThis->u.s.fSetPromiscuous = false;
pThis->u.s.fNeedSetPromiscuous = false;
- //pThis->u.s.Mac = {0};
+ //pThis->u.s.MacAddr = {0};
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/darwin/loadnetflt.sh b/src/VBox/HostDrivers/VBoxNetFlt/darwin/loadnetflt.sh
index fde0f4265..81ca4be5b 100755
--- a/src/VBox/HostDrivers/VBoxNetFlt/darwin/loadnetflt.sh
+++ b/src/VBox/HostDrivers/VBoxNetFlt/darwin/loadnetflt.sh
@@ -4,7 +4,7 @@
#
#
-# Copyright (C) 2006-2008 Sun Microsystems, Inc.
+# Copyright (C) 2006-2008 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -14,10 +14,6 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
SCRIPT_NAME="loadnetflt"
XNU_VERSION=`LC_ALL=C uname -r | LC_ALL=C cut -d . -f 1`
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
index e45df4d5f..c51a2d4d7 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile
@@ -1,11 +1,11 @@
-# $Id: Makefile $
+# $Id: Makefile 28800 2010-04-27 08:22:32Z vboxsync $
## @file
# Makefile for the VirtualBox FreeBSD Host Driver.
#
#
#
-# Copyright (C) 2006-2007 Sun Microsystems, Inc.
+# Copyright (C) 2006-2007 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -15,10 +15,6 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
KMOD = vboxnetflt
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
index e9edbd223..4d13c2350 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: VBoxNetFlt-freebsd.c $ */
+/* $Id: VBoxNetFlt-freebsd.c 28830 2010-04-27 14:05:25Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), FreeBSD Specific Code.
*/
@@ -60,6 +60,7 @@
#include <VBox/version.h>
#include <VBox/err.h>
#include <VBox/log.h>
+#include <VBox/intnetinline.h>
#include <iprt/initterm.h>
#include <iprt/string.h>
#include <iprt/spinlock.h>
@@ -187,13 +188,7 @@ static void vboxNetFltFreeBSDMBufToSG(PVBOXNETFLTINS pThis, struct mbuf *m, PINT
unsigned int i;
struct mbuf *m0;
- pSG->cbTotal = m_length(m, NULL);
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsAlloc = cSegs;
+ IntNetSgInitTempSegs(pSG, m_length(m, NULL), cSegs, 0 /*cSegsUsed*/);
for (m0 = m, i = segOffset; m0; m0 = m0->m_next)
{
@@ -216,6 +211,7 @@ static void vboxNetFltFreeBSDMBufToSG(PVBOXNETFLTINS pThis, struct mbuf *m, PINT
i++;
}
#endif
+
pSG->cSegsUsed = i;
}
@@ -228,7 +224,7 @@ static struct mbuf * vboxNetFltFreeBSDSGMBufFromSG(PVBOXNETFLTINS pThis, PINTNET
int error;
unsigned int i;
- if (pSG->cbTotal == 0 || pSG->aSegs[0].cb == 0)
+ if (pSG->cbTotal == 0)
return (NULL);
m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
@@ -319,7 +315,7 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item)
struct m_tag *mtag;
bool fActive;
- fActive = ASMAtomicUoReadBool(&pThis->fActive);
+ fActive = vboxNetFltTryRetainBusyActive(pThis);
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
@@ -341,6 +337,8 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item)
if (mtag != NULL || !fActive)
{
ether_demux(ifp, m);
+ if (fActive)
+ vboxNetFltRelease(pThis, true /*fBusy*/);
return (0);
}
mtx_lock_spin(&pThis->u.s.inq.ifq_mtx);
@@ -348,13 +346,18 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item)
mtx_unlock_spin(&pThis->u.s.inq.ifq_mtx);
taskqueue_enqueue_fast(taskqueue_fast, &pThis->u.s.tskin);
}
- /**
+ /*
* Handle mbufs on the outgoing hook, frames going to the interface
*/
else if (pThis->u.s.output == hook)
{
if (mtag != NULL || !fActive)
- return ether_output_frame(ifp, m);
+ {
+ int rc = ether_output_frame(ifp, m);
+ if (fActive)
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ return rc;
+ }
mtx_lock_spin(&pThis->u.s.outq.ifq_mtx);
_IF_ENQUEUE(&pThis->u.s.outq, m);
mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx);
@@ -364,6 +367,9 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item)
{
m_freem(m);
}
+
+ if (fActive)
+ vboxNetFltRelease(pThis, true /*fBusy*/);
return (0);
}
@@ -373,8 +379,7 @@ static int ng_vboxnetflt_shutdown(node_p node)
bool fActive;
/* Prevent node shutdown if we're active */
- fActive = ASMAtomicUoReadBool(&pThis->fActive);
- if (fActive)
+ if (pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE)
return (EBUSY);
NG_NODE_UNREF(node);
return (0);
@@ -418,7 +423,7 @@ static void vboxNetFltFreeBSDinput(void *arg, int pending)
/* Create a copy and deliver to the virtual switch */
pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
- fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
+ fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_WIRE);
RTMemTmpFree(pSG);
if (fDropIt)
m_freem(m);
@@ -528,6 +533,13 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
return VINF_SUCCESS;
}
+static bool vboxNetFltFreeBsdIsPromiscuous(PVBOXNETFLTINS pThis)
+{
+ /** @todo This isn't taking into account that we put the interface in
+ * promiscuous mode. */
+ return (pThis->u.s.flags & IFF_PROMISC) ? true : false;
+}
+
int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
{
char nam[NG_NODESIZ];
@@ -544,11 +556,13 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0)
return VERR_INTERNAL_ERROR;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.ifp, ifp);
pThis->u.s.node = node;
- bcopy(IF_LLADDR(ifp), &pThis->u.s.Mac, ETHER_ADDR_LEN);
+ bcopy(IF_LLADDR(ifp), &pThis->u.s.MacAddr, ETHER_ADDR_LEN);
ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
+
/* Initialize deferred input queue */
bzero(&pThis->u.s.inq, sizeof(struct ifqueue));
mtx_init(&pThis->u.s.inq.ifq_mtx, "vboxnetflt inq", NULL, MTX_SPIN);
@@ -559,13 +573,27 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
mtx_init(&pThis->u.s.outq.ifq_mtx, "vboxnetflt outq", NULL, MTX_SPIN);
TASK_INIT(&pThis->u.s.tskout, 0, vboxNetFltFreeBSDoutput, pThis);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
NG_NODE_SET_PRIVATE(node, pThis);
+
/* Attempt to name it vboxnetflt_<ifname> */
snprintf(nam, NG_NODESIZ, "vboxnetflt_%s", pThis->szName);
ng_name_node(node, nam);
+ /* Report MAC address, promiscuous mode and GSO capabilities. */
+ /** @todo keep these reports up to date, either by polling for changes or
+ * intercept some control flow if possible. */
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ Assert(pThis->pSwitchPort);
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, vboxNetFltFreeBsdIsPromiscuous(pThis));
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
+
return VINF_SUCCESS;
}
@@ -707,23 +735,6 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
}
}
-bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
-{
- return (pThis->u.s.flags & IFF_PROMISC) ? true : false;
-}
-
-void vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
-{
- *pMac = pThis->u.s.Mac;
-}
-
-bool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
-{
- return pThis->u.s.Mac.au16[0] == pMac->au16[0]
- && pThis->u.s.Mac.au16[1] == pMac->au16[1]
- && pThis->u.s.Mac.au16[2] == pMac->au16[2];
-}
-
int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
{
return VINF_SUCCESS;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
index cefcaa465..9290f0edf 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
+++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt
@@ -1,11 +1,11 @@
#!/bin/sh
-# $Id: files_vboxnetflt $
+# $Id: files_vboxnetflt 29250 2010-05-09 17:53:58Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
#
-# Copyright (C) 2007 Sun Microsystems, Inc.
+# Copyright (C) 2007-2010 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -24,15 +24,13 @@
# You may elect to license modified versions of this file under the
# terms and conditions of either the GPL or the CDDL or both.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \
${PATH_ROOT}/include/iprt/alloca.h=>include/iprt/alloca.h \
${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \
+ ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \
+ ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \
${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \
${PATH_ROOT}/include/iprt/avl.h=>include/iprt/avl.h \
${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \
@@ -63,6 +61,7 @@ VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
${PATH_ROOT}/include/VBox/intnet.h=>include/VBox/intnet.h \
+ ${PATH_ROOT}/include/VBox/intnetinline.h=>include/VBox/intnetinline.h \
${PATH_ROOT}/include/VBox/stam.h=>include/VBox/stam.h \
${PATH_ROOT}/include/VBox/sup.h=>include/VBox/sup.h \
${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
@@ -75,10 +74,8 @@ VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c=>SUPR0IdcClientComponent.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h=>SUPR0IdcClientInternal.h \
${PATH_ROOT}/src/VBox/HostDrivers/Support/freebsd/SUPR0IdcClient-freebsd.c=>SUPR0IdcClient-freebsd.c \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/initterm.h=>include/internal/initterm.h \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/iprt.h=>include/internal/iprt.h \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/magics.h=>include/internal/magics.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h=>r0drv/freebsd/the-freebsd-kernel.h \
${PATH_OUT}/version-generated.h=>version-generated.h \
+ ${PATH_OUT}/product-generated.h=>product-generated.h \
"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/Makefile b/src/VBox/HostDrivers/VBoxNetFlt/linux/Makefile
index ceefc45f1..63bc82587 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/Makefile
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/Makefile
@@ -5,7 +5,7 @@
#
#
-# Copyright (C) 2006-2007 Sun Microsystems, Inc.
+# Copyright (C) 2006-2007 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -15,10 +15,6 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
#
# First, figure out which architecture we're targeting and the build type.
@@ -69,7 +65,7 @@ OBJS = \
VBoxNetFlt.o \
SUPR0IdcClient.o \
SUPR0IdcClientComponent.o \
- SUPR0IdcClient-linux.o \
+ linux/SUPR0IdcClient-linux.o
ifeq ($(BUILD_TARGET_ARCH),x86)
OBJS += math/gcc/divdi3.o \
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
index f03c90c1b..3287ffe08 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-linux.c $ */
+/* $Id: VBoxNetFlt-linux.c 28830 2010-04-27 14:05:25Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Linux Specific Code.
*/
/*
- * Copyright (C) 2006-2008 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,26 +13,27 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
+#define VBOXNETFLT_LINUX_NO_XMIT_QUEUE
#include "the-linux-kernel.h"
#include "version-generated.h"
+#include "product-generated.h"
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/miscdevice.h>
#include <linux/ip.h>
-#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
#include <VBox/log.h>
#include <VBox/err.h>
+#include <VBox/intnetinline.h>
+#include <VBox/pdmnetinline.h>
+#include <VBox/param.h>
#include <iprt/alloca.h>
#include <iprt/assert.h>
#include <iprt/spinlock.h>
@@ -40,6 +41,7 @@
#include <iprt/initterm.h>
#include <iprt/process.h>
#include <iprt/mem.h>
+#include <iprt/net.h>
#include <iprt/log.h>
#include <iprt/mp.h>
#include <iprt/mem.h>
@@ -48,74 +50,76 @@
#define VBOXNETFLT_OS_SPECFIC 1
#include "../VBoxNetFltInternal.h"
-#define VBOX_FLT_NB_TO_INST(pNB) ((PVBOXNETFLTINS)((uint8_t *)pNB - \
- RT_OFFSETOF(VBOXNETFLTINS, u.s.Notifier)))
-#define VBOX_FLT_PT_TO_INST(pPT) ((PVBOXNETFLTINS)((uint8_t *)pPT - \
- RT_OFFSETOF(VBOXNETFLTINS, u.s.PacketType)))
-#define VBOX_FLT_XT_TO_INST(pXT) ((PVBOXNETFLTINS)((uint8_t *)pXT - \
- RT_OFFSETOF(VBOXNETFLTINS, u.s.XmitTask)))
-#define VBOX_GET_PCOUNT(pDev) (pDev->promiscuity)
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+#define VBOX_FLT_NB_TO_INST(pNB) RT_FROM_MEMBER(pNB, VBOXNETFLTINS, u.s.Notifier)
+#define VBOX_FLT_PT_TO_INST(pPT) RT_FROM_MEMBER(pPT, VBOXNETFLTINS, u.s.PacketType)
+#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
+# define VBOX_FLT_XT_TO_INST(pXT) RT_FROM_MEMBER(pXT, VBOXNETFLTINS, u.s.XmitTask)
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
-# define VBOX_SKB_RESET_NETWORK_HDR(skb) skb_reset_network_header(skb)
-# define VBOX_SKB_RESET_MAC_HDR(skb) skb_reset_mac_header(skb)
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
-# define VBOX_SKB_RESET_NETWORK_HDR(skb) skb->nh.raw = skb->data
-# define VBOX_SKB_RESET_MAC_HDR(skb) skb->mac.raw = skb->data
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
+# define VBOX_SKB_RESET_NETWORK_HDR(skb) skb_reset_network_header(skb)
+# define VBOX_SKB_RESET_MAC_HDR(skb) skb_reset_mac_header(skb)
+#else
+# define VBOX_SKB_RESET_NETWORK_HDR(skb) skb->nh.raw = skb->data
+# define VBOX_SKB_RESET_MAC_HDR(skb) skb->mac.raw = skb->data
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
-# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(skb)
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) */
-# define CHECKSUM_PARTIAL CHECKSUM_HW
+# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(skb)
+#else
+# define CHECKSUM_PARTIAL CHECKSUM_HW
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
-# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(skb, 0)
-# else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) */
+# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(skb, 0)
+# else
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
-# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(&skb, 0)
-# else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7) */
-# define VBOX_SKB_CHECKSUM_HELP(skb) (!skb_checksum_help(skb))
-# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7) */
-# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-# define VBOX_SKB_IS_GSO(skb) skb_is_gso(skb)
- /* No features, very dumb device */
-# define VBOX_SKB_GSO_SEGMENT(skb) skb_gso_segment(skb, 0)
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) */
-# define VBOX_SKB_IS_GSO(skb) false
-# define VBOX_SKB_GSO_SEGMENT(skb) NULL
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) */
+# define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(&skb, 0)
+# else
+# define VBOX_SKB_CHECKSUM_HELP(skb) (!skb_checksum_help(skb))
+# endif
+# endif
+#endif
#ifndef NET_IP_ALIGN
# define NET_IP_ALIGN 2
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
-unsigned dev_get_flags(const struct net_device *dev)
-{
- unsigned flags;
+#if 0
+/** Create scatter / gather segments for fragments. When not used, we will
+ * linearize the socket buffer before creating the internal networking SG. */
+# define VBOXNETFLT_SG_SUPPORT 1
+#endif
- flags = (dev->flags & ~(IFF_PROMISC |
- IFF_ALLMULTI |
- IFF_RUNNING)) |
- (dev->gflags & (IFF_PROMISC |
- IFF_ALLMULTI));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+/** Indicates that the linux kernel may send us GSO frames. */
+# define VBOXNETFLT_WITH_GSO 1
- if (netif_running(dev) && netif_carrier_ok(dev))
- flags |= IFF_RUNNING;
+/** This enables or disables the transmitting of GSO frame from the internal
+ * network and to the host. */
+# define VBOXNETFLT_WITH_GSO_XMIT_HOST 1
+
+# if 0 /** @todo This is currently disable because it causes performance loss of 5-10%. */
+/** This enables or disables the transmitting of GSO frame from the internal
+ * network and to the wire. */
+# define VBOXNETFLT_WITH_GSO_XMIT_WIRE 1
+# endif
+
+/** This enables or disables the forwarding/flooding of GSO frame from the host
+ * to the internal network. */
+# define VBOXNETFLT_WITH_GSO_RECV 1
+
+#endif
- return flags;
-}
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) */
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static int VBoxNetFltLinuxInit(void);
static void VBoxNetFltLinuxUnload(void);
+static void vboxNetFltLinuxForwardToIntNet(PVBOXNETFLTINS pThis, struct sk_buff *pBuf);
/*******************************************************************************
@@ -129,14 +133,33 @@ static VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
module_init(VBoxNetFltLinuxInit);
module_exit(VBoxNetFltLinuxUnload);
-MODULE_AUTHOR("Sun Microsystems, Inc.");
-MODULE_DESCRIPTION("VirtualBox Network Filter Driver");
+MODULE_AUTHOR(VBOX_VENDOR);
+MODULE_DESCRIPTION(VBOX_PRODUCT " Network Filter Driver");
MODULE_LICENSE("GPL");
#ifdef MODULE_VERSION
MODULE_VERSION(VBOX_VERSION_STRING " (" RT_XSTR(INTNETTRUNKIFPORT_VERSION) ")");
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) && defined(LOG_ENABLED)
+unsigned dev_get_flags(const struct net_device *dev)
+{
+ unsigned flags;
+
+ flags = (dev->flags & ~(IFF_PROMISC |
+ IFF_ALLMULTI |
+ IFF_RUNNING)) |
+ (dev->gflags & (IFF_PROMISC |
+ IFF_ALLMULTI));
+
+ if (netif_running(dev) && netif_carrier_ok(dev))
+ flags |= IFF_RUNNING;
+
+ return flags;
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12) */
+
+
/**
* Initialize module.
*
@@ -202,6 +225,178 @@ static void __exit VBoxNetFltLinuxUnload(void)
Log(("VBoxNetFltLinuxUnload - done\n"));
}
+/**
+ * Experiment where we filter trafic from the host to the internal network
+ * before it reaches the NIC driver.
+ *
+ * The current code uses a very ugly hack and only works on kernels using the
+ * net_device_ops (>= 2.6.29). It has been shown to give us a
+ * performance boost of 60-100% though. So, we have to find some less hacky way
+ * of getting this job done eventually.
+ *
+ * #define VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+ */
+#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+
+/**
+ * The overridden net_device_ops of the device we're attached to.
+ *
+ * Requires Linux 2.6.29 or later.
+ *
+ * This is a very dirty hack that was create to explore how much we can improve
+ * the host to guest transfers by not CC'ing the NIC.
+ */
+typedef struct VBoxNetDeviceOpsOverride
+{
+ /** Our overridden ops. */
+ struct net_device_ops Ops;
+ /** Magic word. */
+ uint32_t u32Magic;
+ /** Pointer to the original ops. */
+ struct net_device_ops const *pOrgOps;
+ /** Pointer to the net filter instance. */
+ PVBOXNETFLTINS pVBoxNetFlt;
+ /** The number of filtered packages. */
+ uint64_t cFiltered;
+ /** The total number of packets */
+ uint64_t cTotal;
+} VBOXNETDEVICEOPSOVERRIDE, *PVBOXNETDEVICEOPSOVERRIDE;
+/** VBOXNETDEVICEOPSOVERRIDE::u32Magic value. */
+#define VBOXNETDEVICEOPSOVERRIDE_MAGIC UINT32_C(0x00c0ffee)
+
+/**
+ * ndo_start_xmit wrapper that drops packets that shouldn't go to the wire
+ * because they belong on the internal network.
+ *
+ * @returns NETDEV_TX_XXX.
+ * @param pSkb The socket buffer to transmit.
+ * @param pDev The net device.
+ */
+static int vboxNetFltLinuxStartXmitFilter(struct sk_buff *pSkb, struct net_device *pDev)
+{
+ PVBOXNETDEVICEOPSOVERRIDE pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->netdev_ops;
+ uint8_t abHdrBuf[sizeof(RTNETETHERHDR) + sizeof(uint32_t) + RTNETIPV4_MIN_LEN];
+ PCRTNETETHERHDR pEtherHdr;
+ PINTNETTRUNKSWPORT pSwitchPort;
+
+
+ /*
+ * Validate the override structure.
+ *
+ * Note! We're racing vboxNetFltLinuxUnhookDev here. If this was supposed
+ * to be production quality code, we would have to be much more
+ * careful here and avoid the race.
+ */
+ if ( !VALID_PTR(pOverride)
+ || pOverride->u32Magic != VBOXNETDEVICEOPSOVERRIDE_MAGIC
+ || !VALID_PTR(pOverride->pOrgOps))
+ {
+ printk("vboxNetFltLinuxStartXmitFilter: bad override %p\n", pOverride);
+ dev_kfree_skb(pSkb);
+ return NETDEV_TX_OK;
+ }
+ pOverride->cTotal++;
+
+ /*
+ * Do the filtering base on the defaul OUI of our virtual NICs
+ *
+ * Note! In a real solution, we would ask the switch whether the
+ * destination MAC is 100% to be on the internal network and then
+ * drop it.
+ */
+ pEtherHdr = (PCRTNETETHERHDR)skb_header_pointer(pSkb, 0, sizeof(abHdrBuf), &abHdrBuf[0]);
+ if ( pEtherHdr
+ && VALID_PTR(pOverride->pVBoxNetFlt)
+ && (pSwitchPort = pOverride->pVBoxNetFlt->pSwitchPort) != NULL
+ && VALID_PTR(pSwitchPort)
+ )
+ {
+ INTNETSWDECISION enmDecision;
+ uint32_t cbHdrs = skb_headlen(pSkb);
+ cbHdrs = RT_MAX(cbHdrs, sizeof(abHdrBuf));
+
+ /** @todo consider reference counting, etc. */
+ enmDecision = pSwitchPort->pfnPreRecv(pSwitchPort, pEtherHdr, cbHdrs, INTNETTRUNKDIR_HOST);
+ if (enmDecision == INTNETSWDECISION_INTNET)
+ {
+ dev_kfree_skb(pSkb);
+ pOverride->cFiltered++;
+ return NETDEV_TX_OK;
+ }
+ }
+
+ return pOverride->pOrgOps->ndo_start_xmit(pSkb, pDev);
+}
+
+/**
+ * Hooks the device ndo_start_xmit operation of the device.
+ *
+ * @param pThis The net filter instance.
+ * @param pDev The net device.
+ */
+static void vboxNetFltLinuxHookDev(PVBOXNETFLTINS pThis, struct net_device *pDev)
+{
+ PVBOXNETDEVICEOPSOVERRIDE pOverride;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ pOverride = RTMemAlloc(sizeof(*pOverride));
+ if (!pOverride)
+ return;
+ pOverride->pOrgOps = pDev->netdev_ops;
+ pOverride->Ops = *pDev->netdev_ops;
+ pOverride->Ops.ndo_start_xmit = vboxNetFltLinuxStartXmitFilter;
+ pOverride->u32Magic = VBOXNETDEVICEOPSOVERRIDE_MAGIC;
+ pOverride->cTotal = 0;
+ pOverride->cFiltered = 0;
+ pOverride->pVBoxNetFlt = pThis;
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); /* (this isn't necessary, but so what) */
+ ASMAtomicXchgPtr((void * volatile *)&pDev->netdev_ops, pOverride);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+}
+
+/**
+ * Undos what vboxNetFltLinuxHookDev did.
+ *
+ * @param pThis The net filter instance.
+ * @param pDev The net device. Can be NULL, in which case
+ * we'll try retrieve it from @a pThis.
+ */
+static void vboxNetFltLinuxUnhookDev(PVBOXNETFLTINS pThis, struct net_device *pDev)
+{
+ PVBOXNETDEVICEOPSOVERRIDE pOverride;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ if (!pDev)
+ pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
+ if (VALID_PTR(pDev))
+ {
+ pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->netdev_ops;
+ if ( VALID_PTR(pOverride)
+ && pOverride->u32Magic == VBOXNETDEVICEOPSOVERRIDE_MAGIC
+ && VALID_PTR(pOverride->pOrgOps)
+ )
+ {
+ ASMAtomicXchgPtr((void * volatile *)&pDev->netdev_ops, pOverride->pOrgOps);
+ ASMAtomicWriteU32(&pOverride->u32Magic, 0);
+ }
+ else
+ pOverride = NULL;
+ }
+ else
+ pOverride = NULL;
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
+ if (pOverride)
+ {
+ printk("vboxnetflt: dropped %llu out of %llu packets\n", pOverride->cFiltered, pOverride->cTotal);
+ RTMemFree(pOverride);
+ }
+}
+
+#endif /* VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT */
+
/**
* Reads and retains the host interface handle.
@@ -284,58 +479,116 @@ DECLINLINE(bool) vboxNetFltLinuxSkBufIsOur(struct sk_buff *pBuf)
* @returns Pointer to the sk_buff.
* @param pThis The instance.
* @param pSG The (scatter/)gather list.
+ * @param fDstWire Set if the destination is the wire.
*/
static struct sk_buff *vboxNetFltLinuxSkBufFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, bool fDstWire)
{
struct sk_buff *pPkt;
struct net_device *pDev;
- /*
- * Because we're lazy, we will ASSUME that all SGs coming from INTNET
- * will only contain one single segment.
- */
- if (pSG->cSegsUsed != 1 || pSG->cbTotal != pSG->aSegs[0].cb)
- {
- LogRel(("VBoxNetFlt: Dropped multi-segment(%d) packet coming from internal network.\n", pSG->cSegsUsed));
- return NULL;
- }
+ unsigned fGsoType = 0;
+
if (pSG->cbTotal == 0)
{
LogRel(("VBoxNetFlt: Dropped empty packet coming from internal network.\n"));
return NULL;
}
+ /** @todo We should use fragments mapping the SG buffers with large packets.
+ * 256 bytes seems to be the a threshold used a lot for this. It
+ * requires some nasty work on the intnet side though... */
/*
* Allocate a packet and copy over the data.
- *
*/
pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
pPkt = dev_alloc_skb(pSG->cbTotal + NET_IP_ALIGN);
- if (pPkt)
+ if (RT_UNLIKELY(!pPkt))
+ {
+ Log(("vboxNetFltLinuxSkBufFromSG: Failed to allocate sk_buff(%u).\n", pSG->cbTotal));
+ pSG->pvUserData = NULL;
+ return NULL;
+ }
+ pPkt->dev = pDev;
+ pPkt->ip_summed = CHECKSUM_NONE;
+
+ /* Align IP header on 16-byte boundary: 2 + 14 (ethernet hdr size). */
+ skb_reserve(pPkt, NET_IP_ALIGN);
+
+ /* Copy the segments. */
+ skb_put(pPkt, pSG->cbTotal);
+ IntNetSgRead(pSG, pPkt->data);
+
+#if defined(VBOXNETFLT_WITH_GSO_XMIT_WIRE) || defined(VBOXNETFLT_WITH_GSO_XMIT_HOST)
+ /*
+ * Setup GSO if used by this packet.
+ */
+ switch ((PDMNETWORKGSOTYPE)pSG->GsoCtx.u8Type)
{
- pPkt->dev = pDev;
- /* Align IP header on 16-byte boundary: 2 + 14 (ethernet hdr size). */
- skb_reserve(pPkt, NET_IP_ALIGN);
- skb_put(pPkt, pSG->cbTotal);
- memcpy(pPkt->data, pSG->aSegs[0].pv, pSG->cbTotal);
- /* Set protocol and packet_type fields. */
- pPkt->protocol = eth_type_trans(pPkt, pDev);
- pPkt->ip_summed = CHECKSUM_NONE;
+ default:
+ AssertMsgFailed(("%u (%s)\n", pSG->GsoCtx.u8Type, PDMNetGsoTypeName((PDMNETWORKGSOTYPE)pSG->GsoCtx.u8Type) ));
+ /* fall thru */
+ case PDMNETWORKGSOTYPE_INVALID:
+ fGsoType = 0;
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ fGsoType = SKB_GSO_TCPV4;
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ fGsoType = SKB_GSO_UDP;
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ fGsoType = SKB_GSO_TCPV6;
+ break;
+ }
+ if (fGsoType)
+ {
+ struct skb_shared_info *pShInfo = skb_shinfo(pPkt);
+
+ pShInfo->gso_type = fGsoType | SKB_GSO_DODGY;
+ pShInfo->gso_size = pSG->GsoCtx.cbMaxSeg;
+ pShInfo->gso_segs = PDMNetGsoCalcSegmentCount(&pSG->GsoCtx, pSG->cbTotal);
+
if (fDstWire)
{
- VBOX_SKB_RESET_NETWORK_HDR(pPkt);
- /* Restore ethernet header back. */
- skb_push(pPkt, ETH_HLEN);
- VBOX_SKB_RESET_MAC_HDR(pPkt);
+ Assert(skb_headlen(pPkt) >= pSG->GsoCtx.cbHdrs);
+ pPkt->ip_summed = CHECKSUM_PARTIAL;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ pPkt->csum_start = skb_headroom(pPkt) + pSG->GsoCtx.offHdr2;
+ if (fGsoType & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))
+ pPkt->csum_offset = RT_OFFSETOF(RTNETTCP, th_sum);
+ else
+ pPkt->csum_offset = RT_OFFSETOF(RTNETUDP, uh_sum);
+# else
+ pPkt->h.raw = pPkt->data + pSG->GsoCtx.offHdr2;
+ if (fGsoType & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))
+ pPkt->csum = RT_OFFSETOF(RTNETTCP, th_sum);
+ else
+ pPkt->csum = RT_OFFSETOF(RTNETUDP, uh_sum);
+# endif
+ }
+ else
+ {
+ pPkt->ip_summed = CHECKSUM_UNNECESSARY;
+ pPkt->csum = 0;
+ PDMNetGsoPrepForDirectUse(&pSG->GsoCtx, pPkt->data, pSG->cbTotal, false /*fPayloadChecksum*/);
}
- VBOXNETFLT_SKB_TAG(pPkt) = VBOXNETFLT_CB_TAG(pPkt);
+ }
+#endif /* VBOXNETFLT_WITH_GSO_XMIT_WIRE || VBOXNETFLT_WITH_GSO_XMIT_HOST */
+
+ /*
+ * Finish up the socket buffer.
+ */
+ pPkt->protocol = eth_type_trans(pPkt, pDev);
+ if (fDstWire)
+ {
+ VBOX_SKB_RESET_NETWORK_HDR(pPkt);
- return pPkt;
+ /* Restore ethernet header back. */
+ skb_push(pPkt, ETH_HLEN); /** @todo VLAN: +4 if VLAN? */
+ VBOX_SKB_RESET_MAC_HDR(pPkt);
}
- else
- Log(("vboxNetFltLinuxSkBufFromSG: Failed to allocate sk_buff(%u).\n", pSG->cbTotal));
- pSG->pvUserData = NULL;
+ VBOXNETFLT_SKB_TAG(pPkt) = VBOXNETFLT_CB_TAG(pPkt);
- return NULL;
+ return pPkt;
}
@@ -350,21 +603,18 @@ static struct sk_buff *vboxNetFltLinuxSkBufFromSG(PVBOXNETFLTINS pThis, PINTNETS
* @param cSegs The number of segments allocated for the SG.
* This should match the number in the mbuf exactly!
* @param fSrc The source of the frame.
+ * @param pGso Pointer to the GSO context if it's a GSO
+ * internal network frame. NULL if regular frame.
*/
-DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff *pBuf, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)
+DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff *pBuf, PINTNETSG pSG,
+ unsigned cSegs, uint32_t fSrc, PCPDMNETWORKGSO pGsoCtx)
{
int i;
NOREF(pThis);
Assert(!skb_shinfo(pBuf)->frag_list);
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsAlloc = cSegs;
-
- if (fSrc & INTNETTRUNKDIR_WIRE)
+
+ if (fSrc & INTNETTRUNKDIR_WIRE)
{
/*
* The packet came from wire, ethernet header was removed by device driver.
@@ -372,7 +622,12 @@ DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff *
*/
skb_push(pBuf, ETH_HLEN);
}
- pSG->cbTotal = pBuf->len;
+
+ if (!pGsoCtx)
+ IntNetSgInitTempSegs(pSG, pBuf->len, cSegs, 0 /*cSegsUsed*/);
+ else
+ IntNetSgInitTempSegsGso(pSG, pBuf->len, cSegs, 0 /*cSegsUsed*/, pGsoCtx);
+
#ifdef VBOXNETFLT_SG_SUPPORT
pSG->aSegs[0].cb = skb_headlen(pBuf);
pSG->aSegs[0].pv = pBuf->data;
@@ -386,14 +641,16 @@ DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff *
printk("%p = kmap()\n", pSG->aSegs[i+1].pv);
pSG->aSegs[i+1].Phys = NIL_RTHCPHYS;
}
- pSG->cSegsUsed = ++i;
+ ++i;
+
#else
pSG->aSegs[0].cb = pBuf->len;
pSG->aSegs[0].pv = pBuf->data;
pSG->aSegs[0].Phys = NIL_RTHCPHYS;
- pSG->cSegsUsed = i = 1;
+ i = 1;
#endif
+ pSG->cSegsUsed = i;
#ifdef PADD_RUNT_FRAMES_FROM_HOST
/*
@@ -414,8 +671,10 @@ DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff *
pSG->aSegs[i].cb = 60 - pSG->cbTotal;
pSG->cbTotal = 60;
pSG->cSegsUsed++;
+ Assert(i + 1 <= pSG->cSegsAlloc)
}
#endif
+
Log4(("vboxNetFltLinuxSkBufToSG: allocated=%d, segments=%d frags=%d next=%p frag_list=%p pkt_type=%x fSrc=%x\n",
pSG->cSegsAlloc, pSG->cSegsUsed, skb_shinfo(pBuf)->nr_frags, pBuf->next, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type, fSrc));
for (i = 0; i < pSG->cSegsUsed; i++)
@@ -490,26 +749,38 @@ static int vboxNetFltLinuxPacketHandler(struct sk_buff *pBuf,
return 0;
}
pBuf = pCopy;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
Log3(("vboxNetFltLinuxPacketHandler: skb copy len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x\n",
pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type));
-#else
+# else
Log3(("vboxNetFltLinuxPacketHandler: skb copy len=%u data_len=%u truesize=%u next=%p nr_frags=%u tso_size=%u tso_seqs=%u frag_list=%p pkt_type=%x\n",
pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->tso_size, skb_shinfo(pBuf)->tso_segs, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type));
-#endif
+# endif
}
#endif
+#ifdef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
+ /* Forward it to the internal network. */
+ vboxNetFltLinuxForwardToIntNet(pThis, pBuf);
+#else
/* Add the packet to transmit queue and schedule the bottom half. */
skb_queue_tail(&pThis->u.s.XmitQueue, pBuf);
schedule_work(&pThis->u.s.XmitTask);
Log4(("vboxNetFltLinuxPacketHandler: scheduled work %p for sk_buff %p\n",
&pThis->u.s.XmitTask, pBuf));
+#endif
+
/* It does not really matter what we return, it is ignored by the kernel. */
return 0;
}
-static unsigned vboxNetFltLinuxSGSegments(PVBOXNETFLTINS pThis, struct sk_buff *pBuf)
+/**
+ * Calculate the number of INTNETSEG segments the socket buffer will need.
+ *
+ * @returns Segment count.
+ * @param pBuf The socket buffer.
+ */
+DECLINLINE(unsigned) vboxNetFltLinuxCalcSGSegments(struct sk_buff *pBuf)
{
#ifdef VBOXNETFLT_SG_SUPPORT
unsigned cSegs = 1 + skb_shinfo(pBuf)->nr_frags;
@@ -517,17 +788,18 @@ static unsigned vboxNetFltLinuxSGSegments(PVBOXNETFLTINS pThis, struct sk_buff *
unsigned cSegs = 1;
#endif
#ifdef PADD_RUNT_FRAMES_FROM_HOST
- /*
- * Add a trailer if the frame is too small.
- */
+ /* vboxNetFltLinuxSkBufToSG adds a padding segment if it's a runt. */
if (pBuf->len < 60)
cSegs++;
#endif
return cSegs;
}
-/* WARNING! This function should only be called after vboxNetFltLinuxSkBufToSG()! */
-static void vboxNetFltLinuxDestroySG(struct sk_buff *pBuf, PINTNETSG pSG)
+/**
+ * Destroy the intnet scatter / gather buffer created by
+ * vboxNetFltLinuxSkBufToSG.
+ */
+static void vboxNetFltLinuxDestroySG(PINTNETSG pSG)
{
#ifdef VBOXNETFLT_SG_SUPPORT
int i;
@@ -541,9 +813,10 @@ static void vboxNetFltLinuxDestroySG(struct sk_buff *pBuf, PINTNETSG pSG)
NOREF(pSG);
}
-#ifndef LOG_ENABLED
-#define vboxNetFltDumpPacket(a, b, c, d)
-#else
+#ifdef LOG_ENABLED
+/**
+ * Logging helper.
+ */
static void vboxNetFltDumpPacket(PINTNETSG pSG, bool fEgress, const char *pszWhere, int iIncrement)
{
uint8_t *pInt, *pExt;
@@ -567,23 +840,275 @@ static void vboxNetFltDumpPacket(PINTNETSG pSG, bool fEgress, const char *pszWhe
pSG->cbTotal, iPacketNo));
Log3(("%.*Rhxd\n", pSG->aSegs[0].cb, pSG->aSegs[0].pv));
}
+#else
+# define vboxNetFltDumpPacket(a, b, c, d) do {} while (0)
#endif
+#ifdef VBOXNETFLT_WITH_GSO_RECV
+
+/**
+ * Worker for vboxNetFltLinuxForwardToIntNet that checks if we can forwards a
+ * GSO socket buffer without having to segment it.
+ *
+ * @returns true on success, false if needs segmenting.
+ * @param pThis The net filter instance.
+ * @param pSkb The GSO socket buffer.
+ * @param fSrc The source.
+ * @param pGsoCtx Where to return the GSO context on success.
+ */
+static bool vboxNetFltLinuxCanForwardAsGso(PVBOXNETFLTINS pThis, struct sk_buff *pSkb, uint32_t fSrc,
+ PPDMNETWORKGSO pGsoCtx)
+{
+ PDMNETWORKGSOTYPE enmGsoType;
+ uint16_t uEtherType;
+ unsigned int cbTransport;
+ unsigned int offTransport;
+ unsigned int cbTransportHdr;
+ unsigned uProtocol;
+ union
+ {
+ RTNETIPV4 IPv4;
+ RTNETIPV6 IPv6;
+ RTNETTCP Tcp;
+ uint8_t ab[40];
+ uint16_t au16[40/2];
+ uint32_t au32[40/4];
+ } Buf;
+
+ /*
+ * Check the GSO properties of the socket buffer and make sure it fits.
+ */
+ /** @todo Figure out how to handle SKB_GSO_TCP_ECN! */
+ if (RT_UNLIKELY( skb_shinfo(pSkb)->gso_type & ~(SKB_GSO_UDP | SKB_GSO_DODGY | SKB_GSO_TCPV6 | SKB_GSO_TCPV4) ))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: gso_type=%#x\n", skb_shinfo(pSkb)->gso_type));
+ return false;
+ }
+ if (RT_UNLIKELY( skb_shinfo(pSkb)->gso_size < 1
+ || pSkb->len > VBOX_MAX_GSO_SIZE ))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: gso_size=%#x skb_len=%#x (max=%#x)\n", skb_shinfo(pSkb)->gso_size, pSkb->len, VBOX_MAX_GSO_SIZE));
+ return false;
+ }
+ if (RT_UNLIKELY(fSrc & INTNETTRUNKDIR_WIRE))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: fSrc=wire\n"));
+ return false;
+ }
+
+ /*
+ * skb_gso_segment does the following. Do we need to do it as well?
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ skb_reset_mac_header(pSkb);
+ pSkb->mac_len = pSkb->network_header - pSkb->mac_header;
+#else
+ pSkb->mac.raw = pSkb->data;
+ pSkb->mac_len = pSkb->nh.raw - pSkb->data;
+#endif
+
+ /*
+ * Switch on the ethertype.
+ */
+ uEtherType = pSkb->protocol;
+ if ( uEtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_VLAN)
+ && pSkb->mac_len == sizeof(RTNETETHERHDR) + sizeof(uint32_t))
+ {
+ uint16_t const *puEtherType = skb_header_pointer(pSkb, sizeof(RTNETETHERHDR) + sizeof(uint16_t), sizeof(uint16_t), &Buf);
+ if (puEtherType)
+ uEtherType = *puEtherType;
+ }
+ switch (uEtherType)
+ {
+ case RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4):
+ {
+ unsigned int cbHdr;
+ PCRTNETIPV4 pIPv4 = (PCRTNETIPV4)skb_header_pointer(pSkb, pSkb->mac_len, sizeof(Buf.IPv4), &Buf);
+ if (RT_UNLIKELY(!pIPv4))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: failed to access IPv4 hdr\n"));
+ return false;
+ }
+
+ cbHdr = pIPv4->ip_hl * 4;
+ cbTransport = RT_N2H_U16(pIPv4->ip_len);
+ if (RT_UNLIKELY( cbHdr < RTNETIPV4_MIN_LEN
+ || cbHdr > cbTransport ))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: invalid IPv4 lengths: ip_hl=%u ip_len=%u\n", pIPv4->ip_hl, RT_N2H_U16(pIPv4->ip_len)));
+ return false;
+ }
+ cbTransport -= cbHdr;
+ offTransport = pSkb->mac_len + cbHdr;
+ uProtocol = pIPv4->ip_p;
+ if (uProtocol == RTNETIPV4_PROT_TCP)
+ enmGsoType = PDMNETWORKGSOTYPE_IPV4_TCP;
+ else if (uProtocol == RTNETIPV4_PROT_UDP)
+ enmGsoType = PDMNETWORKGSOTYPE_IPV4_UDP;
+ else /** @todo IPv6: 4to6 tunneling */
+ enmGsoType = PDMNETWORKGSOTYPE_INVALID;
+ break;
+ }
+
+ case RT_H2N_U16_C(RTNET_ETHERTYPE_IPV6):
+ {
+ PCRTNETIPV6 pIPv6 = (PCRTNETIPV6)skb_header_pointer(pSkb, pSkb->mac_len, sizeof(Buf.IPv6), &Buf);
+ if (RT_UNLIKELY(!pIPv6))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: failed to access IPv6 hdr\n"));
+ return false;
+ }
+
+ cbTransport = RT_N2H_U16(pIPv6->ip6_plen);
+ offTransport = pSkb->mac_len + sizeof(RTNETIPV6);
+ uProtocol = pIPv6->ip6_nxt;
+ /** @todo IPv6: Dig our way out of the other headers. */
+ if (uProtocol == RTNETIPV4_PROT_TCP)
+ enmGsoType = PDMNETWORKGSOTYPE_IPV6_TCP;
+ else if (uProtocol == RTNETIPV4_PROT_UDP)
+ enmGsoType = PDMNETWORKGSOTYPE_IPV4_UDP;
+ else
+ enmGsoType = PDMNETWORKGSOTYPE_INVALID;
+ break;
+ }
+
+ default:
+ Log5(("vboxNetFltLinuxCanForwardAsGso: uEtherType=%#x\n", RT_H2N_U16(uEtherType)));
+ return false;
+ }
+
+ if (enmGsoType == PDMNETWORKGSOTYPE_INVALID)
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: Unsupported protocol %d\n", uProtocol));
+ return false;
+ }
+
+ if (RT_UNLIKELY( offTransport + cbTransport <= offTransport
+ || offTransport + cbTransport > pSkb->len
+ || cbTransport < (uProtocol == RTNETIPV4_PROT_TCP ? RTNETTCP_MIN_LEN : RTNETUDP_MIN_LEN)) )
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: Bad transport length; off=%#x + cb=%#x => %#x; skb_len=%#x (%s)\n",
+ offTransport, cbTransport, offTransport + cbTransport, pSkb->len, PDMNetGsoTypeName(enmGsoType) ));
+ return false;
+ }
+
+ /*
+ * Check the TCP/UDP bits.
+ */
+ if (uProtocol == RTNETIPV4_PROT_TCP)
+ {
+ PCRTNETTCP pTcp = (PCRTNETTCP)skb_header_pointer(pSkb, offTransport, sizeof(Buf.Tcp), &Buf);
+ if (RT_UNLIKELY(!pTcp))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: failed to access TCP hdr\n"));
+ return false;
+ }
+
+ cbTransportHdr = pTcp->th_off * 4;
+ if (RT_UNLIKELY( cbTransportHdr < RTNETTCP_MIN_LEN
+ || cbTransportHdr > cbTransport
+ || offTransport + cbTransportHdr >= UINT8_MAX
+ || offTransport + cbTransportHdr >= pSkb->len ))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: No space for TCP header; off=%#x cb=%#x skb_len=%#x\n", offTransport, cbTransportHdr, pSkb->len));
+ return false;
+ }
+
+ }
+ else
+ {
+ Assert(uProtocol == RTNETIPV4_PROT_UDP);
+ cbTransportHdr = sizeof(RTNETUDP);
+ if (RT_UNLIKELY( offTransport + cbTransportHdr >= UINT8_MAX
+ || offTransport + cbTransportHdr >= pSkb->len ))
+ {
+ Log5(("vboxNetFltLinuxCanForwardAsGso: No space for UDP header; off=%#x skb_len=%#x\n", offTransport, pSkb->len));
+ return false;
+ }
+ }
+
+ /*
+ * We're good, init the GSO context.
+ */
+ pGsoCtx->u8Type = enmGsoType;
+ pGsoCtx->cbHdrs = offTransport + cbTransportHdr;
+ pGsoCtx->cbMaxSeg = skb_shinfo(pSkb)->gso_size;
+ pGsoCtx->offHdr1 = pSkb->mac_len;
+ pGsoCtx->offHdr2 = offTransport;
+ pGsoCtx->au8Unused[0] = 0;
+ pGsoCtx->au8Unused[1] = 0;
+
+ return true;
+}
+
+/**
+ * Forward the socket buffer as a GSO internal network frame.
+ *
+ * @returns IPRT status code.
+ * @param pThis The net filter instance.
+ * @param pSkb The GSO socket buffer.
+ * @param fSrc The source.
+ * @param pGsoCtx Where to return the GSO context on success.
+ */
+static int vboxNetFltLinuxForwardAsGso(PVBOXNETFLTINS pThis, struct sk_buff *pSkb, uint32_t fSrc, PCPDMNETWORKGSO pGsoCtx)
+{
+ int rc;
+ unsigned cSegs = vboxNetFltLinuxCalcSGSegments(pSkb);
+ if (RT_LIKELY(cSegs <= MAX_SKB_FRAGS + 1))
+ {
+ PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
+ if (RT_LIKELY(pSG))
+ {
+ vboxNetFltLinuxSkBufToSG(pThis, pSkb, pSG, cSegs, fSrc, pGsoCtx);
+
+ vboxNetFltDumpPacket(pSG, false, (fSrc & INTNETTRUNKDIR_HOST) ? "host" : "wire", 1);
+ pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
+
+ vboxNetFltLinuxDestroySG(pSG);
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ Log(("VBoxNetFlt: Dropping the sk_buff (failure case).\n"));
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ else
+ {
+ Log(("VBoxNetFlt: Bad sk_buff? cSegs=%#x.\n", cSegs));
+ rc = VERR_INTERNAL_ERROR_3;
+ }
+
+ Log4(("VBoxNetFlt: Dropping the sk_buff.\n"));
+ dev_kfree_skb(pSkb);
+ return rc;
+}
+
+#endif /* VBOXNETFLT_WITH_GSO_RECV */
+
+/**
+ * Worker for vboxNetFltLinuxForwardToIntNet.
+ *
+ * @returns VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param pThis The net filter instance.
+ * @param pBuf The socket buffer.
+ * @param fSrc The source.
+ */
static int vboxNetFltLinuxForwardSegment(PVBOXNETFLTINS pThis, struct sk_buff *pBuf, uint32_t fSrc)
{
- int rc;
- unsigned cSegs = vboxNetFltLinuxSGSegments(pThis, pBuf);
- if (cSegs < MAX_SKB_FRAGS)
+ int rc;
+ unsigned cSegs = vboxNetFltLinuxCalcSGSegments(pBuf);
+ if (cSegs <= MAX_SKB_FRAGS + 1)
{
PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
if (RT_LIKELY(pSG))
{
- vboxNetFltLinuxSkBufToSG(pThis, pBuf, pSG, cSegs, fSrc);
+ vboxNetFltLinuxSkBufToSG(pThis, pBuf, pSG, cSegs, fSrc, NULL /*pGsoCtx*/);
vboxNetFltDumpPacket(pSG, false, (fSrc & INTNETTRUNKDIR_HOST) ? "host" : "wire", 1);
pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
- vboxNetFltLinuxDestroySG(pBuf, pSG);
+ vboxNetFltLinuxDestroySG(pSG);
rc = VINF_SUCCESS;
}
else
@@ -603,39 +1128,50 @@ static int vboxNetFltLinuxForwardSegment(PVBOXNETFLTINS pThis, struct sk_buff *p
return rc;
}
+/**
+ *
+ * @param pBuf The socket buffer. This is consumed by this function.
+ */
static void vboxNetFltLinuxForwardToIntNet(PVBOXNETFLTINS pThis, struct sk_buff *pBuf)
{
uint32_t fSrc = pBuf->pkt_type == PACKET_OUTGOING ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE;
- if (VBOX_SKB_IS_GSO(pBuf))
+#ifdef VBOXNETFLT_WITH_GSO
+ if (skb_is_gso(pBuf))
{
- /* Need to segment the packet */
- struct sk_buff *pNext, *pSegment;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
- Log3(("vboxNetFltLinuxForwardToIntNet: skb len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x ip_summed=%d\n",
- pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type, pBuf->ip_summed));
-#endif
-
- pSegment = VBOX_SKB_GSO_SEGMENT(pBuf);
- if (IS_ERR(pSegment))
+ PDMNETWORKGSO GsoCtx;
+ Log3(("vboxNetFltLinuxForwardToIntNet: skb len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x ip_summed=%d\n",
+ pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type, pBuf->ip_summed));
+# ifdef VBOXNETFLT_WITH_GSO_RECV
+ if ( (skb_shinfo(pBuf)->gso_type & (SKB_GSO_UDP | SKB_GSO_TCPV6 | SKB_GSO_TCPV4))
+ && vboxNetFltLinuxCanForwardAsGso(pThis, pBuf, fSrc, &GsoCtx) )
+ vboxNetFltLinuxForwardAsGso(pThis, pBuf, fSrc, &GsoCtx);
+ else
+# endif
{
+ /* Need to segment the packet */
+ struct sk_buff *pNext;
+ struct sk_buff *pSegment = skb_gso_segment(pBuf, 0 /*supported features*/);
+ if (IS_ERR(pSegment))
+ {
+ dev_kfree_skb(pBuf);
+ LogRel(("VBoxNetFlt: Failed to segment a packet (%d).\n", PTR_ERR(pSegment)));
+ return;
+ }
+
+ for (; pSegment; pSegment = pNext)
+ {
+ Log3(("vboxNetFltLinuxForwardToIntNet: segment len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x\n",
+ pSegment->len, pSegment->data_len, pSegment->truesize, pSegment->next, skb_shinfo(pSegment)->nr_frags, skb_shinfo(pSegment)->gso_size, skb_shinfo(pSegment)->gso_segs, skb_shinfo(pSegment)->gso_type, skb_shinfo(pSegment)->frag_list, pSegment->pkt_type));
+ pNext = pSegment->next;
+ pSegment->next = 0;
+ vboxNetFltLinuxForwardSegment(pThis, pSegment, fSrc);
+ }
dev_kfree_skb(pBuf);
- LogRel(("VBoxNetFlt: Failed to segment a packet (%d).\n", PTR_ERR(pBuf)));
- return;
- }
- for (; pSegment; pSegment = pNext)
- {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
- Log3(("vboxNetFltLinuxForwardToIntNet: segment len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x\n",
- pSegment->len, pSegment->data_len, pSegment->truesize, pSegment->next, skb_shinfo(pSegment)->nr_frags, skb_shinfo(pSegment)->gso_size, skb_shinfo(pSegment)->gso_segs, skb_shinfo(pSegment)->gso_type, skb_shinfo(pSegment)->frag_list, pSegment->pkt_type));
-#endif
- pNext = pSegment->next;
- pSegment->next = 0;
- vboxNetFltLinuxForwardSegment(pThis, pSegment, fSrc);
}
- dev_kfree_skb(pBuf);
}
else
+#endif /* VBOXNETFLT_WITH_GSO */
{
if (pBuf->ip_summed == CHECKSUM_PARTIAL && pBuf->pkt_type == PACKET_OUTGOING)
{
@@ -663,43 +1199,116 @@ static void vboxNetFltLinuxForwardToIntNet(PVBOXNETFLTINS pThis, struct sk_buff
}
vboxNetFltLinuxForwardSegment(pThis, pBuf, fSrc);
}
- /*
- * Create a (scatter/)gather list for the sk_buff and feed it to the internal network.
- */
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
+/**
+ * Work queue handler that forwards the socket buffers queued by
+ * vboxNetFltLinuxPacketHandler to the internal network.
+ *
+ * @param pWork The work queue.
+ */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
static void vboxNetFltLinuxXmitTask(struct work_struct *pWork)
-#else
+# else
static void vboxNetFltLinuxXmitTask(void *pWork)
-#endif
+# endif
{
+ PVBOXNETFLTINS pThis = VBOX_FLT_XT_TO_INST(pWork);
struct sk_buff *pBuf;
- bool fActive;
- PVBOXNETFLTINS pThis;
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
Log4(("vboxNetFltLinuxXmitTask: Got work %p.\n", pWork));
- pThis = VBOX_FLT_XT_TO_INST(pWork);
+
/*
* Active? Retain the instance and increment the busy counter.
*/
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
- fActive = ASMAtomicUoReadBool(&pThis->fActive);
- if (fActive)
- vboxNetFltRetain(pThis, true /* fBusy */);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
- if (!fActive)
- return;
+ if (vboxNetFltTryRetainBusyActive(pThis))
+ {
+ while ((pBuf = skb_dequeue(&pThis->u.s.XmitQueue)) != NULL)
+ vboxNetFltLinuxForwardToIntNet(pThis, pBuf);
- while ((pBuf = skb_dequeue(&pThis->u.s.XmitQueue)) != 0)
- vboxNetFltLinuxForwardToIntNet(pThis, pBuf);
+ vboxNetFltRelease(pThis, true /* fBusy */);
+ }
+ else
+ {
+ /** @todo Shouldn't we just drop the packets here? There is little point in
+ * making them accumulate when the VM is paused and it'll only waste
+ * kernel memory anyway... Hmm. maybe wait a short while (2-5 secs)
+ * before start draining the packets (goes for the intnet ring buf
+ * too)? */
+ }
+}
+#endif /* !VBOXNETFLT_LINUX_NO_XMIT_QUEUE */
+
+/**
+ * Reports the GSO capabilites of the hardware NIC.
+ *
+ * @param pThis The net filter instance. The caller hold a
+ * reference to this.
+ */
+static void vboxNetFltLinuxReportNicGsoCapabilities(PVBOXNETFLTINS pThis)
+{
+#ifdef VBOXNETFLT_WITH_GSO_XMIT_WIRE
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ struct net_device *pDev;
+ PINTNETTRUNKSWPORT pSwitchPort;
+ unsigned int fFeatures;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+
+ pSwitchPort = pThis->pSwitchPort; /* this doesn't need to be here, but it doesn't harm. */
+ pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
+ if (pDev)
+ fFeatures = pDev->features;
+ else
+ fFeatures = 0;
+
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
+ if (pThis->pSwitchPort)
+ {
+ /* Set/update the GSO capabilities of the NIC. */
+ uint32_t fGsoCapabilites = 0;
+ if (fFeatures & NETIF_F_TSO)
+ fGsoCapabilites |= RT_BIT_32(PDMNETWORKGSOTYPE_IPV4_TCP);
+ if (fFeatures & NETIF_F_TSO6)
+ fGsoCapabilites |= RT_BIT_32(PDMNETWORKGSOTYPE_IPV6_TCP);
+# if 0 /** @todo GSO: Test UDP offloading (UFO) on linux. */
+ if (fFeatures & NETIF_F_UFO)
+ fGsoCapabilites |= RT_BIT_32(PDMNETWORKGSOTYPE_IPV4_UDP);
+ if (fFeatures & NETIF_F_UFO)
+ fGsoCapabilites |= RT_BIT_32(PDMNETWORKGSOTYPE_IPV6_UDP);
+# endif
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, fGsoCapabilites, INTNETTRUNKDIR_WIRE);
+ }
+
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
+#endif /* VBOXNETFLT_WITH_GSO_XMIT_WIRE */
+}
- vboxNetFltRelease(pThis, true /* fBusy */);
+/**
+ * Helper that determins whether the host (ignoreing us) is operating the
+ * interface in promiscuous mode or not.
+ */
+static bool vboxNetFltLinuxPromiscuous(PVBOXNETFLTINS pThis)
+{
+ bool fRc = false;
+ struct net_device * pDev = vboxNetFltLinuxRetainNetDev(pThis);
+ if (pDev)
+ {
+ fRc = !!(pDev->promiscuity - (ASMAtomicUoReadBool(&pThis->u.s.fPromiscuousSet) & 1));
+ LogFlow(("vboxNetFltPortOsIsPromiscuous: returns %d, pDev->promiscuity=%d, fPromiscuousSet=%d\n",
+ fRc, pDev->promiscuity, pThis->u.s.fPromiscuousSet));
+ vboxNetFltLinuxReleaseNetDev(pThis, pDev);
+ }
+ return fRc;
}
/**
- * Internal worker for vboxNetFltOsInitInstance and vboxNetFltOsMaybeRediscovered.
+ * Internal worker for vboxNetFltLinuxNotifierCallback.
*
* @returns VBox status code.
* @param pThis The instance.
@@ -708,35 +1317,41 @@ static void vboxNetFltLinuxXmitTask(void *pWork)
*/
static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_device *pDev)
{
- struct packet_type *pt;
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-
LogFlow(("vboxNetFltLinuxAttachToInterface: pThis=%p (%s)\n", pThis, pThis->szName));
- if (!pDev)
- {
- Log(("VBoxNetFlt: failed to find device '%s'\n", pThis->szName));
- return VERR_INTNET_FLT_IF_NOT_FOUND;
- }
-
+ /*
+ * Retain and store the device.
+ */
dev_hold(pDev);
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pDev, pDev);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
Log(("vboxNetFltLinuxAttachToInterface: Device %p(%s) retained. ref=%d\n", pDev, pDev->name, atomic_read(&pDev->refcnt)));
Log(("vboxNetFltLinuxAttachToInterface: Got pDev=%p pThis=%p pThis->u.s.pDev=%p\n", pDev, pThis, ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev)));
+
+ /* Get the mac address while we still have a valid net_device reference. */
+ memcpy(&pThis->u.s.MacAddr, pDev->dev_addr, sizeof(pThis->u.s.MacAddr));
+
/*
- * Get the mac address while we still have a valid ifnet reference.
+ * Install a packet filter for this device with a protocol wildcard (ETH_P_ALL).
*/
- memcpy(&pThis->u.s.Mac, pDev->dev_addr, sizeof(pThis->u.s.Mac));
+ pThis->u.s.PacketType.type = __constant_htons(ETH_P_ALL);
+ pThis->u.s.PacketType.dev = pDev;
+ pThis->u.s.PacketType.func = vboxNetFltLinuxPacketHandler;
+ dev_add_pack(&pThis->u.s.PacketType);
- pt = &pThis->u.s.PacketType;
- pt->type = __constant_htons(ETH_P_ALL);
- pt->dev = pDev;
- pt->func = vboxNetFltLinuxPacketHandler;
- dev_add_pack(pt);
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+ vboxNetFltLinuxHookDev(pThis, pDev);
+#endif
+
+ /*
+ * Set indicators that require the spinlock. Be abit paranoid about racing
+ * the device notification handle.
+ */
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
if (pDev)
{
@@ -744,20 +1359,38 @@ static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_dev
ASMAtomicUoWriteBool(&pThis->u.s.fRegistered, true);
pDev = NULL; /* don't dereference it */
}
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
Log(("vboxNetFltLinuxAttachToInterface: this=%p: Packet handler installed.\n", pThis));
- /* Release the interface on failure. */
- if (pDev)
+ /*
+ * If the above succeeded report GSO capabilites, if not undo and
+ * release the device.
+ */
+ if (!pDev)
+ {
+ Assert(pThis->pSwitchPort);
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ vboxNetFltLinuxReportNicGsoCapabilities(pThis);
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, vboxNetFltLinuxPromiscuous(pThis));
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
+ }
+ else
{
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+ vboxNetFltLinuxUnhookDev(pThis, pDev);
+#endif
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pDev, NULL);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
dev_put(pDev);
Log(("vboxNetFltLinuxAttachToInterface: Device %p(%s) released. ref=%d\n", pDev, pDev->name, atomic_read(&pDev->refcnt)));
}
- LogRel(("VBoxNetFlt: attached to '%s' / %.*Rhxs\n", pThis->szName, sizeof(pThis->u.s.Mac), &pThis->u.s.Mac));
+ LogRel(("VBoxNetFlt: attached to '%s' / %.*Rhxs\n", pThis->szName, sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
return VINF_SUCCESS;
}
@@ -767,14 +1400,21 @@ static int vboxNetFltLinuxUnregisterDevice(PVBOXNETFLTINS pThis, struct net_devi
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
Assert(!pThis->fDisconnectedFromHost);
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+
+#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+ vboxNetFltLinuxUnhookDev(pThis, pDev);
+#endif
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
ASMAtomicWriteBool(&pThis->u.s.fRegistered, false);
ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pDev, NULL);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
dev_remove_pack(&pThis->u.s.PacketType);
+#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
skb_queue_purge(&pThis->u.s.XmitQueue);
+#endif
Log(("vboxNetFltLinuxUnregisterDevice: this=%p: Packet handler removed, xmit queue purged.\n", pThis));
Log(("vboxNetFltLinuxUnregisterDevice: Device %p(%s) released. ref=%d\n", pDev, pDev->name, atomic_read(&pDev->refcnt)));
dev_put(pDev);
@@ -785,15 +1425,16 @@ static int vboxNetFltLinuxUnregisterDevice(PVBOXNETFLTINS pThis, struct net_devi
static int vboxNetFltLinuxDeviceIsUp(PVBOXNETFLTINS pThis, struct net_device *pDev)
{
/* Check if we are not suspended and promiscuous mode has not been set. */
- if (ASMAtomicUoReadBool(&pThis->fActive) && !ASMAtomicUoReadBool(&pThis->u.s.fPromiscuousSet))
+ if ( pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE
+ && !ASMAtomicUoReadBool(&pThis->u.s.fPromiscuousSet))
{
/* Note that there is no need for locking as the kernel got hold of the lock already. */
dev_set_promiscuity(pDev, 1);
ASMAtomicWriteBool(&pThis->u.s.fPromiscuousSet, true);
- Log(("vboxNetFltLinuxDeviceIsUp: enabled promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltLinuxDeviceIsUp: enabled promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
}
else
- Log(("vboxNetFltLinuxDeviceIsUp: no need to enable promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltLinuxDeviceIsUp: no need to enable promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
return NOTIFY_OK;
}
@@ -805,24 +1446,18 @@ static int vboxNetFltLinuxDeviceGoingDown(PVBOXNETFLTINS pThis, struct net_devic
/* Note that there is no need for locking as the kernel got hold of the lock already. */
dev_set_promiscuity(pDev, -1);
ASMAtomicWriteBool(&pThis->u.s.fPromiscuousSet, false);
- Log(("vboxNetFltLinuxDeviceGoingDown: disabled promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltLinuxDeviceGoingDown: disabled promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
}
else
- Log(("vboxNetFltLinuxDeviceGoingDown: no need to disable promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltLinuxDeviceGoingDown: no need to disable promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
return NOTIFY_OK;
}
-static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned long ulEventType, void *ptr)
-
+#ifdef LOG_ENABLED
+/** Stringify the NETDEV_XXX constants. */
+static const char *vboxNetFltLinuxGetNetDevEventName(unsigned long ulEventType)
{
- int rc = NOTIFY_OK;
-#ifdef DEBUG
- char *pszEvent = "<unknown>";
-#endif
- struct net_device *pDev = (struct net_device *)ptr;
- PVBOXNETFLTINS pThis = VBOX_FLT_NB_TO_INST(self);
-
-#ifdef DEBUG
+ const char *pszEvent = "NETDRV_<unknown>";
switch (ulEventType)
{
case NETDEV_REGISTER: pszEvent = "NETDEV_REGISTER"; break;
@@ -835,33 +1470,64 @@ static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned
case NETDEV_CHANGEMTU: pszEvent = "NETDEV_CHANGEMTU"; break;
case NETDEV_CHANGEADDR: pszEvent = "NETDEV_CHANGEADDR"; break;
case NETDEV_GOING_DOWN: pszEvent = "NETDEV_GOING_DOWN"; break;
+# ifdef NETDEV_FEAT_CHANGE
+ case NETDEV_FEAT_CHANGE: pszEvent = "NETDEV_FEAT_CHANGE"; break;
+# endif
}
+ return pszEvent;
+}
+#endif /* LOG_ENABLED */
+
+/**
+ * Callback for listening to netdevice events.
+ *
+ * This works the rediscovery, clean up on unregistration, promiscuity on
+ * up/down, and GSO feature changes from ethtool.
+ *
+ * @returns NOTIFY_OK
+ * @param self Pointer to our notifier registration block.
+ * @param ulEventType The event.
+ * @param ptr Event specific, but it is usually the device it
+ * relates to.
+ */
+static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned long ulEventType, void *ptr)
+
+{
+ PVBOXNETFLTINS pThis = VBOX_FLT_NB_TO_INST(self);
+ struct net_device *pDev = (struct net_device *)ptr;
+ int rc = NOTIFY_OK;
+
Log(("VBoxNetFlt: got event %s(0x%lx) on %s, pDev=%p pThis=%p pThis->u.s.pDev=%p\n",
- pszEvent, ulEventType, pDev->name, pDev, pThis, ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev)));
-#endif
- if (ulEventType == NETDEV_REGISTER && !strcmp(pDev->name, pThis->szName))
+ vboxNetFltLinuxGetNetDevEventName(ulEventType), ulEventType, pDev->name, pDev, pThis, ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev)));
+ if ( ulEventType == NETDEV_REGISTER
+ && !strcmp(pDev->name, pThis->szName))
{
vboxNetFltLinuxAttachToInterface(pThis, pDev);
}
else
{
pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
- if (pDev != ptr)
- return NOTIFY_OK;
- rc = NOTIFY_OK;
- switch (ulEventType)
+ if (pDev == ptr)
{
- case NETDEV_UNREGISTER:
- rc = vboxNetFltLinuxUnregisterDevice(pThis, pDev);
- break;
- case NETDEV_UP:
- rc = vboxNetFltLinuxDeviceIsUp(pThis, pDev);
- break;
- case NETDEV_GOING_DOWN:
- rc = vboxNetFltLinuxDeviceGoingDown(pThis, pDev);
- break;
- case NETDEV_CHANGENAME:
- break;
+ switch (ulEventType)
+ {
+ case NETDEV_UNREGISTER:
+ rc = vboxNetFltLinuxUnregisterDevice(pThis, pDev);
+ break;
+ case NETDEV_UP:
+ rc = vboxNetFltLinuxDeviceIsUp(pThis, pDev);
+ break;
+ case NETDEV_GOING_DOWN:
+ rc = vboxNetFltLinuxDeviceGoingDown(pThis, pDev);
+ break;
+ case NETDEV_CHANGENAME:
+ break;
+#ifdef NETDEV_FEAT_CHANGE
+ case NETDEV_FEAT_CHANGE:
+ vboxNetFltLinuxReportNicGsoCapabilities(pThis);
+ break;
+#endif
+ }
}
}
@@ -929,36 +1595,6 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
}
-bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
-{
- bool fRc = false;
- struct net_device * pDev = vboxNetFltLinuxRetainNetDev(pThis);
- if (pDev)
- {
- fRc = !!(pDev->promiscuity - (ASMAtomicUoReadBool(&pThis->u.s.fPromiscuousSet) & 1));
- LogFlow(("vboxNetFltPortOsIsPromiscuous: returns %d, pDev->promiscuity=%d, fPromiscuousSet=%d\n",
- fRc, pDev->promiscuity, pThis->u.s.fPromiscuousSet));
- vboxNetFltLinuxReleaseNetDev(pThis, pDev);
- }
- return fRc;
-}
-
-
-void vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
-{
- *pMac = pThis->u.s.Mac;
-}
-
-
-bool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
-{
- /* ASSUMES that the MAC address never changes. */
- return pThis->u.s.Mac.au16[0] == pMac->au16[0]
- && pThis->u.s.Mac.au16[1] == pMac->au16[1]
- && pThis->u.s.Mac.au16[2] == pMac->au16[2];
-}
-
-
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
{
struct net_device * pDev;
@@ -981,7 +1617,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
*/
#ifdef LOG_ENABLED
u_int16_t fIf;
- unsigned const cPromiscBefore = VBOX_GET_PCOUNT(pDev);
+ unsigned const cPromiscBefore = pDev->promiscuity;
#endif
if (fActive)
{
@@ -991,7 +1627,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
dev_set_promiscuity(pDev, 1);
rtnl_unlock();
pThis->u.s.fPromiscuousSet = true;
- Log(("vboxNetFltPortOsSetActive: enabled promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltPortOsSetActive: enabled promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
}
else
{
@@ -1000,13 +1636,13 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
rtnl_lock();
dev_set_promiscuity(pDev, -1);
rtnl_unlock();
- Log(("vboxNetFltPortOsSetActive: disabled promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pDev)));
+ Log(("vboxNetFltPortOsSetActive: disabled promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
}
pThis->u.s.fPromiscuousSet = false;
#ifdef LOG_ENABLED
fIf = dev_get_flags(pDev);
- Log(("VBoxNetFlt: fIf=%#x; %d->%d\n", fIf, cPromiscBefore, VBOX_GET_PCOUNT(pDev)));
+ Log(("VBoxNetFlt: fIf=%#x; %d->%d\n", fIf, cPromiscBefore, pDev->promiscuity));
#endif
}
@@ -1024,25 +1660,55 @@ int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
int vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
{
- /* Nothing to do here. */
+ /*
+ * Report the GSO capabilities of the host and device (if connected).
+ * Note! No need to mark ourselves busy here.
+ */
+ /** @todo duplicate work here now? Attach */
+#if defined(VBOXNETFLT_WITH_GSO_XMIT_HOST)
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort,
+ 0
+ | RT_BIT_32(PDMNETWORKGSOTYPE_IPV4_TCP)
+ | RT_BIT_32(PDMNETWORKGSOTYPE_IPV6_TCP)
+# if 0 /** @todo GSO: Test UDP offloading (UFO) on linux. */
+ | RT_BIT_32(PDMNETWORKGSOTYPE_IPV4_UDP)
+ | RT_BIT_32(PDMNETWORKGSOTYPE_IPV6_UDP)
+# endif
+ , INTNETTRUNKDIR_HOST);
+
+#endif
+ vboxNetFltLinuxReportNicGsoCapabilities(pThis);
+
return VINF_SUCCESS;
}
void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
{
- struct net_device *pDev;
- bool fRegistered;
- RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
+ struct net_device *pDev;
+ bool fRegistered;
+ RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
+ vboxNetFltLinuxUnhookDev(pThis, NULL);
+#endif
+
+ /** @todo This code may race vboxNetFltLinuxUnregisterDevice (very very
+ * unlikely, but none the less). Since it doesn't actually update the
+ * state (just reads it), it is likely to panic in some interesting
+ * ways. */
+
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
fRegistered = ASMAtomicUoReadBool(&pThis->u.s.fRegistered);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
+
if (fRegistered)
{
dev_remove_pack(&pThis->u.s.PacketType);
+#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
skb_queue_purge(&pThis->u.s.XmitQueue);
+#endif
Log(("vboxNetFltOsDeleteInstance: this=%p: Packet handler removed, xmit queue purged.\n", pThis));
Log(("vboxNetFltOsDeleteInstance: Device %p(%s) released. ref=%d\n", pDev, pDev->name, atomic_read(&pDev->refcnt)));
dev_put(pDev);
@@ -1086,11 +1752,13 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
pThis->u.s.fRegistered = false;
pThis->u.s.fPromiscuousSet = false;
memset(&pThis->u.s.PacketType, 0, sizeof(pThis->u.s.PacketType));
+#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
skb_queue_head_init(&pThis->u.s.XmitQueue);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
INIT_WORK(&pThis->u.s.XmitTask, vboxNetFltLinuxXmitTask);
-#else
+# else
INIT_WORK(&pThis->u.s.XmitTask, vboxNetFltLinuxXmitTask, &pThis->u.s.XmitTask);
+# endif
#endif
return VINF_SUCCESS;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
index 7cf0de61a..cd2bef091 100755..100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt
@@ -1,11 +1,11 @@
#!/bin/sh
-# $Id: $
+# $Id: files_vboxnetflt 29250 2010-05-09 17:53:58Z vboxsync $
## @file
# Shared file between Makefile.kmk and export_modules
#
#
-# Copyright (C) 2007 Sun Microsystems, Inc.
+# Copyright (C) 2007-2010 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -15,15 +15,13 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \
${PATH_ROOT}/include/iprt/alloca.h=>include/iprt/alloca.h \
${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \
+ ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \
+ ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \
${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \
${PATH_ROOT}/include/iprt/avl.h=>include/iprt/avl.h \
${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \
@@ -36,6 +34,7 @@ VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \
${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \
${PATH_ROOT}/include/iprt/mp.h=>include/iprt/mp.h \
+ ${PATH_ROOT}/include/iprt/net.h=>include/iprt/net.h \
${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \
${PATH_ROOT}/include/iprt/power.h=>include/iprt/power.h \
${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \
@@ -54,6 +53,9 @@ VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
${PATH_ROOT}/include/VBox/intnet.h=>include/VBox/intnet.h \
+ ${PATH_ROOT}/include/VBox/intnetinline.h=>include/VBox/intnetinline.h \
+ ${PATH_ROOT}/include/VBox/pdmnetinline.h=>include/VBox/pdmnetinline.h \
+ ${PATH_ROOT}/include/VBox/param.h=>include/VBox/param.h \
${PATH_ROOT}/include/VBox/stam.h=>include/VBox/stam.h \
${PATH_ROOT}/include/VBox/sup.h=>include/VBox/sup.h \
${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
@@ -64,17 +66,15 @@ VBOX_VBOXNETFLT_SOURCES=" \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClient.c=>SUPR0IdcClient.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientComponent.c=>SUPR0IdcClientComponent.c \
${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPR0IdcClientInternal.h=>SUPR0IdcClientInternal.h \
- ${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c=>SUPR0IdcClient-linux.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/Support/linux/SUPR0IdcClient-linux.c=>linux/SUPR0IdcClient-linux.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/divdi3.c=>math/gcc/divdi3.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/moddi3.c=>math/gcc/moddi3.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/qdivrem.c=>math/gcc/qdivrem.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/quad.h=>math/gcc/quad.h \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivdi3.c=>math/gcc/udivdi3.c \
${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/umoddi3.c=>math/gcc/umoddi3.c \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/initterm.h=>include/internal/initterm.h \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/iprt.h=>include/internal/iprt.h \
- ${PATH_ROOT}/src/VBox/Runtime/include/internal/magics.h=>include/internal/magics.h \
${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
${PATH_OUT}/version-generated.h=>version-generated.h \
+ ${PATH_OUT}/product-generated.h=>product-generated.h \
"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
index ae86a5130..41a59ce57 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-solaris.c $ */
+/* $Id: VBoxNetFlt-solaris.c 28961 2010-05-03 08:22:37Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code.
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*******************************************************************************
@@ -25,7 +21,7 @@
#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
#include <VBox/log.h>
#include <VBox/err.h>
-#include <VBox/cdefs.h>
+#include <VBox/intnetinline.h>
#include <VBox/version.h>
#include <iprt/string.h>
#include <iprt/initterm.h>
@@ -97,10 +93,12 @@
#define DEVICE_DESC_MOD "VirtualBox NetMod"
#if defined(DEBUG_ramshankar)
+# undef LogFlowFunc
+# define LogFlowFunc LogRel
# undef Log
-# define Log LogRel
+# define Log LogRel
# undef LogFlow
-# define LogFlow LogRel
+# define LogFlow LogRel
#endif
#ifdef VBOXNETFLT_SOLARIS_IPV6_POLLING
@@ -274,10 +272,12 @@ static struct modlstrmod g_VBoxNetFltSolarisModule =
*/
static struct modlinkage g_VBoxNetFltSolarisModLinkage =
{
- MODREV_1, /* loadable module system revision */
- &g_VBoxNetFltSolarisDriver, /* streams driver framework */
- &g_VBoxNetFltSolarisModule, /* streams module framework */
- NULL /* terminate array of linkage structures */
+ MODREV_1, /* loadable module system revision */
+ {
+ &g_VBoxNetFltSolarisDriver, /* streams driver framework */
+ &g_VBoxNetFltSolarisModule, /* streams module framework */
+ NULL /* terminate array of linkage structures */
+ }
};
struct vboxnetflt_state_t;
@@ -412,7 +412,7 @@ static int g_VBoxNetFltSolarisPollInterval = -1;
*/
int _init(void)
{
- LogFlow((DEVICE_NAME ":_init\n"));
+ LogFlowFunc((DEVICE_NAME ":_init\n"));
/*
* Prevent module autounloading.
@@ -483,7 +483,7 @@ int _init(void)
int _fini(void)
{
int rc;
- LogFlow((DEVICE_NAME ":_fini\n"));
+ LogFlowFunc((DEVICE_NAME ":_fini\n"));
/*
* Undo the work done during start (in reverse order).
@@ -519,7 +519,7 @@ int _fini(void)
int _info(struct modinfo *pModInfo)
{
- LogFlow((DEVICE_NAME ":_info\n"));
+ LogFlowFunc((DEVICE_NAME ":_info\n"));
int rc = mod_info(&g_VBoxNetFltSolarisModLinkage, pModInfo);
@@ -538,7 +538,7 @@ int _info(struct modinfo *pModInfo)
*/
static int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
switch (enmCmd)
{
@@ -578,8 +578,11 @@ static int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
/* Nothing to do here... */
return DDI_SUCCESS;
}
+
+ /* case DDI_PM_RESUME: */
+ default:
+ return DDI_FAILURE;
}
- return DDI_FAILURE;
}
@@ -593,13 +596,12 @@ static int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
*/
static int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
{
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
switch (enmCmd)
{
case DDI_DETACH:
{
- int instance = ddi_get_instance(pDip);
ddi_remove_minor_node(pDip, NULL);
return DDI_SUCCESS;
}
@@ -609,8 +611,12 @@ static int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
/* Nothing to do here... */
return DDI_SUCCESS;
}
+
+ /* case DDI_PM_SUSPEND: */
+ /* case DDI_HOT_PLUG_DETACH: */
+ default:
+ return DDI_FAILURE;
}
- return DDI_FAILURE;
}
@@ -626,7 +632,7 @@ static int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
*/
static int VBoxNetFltSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppResult)
{
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisGetInfo pDip=%p enmCmd=%d pArg=%p instance=%d\n", pDip, enmCmd,
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisGetInfo pDip=%p enmCmd=%d pArg=%p instance=%d\n", pDip, enmCmd,
getminor((dev_t)pvArg)));
switch (enmCmd)
@@ -664,7 +670,7 @@ static int VBoxNetFltSolarisModOpen(queue_t *pQueue, dev_t *pDev, int fOpenMode,
{
Assert(pQueue);
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModOpen pQueue=%p pDev=%p fOpenMode=%d fStreamMode=%d\n", pQueue, pDev,
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisModOpen pQueue=%p pDev=%p fOpenMode=%d fStreamMode=%d\n", pQueue, pDev,
fOpenMode, fStreamMode));
/*
@@ -865,7 +871,7 @@ static int VBoxNetFltSolarisModClose(queue_t *pQueue, int fOpenMode, cred_t *pCr
{
Assert(pQueue);
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModClose pQueue=%p fOpenMode=%d\n", pQueue, fOpenMode));
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisModClose pQueue=%p fOpenMode=%d\n", pQueue, fOpenMode));
vboxnetflt_stream_t *pStream = NULL;
vboxnetflt_stream_t **ppPrevStream = NULL;
@@ -978,7 +984,7 @@ static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg)
if (!pMsg)
return 0;
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut pQueue=%p pMsg=%p\n", pQueue, pMsg));
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisModReadPut pQueue=%p pMsg=%p\n", pQueue, pMsg));
bool fSendUpstream = true;
vboxnetflt_stream_t *pStream = pQueue->q_ptr;
@@ -1001,10 +1007,10 @@ static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg)
* the promiscuous OFF acknowledgement case).
*/
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
- const bool fActive = ASMAtomicUoReadBool(&pThis->fActive);
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
+ const bool fActive = pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE;
vboxNetFltRetain(pThis, true /* fBusy */);
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
vboxnetflt_promisc_stream_t *pPromiscStream = (vboxnetflt_promisc_stream_t *)pStream;
@@ -1058,31 +1064,23 @@ static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg)
break;
}
- bcopy(pMsg->b_rptr + cOffset, &pThis->u.s.Mac, sizeof(pThis->u.s.Mac));
+ bcopy(pMsg->b_rptr + cOffset, &pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_NOTE_PHYS_ADDR. New Mac=%.*Rhxs\n",
- sizeof(pThis->u.s.Mac), &pThis->u.s.Mac));
+ sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
break;
}
case DL_NOTE_LINK_UP:
{
- const bool fDisconnected = ASMAtomicUoReadBool(&pThis->fActive);
- if (fDisconnected)
- {
- ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, false);
+ if (ASMAtomicXchgBool(&pThis->fDisconnectedFromHost, false))
LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_NOTE_LINK_UP.\n"));
- }
break;
}
case DL_NOTE_LINK_DOWN:
{
- const bool fDisconnected = ASMAtomicUoReadBool(&pThis->fActive);
- if (!fDisconnected)
- {
- ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
+ if (!ASMAtomicXchgBool(&pThis->fDisconnectedFromHost, true))
LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_NOTE_LINK_DOWN.\n"));
- }
break;
}
}
@@ -1209,7 +1207,7 @@ static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg)
*/
static int VBoxNetFltSolarisModWritePut(queue_t *pQueue, mblk_t *pMsg)
{
- LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut pQueue=%p pMsg=%p\n", pQueue, pMsg));
+ LogFlowFunc((DEVICE_NAME ":VBoxNetFltSolarisModWritePut pQueue=%p pMsg=%p\n", pQueue, pMsg));
putnext(pQueue, pMsg);
return 0;
@@ -1224,7 +1222,7 @@ static int VBoxNetFltSolarisModWritePut(queue_t *pQueue, mblk_t *pMsg)
*/
static int vboxNetFltSolarisSetRawMode(vboxnetflt_promisc_stream_t *pPromiscStream)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisSetRawMode pPromiscStream=%p\n", pPromiscStream));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisSetRawMode pPromiscStream=%p\n", pPromiscStream));
mblk_t *pRawMsg = NULL;
pRawMsg = mkiocb(DLIOCRAW);
@@ -1253,7 +1251,7 @@ static int vboxNetFltSolarisSetRawMode(vboxnetflt_promisc_stream_t *pPromiscStre
*/
static int vboxNetFltSolarisSetFastMode(queue_t *pQueue)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisSetFastMode pQueue=%p\n", pQueue));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisSetFastMode pQueue=%p\n", pQueue));
mblk_t *pFastMsg = mkiocb(DL_IOC_HDR_INFO);
if (RT_UNLIKELY(!pFastMsg))
@@ -1302,7 +1300,7 @@ static int vboxNetFltSolarisSetFastMode(queue_t *pQueue)
*/
static int vboxNetFltSolarisPromiscReq(queue_t *pQueue, bool fPromisc)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisPromiscReq pQueue=%p fPromisc=%d\n", pQueue, fPromisc));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisPromiscReq pQueue=%p fPromisc=%d\n", pQueue, fPromisc));
t_uscalar_t Cmd;
size_t cbReq = 0;
@@ -1354,7 +1352,7 @@ static int vboxNetFltSolarisPromiscReq(queue_t *pQueue, bool fPromisc)
*/
static int vboxNetFltSolarisPhysAddrReq(queue_t *pQueue)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisPhysAddrReq pQueue=%p\n", pQueue));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisPhysAddrReq pQueue=%p\n", pQueue));
t_uscalar_t Cmd = DL_PHYS_ADDR_REQ;
size_t cbReq = DL_PHYS_ADDR_REQ_SIZE;
@@ -1379,16 +1377,24 @@ static int vboxNetFltSolarisPhysAddrReq(queue_t *pQueue)
*/
static void vboxNetFltSolarisCachePhysAddr(PVBOXNETFLTINS pThis, mblk_t *pMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisCachePhysAddr pThis=%p pMsg=%p\n", pThis, pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisCachePhysAddr pThis=%p pMsg=%p\n", pThis, pMsg));
AssertCompile(sizeof(RTMAC) == ETHERADDRL);
dl_phys_addr_ack_t *pPhysAddrAck = (dl_phys_addr_ack_t *)pMsg->b_rptr;
- if (pPhysAddrAck->dl_addr_length == sizeof(pThis->u.s.Mac))
+ if (pPhysAddrAck->dl_addr_length == sizeof(pThis->u.s.MacAddr))
{
- bcopy(pMsg->b_rptr + pPhysAddrAck->dl_addr_offset, &pThis->u.s.Mac, sizeof(pThis->u.s.Mac));
+ bcopy(pMsg->b_rptr + pPhysAddrAck->dl_addr_offset, &pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
+
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisCachePhysAddr: DL_PHYS_ADDR_ACK: Mac=%.*Rhxs\n",
+ sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisCachePhysAddr: DL_PHYS_ADDR_ACK: Mac=%.*Rhxs\n", sizeof(pThis->u.s.Mac),
- &pThis->u.s.Mac));
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ Assert(pThis->pSwitchPort);
+ if (pThis->pSwitchPort)
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
}
else
{
@@ -1407,7 +1413,7 @@ static void vboxNetFltSolarisCachePhysAddr(PVBOXNETFLTINS pThis, mblk_t *pMsg)
*/
static int vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisBindReq SAP=%d\n", SAP));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisBindReq SAP=%d\n", SAP));
mblk_t *pBindMsg = mexchange(NULL, NULL, DL_BIND_REQ_SIZE, M_PROTO, DL_BIND_REQ);
if (RT_UNLIKELY(!pBindMsg))
@@ -1433,7 +1439,7 @@ static int vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP)
*/
static int vboxNetFltSolarisNotifyReq(queue_t *pQueue)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisNotifyReq\n"));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisNotifyReq\n"));
mblk_t *pNotifyMsg = mexchange(NULL, NULL, DL_NOTIFY_REQ_SIZE, M_PROTO, DL_NOTIFY_REQ);
if (RT_UNLIKELY(!pNotifyMsg))
@@ -1668,7 +1674,7 @@ static int vboxNetFltSolarisMuxIdToFd(vnode_t *pVNode, int MuxId, int *pFd)
*/
static int vboxNetFltSolarisRelinkIp4(vnode_t *pVNode, struct lifreq *pInterface, int IpMuxFd, int ArpMuxFd)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisRelinkIp4: pVNode=%p pInterface=%p IpMuxFd=%d ArpMuxFd=%d\n", pVNode,
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisRelinkIp4: pVNode=%p pInterface=%p IpMuxFd=%d ArpMuxFd=%d\n", pVNode,
pInterface, IpMuxFd, ArpMuxFd));
int NewIpMuxId;
@@ -1703,7 +1709,7 @@ static int vboxNetFltSolarisRelinkIp4(vnode_t *pVNode, struct lifreq *pInterface
*/
static int vboxNetFltSolarisRelinkIp6(vnode_t *pVNode, struct lifreq *pInterface, int Ip6MuxFd)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisRelinkIp6: pVNode=%p pInterface=%p Ip6MuxFd=%d\n", pVNode, pInterface, Ip6MuxFd));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisRelinkIp6: pVNode=%p pInterface=%p Ip6MuxFd=%d\n", pVNode, pInterface, Ip6MuxFd));
int NewIp6MuxId;
int rc = strioctl(pVNode, I_PLINK, (intptr_t)Ip6MuxFd, 0, K_TO_K, kcred, &NewIp6MuxId);
@@ -1732,7 +1738,7 @@ static int vboxNetFltSolarisRelinkIp6(vnode_t *pVNode, struct lifreq *pInterface
*/
static int vboxNetFltSolarisDetermineModPos(bool fAttach, vnode_t *pVNode, int *pModPos)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisDetermineModPos: fAttach=%d pVNode=%p pModPos=%p\n", fAttach, pVNode, pModPos));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisDetermineModPos: fAttach=%d pVNode=%p pModPos=%p\n", fAttach, pVNode, pModPos));
int cMod;
int rc = strioctl(pVNode, I_LIST, (intptr_t)NULL, 0, K_TO_K, kcred, &cMod);
@@ -1980,7 +1986,7 @@ static int vboxNetFltSolarisOpenStream(PVBOXNETFLTINS pThis)
*/
static void vboxNetFltSolarisCloseStream(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisCloseStream pThis=%p\n"));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisCloseStream pThis=%p\n"));
if (pThis->u.s.hIface)
{
@@ -1999,7 +2005,7 @@ static void vboxNetFltSolarisCloseStream(PVBOXNETFLTINS pThis)
*/
static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachIp4 pThis=%p fAttach=%d\n", pThis, fAttach));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisAttachIp4 pThis=%p fAttach=%d\n", pThis, fAttach));
/*
* Statuatory Warning: Hackish code ahead.
@@ -2084,7 +2090,6 @@ static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach)
* We need to I_PUNLINK on these multiplexor IDs before we can start
* operating on the lower stream as insertions are direct operations on the lower stream.
*/
- int ret;
rc = strioctl(pUdp4VNode, I_PUNLINK, (intptr_t)Ip4Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret);
rc2 = strioctl(pUdp4VNode, I_PUNLINK, (intptr_t)Ip4Interface.lifr_arp_muxid, 0, K_TO_K, kcred, &ret);
if ( !rc
@@ -2267,7 +2272,7 @@ static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach)
*/
static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachIp6 pThis=%p fAttach=%d\n", pThis, fAttach));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisAttachIp6 pThis=%p fAttach=%d\n", pThis, fAttach));
/*
* Statuatory Warning: Hackish code ahead.
@@ -2284,11 +2289,9 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
StrMod.pos = -1; /* this is filled in later. */
int rc;
- int rc2;
int ret;
ldi_ident_t DeviceIdent = ldi_ident_from_anon();
ldi_handle_t Ip6DevHandle;
- ldi_handle_t Udp6DevHandle;
/*
* Open the IPv6 stream as a layered devices.
@@ -2335,7 +2338,6 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
* We need to I_PUNLINK on these multiplexor IDs before we can start
* operating on the lower stream as insertions are direct operations on the lower stream.
*/
- int ret;
rc = strioctl(pUdp6VNode, I_PUNLINK, (intptr_t)Ip6Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret);
if (!rc)
{
@@ -2422,7 +2424,7 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
}
}
else
- LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to find position. rc=%d rc2=%d\n", rc, rc2));
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to find position. rc=%d\n", rc));
releasef(Ip6MuxFd);
}
@@ -2430,10 +2432,10 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get vnode from MuxFd.\n"));
}
else
- LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2));
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to unlink upper stream rc=%d.\n", rc));
}
else
- LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get MuxFd from MuxId. rc=%d rc2=%d\n", rc, rc2));
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get MuxFd from MuxId. rc=%d\n", rc));
}
else
LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get Mux Ids. rc=%d\n", rc));
@@ -2467,7 +2469,7 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
*/
static void vboxNetFltSolarispIp6Timer(PRTTIMER pTimer, void *pvData, uint64_t iTick)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarispIp6Timer pTimer=%p pvData=%p\n", pTimer, pvData));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarispIp6Timer pTimer=%p pvData=%p\n", pTimer, pvData));
PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvData;
if ( RT_LIKELY(pThis)
@@ -2506,7 +2508,7 @@ static void vboxNetFltSolarispIp6Timer(PRTTIMER pTimer, void *pvData, uint64_t i
*/
static int vboxNetFltSolarisSetupIp6Polling(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisSetupIp6Polling pThis=%p\n", pThis));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisSetupIp6Polling pThis=%p\n", pThis));
int rc = VERR_GENERAL_FAILURE;
vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvPromiscStream);
@@ -2558,7 +2560,7 @@ static int vboxNetFltSolarisSetupIp6Polling(PVBOXNETFLTINS pThis)
*/
static int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisDetachFromInterface pThis=%p\n", pThis));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisDetachFromInterface pThis=%p\n", pThis));
ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
vboxNetFltSolarisCloseStream(pThis);
@@ -2591,8 +2593,13 @@ static int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis)
*/
static int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface pThis=%p\n", pThis));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface pThis=%p\n", pThis));
+ /*
+ * Since this is asynchronous streams injection, let the attach succeed before we can start
+ * processing the stream.
+ */
+ ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
int rc = vboxNetFltSolarisOpenStream(pThis);
if (RT_SUCCESS(rc))
{
@@ -2625,9 +2632,24 @@ static int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis)
#endif
/*
+ * Report promiscuousness and capabilities.
+ */
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ Assert(pThis->pSwitchPort);
+ /** @todo There is no easy way of obtaining the global host side promiscuous
+ * counter. Currently we just return false. */
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false);
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
+
+ /*
* Ipv4 is successful, and maybe Ipv6, we're ready for transfers.
*/
ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, false);
+
return VINF_SUCCESS;
}
@@ -2649,7 +2671,7 @@ static int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis)
*/
static mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG pThis=%p pSG=%p\n", pThis, pSG));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG pThis=%p pSG=%p\n", pThis, pSG));
mblk_t *pMsg = allocb(pSG->cbTotal, BPRI_MED);
if (RT_UNLIKELY(!pMsg))
@@ -2713,19 +2735,12 @@ static unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pM
*/
static int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pThis=%p pMsg=%p pSG=%p cSegs=%d\n", pThis, pMsg, pSG, cSegs));
-
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->cbTotal = 0;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsAlloc = cSegs;
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pThis=%p pMsg=%p pSG=%p cSegs=%d\n", pThis, pMsg, pSG, cSegs));
/*
- * Convert the message block to segments.
+ * Convert the message block to segments. Work INTNETSG::cbTotal.
*/
+ IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
mblk_t *pCur = pMsg;
unsigned iSeg = 0;
while (pCur)
@@ -2755,6 +2770,7 @@ static int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNET
pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal;
pSG->cbTotal = 60;
pSG->cSegsUsed++;
+ Assert(iSeg + 1 < cSegs);
}
#endif
@@ -2776,7 +2792,7 @@ static int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNET
*/
static int vboxNetFltSolarisRawToUnitData(mblk_t *pMsg, mblk_t **ppDlpiMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisRawToUnitData pMsg=%p\n", pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisRawToUnitData pMsg=%p\n", pMsg));
if (DB_TYPE(pMsg) != M_DATA)
return VERR_NO_MEMORY;
@@ -2828,7 +2844,7 @@ static int vboxNetFltSolarisRawToUnitData(mblk_t *pMsg, mblk_t **ppDlpiMsg)
*/
static int vboxNetFltSolarisUnitDataToRaw(PVBOXNETFLTINS pThis, mblk_t *pMsg, mblk_t **ppRawMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisUnitDataToRaw pMsg=%p\n", pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisUnitDataToRaw pMsg=%p\n", pMsg));
if ( !pMsg->b_cont
|| DB_TYPE(pMsg) != M_PROTO)
@@ -2868,7 +2884,7 @@ static int vboxNetFltSolarisUnitDataToRaw(PVBOXNETFLTINS pThis, mblk_t *pMsg, mb
dl_unitdata_req_t *pDlpiMsg = (dl_unitdata_req_t *)pMsg->b_rptr;
bcopy(pMsg->b_rptr + pDlpiMsg->dl_dest_addr_offset, &EthHdr.DstMac, sizeof(EthHdr.DstMac));
- bcopy(&pThis->u.s.Mac, &EthHdr.SrcMac, sizeof(EthHdr.SrcMac));
+ bcopy(&pThis->u.s.MacAddr, &EthHdr.SrcMac, sizeof(EthHdr.SrcMac));
vboxnetflt_dladdr_t *pDLSapAddr = (vboxnetflt_dladdr_t *)(pMsg->b_rptr + pDlpiMsg->dl_dest_addr_offset);
EthHdr.EtherType = RT_H2BE_U16(pDLSapAddr->SAP);
@@ -2947,7 +2963,7 @@ static int vboxNetFltSolarisQueueLoopback(PVBOXNETFLTINS pThis, vboxnetflt_promi
Assert(DB_TYPE(pMsg) == M_DATA);
Assert(pPromiscStream);
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisQueueLoopback pThis=%p pPromiscStream=%p pMsg=%p\n", pThis, pPromiscStream, pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisQueueLoopback pThis=%p pPromiscStream=%p pMsg=%p\n", pThis, pPromiscStream, pMsg));
if (RT_UNLIKELY(pMsg->b_cont))
{
@@ -3075,7 +3091,7 @@ static bool vboxNetFltSolarisIsOurMBlk(PVBOXNETFLTINS pThis, vboxnetflt_promisc_
Assert(pMsg);
Assert(DB_TYPE(pMsg) == M_DATA);
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisIsOurMBlk pThis=%p pMsg=%p\n", pThis, pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisIsOurMBlk pThis=%p pMsg=%p\n", pThis, pMsg));
if (pMsg->b_cont)
{
@@ -3151,6 +3167,21 @@ static bool vboxNetFltSolarisIsOurMBlk(PVBOXNETFLTINS pThis, vboxnetflt_promisc_
/**
+ * Helper.
+ */
+DECLINLINE(bool) vboxNetFltPortSolarisIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
+{
+ /*
+ * MAC address change acknowledgements are intercepted on the read side
+ * hence theoritically we are always update to date with any changes.
+ */
+ return pThis->u.s.MacAddr.au16[0] == pMac->au16[0]
+ && pThis->u.s.MacAddr.au16[1] == pMac->au16[1]
+ && pThis->u.s.MacAddr.au16[2] == pMac->au16[2];
+}
+
+
+/**
* Worker for routing messages from the wire or from the host.
*
* @returns VBox status code.
@@ -3161,7 +3192,7 @@ static bool vboxNetFltSolarisIsOurMBlk(PVBOXNETFLTINS pThis, vboxnetflt_promisc_
*/
static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStream, queue_t *pQueue, mblk_t *pMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisRecv pThis=%p pMsg=%p\n", pThis, pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisRecv pThis=%p pMsg=%p\n", pThis, pMsg));
AssertCompile(sizeof(struct ether_header) == sizeof(RTNETETHERHDR));
Assert(pStream->Type == kPromiscStream);
@@ -3212,7 +3243,7 @@ static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStr
*/
uint32_t fSrc = INTNETTRUNKDIR_WIRE;
PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr;
- if (vboxNetFltPortOsIsHostMac(pThis, &pEthHdr->SrcMac))
+ if (vboxNetFltPortSolarisIsHostMac(pThis, &pEthHdr->SrcMac))
fSrc = INTNETTRUNKDIR_HOST;
/*
@@ -3287,7 +3318,7 @@ static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStr
pMsg->b_rptr += cbEthPrefix + sizeof(VLANHEADER);
pStrippedMsg->b_cont = pMsg;
pMsg = pStrippedMsg;
- LogFlow((DEVICE_NAME ":Stripped priority VLAN tag.\n"));
+ LogFlow((DEVICE_NAME ":Stripped VLAN tag.\n"));
}
else
{
@@ -3348,7 +3379,7 @@ static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStr
*/
static mblk_t *vboxNetFltSolarisFixChecksums(mblk_t *pMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisFixChecksums pMsg=%p\n"));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisFixChecksums pMsg=%p\n"));
Assert(DB_TYPE(pMsg) == M_DATA);
@@ -3475,7 +3506,7 @@ static mblk_t *vboxNetFltSolarisFixChecksums(mblk_t *pMsg)
*/
static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
{
- LogFlow((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n", pMsg));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n", pMsg));
PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pMsg->b_rptr;
uint8_t *pb = pMsg->b_rptr;
@@ -3486,9 +3517,9 @@ static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
if (!pMsg->b_cont)
{
if (pIpHdr->ip_p == RTNETIPV4_PROT_ICMP)
- LogFlow((DEVICE_NAME ":ICMP D=%.6Rhxs S=%.6Rhxs T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
+ LogRel((DEVICE_NAME ":ICMP D=%.6Rhxs S=%.6Rhxs T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
else if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
- LogFlow((DEVICE_NAME ":TCP D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
+ LogRel((DEVICE_NAME ":TCP D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
{
PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
@@ -3507,35 +3538,28 @@ static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
}
else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_VLAN))
{
- typedef struct VLANHEADER
- {
- int Pcp:3;
- int Cfi:1;
- int Vid:12;
- } VLANHEADER;
-
- VLANHEADER *pVlanHdr = (VLANHEADER *)(pMsg->b_rptr + sizeof(RTNETETHERHDR));
- LogFlow((DEVICE_NAME ":VLAN Pcp=%d Cfi=%d Id=%d\n", pVlanHdr->Pcp, pVlanHdr->Cfi, pVlanHdr->Vid >> 4));
- LogFlow((DEVICE_NAME "%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr));
+ PVLANHEADER pVlanHdr = (PVLANHEADER)(pMsg->b_rptr + sizeof(RTNETETHERHDR) - sizeof(pEthHdr->EtherType));
+ LogRel((DEVICE_NAME ":VLAN Pcp=%u Cfi=%u Id=%u\n", VLAN_PRI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_CFI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_ID(RT_BE2H_U16(pVlanHdr->Data))));
+ LogRel((DEVICE_NAME "%.*Rhxd\n", sizeof(VLANHEADER), pVlanHdr));
}
else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP))
{
PRTNETARPHDR pArpHdr = (PRTNETARPHDR)(pEthHdr + 1);
- LogFlow((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
+ LogRel((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
}
else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
{
- LogFlow((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
+ LogRel((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
}
else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_1)
|| pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_2)
|| pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_3))
{
- LogFlow((DEVICE_NAME ":IPX packet.\n"));
+ LogRel((DEVICE_NAME ":IPX packet.\n"));
}
else
{
- LogFlow((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
+ LogRel((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
&pEthHdr->SrcMac));
/* LogFlow((DEVICE_NAME ":%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr)); */
}
@@ -3544,38 +3568,12 @@ static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
/* -=-=-=-=-=- Common Hooks -=-=-=-=-=- */
-bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
-{
- /*
- * There is no easy way of obtaining the global host side promiscuous counter.
- * Currently we just return false.
- */
- return false;
-}
-
-
-void vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
-{
- LogFlow((DEVICE_NAME ":vboxNetFltPortOsGetMacAddress pThis=%p\n", pThis));
- *pMac = pThis->u.s.Mac;
-}
-
-bool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
-{
- /*
- * MAC address change acknowledgements are intercepted on the read side
- * hence theoritically we are always update to date with any changes.
- */
- return pThis->u.s.Mac.au16[0] == pMac->au16[0]
- && pThis->u.s.Mac.au16[1] == pMac->au16[1]
- && pThis->u.s.Mac.au16[2] == pMac->au16[2];
-}
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
{
- LogFlow((DEVICE_NAME ":vboxNetFltPortOsSetActive pThis=%p fActive=%d\n", pThis, fActive));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltPortOsSetActive pThis=%p fActive=%d\n", pThis, fActive));
/*
* Enable/disable promiscuous mode.
@@ -3599,7 +3597,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltOsDisconnectIt pThis=%p\n", pThis));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltOsDisconnectIt pThis=%p\n", pThis));
vboxNetFltSolarisDetachFromInterface(pThis);
@@ -3630,14 +3628,14 @@ int vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
{
- LogFlow((DEVICE_NAME ":vboxNetFltOsDeleteInstance pThis=%p\n", pThis));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltOsDeleteInstance pThis=%p\n", pThis));
/* Nothing to do here. */
}
int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
{
- LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p\n"));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p\n"));
/*
* Mutex used for loopback lockouts.
@@ -3646,7 +3644,7 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
if (RT_SUCCESS(rc))
{
#ifdef VBOXNETFLT_SOLARIS_IPV6_POLLING
- int rc = RTSemFastMutexCreate(&pThis->u.s.hPollMtx);
+ rc = RTSemFastMutexCreate(&pThis->u.s.hPollMtx);
if (RT_SUCCESS(rc))
{
#endif
@@ -3685,12 +3683,14 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
pThis->u.s.pvIp6Stream = NULL;
pThis->u.s.pvArpStream = NULL;
pThis->u.s.pvPromiscStream = NULL;
+ pThis->u.s.fAttaching = false;
+ pThis->u.s.fVLAN = false;
pThis->u.s.hFastMtx = NIL_RTSEMFASTMUTEX;
pThis->u.s.fVLAN = false;
#ifdef VBOXNETFLT_SOLARIS_IPV6_POLLING
pThis->u.s.hPollMtx = NIL_RTSEMFASTMUTEX;
#endif
- bzero(&pThis->u.s.Mac, sizeof(pThis->u.s.Mac));
+ bzero(&pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
return VINF_SUCCESS;
}
@@ -3707,7 +3707,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
{
- LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p pSG=%p fDst=%d\n", pThis, pSG, fDst));
+ LogFlowFunc((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p pSG=%p fDst=%d\n", pThis, pSG, fDst));
int rc = VINF_SUCCESS;
if (fDst & INTNETTRUNKDIR_WIRE)
@@ -3833,7 +3833,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
* Construct a DL_UNITDATA_IND style message for ARP as it doesn't understand fast path.
*/
mblk_t *pDlpiMsg;
- int rc = vboxNetFltSolarisRawToUnitData(pMsg, &pDlpiMsg);
+ rc = vboxNetFltSolarisRawToUnitData(pMsg, &pDlpiMsg);
if (RT_SUCCESS(rc))
{
pMsg = pDlpiMsg;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c
new file mode 100644
index 000000000..4c2ae1570
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c
@@ -0,0 +1,1063 @@
+/* $Id: VBoxNetFltBow-solaris.c 28830 2010-04-27 14:05:25Z vboxsync $ */
+/** @file
+ * VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code.
+ */
+
+/*
+ * Copyright (C) 2008 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/intnetinline.h>
+#include <VBox/version.h>
+#include <iprt/initterm.h>
+#include <iprt/alloca.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/string.h>
+#include <iprt/net.h>
+#include <iprt/spinlock.h>
+
+#include <sys/types.h>
+#include <sys/modctl.h>
+#include <sys/conf.h>
+#include <sys/stat.h>
+#include <sys/ddi.h>
+#include <sys/gld.h>
+#include <sys/sunddi.h>
+#include <sys/strsubr.h>
+#include <sys/dlpi.h>
+#include <sys/dls_mgmt.h>
+#include <sys/mac.h>
+#include <sys/strsun.h>
+#include <sys/sunddi.h>
+
+#include "include/mac_provider.h" /* dependency for other headers */
+#include "include/mac_client.h" /* for mac_* */
+#include "include/mac_client_priv.h" /* for mac_info, mac_capab_get etc. */
+#if 0
+#include "include/dls.h" /* for dls_mgmt_* */
+#include "include/dld_ioc.h" /* required by vnic.h */
+#include "include/vnic.h" /* for vnic_ioc_diag_t */
+#include "include/vnic_impl.h" /* for vnic_dev_create */
+#endif
+
+#define VBOXNETFLT_OS_SPECFIC 1
+#include "../VBoxNetFltInternal.h"
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** The module name. */
+#define DEVICE_NAME "vboxflt"
+/** The module descriptions as seen in 'modinfo'. */
+#define DEVICE_DESC_DRV "VirtualBox NetBow"
+/** The dynamically created VNIC name */
+#define VBOXFLT_VNIC_NAME "vboxvnic"
+/** Debugging switch for using symbols in kmdb */
+# define LOCAL static
+
+#if defined(DEBUG_ramshankar)
+# undef Log
+# define Log LogRel
+# undef LogFlow
+# define LogFlow LogRel
+# undef LOCAL
+# define LOCAL
+#endif
+
+
+/*******************************************************************************
+* Kernel Entry Hooks *
+*******************************************************************************/
+LOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
+LOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
+LOCAL int VBoxNetFltSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * cb_ops: for drivers that support char/block entry points
+ */
+static struct cb_ops g_VBoxNetFltSolarisCbOps =
+{
+ nulldev, /* c open */
+ nulldev, /* c close */
+ nodev, /* b strategy */
+ nodev, /* b dump */
+ nodev, /* b print */
+ nodev, /* c read */
+ nodev, /* c write*/
+ nodev, /* c ioctl*/
+ nodev, /* c devmap */
+ nodev, /* c mmap */
+ nodev, /* c segmap */
+ nochpoll, /* c poll */
+ ddi_prop_op, /* property ops */
+ NULL, /* streamtab */
+ D_NEW | D_MP, /* compat. flag */
+ CB_REV, /* revision */
+ nodev, /* c aread */
+ nodev /* c awrite */
+};
+
+/**
+ * dev_ops: for driver device operations
+ */
+static struct dev_ops g_VBoxNetFltSolarisDevOps =
+{
+ DEVO_REV, /* driver build revision */
+ 0, /* ref count */
+ VBoxNetFltSolarisGetInfo,
+ nulldev, /* identify */
+ nulldev, /* probe */
+ VBoxNetFltSolarisAttach,
+ VBoxNetFltSolarisDetach,
+ nodev, /* reset */
+ &g_VBoxNetFltSolarisCbOps,
+ NULL, /* bus ops */
+ nodev, /* power */
+ ddi_quiesce_not_needed
+};
+
+/**
+ * modldrv: export driver specifics to the kernel
+ */
+static struct modldrv g_VBoxNetFltSolarisModule =
+{
+ &mod_driverops, /* extern from kernel */
+ DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
+ &g_VBoxNetFltSolarisDevOps
+};
+
+/**
+ * modlinkage: export install/remove/info to the kernel
+ */
+static struct modlinkage g_VBoxNetFltSolarisModLinkage =
+{
+ MODREV_1,
+ {
+ &g_VBoxNetFltSolarisModule,
+ NULL,
+ }
+};
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Global Device handle we only support one instance. */
+static dev_info_t *g_pVBoxNetFltSolarisDip = NULL;
+/** Global Mutex (actually an rw lock). */
+static RTSEMFASTMUTEX g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
+/** The (common) global data. */
+static VBOXNETFLTGLOBALS g_VBoxNetFltSolarisGlobals;
+
+
+/*******************************************************************************
+* Internal Function *
+*******************************************************************************/
+LOCAL mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst);
+LOCAL unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg);
+LOCAL int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc);
+
+LOCAL int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis, bool fRediscovery);
+LOCAL int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis);
+LOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback);
+
+
+/**
+ * Kernel entry points
+ */
+int _init(void)
+{
+ LogFlow((DEVICE_NAME ":_init\n"));
+
+ /*
+ * Prevent module autounloading.
+ */
+ modctl_t *pModCtl = mod_getctl(&g_VBoxNetFltSolarisModLinkage);
+ if (pModCtl)
+ pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
+ else
+ LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
+
+ /*
+ * Initialize IPRT.
+ */
+ int rc = RTR0Init(0);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Initialize Solaris specific globals here.
+ */
+ rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Initialize the globals and connect to the support driver.
+ *
+ * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
+ * for establishing the connect to the support driver.
+ */
+ memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
+ rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
+ if (RT_SUCCESS(rc))
+ {
+ rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
+ if (!rc)
+ return rc;
+
+ LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
+ vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
+ }
+ else
+ LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
+
+ RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
+ g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ RTR0Term();
+ }
+ else
+ LogRel((DEVICE_NAME ":failed to initialize IPRT (rc=%d)\n", rc));
+
+ memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
+ return RTErrConvertToErrno(rc);
+}
+
+
+int _fini(void)
+{
+ int rc;
+ LogFlow((DEVICE_NAME ":_fini\n"));
+
+ /*
+ * Undo the work done during start (in reverse order).
+ */
+ rc = vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
+ if (RT_FAILURE(rc))
+ {
+ LogRel((DEVICE_NAME ":_fini - busy!\n"));
+ return EBUSY;
+ }
+
+ rc = mod_remove(&g_VBoxNetFltSolarisModLinkage);
+ if (!rc)
+ {
+ if (g_VBoxNetFltSolarisMtx != NIL_RTSEMFASTMUTEX)
+ {
+ RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
+ g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
+ }
+
+ RTR0Term();
+ }
+
+ return rc;
+}
+
+
+int _info(struct modinfo *pModInfo)
+{
+ LogFlow((DEVICE_NAME ":_info\n"));
+
+ int rc = mod_info(&g_VBoxNetFltSolarisModLinkage, pModInfo);
+
+ LogFlow((DEVICE_NAME ":_info returns %d\n", rc));
+ return rc;
+}
+
+
+/**
+ * Attach entry point, to attach a device to the system or resume it.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (attach/resume).
+ *
+ * @returns corresponding solaris error code.
+ */
+LOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
+{
+ LogFlow((DEVICE_NAME ":VBoxNetFltSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+
+ switch (enmCmd)
+ {
+ case DDI_ATTACH:
+ {
+ int instance = ddi_get_instance(pDip);
+ int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0, "none", "none", 0666);
+ if (rc == DDI_SUCCESS)
+ {
+ g_pVBoxNetFltSolarisDip = pDip;
+ ddi_report_dev(pDip);
+ return DDI_SUCCESS;
+ }
+ else
+ LogRel((DEVICE_NAME ":VBoxNetFltSolarisAttach failed to create minor node. rc=%d\n", rc));
+ return DDI_FAILURE;
+ }
+
+ case DDI_RESUME:
+ {
+ /* Nothing to do here... */
+ return DDI_SUCCESS;
+ }
+
+ /* case DDI_PM_RESUME: */
+ default:
+ return DDI_FAILURE;
+ }
+}
+
+
+/**
+ * Detach entry point, to detach a device to the system or suspend it.
+ *
+ * @param pDip The module structure instance.
+ * @param enmCmd Operation type (detach/suspend).
+ *
+ * @returns corresponding solaris error code.
+ */
+LOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
+{
+ LogFlow((DEVICE_NAME ":VBoxNetFltSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd));
+
+ switch (enmCmd)
+ {
+ case DDI_DETACH:
+ {
+ ddi_remove_minor_node(pDip, NULL);
+ return DDI_SUCCESS;
+ }
+
+ case DDI_RESUME:
+ {
+ /* Nothing to do here... */
+ return DDI_SUCCESS;
+ }
+
+ /* case DDI_PM_SUSPEND: */
+ /* case DDI_HOT_PLUG_DETACH: */
+ default:
+ return DDI_FAILURE;
+ }
+}
+
+
+/**
+ * Info entry point, called by solaris kernel for obtaining driver info.
+ *
+ * @param pDip The module structure instance (do not use).
+ * @param enmCmd Information request type.
+ * @param pvArg Type specific argument.
+ * @param ppvResult Where to store the requested info.
+ *
+ * @returns corresponding solaris error code.
+ */
+LOCAL int VBoxNetFltSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppResult)
+{
+ LogFlow((DEVICE_NAME ":VBoxNetFltSolarisGetInfo pDip=%p enmCmd=%d pArg=%p instance=%d\n", pDip, enmCmd, getminor((dev_t)pvArg)));
+
+ switch (enmCmd)
+ {
+ case DDI_INFO_DEVT2DEVINFO:
+ {
+ *ppResult = g_pVBoxNetFltSolarisDip;
+ return DDI_SUCCESS;
+ }
+
+ case DDI_INFO_DEVT2INSTANCE:
+ {
+ int instance = getminor((dev_t)pvArg);
+ *ppResult = (void *)(uintptr_t)instance;
+ return DDI_SUCCESS;
+ }
+ }
+
+ return DDI_FAILURE;
+}
+
+
+/**
+ * Create a solaris message block from the SG list.
+ *
+ * @param pThis The instance.
+ * @param pSG Pointer to the scatter-gather list.
+ *
+ * @returns Solaris message block.
+ */
+LOCAL mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG pThis=%p pSG=%p\n", pThis, pSG));
+
+ mblk_t *pMsg = allocb(pSG->cbTotal, BPRI_HI);
+ if (RT_UNLIKELY(!pMsg))
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG failed to alloc %d bytes for mblk_t.\n", pSG->cbTotal));
+ return NULL;
+ }
+
+ /*
+ * Single buffer copy. Maybe later explore the
+ * need/possibility for using a mblk_t chain rather.
+ */
+ for (unsigned i = 0; i < pSG->cSegsUsed; i++)
+ {
+ if (pSG->aSegs[i].pv)
+ {
+ bcopy(pSG->aSegs[i].pv, pMsg->b_wptr, pSG->aSegs[i].cb);
+ pMsg->b_wptr += pSG->aSegs[i].cb;
+ }
+ }
+ DB_TYPE(pMsg) = M_DATA;
+ return pMsg;
+}
+
+
+/**
+ * Calculate the number of segments required for this message block.
+ *
+ * @param pThis The instance
+ * @param pMsg Pointer to the data message.
+ *
+ * @returns Number of segments.
+ */
+LOCAL unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg)
+{
+ unsigned cSegs = 0;
+ for (mblk_t *pCur = pMsg; pCur; pCur = pCur->b_cont)
+ if (MBLKL(pCur))
+ cSegs++;
+
+#ifdef PADD_RUNT_FRAMES_FROM_HOST
+ if (msgdsize(pMsg) < 60)
+ cSegs++;
+#endif
+
+ NOREF(pThis);
+ return RT_MAX(cSegs, 1);
+}
+
+
+/**
+ * Initializes an SG list from the given message block.
+ *
+ * @param pThis The instance.
+ * @param pMsg Pointer to the data message.
+ The caller must ensure it's not a control message block.
+ * @param pSG Pointer to the SG.
+ * @param cSegs Number of segments in the SG.
+ * This should match the number in the message block exactly!
+ * @param fSrc The source of the message.
+ *
+ * @returns VBox status code.
+ */
+LOCAL int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pThis=%p pMsg=%p pSG=%p cSegs=%d\n", pThis, pMsg, pSG, cSegs));
+
+ /*
+ * Convert the message block to segments. Works cbTotal and sets cSegsUsed.
+ */
+ IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
+ mblk_t *pCur = pMsg;
+ unsigned iSeg = 0;
+ while (pCur)
+ {
+ size_t cbSeg = MBLKL(pCur);
+ if (cbSeg)
+ {
+ void *pvSeg = pCur->b_rptr;
+ pSG->aSegs[iSeg].pv = pvSeg;
+ pSG->aSegs[iSeg].cb = cbSeg;
+ pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
+ pSG->cbTotal += cbSeg;
+ iSeg++;
+ }
+ pCur = pCur->b_cont;
+ }
+ pSG->cSegsUsed = iSeg;
+
+#ifdef PADD_RUNT_FRAMES_FROM_HOST
+ if (pSG->cbTotal < 60 && (fSrc & INTNETTRUNKDIR_HOST))
+ {
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG pulling up to length.\n"));
+
+ static uint8_t const s_abZero[128] = {0};
+ pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
+ pSG->aSegs[iSeg].pv = (void *)&s_abZero[0];
+ pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal;
+ pSG->cbTotal = 60;
+ pSG->cSegsUsed++;
+ Assert(iSeg + 1 < cSegs);
+ }
+#endif
+
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG iSeg=%d pSG->cbTotal=%d msgdsize=%d\n", iSeg, pSG->cbTotal, msgdsize(pMsg)));
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Simple packet dump, used for internal debugging.
+ *
+ * @param pMsg Pointer to the message to analyze and dump.
+ */
+static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n", pMsg));
+
+ PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pMsg->b_rptr;
+ uint8_t *pb = pMsg->b_rptr;
+ if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV4))
+ {
+ PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1);
+ if (!pMsg->b_cont)
+ {
+ if (pIpHdr->ip_p == RTNETIPV4_PROT_ICMP)
+ LogFlow((DEVICE_NAME ":ICMP D=%.6Rhxs S=%.6Rhxs T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
+ else if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
+ LogFlow((DEVICE_NAME ":TCP D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
+ else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
+ {
+ PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
+ if ( RT_BE2H_U16(pUdpHdr->uh_sport) == 67
+ && RT_BE2H_U16(pUdpHdr->uh_dport) == 68)
+ {
+ LogRel((DEVICE_NAME ":UDP bootp ack D=%.6Rhxs S=%.6Rhxs UDP_CheckSum=%04x Computex=%04x\n", pb, pb + 6,
+ RT_BE2H_U16(pUdpHdr->uh_sum), RT_BE2H_U16(RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1))));
+ }
+ }
+ }
+ else
+ {
+ LogFlow((DEVICE_NAME ":Chained IP packet. Skipping validity check.\n"));
+ }
+ }
+ else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_VLAN))
+ {
+ typedef struct VLANHEADER
+ {
+ int Pcp:3;
+ int Cfi:1;
+ int Vid:12;
+ } VLANHEADER;
+
+ VLANHEADER *pVlanHdr = (VLANHEADER *)(pMsg->b_rptr + sizeof(RTNETETHERHDR));
+ LogFlow((DEVICE_NAME ":VLAN Pcp=%d Cfi=%d Id=%d\n", pVlanHdr->Pcp, pVlanHdr->Cfi, pVlanHdr->Vid >> 4));
+ LogFlow((DEVICE_NAME "%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr));
+ }
+ else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP))
+ {
+ PRTNETARPHDR pArpHdr = (PRTNETARPHDR)(pEthHdr + 1);
+ LogFlow((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
+ }
+ else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
+ {
+ LogFlow((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
+ }
+ else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_1)
+ || pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_2)
+ || pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_3))
+ {
+ LogFlow((DEVICE_NAME ":IPX packet.\n"));
+ }
+ else
+ {
+ LogFlow((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
+ &pEthHdr->SrcMac));
+ /* LogFlow((DEVICE_NAME ":%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr)); */
+ }
+}
+
+
+/**
+ * Helper.
+ */
+DECLINLINE(bool) vboxNetFltPortSolarisIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
+{
+ return pThis->u.s.MacAddr.au16[0] == pMac->au16[0]
+ && pThis->u.s.MacAddr.au16[1] == pMac->au16[1]
+ && pThis->u.s.MacAddr.au16[2] == pMac->au16[2];
+}
+
+
+/**
+ * Receive (rx) entry point.
+ *
+ * @param pvData Private data.
+ * @param hResource The resource handle.
+ * @param pMsg The packet.
+ * @param fLoopback Whether this is a loopback packet or not.
+ */
+LOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisRecv pvData=%p pMsg=%p fLoopback=%d cbData=%d\n", pvData, pMsg, fLoopback, pMsg ? MBLKL(pMsg) : 0));
+
+ PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvData;
+ AssertPtrReturnVoid(pThis);
+ AssertPtrReturnVoid(pMsg);
+
+ /*
+ * Active? Retain the instance and increment the busy counter.
+ */
+ if (!vboxNetFltTryRetainBusyActive(pThis))
+ return;
+
+ uint32_t fSrc = INTNETTRUNKDIR_WIRE;
+ PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr;
+ if ( MBLKL(pMsg) >= sizeof(RTNETETHERHDR)
+ && vboxNetFltPortSolarisIsHostMac(pThis, &pEthHdr->SrcMac))
+ fSrc = INTNETTRUNKDIR_HOST;
+
+ /*
+ * Route all received packets into the internal network.
+ */
+ unsigned cSegs = vboxNetFltSolarisMBlkCalcSGSegs(pThis, pMsg);
+ PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
+ int rc = vboxNetFltSolarisMBlkToSG(pThis, pMsg, pSG, cSegs, fSrc);
+ if (RT_SUCCESS(rc))
+ pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
+ else
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed. rc=%d\n", rc));
+
+ vboxNetFltRelease(pThis, true /* fBusy */);
+ freemsgchain(pMsg);
+
+ NOREF(hResource);
+}
+
+
+/**
+ * Create a VNIC dynamically over the given interface.
+ *
+ * @param pThis The VM connection instance.
+ *
+ * @returns corresponding VBox error code.
+ */
+LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis)
+{
+#if 0
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC pThis=%p\n", pThis));
+
+ datalink_id_t InterfaceLinkId;
+ int rc = dls_mgmt_get_linkid(pThis->szName, &InterfaceLinkId);
+ if (!rc)
+ {
+ dev_t DeviceNum = makedevice(ddi_driver_major(g_pVBoxNetFltSolarisDip), pThis->u.s.uInstance);
+ char szVNICName[sizeof(VBOXFLT_VNIC_NAME) + 16];
+ RTStrPrintf(szVNICName, sizeof(szVNICName), "%s%d", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance);
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC Creating VNIC '%s' over '%s'\n", szVNICName, pThis->szName));
+ rc = dls_mgmt_create(szVNICName, DeviceNum, DATALINK_CLASS_VNIC, DL_ETHER, B_FALSE /* Persist */, &pThis->u.s.VNICLinkId);
+ if (!rc)
+ {
+ /* -XXX- @todo remove hardcoded Guest MAC address, should be sent from guest later. */
+ RTMAC GuestMac;
+ GuestMac.au8[0] = 0x08;
+ GuestMac.au8[1] = 0x00;
+ GuestMac.au8[2] = 0x27;
+ GuestMac.au8[3] = 0xFE;
+ GuestMac.au8[4] = 0x21;
+ GuestMac.au8[5] = 0x03;
+
+ AssertCompile(sizeof(RTMAC) <= MAXMACADDRLEN);
+ uchar_t MacAddr[MAXMACADDRLEN];
+ bzero(MacAddr, sizeof(MacAddr));
+ bcopy(GuestMac.au8, MacAddr, RT_MIN(sizeof(GuestMac), sizeof(MacAddr)));
+
+ int MacSlot = 0;
+ vnic_ioc_diag_t Diag = VNIC_IOC_DIAG_NONE;
+ vnic_mac_addr_type_t MacAddrType = VNIC_MAC_ADDR_TYPE_FIXED;
+ int cbMac = sizeof(RTMAC);
+ int fFlags = VNIC_IOC_CREATE_NODUPCHECK | VNIC_IOC_CREATE_REQ_HWRINGS;
+ rc = vnic_dev_create(pThis->u.s.VNICLinkId, InterfaceLinkId, &MacAddrType, &cbMac, MacAddr,
+ &MacSlot, 0 /* Mac Prefix */, 0 /* VLAN Id */, NULL /* Resources Caps */,
+ fFlags, &Diag, kcred);
+ if (rc)
+ {
+ if (Diag == VNIC_IOC_DIAG_NO_HWRINGS)
+ {
+ /*
+ * No hardware rings available, retry without requesting hardware ring.
+ */
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC No hardware rings available for VNIC over '%s'. Recreating VNIC '%s'\n", pThis->szName,
+ szVNICName));
+
+ fFlags = VNIC_IOC_CREATE_NODUPCHECK;
+ rc = vnic_dev_create(pThis->u.s.VNICLinkId, InterfaceLinkId, &MacAddrType, &cbMac, MacAddr,
+ &MacSlot, 0 /* Mac Prefix */, 0 /* VLAN Id */, NULL /* Resources Caps */,
+ fFlags, &Diag, kcred);
+ }
+ }
+
+ if (!rc)
+ {
+ pThis->u.s.fCreatedVNIC = true;
+ pThis->u.s.uInstance++;
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s'\n", "vboxvnic", pThis->szName));
+ return VINF_SUCCESS;
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create VNIC over '%s'. rc=%d Diagnosis=%d\n", pThis->szName,
+ rc, Diag));
+ rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
+ }
+
+ dls_mgmt_destroy(pThis->u.s.VNICLinkId, B_FALSE /* Persist */);
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create a link id for a VNIC over '%s' rc=%d\n", pThis->szName, rc));
+ rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
+ }
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to find interface '%s' rc=%d\n", pThis->szName, rc));
+ rc = VERR_INTNET_FLT_IF_NOT_FOUND;
+ }
+
+ return rc;
+#endif
+}
+
+
+/**
+ * Attach to the network interface.
+ *
+ * @param pThis The VM connection instance.
+ * @param fRediscovery Whether this is a rediscovery attempt after disconnect.
+ *
+ * @returns corresponding VBox error code.
+ */
+LOCAL int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis, bool fRediscovery)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface pThis=%p fRediscovery=%d\n", pThis, fRediscovery));
+
+ AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+
+ /*
+ * Open the underlying interface (lower MAC) and get it's handle.
+ */
+ int rc = mac_open_by_linkname(pThis->szName, &pThis->u.s.hInterface);
+ if (RT_LIKELY(!rc))
+ {
+ /*
+ * If this is not a VNIC, create a VNIC and open it instead.
+ */
+ rc = mac_is_vnic(pThis->u.s.hInterface);
+ if (!rc)
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface '%s' is not a VNIC. Creating one.\n", pThis->szName));
+
+ mac_close(pThis->u.s.hInterface);
+ pThis->u.s.hInterface = NULL;
+ rc = vboxNetFltSolarisCreateVNIC(pThis);
+ if (RT_SUCCESS(rc))
+ rc = mac_open_by_linkid(pThis->u.s.VNICLinkId, &pThis->u.s.hInterface);
+ else
+ {
+ pThis->u.s.hInterface = NULL;
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to create VNIC. rc=%Rrc\n", rc));
+ }
+ }
+ else
+ rc = VINF_SUCCESS;
+
+ /*
+ * At this point "hInterface" should be a handle to a VNIC, we no longer would deal with physical interface
+ * if it has been passed by the user.
+ */
+ if (RT_SUCCESS(rc))
+ {
+ const mac_info_t *pMacInfo = mac_info(pThis->u.s.hInterface);
+ if (RT_LIKELY(pMacInfo))
+ {
+ if ( pMacInfo->mi_media == DL_ETHER
+ && pMacInfo->mi_nativemedia == DL_ETHER)
+ {
+ /*
+ * Obtain the MAC address of the interface.
+ */
+ AssertCompile(sizeof(RTMAC) == ETHERADDRL);
+ mac_unicast_primary_get(pThis->u.s.hInterface, (uint8_t *)&pThis->u.s.MacAddr.au8);
+
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface MAC address of %s is %.*Rhxs\n", pThis->szName,
+ sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
+
+ /** @todo Obtain the MTU size using mac_sdu_get() */
+ /** @todo Obtain capabilities (hardware checksum etc.) using mac_capab_get() */
+
+ /*
+ * Open a client connection to the lower MAC interface.
+ */
+ rc = mac_client_open(pThis->u.s.hInterface, &pThis->u.s.hClient,
+ NULL /* name of this client */,
+ MAC_OPEN_FLAGS_USE_DATALINK_NAME | /* client name same as underlying NIC */
+ MAC_OPEN_FLAGS_MULTI_PRIMARY /* allow multiple primary unicasts */
+ );
+ if (RT_LIKELY(!rc))
+ {
+ /** @todo -XXX- if possible we must move unicast_add and rx_set to when the Guest advertises it's MAC to us. */
+
+ /*
+ * Set a unicast address for this client and the packet receive callback.
+ * We want to use the primary unicast address of the underlying interface (VNIC) hence we pass NULL.
+ * Also we don't really set the RX function here, this is done when we activate promiscuous mode.
+ */
+ mac_diag_t MacDiag;
+ rc = mac_unicast_add(pThis->u.s.hClient, NULL /* MAC Address */,
+ MAC_UNICAST_PRIMARY | MAC_UNICAST_STRIP_DISABLE |
+ MAC_UNICAST_DISABLE_TX_VID_CHECK | MAC_UNICAST_NODUPCHECK | MAC_UNICAST_HW,
+ &pThis->u.s.hUnicast, 0 /* VLAN id */, &MacDiag);
+ if (!rc)
+ {
+ /*
+ * Report MAC address, promiscuous mode and capabilities.
+ */
+ if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ Assert(pThis->pSwitchPort);
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
+
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface successfully attached over '%s'\n", pThis->szName));
+ return VINF_SUCCESS;
+ }
+
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to set client MAC address over link '%s' rc=%d\n",
+ pThis->szName, rc));
+
+ mac_client_close(pThis->u.s.hClient, 0 /* fFlags */);
+ pThis->u.s.hClient = NULL;
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to create client over link '%s' rc=%d\n",
+ pThis->szName, rc));
+ }
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface media type incompatible: %d %d\n", pMacInfo->mi_media,
+ pMacInfo->mi_nativemedia));
+ rc = EPROTO;
+ }
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to obtain info for link '%s'\n", pThis->szName));
+ rc = ENXIO;
+ }
+ }
+ else
+ {
+ LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface VNIC creation failed over '%s'\n", pThis->szName));
+ rc = ENXIO;
+ }
+
+ if (pThis->u.s.hInterface)
+ {
+ mac_close(pThis->u.s.hInterface);
+ pThis->u.s.hInterface = NULL;
+ }
+ }
+ else
+ LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to open link '%s' rc=%d\n", pThis->szName, rc));
+
+ return RTErrConvertFromErrno(rc);
+}
+
+
+
+/**
+ * Detach from the network interface.
+ *
+ * @param pThis The VM connection instance.
+ * @returns corresponding VBox error code.
+ */
+LOCAL int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis)
+{
+ AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+
+ if (pThis->u.s.hPromiscuous)
+ {
+ mac_promisc_remove(pThis->u.s.hPromiscuous);
+ pThis->u.s.hPromiscuous = NULL;
+ }
+
+ if (pThis->u.s.hClient)
+ {
+ if (pThis->u.s.hUnicast)
+ {
+ mac_unicast_remove(pThis->u.s.hClient, pThis->u.s.hUnicast);
+ pThis->u.s.hUnicast = NULL;
+ }
+
+ mac_rx_clear(pThis->u.s.hClient);
+
+ mac_client_close(pThis->u.s.hClient, 0 /* fFlags */);
+ pThis->u.s.hClient = NULL;
+ }
+
+ if (pThis->u.s.hInterface)
+ {
+ mac_close(pThis->u.s.hInterface);
+ pThis->u.s.hInterface = NULL;
+ }
+
+ if (pThis->u.s.fCreatedVNIC)
+ {
+#if 0
+ vnic_dev_delete(pThis->u.s.VNICLinkId, 0 /* Flags -- ununsed in snv_127 */, kcred);
+ dls_mgmt_destroy(pThis->u.s.VNICLinkId, B_FALSE /* Persist */);
+ pThis->u.s.VNICLinkId = DATALINK_INVALID_LINKID;
+ pThis->u.s.fCreatedVNIC = false;
+#endif
+ }
+}
+
+
+/* -=-=-=-=-=- Common Hooks -=-=-=-=-=- */
+
+
+void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltPortOsSetActive pThis=%p fActive=%d\n", pThis, fActive));
+
+ if (fActive)
+ {
+ /*
+ * Activate promiscuous mode.
+ */
+ if (!pThis->u.s.hPromiscuous)
+ {
+ int rc = mac_promisc_add(pThis->u.s.hClient, MAC_CLIENT_PROMISC_ALL, vboxNetFltSolarisRecv, pThis, &pThis->u.s.hPromiscuous,
+ MAC_PROMISC_FLAGS_NO_TX_LOOP);
+ if (rc)
+ LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive cannot enable promiscuous mode for '%s' rc=%d\n", pThis->szName, rc));
+ }
+ }
+ else
+ {
+ /*
+ * Deactivate promiscuous mode.
+ */
+ if (pThis->u.s.hPromiscuous)
+ {
+ mac_promisc_remove(pThis->u.s.hPromiscuous);
+ pThis->u.s.hPromiscuous = NULL;
+ }
+ }
+}
+
+
+int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltOsDisconnectIt pThis=%p\n", pThis));
+ return vboxNetFltSolarisDetachFromInterface(pThis);
+}
+
+
+int vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltOsConnectIt pThis=%p\n", pThis));
+ return vboxNetFltSolarisAttachToInterface(pThis, false /* fRediscovery */);
+}
+
+
+void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltOsDeleteInstance pThis=%p\n", pThis));
+}
+
+
+int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
+{
+ LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p pvContext=%p\n", pThis, pvContext));
+
+ return VINF_SUCCESS;
+}
+
+
+int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
+{
+ /*
+ * Init. the solaris specific data.
+ */
+ pThis->u.s.VNICLinkId = DATALINK_INVALID_LINKID;
+ pThis->u.s.uInstance = 0;
+ pThis->u.s.fCreatedVNIC = false;
+ pThis->u.s.hInterface = NULL;
+ pThis->u.s.hClient = NULL;
+ pThis->u.s.hUnicast = NULL;
+ pThis->u.s.hPromiscuous = NULL;
+ bzero(&pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
+ return VINF_SUCCESS;
+}
+
+
+bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
+{
+ /*
+ * @todo Think about this.
+ */
+ return false;
+}
+
+
+int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
+{
+ /*
+ * Xmit the packet down the interface (tx)
+ */
+ int rc = VERR_INVALID_HANDLE;
+ if (RT_LIKELY(pThis->u.s.hClient))
+ {
+ mblk_t *pMsg = vboxNetFltSolarisMBlkFromSG(pThis, pSG, fDst);
+ if (RT_LIKELY(pMsg))
+ {
+ LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p cbData=%d\n", pThis, MBLKL(pMsg)));
+
+ mac_tx_cookie_t pXmitCookie = mac_tx(pThis->u.s.hClient, pMsg, 0 /* Hint */, MAC_DROP_ON_NO_DESC, NULL /* return message */);
+ if (RT_LIKELY(!pXmitCookie))
+ return VINF_SUCCESS;
+
+ pMsg = NULL;
+ rc = VERR_NET_IO_ERROR;
+ LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit Xmit failed.\n"));
+ }
+ else
+ {
+ LogRel((DEVICE_NAME ":vboxNetFltPortOsXmit no memory for allocating Xmit packet.\n"));
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ else
+ LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit missing client.\n"));
+
+ return rc;
+}
+
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h
new file mode 100644
index 000000000..e5524214e
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h
@@ -0,0 +1,199 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009-2010 Oracle Corporation. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This file captures the MAC client API definitions. It can be
+ * included from any MAC clients.
+ */
+
+#ifndef _SYS_MAC_CLIENT_H
+#define _SYS_MAC_CLIENT_H
+
+#include <sys/mac.h>
+#include <sys/mac_flow.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _KERNEL
+
+/*
+ * MAC client interface.
+ */
+
+typedef struct __mac_client_handle *mac_client_handle_t;
+typedef struct __mac_unicast_handle *mac_unicast_handle_t;
+typedef struct __mac_promisc_handle *mac_promisc_handle_t;
+typedef struct __mac_perim_handle *mac_perim_handle_t;
+typedef uintptr_t mac_tx_cookie_t;
+
+typedef void (*mac_tx_notify_t)(void *, mac_tx_cookie_t);
+
+typedef enum {
+ MAC_DIAG_NONE,
+ MAC_DIAG_MACADDR_NIC,
+ MAC_DIAG_MACADDR_INUSE,
+ MAC_DIAG_MACADDR_INVALID,
+ MAC_DIAG_MACADDRLEN_INVALID,
+ MAC_DIAG_MACFACTORYSLOTINVALID,
+ MAC_DIAG_MACFACTORYSLOTUSED,
+ MAC_DIAG_MACFACTORYSLOTALLUSED,
+ MAC_DIAG_MACFACTORYNOTSUP,
+ MAC_DIAG_MACPREFIX_INVALID,
+ MAC_DIAG_MACPREFIXLEN_INVALID,
+ MAC_DIAG_MACNO_HWRINGS
+} mac_diag_t;
+
+typedef enum {
+ MAC_CLIENT_PROMISC_ALL,
+ MAC_CLIENT_PROMISC_FILTERED,
+ MAC_CLIENT_PROMISC_MULTI
+} mac_client_promisc_type_t;
+
+/* flags passed to mac_unicast_add() */
+#define MAC_UNICAST_NODUPCHECK 0x0001
+#define MAC_UNICAST_PRIMARY 0x0002
+#define MAC_UNICAST_HW 0x0004
+#define MAC_UNICAST_VNIC_PRIMARY 0x0008
+#define MAC_UNICAST_TAG_DISABLE 0x0010
+#define MAC_UNICAST_STRIP_DISABLE 0x0020
+#define MAC_UNICAST_DISABLE_TX_VID_CHECK 0x0040
+
+/* flags passed to mac_client_open */
+#define MAC_OPEN_FLAGS_IS_VNIC 0x0001
+#define MAC_OPEN_FLAGS_EXCLUSIVE 0x0002
+#define MAC_OPEN_FLAGS_IS_AGGR_PORT 0x0004
+#define MAC_OPEN_FLAGS_NO_HWRINGS 0x0008
+#define MAC_OPEN_FLAGS_SHARES_DESIRED 0x0010
+#define MAC_OPEN_FLAGS_USE_DATALINK_NAME 0x0020
+#define MAC_OPEN_FLAGS_REQ_HWRINGS 0x0040
+#define MAC_OPEN_FLAGS_MULTI_PRIMARY 0x0080
+
+/* flags passed to mac_client_close */
+#define MAC_CLOSE_FLAGS_IS_VNIC 0x0001
+#define MAC_CLOSE_FLAGS_EXCLUSIVE 0x0002
+#define MAC_CLOSE_FLAGS_IS_AGGR_PORT 0x0004
+
+/* flags passed to mac_promisc_add() */
+#define MAC_PROMISC_FLAGS_NO_TX_LOOP 0x0001
+#define MAC_PROMISC_FLAGS_NO_PHYS 0x0002
+#define MAC_PROMISC_FLAGS_VLAN_TAG_STRIP 0x0004
+#define MAC_PROMISC_FLAGS_NO_COPY 0x0008
+
+/* flags passed to mac_tx() */
+#define MAC_DROP_ON_NO_DESC 0x01 /* freemsg() if no tx descs */
+#define MAC_TX_NO_ENQUEUE 0x02 /* don't enqueue mblks if not xmit'ed */
+#define MAC_TX_NO_HOLD 0x04 /* don't bump the active Tx count */
+
+extern int mac_client_open(mac_handle_t, mac_client_handle_t *, char *,
+ uint16_t);
+extern void mac_client_close(mac_client_handle_t, uint16_t);
+
+extern int mac_unicast_add(mac_client_handle_t, uint8_t *, uint16_t,
+ mac_unicast_handle_t *, uint16_t, mac_diag_t *);
+extern int mac_unicast_add_set_rx(mac_client_handle_t, uint8_t *, uint16_t,
+ mac_unicast_handle_t *, uint16_t, mac_diag_t *, mac_rx_t, void *);
+extern int mac_unicast_remove(mac_client_handle_t, mac_unicast_handle_t);
+
+extern int mac_multicast_add(mac_client_handle_t, const uint8_t *);
+extern void mac_multicast_remove(mac_client_handle_t, const uint8_t *);
+
+extern void mac_rx_set(mac_client_handle_t, mac_rx_t, void *);
+extern void mac_rx_clear(mac_client_handle_t);
+extern mac_tx_cookie_t mac_tx(mac_client_handle_t, mblk_t *,
+ uintptr_t, uint16_t, mblk_t **);
+extern boolean_t mac_tx_is_flow_blocked(mac_client_handle_t, mac_tx_cookie_t);
+extern uint64_t mac_client_stat_get(mac_client_handle_t, uint_t);
+
+extern int mac_promisc_add(mac_client_handle_t, mac_client_promisc_type_t,
+ mac_rx_t, void *, mac_promisc_handle_t *, uint16_t);
+extern void mac_promisc_remove(mac_promisc_handle_t);
+
+extern mac_notify_handle_t mac_notify_add(mac_handle_t, mac_notify_t, void *);
+extern int mac_notify_remove(mac_notify_handle_t, boolean_t);
+extern void mac_notify_remove_wait(mac_handle_t);
+extern int mac_rename_primary(mac_handle_t, const char *);
+extern char *mac_client_name(mac_client_handle_t);
+
+extern int mac_open(const char *, mac_handle_t *);
+extern void mac_close(mac_handle_t);
+extern uint64_t mac_stat_get(mac_handle_t, uint_t);
+
+extern int mac_unicast_primary_set(mac_handle_t, const uint8_t *);
+extern void mac_unicast_primary_get(mac_handle_t, uint8_t *);
+extern void mac_unicast_primary_info(mac_handle_t, char *, boolean_t *);
+
+extern boolean_t mac_dst_get(mac_handle_t, uint8_t *);
+
+extern int mac_addr_random(mac_client_handle_t, uint_t, uint8_t *,
+ mac_diag_t *);
+
+extern int mac_addr_factory_reserve(mac_client_handle_t, int *);
+extern void mac_addr_factory_release(mac_client_handle_t, uint_t);
+extern void mac_addr_factory_value(mac_handle_t, int, uchar_t *, uint_t *,
+ char *, boolean_t *);
+extern uint_t mac_addr_factory_num(mac_handle_t);
+
+extern mac_tx_notify_handle_t mac_client_tx_notify(mac_client_handle_t,
+ mac_tx_notify_t, void *);
+
+extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
+extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
+extern int mac_client_set_resources(mac_client_handle_t,
+ mac_resource_props_t *);
+extern void mac_client_get_resources(mac_client_handle_t,
+ mac_resource_props_t *);
+
+/* bridging-related interfaces */
+extern int mac_set_pvid(mac_handle_t, uint16_t);
+extern uint16_t mac_get_pvid(mac_handle_t);
+extern uint32_t mac_get_llimit(mac_handle_t);
+extern uint32_t mac_get_ldecay(mac_handle_t);
+
+extern int mac_share_capable(mac_handle_t);
+extern int mac_share_bind(mac_client_handle_t, uint64_t, uint64_t *);
+extern void mac_share_unbind(mac_client_handle_t);
+
+extern int mac_set_mtu(mac_handle_t, uint_t, uint_t *);
+
+extern uint_t mac_hwgrp_num(mac_handle_t);
+extern void mac_get_hwgrp_info(mac_handle_t, int, uint_t *, uint_t *,
+ uint_t *, uint_t *, char *);
+
+extern uint32_t mac_no_notification(mac_handle_t);
+extern int mac_set_prop(mac_handle_t, mac_prop_t *, void *, uint_t);
+extern int mac_get_prop(mac_handle_t, mac_prop_t *, void *, uint_t, uint_t *);
+
+extern boolean_t mac_is_vnic(mac_handle_t);
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MAC_CLIENT_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h
new file mode 100644
index 000000000..19ae1d057
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h
@@ -0,0 +1,156 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009-2010 Oracle Corporation. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This file contains *private* MAC API definitions. This header file
+ * should only be included by kernel components which are part of the
+ * GLDv3 stack (dld, dls, aggr, softmac).
+ */
+
+#ifndef _SYS_MAC_CLIENT_PRIV_H
+#define _SYS_MAC_CLIENT_PRIV_H
+
+#include <sys/mac.h>
+#include <sys/mac_flow.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _KERNEL
+
+#ifdef DEBUG
+#define MAC_PERIM_HELD(mph) mac_perim_held(mph)
+#else
+#define MAC_PERIM_HELD(mph)
+#endif
+
+extern boolean_t mac_rx_bypass_set(mac_client_handle_t, mac_direct_rx_t,
+ void *);
+extern void mac_rx_bypass_enable(mac_client_handle_t);
+extern void mac_rx_bypass_disable(mac_client_handle_t);
+
+extern const mac_info_t *mac_info(mac_handle_t);
+extern boolean_t mac_info_get(const char *, mac_info_t *);
+extern boolean_t mac_promisc_get(mac_handle_t);
+
+extern int mac_start(mac_handle_t);
+extern void mac_stop(mac_handle_t);
+
+extern void mac_ioctl(mac_handle_t, queue_t *, mblk_t *);
+extern link_state_t mac_link_get(mac_handle_t);
+extern void mac_resource_set(mac_client_handle_t, mac_resource_add_t, void *);
+extern dev_info_t *mac_devinfo_get(mac_handle_t);
+extern void *mac_driver(mac_handle_t);
+extern boolean_t mac_capab_get(mac_handle_t, mac_capab_t, void *);
+extern boolean_t mac_sap_verify(mac_handle_t, uint32_t, uint32_t *);
+extern mblk_t *mac_header(mac_handle_t, const uint8_t *, uint32_t, mblk_t *,
+ size_t);
+extern int mac_header_info(mac_handle_t, mblk_t *, mac_header_info_t *);
+extern int mac_vlan_header_info(mac_handle_t, mblk_t *, mac_header_info_t *);
+extern mblk_t *mac_header_cook(mac_handle_t, mblk_t *);
+extern mblk_t *mac_header_uncook(mac_handle_t, mblk_t *);
+
+extern void mac_resource_set_common(mac_client_handle_t,
+ mac_resource_add_t, mac_resource_remove_t, mac_resource_quiesce_t,
+ mac_resource_restart_t, mac_resource_bind_t, void *);
+
+extern void mac_perim_enter_by_mh(mac_handle_t, mac_perim_handle_t *);
+extern int mac_perim_enter_by_macname(const char *, mac_perim_handle_t *);
+extern int mac_perim_enter_by_linkid(datalink_id_t, mac_perim_handle_t *);
+extern void mac_perim_exit(mac_perim_handle_t);
+extern boolean_t mac_perim_held(mac_handle_t);
+
+extern uint16_t mac_client_vid(mac_client_handle_t);
+extern int mac_vnic_unicast_set(mac_client_handle_t, const uint8_t *);
+extern boolean_t mac_client_is_vlan_vnic(mac_client_handle_t);
+
+extern void mac_client_poll_enable(mac_client_handle_t);
+extern void mac_client_poll_disable(mac_client_handle_t);
+
+extern int mac_resource_ctl_set(mac_client_handle_t, mac_resource_props_t *);
+extern void mac_resource_ctl_get(mac_client_handle_t, mac_resource_props_t *);
+
+/*
+ * Flow-related APIs for MAC clients.
+ */
+
+extern void mac_link_init_flows(mac_client_handle_t);
+extern void mac_link_release_flows(mac_client_handle_t);
+extern int mac_link_flow_add(datalink_id_t, char *, flow_desc_t *,
+ mac_resource_props_t *);
+extern int mac_link_flow_remove(char *);
+extern int mac_link_flow_modify(char *, mac_resource_props_t *);
+extern boolean_t mac_link_has_flows(mac_client_handle_t);
+
+typedef struct {
+ char fi_flow_name[MAXFLOWNAMELEN];
+ datalink_id_t fi_link_id;
+ flow_desc_t fi_flow_desc;
+ mac_resource_props_t fi_resource_props;
+} mac_flowinfo_t;
+
+extern int mac_link_flow_walk(datalink_id_t,
+ int (*)(mac_flowinfo_t *, void *), void *);
+extern int mac_link_flow_info(char *, mac_flowinfo_t *);
+
+extern void *mac_tx_hold(mac_client_handle_t);
+extern void mac_tx_rele(mac_client_handle_t, void *);
+extern void mac_rx_client_quiesce(mac_client_handle_t);
+extern void mac_rx_client_restart(mac_client_handle_t);
+extern void mac_srs_perm_quiesce(mac_client_handle_t, boolean_t);
+extern int mac_hwrings_get(mac_client_handle_t, mac_group_handle_t *,
+ mac_ring_handle_t *, mac_ring_type_t);
+extern void mac_hwring_setup(mac_ring_handle_t, mac_resource_handle_t);
+extern void mac_hwring_teardown(mac_ring_handle_t);
+extern int mac_hwring_disable_intr(mac_ring_handle_t);
+extern int mac_hwring_enable_intr(mac_ring_handle_t);
+extern int mac_hwring_start(mac_ring_handle_t);
+extern void mac_hwring_stop(mac_ring_handle_t);
+extern mblk_t *mac_hwring_poll(mac_ring_handle_t, int);
+#define MAC_HWRING_POLL(ring, bytes) \
+ (((ring)->mr_info.mri_poll) \
+ ((ring)->mr_info.mri_driver, (bytes)))
+
+extern int mac_hwgroup_addmac(mac_group_handle_t, const uint8_t *);
+extern int mac_hwgroup_remmac(mac_group_handle_t, const uint8_t *);
+
+extern void mac_set_upper_mac(mac_client_handle_t, mac_handle_t);
+
+extern int mac_mark_exclusive(mac_handle_t);
+extern void mac_unmark_exclusive(mac_handle_t);
+
+extern int32_t mac_client_intr_cpu(mac_client_handle_t);
+extern void mac_client_set_intr_cpu(void *, mac_client_handle_t, int32_t);
+extern void *mac_get_devinfo(mac_handle_t);
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MAC_CLIENT_PRIV_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h
new file mode 100644
index 000000000..6960f9229
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h
@@ -0,0 +1,498 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009-2010 Oracle Corporation. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_MAC_PROVIDER_H
+#define _SYS_MAC_PROVIDER_H
+
+#include <sys/types.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/stream.h>
+#include <sys/mkdev.h>
+#include <sys/mac_flow.h>
+#include <sys/mac.h>
+
+/*
+ * MAC Provider Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * MAC version identifier. This is used by mac_alloc() mac_register() to
+ * verify that incompatible drivers don't register.
+ */
+#define MAC_VERSION 0x2
+
+/*
+ * Opaque handle types
+ */
+typedef struct __mac_rule_handle *mac_rule_handle_t;
+
+/*
+ * Statistics
+ */
+
+#define XCVR_UNDEFINED 0
+#define XCVR_NONE 1
+#define XCVR_10 2
+#define XCVR_100T4 3
+#define XCVR_100X 4
+#define XCVR_100T2 5
+#define XCVR_1000X 6
+#define XCVR_1000T 7
+
+#ifdef _KERNEL
+
+/*
+ * Definitions for MAC Drivers Capabilities
+ */
+/*
+ * MAC layer capabilities. These capabilities are handled by the drivers'
+ * mc_capab_get() callbacks. Some capabilities require the driver to fill
+ * in a given data structure, and others are simply boolean capabilities.
+ * Note that capability values must be powers of 2 so that consumers and
+ * providers of this interface can keep track of which capabilities they
+ * care about by keeping a bitfield of these things around somewhere.
+ */
+typedef enum {
+ /*
+ * Capabilities reserved for internal use only
+ */
+ MAC_CAPAB_VNIC = 0x0001, /* data is mac_capab_vnic_t */
+ MAC_CAPAB_ANCHOR_VNIC = 0x0002, /* boolean only, no data */
+ MAC_CAPAB_AGGR = 0x0004, /* data is mac_capab_aggr_t */
+ MAC_CAPAB_NO_NATIVEVLAN = 0x0008, /* boolean only, no data */
+ MAC_CAPAB_NO_ZCOPY = 0x0010, /* boolean only, no data */
+ MAC_CAPAB_LEGACY = 0x0020, /* data is mac_capab_legacy_t */
+ MAC_CAPAB_VRRP = 0x0040, /* data is mac_capab_vrrp_t */
+
+ /*
+ * Public Capabilities
+ */
+ MAC_CAPAB_HCKSUM = 0x0100, /* data is a uint32_t */
+ MAC_CAPAB_LSO = 0x0200, /* data is mac_capab_lso_t */
+ MAC_CAPAB_RINGS = 0x0400, /* data is mac_capab_rings_t */
+ MAC_CAPAB_MULTIFACTADDR = 0x0800, /* mac_data_multifactaddr_t */
+ MAC_CAPAB_SHARES = 0x1000 /* data is mac_capab_share_t */
+
+ /* add new capabilities here */
+} mac_capab_t;
+
+
+/*
+ * LSO capability
+ */
+typedef struct lso_basic_tcp_ipv4_s {
+ t_uscalar_t lso_max; /* maximum payload */
+} lso_basic_tcp_ipv4_t;
+
+/*
+ * Currently supported flags for LSO.
+ */
+#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCP LSO capability */
+
+/*
+ * Future LSO capabilities can be added at the end of the mac_capab_lso_t.
+ * When such capability is added to the GLDv3 framework, the size of the
+ * mac_capab_lso_t it allocates and passes to the drivers increases. Older
+ * drivers wil access only the (upper) sections of that structure, that is the
+ * sections carrying the capabilities they understand. This ensures the
+ * interface can be safely extended in a binary compatible way.
+ */
+typedef struct mac_capab_lso_s {
+ t_uscalar_t lso_flags;
+ lso_basic_tcp_ipv4_t lso_basic_tcp_ipv4;
+ /* Add future lso capabilities here */
+} mac_capab_lso_t;
+
+/*
+ * Multiple Factory MAC Addresses Capability
+ */
+typedef struct mac_capab_multifactaddr_s {
+ /*
+ * Number of factory addresses
+ */
+ uint_t mcm_naddr;
+
+ /*
+ * Callbacks to query all the factory addresses.
+ */
+ void (*mcm_getaddr)(void *, uint_t, uint8_t *);
+} mac_capab_multifactaddr_t;
+
+/*
+ * Info and callbacks of legacy devices.
+ */
+typedef struct mac_capab_legacy_s {
+ /*
+ * Notifications that the legacy device does not support.
+ */
+ uint32_t ml_unsup_note;
+ /*
+ * dev_t of the legacy device; can be held to force attach.
+ */
+ dev_t ml_dev;
+ boolean_t (*ml_active_set)(void *);
+ void (*ml_active_clear)(void *);
+ int (*ml_fastpath_disable)(void *);
+ void (*ml_fastpath_enable)(void *);
+} mac_capab_legacy_t;
+
+/*
+ * MAC driver entry point types.
+ */
+typedef int (*mac_getstat_t)(void *, uint_t, uint64_t *);
+typedef int (*mac_start_t)(void *);
+typedef void (*mac_stop_t)(void *);
+typedef int (*mac_setpromisc_t)(void *, boolean_t);
+typedef int (*mac_multicst_t)(void *, boolean_t, const uint8_t *);
+typedef int (*mac_unicst_t)(void *, const uint8_t *);
+typedef void (*mac_ioctl_t)(void *, queue_t *, mblk_t *);
+typedef void (*mac_resources_t)(void *);
+typedef mblk_t *(*mac_tx_t)(void *, mblk_t *);
+typedef boolean_t (*mac_getcapab_t)(void *, mac_capab_t, void *);
+typedef int (*mac_open_t)(void *);
+typedef void (*mac_close_t)(void *);
+typedef int (*mac_set_prop_t)(void *, const char *, mac_prop_id_t,
+ uint_t, const void *);
+typedef int (*mac_get_prop_t)(void *, const char *, mac_prop_id_t,
+ uint_t, uint_t, void *, uint_t *);
+
+/*
+ * Drivers must set all of these callbacks except for mc_resources,
+ * mc_ioctl, and mc_getcapab, which are optional. If any of these optional
+ * callbacks are set, their appropriate flags must be set in mc_callbacks.
+ * Any future additions to this list must also be accompanied by an
+ * associated mc_callbacks flag so that the framework can grow without
+ * affecting the binary compatibility of the interface.
+ */
+typedef struct mac_callbacks_s {
+ uint_t mc_callbacks; /* Denotes which callbacks are set */
+ mac_getstat_t mc_getstat; /* Get the value of a statistic */
+ mac_start_t mc_start; /* Start the device */
+ mac_stop_t mc_stop; /* Stop the device */
+ mac_setpromisc_t mc_setpromisc; /* Enable or disable promiscuous mode */
+ mac_multicst_t mc_multicst; /* Enable or disable a multicast addr */
+ mac_unicst_t mc_unicst; /* Set the unicast MAC address */
+ mac_tx_t mc_tx; /* Transmit a packet */
+ mac_ioctl_t mc_ioctl; /* Process an unknown ioctl */
+ mac_getcapab_t mc_getcapab; /* Get capability information */
+ mac_open_t mc_open; /* Open the device */
+ mac_close_t mc_close; /* Close the device */
+ mac_set_prop_t mc_setprop;
+ mac_get_prop_t mc_getprop;
+} mac_callbacks_t;
+
+typedef struct mac_priv_prop_s {
+ char mpp_name[MAXLINKPROPNAME];
+ uint_t mpp_flags;
+} mac_priv_prop_t;
+
+/*
+ * Virtualization Capabilities
+ */
+/*
+ * The ordering of entries below is important. MAC_HW_CLASSIFIER
+ * is the cutoff below which are entries which don't depend on
+ * H/W. MAC_HW_CLASSIFIER and entries after that are cases where
+ * H/W has been updated through add/modify/delete APIs.
+ */
+typedef enum {
+ MAC_NO_CLASSIFIER = 0,
+ MAC_SW_CLASSIFIER,
+ MAC_HW_CLASSIFIER
+} mac_classify_type_t;
+
+typedef void (*mac_rx_func_t)(void *, mac_resource_handle_t, mblk_t *,
+ boolean_t);
+
+/*
+ * The virtualization level conveys the extent of the NIC hardware assistance
+ * for traffic steering employed for virtualization:
+ *
+ * MAC_VIRT_NONE: No assist for v12n.
+ *
+ * MAC_VIRT_LEVEL1: Multiple Rx rings with MAC address level
+ * classification between groups of rings.
+ * Requires the support of the MAC_CAPAB_RINGS
+ * capability.
+ *
+ * MAC_VIRT_HIO: Hybrid I/O capable MAC. Require the support
+ * of the MAC_CAPAB_SHARES capability.
+ *
+ * MAC_VIRT_SERIALIZE: Temporary flag *ONLY* for nxge. Mac layer
+ * uses this to enable mac Tx serializer on
+ * outbound traffic and to always enqueue
+ * incoming traffic on Rx soft rings in mac.
+ */
+#define MAC_VIRT_NONE 0x0
+#define MAC_VIRT_LEVEL1 0x1
+#define MAC_VIRT_HIO 0x2
+#define MAC_VIRT_SERIALIZE 0x4
+
+typedef enum {
+ MAC_RING_TYPE_RX = 1, /* Receive ring */
+ MAC_RING_TYPE_TX /* Transmit ring */
+} mac_ring_type_t;
+
+#define MAX_RINGS_PER_GROUP 128
+
+/*
+ * Grouping type of a ring group
+ *
+ * MAC_GROUP_TYPE_STATIC: The ring group can not be re-grouped.
+ * MAC_GROUP_TYPE_DYNAMIC: The ring group support dynamic re-grouping
+ */
+typedef enum {
+ MAC_GROUP_TYPE_STATIC = 1, /* Static ring group */
+ MAC_GROUP_TYPE_DYNAMIC /* Dynamic ring group */
+} mac_group_type_t;
+
+typedef struct __mac_ring_driver *mac_ring_driver_t;
+typedef struct __mac_group_driver *mac_group_driver_t;
+
+typedef struct mac_ring_info_s mac_ring_info_t;
+typedef struct mac_group_info_s mac_group_info_t;
+
+typedef void (*mac_get_ring_t)(void *, mac_ring_type_t, const int, const int,
+ mac_ring_info_t *, mac_ring_handle_t);
+typedef void (*mac_get_group_t)(void *, mac_ring_type_t, const int,
+ mac_group_info_t *, mac_group_handle_t);
+
+typedef void (*mac_group_add_ring_t)(mac_group_driver_t,
+ mac_ring_driver_t, mac_ring_type_t);
+typedef void (*mac_group_rem_ring_t)(mac_group_driver_t,
+ mac_ring_driver_t, mac_ring_type_t);
+
+/*
+ * Multiple Rings Capability
+ */
+typedef struct mac_capab_rings_s {
+ mac_ring_type_t mr_type; /* Ring type: Rx vs Tx */
+ mac_group_type_t mr_group_type; /* Dynamic vs static grouping */
+ uint_t mr_rnum; /* Number of rings */
+ uint_t mr_gnum; /* Number of ring groups */
+ mac_get_ring_t mr_rget; /* Get ring from driver */
+ mac_get_group_t mr_gget; /* Get ring group from driver */
+ mac_group_add_ring_t mr_gaddring; /* Add ring into a group */
+ mac_group_rem_ring_t mr_gremring; /* Remove ring from a group */
+} mac_capab_rings_t;
+
+/*
+ * Common ring functions and driver interfaces
+ */
+typedef int (*mac_ring_start_t)(mac_ring_driver_t, uint64_t);
+typedef void (*mac_ring_stop_t)(mac_ring_driver_t);
+
+typedef mblk_t *(*mac_ring_send_t)(void *, mblk_t *);
+typedef mblk_t *(*mac_ring_poll_t)(void *, int);
+
+typedef struct mac_ring_info_s {
+ mac_ring_driver_t mri_driver;
+ mac_ring_start_t mri_start;
+ mac_ring_stop_t mri_stop;
+ mac_intr_t mri_intr;
+ union {
+ mac_ring_send_t send;
+ mac_ring_poll_t poll;
+ } mrfunion;
+} mac_ring_info_s;
+
+#define mri_tx mrfunion.send
+#define mri_poll mrfunion.poll
+
+typedef int (*mac_group_start_t)(mac_group_driver_t);
+typedef void (*mac_group_stop_t)(mac_group_driver_t);
+typedef int (*mac_add_mac_addr_t)(void *, const uint8_t *);
+typedef int (*mac_rem_mac_addr_t)(void *, const uint8_t *);
+
+struct mac_group_info_s {
+ mac_group_driver_t mgi_driver; /* Driver reference */
+ mac_group_start_t mgi_start; /* Start the group */
+ mac_group_stop_t mgi_stop; /* Stop the group */
+ uint_t mgi_count; /* Count of rings */
+ mac_intr_t mgi_intr; /* Optional per-group intr */
+
+ /* Only used for rx groups */
+ mac_add_mac_addr_t mgi_addmac; /* Add a MAC address */
+ mac_rem_mac_addr_t mgi_remmac; /* Remove a MAC address */
+};
+
+/*
+ * Share management functions.
+ */
+typedef uint64_t mac_share_handle_t;
+
+/*
+ * Allocate and free a share. Returns ENOSPC if all shares have been
+ * previously allocated.
+ */
+typedef int (*mac_alloc_share_t)(void *, mac_share_handle_t *);
+typedef void (*mac_free_share_t)(mac_share_handle_t);
+
+/*
+ * Bind and unbind a share. Binding a share allows a domain
+ * to have direct access to the groups and rings associated with
+ * that share.
+ */
+typedef int (*mac_bind_share_t)(mac_share_handle_t, uint64_t, uint64_t *);
+typedef void (*mac_unbind_share_t)(mac_share_handle_t);
+
+/*
+ * Return information on about a share.
+ */
+typedef void (*mac_share_query_t)(mac_share_handle_t, mac_ring_type_t,
+ mac_ring_handle_t *, uint_t *);
+
+/*
+ * Basic idea, bind previously created ring groups to shares
+ * for them to be exported (or shared) by another domain.
+ * These interfaces bind/unbind the ring group to a share.
+ * The groups and their rings will be shared with the guest
+ * as soon as the share is bound.
+ */
+typedef int (*mac_share_add_group_t)(mac_share_handle_t,
+ mac_group_driver_t);
+typedef int (*mac_share_rem_group_t)(mac_share_handle_t,
+ mac_group_driver_t);
+
+typedef struct mac_capab_share_s {
+ uint_t ms_snum; /* Number of shares (vr's) */
+ void *ms_handle; /* Handle to driver. */
+ mac_alloc_share_t ms_salloc; /* Get a share from driver. */
+ mac_free_share_t ms_sfree; /* Return a share to driver. */
+ mac_share_add_group_t ms_sadd; /* Add a group to the share. */
+ mac_share_rem_group_t ms_sremove; /* Remove group from share. */
+ mac_share_query_t ms_squery; /* Query share constraints */
+ mac_bind_share_t ms_sbind; /* Bind a share */
+ mac_unbind_share_t ms_sunbind; /* Unbind a share */
+} mac_capab_share_t;
+
+typedef struct mac_capab_vrrp_s {
+ /* IPv6 or IPv4? */
+ int mcv_af;
+} mac_capab_vrrp_t;
+
+/*
+ * MAC registration interface
+ */
+typedef struct mac_register_s {
+ uint_t m_version; /* set by mac_alloc() */
+ const char *m_type_ident;
+ void *m_driver; /* Driver private data */
+ dev_info_t *m_dip;
+ uint_t m_instance;
+ uint8_t *m_src_addr;
+ uint8_t *m_dst_addr;
+ mac_callbacks_t *m_callbacks;
+ uint_t m_min_sdu;
+ uint_t m_max_sdu;
+ void *m_pdata;
+ size_t m_pdata_size;
+ uint32_t m_margin;
+ mac_priv_prop_t *m_priv_props;
+ size_t m_priv_prop_count;
+ uint32_t m_v12n; /* Virtualization level */
+} mac_register_t;
+
+/*
+ * Flags for mc_callbacks. Requiring drivers to set the flags associated
+ * with optional callbacks initialized in the structure allows the mac
+ * module to add optional callbacks in the future without requiring drivers
+ * to recompile.
+ */
+#define MC_IOCTL 0x001
+#define MC_GETCAPAB 0x002
+#define MC_OPEN 0x004
+#define MC_CLOSE 0x008
+#define MC_SETPROP 0x010
+#define MC_GETPROP 0x020
+
+/*
+ * Driver interface functions.
+ */
+extern void mac_sdu_get(mac_handle_t, uint_t *, uint_t *);
+extern int mac_maxsdu_update(mac_handle_t, uint_t);
+
+extern mac_register_t *mac_alloc(uint_t);
+extern void mac_free(mac_register_t *);
+extern int mac_register(mac_register_t *, mac_handle_t *);
+extern int mac_disable_nowait(mac_handle_t);
+extern int mac_disable(mac_handle_t);
+extern int mac_unregister(mac_handle_t);
+extern void mac_rx(mac_handle_t, mac_resource_handle_t,
+ mblk_t *);
+extern void mac_rx_ring(mac_handle_t, mac_ring_handle_t,
+ mblk_t *, uint64_t);
+extern void mac_link_update(mac_handle_t, link_state_t);
+extern void mac_link_redo(mac_handle_t, link_state_t);
+extern void mac_unicst_update(mac_handle_t,
+ const uint8_t *);
+extern void mac_dst_update(mac_handle_t, const uint8_t *);
+extern void mac_tx_update(mac_handle_t);
+extern void mac_tx_ring_update(mac_handle_t,
+ mac_ring_handle_t);
+extern void mac_capab_update(mac_handle_t);
+extern int mac_pdata_update(mac_handle_t, void *,
+ size_t);
+extern void mac_multicast_refresh(mac_handle_t,
+ mac_multicst_t, void *, boolean_t);
+extern void mac_unicst_refresh(mac_handle_t, mac_unicst_t,
+ void *);
+extern void mac_promisc_refresh(mac_handle_t,
+ mac_setpromisc_t, void *);
+extern boolean_t mac_margin_update(mac_handle_t, uint32_t);
+extern void mac_margin_get(mac_handle_t, uint32_t *);
+extern int mac_margin_remove(mac_handle_t, uint32_t);
+extern int mac_margin_add(mac_handle_t, uint32_t *,
+ boolean_t);
+extern void mac_init_ops(struct dev_ops *, const char *);
+extern void mac_fini_ops(struct dev_ops *);
+extern int mac_devt_to_instance(dev_t);
+extern minor_t mac_private_minor(void);
+
+extern mactype_register_t *mactype_alloc(uint_t);
+extern void mactype_free(mactype_register_t *);
+extern int mactype_register(mactype_register_t *);
+extern int mactype_unregister(const char *);
+
+extern boolean_t mac_unicst_verify(mac_handle_t,
+ const uint8_t *, uint_t);
+
+extern int mac_group_add_ring(mac_group_handle_t, int);
+extern void mac_group_rem_ring(mac_group_handle_t,
+ mac_ring_handle_t);
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MAC_PROVIDER_H */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf
index 2fe35f518..38737beaf 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxflt.conf
@@ -2,7 +2,7 @@
# Sun VirtualBox
# Solaris Host VBoxFlt Configuration
#
-# Copyright (C) 2008-2009 Sun Microsystems, Inc.
+# Copyright (C) 2008-2009 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -12,10 +12,6 @@
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-# Clara, CA 95054 USA or visit http://www.sun.com if you need
-# additional information or have any questions.
-#
# This needs to go into /platform/i86pc/kernel/drv,
# while the 64-bit driver object goes into the amd64
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp
index b441034a3..303508892 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetAdpInstall.cpp $ */
+/* $Id: NetAdpInstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NetAdpInstall - VBoxNetAdp installer command line tool
*/
/*
- * Copyright (C) 2009 Sun Microsystems, Inc.
+ * Copyright (C) 2009 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <vbox/WinNetConfig.h>
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp
index c53977320..c2628ad9f 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetAdpUninstall.cpp $ */
+/* $Id: NetAdpUninstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NetAdpUninstall - VBoxNetAdp uninstaller command line tool
*/
/*
- * Copyright (C) 2009 Sun Microsystems, Inc.
+ * Copyright (C) 2009 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <vbox/WinNetConfig.h>
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp
index b0d00d2e5..ef3aa122b 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetFltInstall.cpp $ */
+/* $Id: NetFltInstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NetFltInstall - VBoxNetFlt installer command line tool
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <vbox/WinNetConfig.h>
@@ -36,14 +32,13 @@ static VOID winNetCfgLogger (LPCWSTR szString)
}
/** Wrapper aroung GetfullPathNameW that will try an alternative INF location.
- *
- * The default location is the current directory. If not found there, the
- * alternative locatoin is the executable directory. If not found there either,
- * the first alternative is present to the caller.
- */
+ *
+ * The default location is the current directory. If not found there, the
+ * alternative locatoin is the executable directory. If not found there either,
+ * the first alternative is present to the caller.
+ */
static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFull)
{
-#ifdef DEBUG_bird /** @todo make this default behavior after 3.1. */
LPWSTR pwszFilePart;
DWORD dwSize = GetFullPathNameW(pwszName, cchFull, pwszFull, &pwszFilePart);
if(dwSize <= 0)
@@ -65,7 +60,7 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul
if(!wsz[cch])
{
dwSize = GetFullPathNameW(wsz, cchFull, pwszFull, NULL);
- if( dwSize > 0
+ if( dwSize > 0
&& GetFileAttributesW(pwszFull) != INVALID_FILE_ATTRIBUTES)
return dwSize;
break;
@@ -76,7 +71,6 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul
}
/* fallback */
-#endif
return GetFullPathNameW(pwszName, cchFull, pwszFull, NULL);
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp
index a40f9edc5..711042dd0 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp
@@ -1,10 +1,10 @@
-/* $Id: NetFltUninstall.cpp $ */
+/* $Id: NetFltUninstall.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* NetFltUninstall - VBoxNetFlt uninstaller command line tool
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <vbox/WinNetConfig.h>
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf
index 6907c1e89..5b4b226e7 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf
@@ -3,7 +3,7 @@
;
;
-; Copyright (C) 2008 Sun Microsystems, Inc.
+; Copyright (C) 2008 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-; Clara, CA 95054 USA or visit http://www.sun.com if you need
-; additional information or have any questions.
-;
;
; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c
index ae53204dc..056bfdc12 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-win.c $ */
+/* $Id: VBoxNetFlt-win.c 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -24,6 +20,7 @@
*/
#include "VBoxNetFltCommon-win.h"
+#include <VBox/intnetinline.h>
#include <iprt/thread.h>
/** represents the job element of the job queue
@@ -157,7 +154,7 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState)
if(CurNanoTS - StartNanoTS > 20000000)
{
DBGPRINT(("device not idle"));
- Assert(0);
+ AssertFailed();
// break;
}
#endif
@@ -179,9 +176,9 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength)
}
/* frees memory allocated with vboxNetFltWinMemAlloc */
-DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf)
+DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pvMemBuf)
{
- NdisFreeMemory(pMemBuf, 0, 0);
+ NdisFreeMemory(pvMemBuf, 0, 0);
}
/* frees ndis buffers used on send/receive */
@@ -262,7 +259,7 @@ static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool
}
else
{
- Assert(0);
+ AssertFailed();
}
return fStatus;
@@ -288,7 +285,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING
{
if(pDst->MaximumLength < pSrc->Length)
{
- Assert(0);
+ AssertFailed();
Status = NDIS_STATUS_RESOURCES;
}
else
@@ -307,35 +304,13 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING
/************************************************************************************
* PINTNETSG pSG manipulation functions
************************************************************************************/
-static void vboxNetFltWinReinitSG(PINTNETSG pSG)
-{
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsUsed = 0;
- pSG->cbTotal = 0;
-}
-
-static void vboxNetFltWinInitSG(PINTNETSG pSG, UINT cBufferCount)
-{
- pSG->pvOwnerData = NULL;
- pSG->pvUserData = NULL;
- pSG->pvUserData2 = NULL;
- pSG->cUsers = 1;
- pSG->fFlags = INTNETSG_FLAGS_TEMP;
- pSG->cSegsAlloc = cBufferCount;
- pSG->cSegsUsed = 0;
- pSG->cbTotal = 0;
-}
/* moves the contents of the given NDIS_BUFFER and all other buffers chained to it to the PINTNETSG
* the PINTNETSG is expected to contain one segment whose bugger is large enough to maintain
* the contents of the given NDIS_BUFFER and all other buffers chained to it */
static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
{
- UINT cbSeg = 0;
+ UINT cSegs = 0;
PINTNETSEG paSeg;
uint8_t * ptr;
PVOID pVirtualAddress;
@@ -388,7 +363,7 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE
* ndis buffer(s) point to (as opposed to vboxNetFltWinNdisBufferMoveToSG0 which copies the memory from ndis buffers(s) to PINTNETSG) */
static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
{
- UINT cbSeg = 0;
+ UINT cSegs = 0;
NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
PVOID pVirtualAddress;
UINT cbCurrentLength;
@@ -407,21 +382,21 @@ static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG
}
pSG->cbTotal += cbCurrentLength;
- pSG->aSegs[cbSeg].cb = cbCurrentLength;
- pSG->aSegs[cbSeg].pv = pVirtualAddress;
- pSG->aSegs[cbSeg].Phys = NIL_RTHCPHYS;
- cbSeg++;
+ pSG->aSegs[cSegs].cb = cbCurrentLength;
+ pSG->aSegs[cSegs].pv = pVirtualAddress;
+ pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS;
+ cSegs++;
NdisGetNextBuffer(
pBuffer,
&pBuffer);
}
- AssertFatal(cbSeg <= pSG->cSegsAlloc);
+ AssertFatal(cSegs <= pSG->cSegsAlloc);
if(fStatus == NDIS_STATUS_SUCCESS)
{
- pSG->cSegsUsed = cbSeg;
+ pSG->cSegsUsed = cSegs;
}
return fStatus;
@@ -432,13 +407,13 @@ static void vboxNetFltWinDeleteSG(PINTNETSG pSG)
vboxNetFltWinMemFree(pSG);
}
-static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSize)
+static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs)
{
PINTNETSG pSG;
- NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSize]));
+ NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
if(Status == STATUS_SUCCESS)
{
- vboxNetFltWinInitSG(pSG, cSize);
+ IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
return pSG;
}
@@ -448,7 +423,7 @@ static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSize)
/************************************************************************************
* packet queue functions
************************************************************************************/
-
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags
# ifdef DEBUG_NETFLT_PACKETS
@@ -548,7 +523,7 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
/* should never be here since the PINTNETSG is stored only when the underlying miniport
* indicates NDIS_STATUS_RESOURCES, we should never have this when processing
* the "from-host" packets */
- Assert(0);
+ AssertFailed();
LogFlow(("status is not pending, freeing myPacket (%p)\n", pMyPacket));
vboxNetFltWinFreeSGNdisPacket(pMyPacket, false);
}
@@ -565,7 +540,7 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
else
{
/*we failed to create our packet */
- Assert(0);
+ AssertFailed();
fStatus = NDIS_STATUS_FAILURE;
}
@@ -573,24 +548,30 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket
}
#endif
-static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_WORKER pWorker, PPACKET_INFO pInfo)
+static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_WORKER pWorker, PVOID pvPacket, const UINT fFlags)
+#else
+DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacket, const UINT fFlags)
+#endif
{
PNDIS_PACKET pPacket = NULL;
PINTNETSG pSG = NULL;
PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf);
- UINT fFlags;
NDIS_STATUS Status;
#ifndef VBOXNETADP
bool bSrcHost;
- bool bPending;
bool bDropIt;
+# ifndef VBOXNETFLT_NO_PACKET_QUEUE
+ bool bPending;
+# endif
+#endif
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ bool bDeleteSG = false;
#endif
#ifdef DEBUG_NETFLT_PACKETS
/* packet used for matching */
PNDIS_PACKET pTmpPacket = NULL;
#endif
- fFlags = GET_FLAGS_FROM_INFO(pInfo);
#ifndef VBOXNETADP
bSrcHost = (fFlags & PACKET_SRC_HOST) != 0;
#endif
@@ -618,7 +599,8 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
UINT uBytesCopied = 0;
UINT cbPacketLength;
- pPacket = (PNDIS_PACKET)GET_PACKET_FROM_INFO(pInfo);
+ pPacket = (PNDIS_PACKET)pvPacket;
+
LogFlow(("ndis packet info, packet (%p)\n", pPacket));
LogFlow(("preparing pSG"));
@@ -631,6 +613,9 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
Assert(cBufferCount);
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ pSG = vboxNetFltWinCreateSG(cBufferCount);
+#else
/* we can not allocate the INTNETSG on stack since in this case we may get stack overflow
* somewhere outside of our driver (3 pages of system thread stack does not seem to be enough)
*
@@ -651,11 +636,15 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
LogRel(("Failed to reallocate the pSG\n"));
}
}
+#endif
if(pSG)
{
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ bDeleteSG = true;
+#endif
/* reinitialize */
- vboxNetFltWinReinitSG(pSG);
+ IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, pSG->cSegsAlloc, 0 /*cSegsUsed*/);
/* convert the ndis buffers to INTNETSG */
Status = vboxNetFltWinNdisBuffersToSG(pCurrentBuffer, pSG);
@@ -683,7 +672,7 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
#else
/* we have both host and wire in ProtocolReceive */
#endif
- pSG = (PINTNETSG)GET_PACKET_FROM_INFO(pInfo);
+ pSG = (PINTNETSG)pvPacket;
LogFlow(("not ndis packet info, pSG (%p)\n", pSG));
}
@@ -728,13 +717,15 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
}
#endif
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
+
+# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
if(!bDropIt)
{
Status = vboxNetFltWinQuPostPacket(pAdapt, pPacket, pSG, fFlags
-# ifdef DEBUG_NETFLT_PACKETS
+# ifdef DEBUG_NETFLT_PACKETS
, pTmpPacket
-# endif
+# endif
);
if(Status == NDIS_STATUS_PENDING)
@@ -745,7 +736,7 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
}
}
else
-#endif
+# endif
{
Status = NDIS_STATUS_SUCCESS;
}
@@ -755,32 +746,32 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
{
if(!(fFlags & PACKET_MINE))
{
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
/* complete the packets */
if(fFlags & PACKET_SRC_HOST)
{
-#endif
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
+# endif
+# ifndef VBOX_NETFLT_ONDEMAND_BIND
/* NDIS_SET_PACKET_STATUS(pPacket, Status); */
NdisMSendComplete(pAdapt->hMiniportHandle, pPacket, Status);
-#endif
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+# endif
+# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
}
else
{
-#endif
-#ifndef VBOXNETADP
+# endif
+# ifndef VBOXNETADP
NdisReturnPackets(&pPacket, 1);
-#endif
-#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
+# endif
+# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
}
-#endif
+# endif
}
else
{
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
+# ifndef VBOX_NETFLT_ONDEMAND_BIND
Assert(!(fFlags & PACKET_SRC_HOST));
-#endif
+# endif
vboxNetFltWinFreeSGNdisPacket(pPacket, true);
}
}
@@ -789,9 +780,9 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
Assert(pSG);
vboxNetFltWinMemFree(pSG);
}
-#ifndef VBOXNETADP
+# ifndef VBOXNETADP
bPending = false;
-#endif
+# endif
} while(0);
#ifdef DEBUG_NETFLT_PACKETS
@@ -806,7 +797,17 @@ static bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_W
#else
return false;
#endif
+#else /* #ifdef VBOXNETFLT_NO_PACKET_QUEUE */
+ } while(0);
+# ifndef VBOXNETADP
+ return bDropIt;
+# else
+ return true;
+# endif
+#endif
}
+
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/*
* thread start function for the thread which processes the packets enqueued in our send and receive callbacks called by ndis
*
@@ -870,7 +871,7 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
LogFlow(("==> found info (%p)\n", pInfo));
- if(vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo))
+ if(vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags))
{
cNumPostedToHostWire++;
}
@@ -895,7 +896,7 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
PsTerminateSystemThread(STATUS_SUCCESS);
}
-
+#endif
/**
* thread start function for the job processing thread
*
@@ -1077,6 +1078,8 @@ static void vboxNetFltWinJobFiniQueue(PJOB_QUEUE pQueue)
}
}
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
+
/**
* initializes the packet queue
* */
@@ -1136,12 +1139,12 @@ DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance)
// Assert(pAdapt->pPacketQueueSG);
/* using the pPacketQueueSG as an indicator that the packet queue is initialized */
- RTSpinlockAcquire((pInstance)->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts((pInstance)->hSpinlock, &Tmp);
if(pWorker->pSG)
{
pSG = pWorker->pSG;
pWorker->pSG = NULL;
- RTSpinlockRelease((pInstance)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pInstance)->hSpinlock, &Tmp);
KeSetEvent(&pWorker->KillEvent, 0, FALSE);
KeWaitForSingleObject(pWorker->pThread, Executive,
@@ -1155,50 +1158,36 @@ DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance)
}
else
{
- RTSpinlockRelease((pInstance)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pInstance)->hSpinlock, &Tmp);
}
}
+#endif
+
/*
* creates the INTNETSG containing one segment pointing to the buffer of size cbBufSize
* the INTNETSG created should be cleaned with vboxNetFltWinMemFree
*/
-DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG)
+DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG)
{
- UINT cbBufferOffset;
- UINT cbMemSize;
NDIS_STATUS Status;
PINTNETSG pSG;
/* allocation:
* 1. SG_PACKET - with one aSegs pointing to
- * 2. buffer of cbPacketLength containing the entire packet */
- cbBufferOffset = sizeof(INTNETSG);
- /* make sure the buffer is aligned */
- if((cbBufferOffset & (sizeof(PVOID) - 1)) != 0)
- {
- cbBufferOffset += sizeof(PVOID);
- cbBufferOffset &= ~(sizeof(PVOID) - 1);
- }
-
- cbMemSize = cbBufferOffset + cbBufSize;
- Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbMemSize);
+ * 2. buffer of cbPacket containing the entire packet */
+ AssertCompileSizeAlignment(INTNETSG, sizeof(PVOID));
+ Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbPacket + sizeof(INTNETSG));
if(Status == NDIS_STATUS_SUCCESS)
{
- vboxNetFltWinInitSG(pSG, 1);
- pSG->aSegs[0].pv = (uint8_t *)pSG + cbBufferOffset;
- pSG->aSegs[0].Phys = NIL_RTHCPHYS;
- pSG->aSegs[0].cb = cbBufSize;
- pSG->cbTotal = cbBufSize;
- pSG->cSegsUsed = 1;
-
+ IntNetSgInitTemp(pSG, pSG + 1, cbPacket);
LogFlow(("pSG created (%p)\n", pSG));
-
*ppSG = pSG;
}
return Status;
}
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/**
* put the packet info to the queue
*/
@@ -1209,7 +1198,6 @@ DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKE
KeSetEvent(&pWorker->NotifyEvent, IO_NETWORK_INCREMENT, FALSE);
}
-
/**
* puts the packet to the queue
*
@@ -1251,7 +1239,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
fStatus = vboxNetFltWinAllocSG(cbPacketLength, &pSG);
if(fStatus != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
break;
}
@@ -1259,7 +1247,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
if(!pInfo)
{
- Assert(0);
+ AssertFailed();
/* TODO: what status to set? */
fStatus = NDIS_STATUS_FAILURE;
vboxNetFltWinMemFree(pSG);
@@ -1275,7 +1263,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
fStatus = vboxNetFltWinNdisBufferMoveToSG0(pBuffer, pSG);
if(fStatus != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
vboxNetFltWinPpFreePacketInfo(pInfo);
vboxNetFltWinMemFree(pSG);
break;
@@ -1289,7 +1277,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
if(!pInfo)
{
- Assert(0);
+ AssertFailed();
/* TODO: what status to set? */
fStatus = NDIS_STATUS_FAILURE;
break;
@@ -1307,6 +1295,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P
return fStatus;
}
+#endif
#ifndef VBOX_NETFLT_ONDEMAND_BIND
/*
@@ -1471,7 +1460,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac)
if(status != NDIS_STATUS_SUCCESS)
{
/* TODO */
- Assert(0);
+ AssertFailed();
}
return status;
@@ -1496,7 +1485,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHY
else
{
LogRel(("OID_GEN_PHYSICAL_MEDIUM failed: Status (0x%x)", Status));
- Assert(0);
+ AssertFailed();
}
}
return Status;
@@ -1519,7 +1508,7 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
if(status != NDIS_STATUS_SUCCESS)
{
/* TODO */
- Assert(0);
+ AssertFailed();
return false;
}
return (filter & NDIS_PACKET_TYPE_PROMISCUOUS) != 0;
@@ -1527,6 +1516,9 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
{
+/** @todo Need to report changes to the switch via:
+ * pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, fPromisc);
+ */
Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
{
@@ -1543,7 +1535,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
if(fStatus != NDIS_STATUS_SUCCESS)
{
/* TODO: */
- Assert(0);
+ AssertFailed();
return fStatus;
}
@@ -1576,7 +1568,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
if(fStatus != NDIS_STATUS_SUCCESS)
{
/* TODO */
- Assert(0);
+ AssertFailed();
return fStatus;
}
}
@@ -1698,11 +1690,13 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
NDIS_STATUS fStatus;
PNDIS_PACKET pPacket;
- Assert(pSG->cSegsUsed == 1);
- Assert(pSG->cbTotal == pSG->aSegs[0].cb);
Assert(pSG->aSegs[0].pv);
Assert(pSG->cbTotal >= sizeof(ETH_HEADER_SIZE));
+/** @todo Hrmpf, how can we fix this assumption? I fear this'll cause data
+ * corruption and maybe even BSODs ... */
+ AssertReturn(pSG->cSegsUsed == 1 || bCopyMemory, NULL);
+
#ifdef VBOX_NETFLT_ONDEMAND_BIND
NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hSendPacketPoolHandle);
#elif defined(VBOXNETADP)
@@ -1713,7 +1707,7 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
if(fStatus == NDIS_STATUS_SUCCESS)
{
PNDIS_BUFFER pBuffer;
- PVOID pMemBuf;
+ PVOID pvMemBuf;
/* @todo: generally we do not always need to zero-initialize the complete OOB data here, reinitialize only when/what we need,
* however we DO need to reset the status for the packets we indicate via NdisMIndicateReceivePacket to avoid packet loss
@@ -1722,38 +1716,38 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
if(bCopyMemory)
{
- fStatus = vboxNetFltWinMemAlloc(&pMemBuf, pSG->cbTotal);
+ fStatus = vboxNetFltWinMemAlloc(&pvMemBuf, pSG->cbTotal);
if(fStatus == NDIS_STATUS_SUCCESS)
{
- NdisMoveMemory(pMemBuf, pSG->aSegs[0].pv, pSG->cbTotal);
+ IntNetSgRead(pSG, pvMemBuf);
}
else
{
- Assert(0);
+ AssertFailed();
NdisFreePacket(pPacket);
pPacket = NULL;
}
}
else
{
- pMemBuf = pSG->aSegs[0].pv;
+ pvMemBuf = pSG->aSegs[0].pv;
}
if(fStatus == NDIS_STATUS_SUCCESS)
{
#ifdef VBOX_NETFLT_ONDEMAND_BIND
NdisAllocateBuffer(&fStatus, &pBuffer,
pAdapt->hSendBufferPoolHandle,
- pMemBuf,
+ pvMemBuf,
pSG->cbTotal);
#elif defined(VBOXNETADP)
NdisAllocateBuffer(&fStatus, &pBuffer,
pAdapt->hRecvBufferPoolHandle,
- pMemBuf,
+ pvMemBuf,
pSG->cbTotal);
#else
NdisAllocateBuffer(&fStatus, &pBuffer,
bToWire ? pAdapt->hSendBufferPoolHandle : pAdapt->hRecvBufferPoolHandle,
- pMemBuf,
+ pvMemBuf,
pSG->cbTotal);
#endif
@@ -1795,10 +1789,10 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
}
else
{
- Assert(0);
+ AssertFailed();
if(bCopyMemory)
{
- vboxNetFltWinMemFree(pMemBuf);
+ vboxNetFltWinMemFree(pvMemBuf);
}
NdisFreePacket(pPacket);
pPacket = NULL;
@@ -1806,7 +1800,7 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG
}
else
{
- Assert(0);
+ AssertFailed();
NdisFreePacket(pPacket);
pPacket = NULL;
}
@@ -1840,14 +1834,14 @@ DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeM
NdisUnchainBufferAtBack(pPacket, &pBuffer);
if(pBuffer != NULL)
{
- PVOID pMemBuf;
+ PVOID pvMemBuf;
UINT cbLength;
- NdisQueryBufferSafe(pBuffer, &pMemBuf, &cbLength, NormalPagePriority);
+ NdisQueryBufferSafe(pBuffer, &pvMemBuf, &cbLength, NormalPagePriority);
NdisFreeBuffer(pBuffer);
if(bFreeMem)
{
- vboxNetFltWinMemFree(pMemBuf);
+ vboxNetFltWinMemFree(pvMemBuf);
}
}
else
@@ -1918,7 +1912,7 @@ vboxNetFltWinUnload(
if (RT_FAILURE(rc))
{
/* TODO: we can not prevent driver unload here */
- Assert(0);
+ AssertFailed();
Log(("vboxNetFltWinTryFiniIdc - failed, busy.\n"));
}
@@ -2187,8 +2181,8 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO
RtlFreeAnsiString(&AnsiString);
if(RT_FAILURE(rc))
{
- Assert(0);
- Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
+ AssertFailed();
+ Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
break;
}
@@ -2204,8 +2198,8 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO
rc = vboxNetFltWinAttachToInterface(pInstance, &Context, true);
if(RT_FAILURE(rc))
{
- Assert(0);
- Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
+ AssertFailed();
+ Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
/* release netflt */
vboxNetFltRelease(pInstance, false);
@@ -2270,7 +2264,7 @@ static NDIS_STATUS vboxNetFltWinPtFiniUnbind(PADAPT pAdapt)
Status = vboxNetFltWinPtDoUnbinding(pAdapt, true);
if(Status != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
/* TODO: should we break ? */
/* break; */
}
@@ -2311,7 +2305,9 @@ DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt)
#ifndef VBOX_NETFLT_ONDEMAND_BIND
/* moved to vboxNetFltWinDetachFromInterfaceWorker */
#else
+# ifndef VBOXNETFLT_NO_PACKET_QUEUE
vboxNetFltWinQuFiniPacketQueue(pAdapt);
+# endif
#endif
vboxNetFltWinFiniBuffers(pAdapt);
@@ -2392,7 +2388,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt)
Status = vboxNetFltWinMemAlloc((PVOID*)&pAdapt->DeviceName.Buffer, pOurDeviceName->Length);
if(Status != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
pAdapt->DeviceName.Buffer = NULL;
break;
}
@@ -2401,7 +2397,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt)
Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName);
if(Status != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
break;
}
# endif
@@ -2445,7 +2441,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt)
rc = vboxNetFltWinConnectIt(pNetFlt);
if(RT_FAILURE(rc))
{
- Assert(0);
+ AssertFailed();
Status = NDIS_STATUS_FAILURE;
break;
}
@@ -2691,7 +2687,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
if(uTotalPacketLength1 != uTotalPacketLength2)
{
- Assert(0);
+ AssertFailed();
bMatch = false;
}
else
@@ -2744,7 +2740,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p
if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
{
bMatch = false;
- Assert(0);
+ AssertFailed();
break;
}
@@ -2791,7 +2787,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
if(uTotalPacketLength1 != uTotalPacketLength2)
{
- Assert(0);
+ AssertFailed();
bMatch = false;
}
else
@@ -2833,7 +2829,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa
if(memcmp(pMemBuf1, pMemBuf2, ucbLength2Match))
{
bMatch = false;
- Assert(0);
+ AssertFailed();
break;
}
ucbMatch -= ucbLength2Match;
@@ -2944,7 +2940,7 @@ static int vboxNetFltWinInitIdc()
if(g_bIdcInitialized)
{
#ifdef VBOX_NETFLT_ONDEMAND_BIND
- Assert(0);
+ AssertFailed();
#endif
rc = VINF_ALREADY_INITIALIZED;
break;
@@ -3024,7 +3020,7 @@ static int vboxNetFltWinInitNetFlt()
rc = vboxNetFltWinInitNetFltBase();
if(RT_FAILURE(rc))
{
- Assert(0);
+ AssertFailed();
break;
}
@@ -3037,7 +3033,7 @@ static int vboxNetFltWinInitNetFlt()
rc = vboxNetFltWinInitIdc();
if (RT_FAILURE(rc))
{
- Assert(0);
+ AssertFailed();
vboxNetFltWinFiniNetFltBase();
break;
}
@@ -3059,13 +3055,15 @@ static int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
Assert(pThis);
Assert(pThis->fDisconnectedFromHost);
Assert(!pThis->fRediscoveryPending);
- Assert(!pThis->fActive);
+ Assert(pThis->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
#ifndef VBOXNETADP
Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized);
Assert(!pAdapt->hBindingHandle);
#endif
Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Deinitialized);
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
Assert(!pThis->u.s.PacketQueueWorker.pSG);
+#endif
// Assert(!pAdapt->hMiniportHandle);
#ifndef VBOX_NETFLT_ONDEMAND_BIND
@@ -3075,7 +3073,7 @@ static int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
Status = vboxNetFltWinPtFiniUnbind(pAdapt);
if(Status != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
/* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
}
#endif
@@ -3087,7 +3085,9 @@ static int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
static NDIS_STATUS vboxNetFltWinDisconnectIt(PVBOXNETFLTINS pInstance)
{
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
vboxNetFltWinQuFiniPacketQueue(pInstance);
+#endif
return NDIS_STATUS_SUCCESS;
}
@@ -3156,7 +3156,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn
Status = vboxNetFltWinPtFiniUnbind(pAdapt);
if(Status != NDIS_STATUS_SUCCESS)
{
- Assert(0);
+ AssertFailed();
/* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
}
#endif
@@ -3187,6 +3187,35 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn
return Status;
}
+
+/**
+ * Checks if the host (not us) has put the adapter in promiscuous mode.
+ *
+ * @returns true if promiscuous, false if not.
+ * @param pThis The instance.
+ */
+static bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis)
+{
+#ifndef VBOXNETADP
+ PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
+ if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
+ {
+ bool bPromiscuous;
+ if(!vboxNetFltWinReferenceAdapt(pAdapt))
+ return false;
+
+ bPromiscuous = (pAdapt->fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
+ /*vboxNetFltWinIsPromiscuous(pAdapt);*/
+
+ vboxNetFltWinDereferenceAdapt(pAdapt);
+ return bPromiscuous;
+ }
+ return false;
+#else
+ return true;
+#endif
+}
+
/**
* Worker for vboxNetFltWinAttachToInterface.
*
@@ -3262,12 +3291,11 @@ static void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized);
//#endif
- RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
/* 4. mark as connected */
+ RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp);
ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
-
- RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
pAttachInfo->Status = VINF_SUCCESS;
pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS;
@@ -3276,6 +3304,20 @@ static void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
vboxNetFltRelease(pThis, false);
+ /* 5. Report MAC address, promiscuousness and GSO capabilities. */
+ /** @todo Keep these up to date, esp. the promiscuous mode bit. */
+ if ( pThis->pSwitchPort
+ && vboxNetFltTryRetainBusyNotDisconnected(pThis))
+ {
+ pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
+ pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort,
+ vboxNetFltWinIsPromiscuous2(pThis));
+ pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0,
+ INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
+ /** @todo We should be able to do pfnXmit at DISPATCH_LEVEL... */
+ pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
+ vboxNetFltRelease(pThis, true /*fBusy*/);
+ }
return;
}
AssertBreakpoint();
@@ -3319,7 +3361,7 @@ static void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
break;
}
- Status = vboxNetFltWinGetMacAddress(pAdapt, &pThis->u.s.Mac);
+ Status = vboxNetFltWinGetMacAddress(pAdapt, &pThis->u.s.MacAddr);
if (Status != NDIS_STATUS_SUCCESS)
{
vboxNetFltWinPtFiniUnbind(pAdapt);
@@ -3455,7 +3497,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
}
else
{
- Assert(0);
+ AssertFailed();
rc = VERR_NO_MEMORY;
}
}
@@ -3479,7 +3521,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
}
else
{
- Assert(0);
+ AssertFailed();
#ifdef VBOXNETADP
STATISTIC_INCREASE(pAdapt->cRxError);
#endif
@@ -3498,41 +3540,6 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
return rc;
}
-bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
-{
-#ifndef VBOXNETADP
- PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
- if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
- {
- bool bPromiscuous;
- if(!vboxNetFltWinReferenceAdapt(pAdapt))
- return false;
-
- bPromiscuous = (pAdapt->fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
- /*vboxNetFltWinIsPromiscuous(pAdapt);*/
-
- vboxNetFltWinDereferenceAdapt(pAdapt);
- return bPromiscuous;
- }
- return false;
-#else
- return true;
-#endif
-}
-
-void vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
-{
- *pMac = pThis->u.s.Mac;
-}
-
-bool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
-{
- /* ASSUMES that the MAC address never changes. */
- return pThis->u.s.Mac.au16[0] == pMac->au16[0]
- && pThis->u.s.Mac.au16[1] == pMac->au16[1]
- && pThis->u.s.Mac.au16[2] == pMac->au16[2];
-}
-
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
{
#ifndef VBOXNETADP
@@ -3544,25 +3551,25 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
* this might include all packets queued for processing */
for(;;)
{
- if(fActive)
- {
- if(!pThis->u.s.cModePassThruRefs)
- {
- break;
- }
- }
- else
- {
- if(!pThis->u.s.cModeNetFltRefs)
- {
- break;
- }
- }
- vboxNetFltWinSleep(2);
+ if(fActive)
+ {
+ if(!pThis->u.s.cModePassThruRefs)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if(!pThis->u.s.cModeNetFltRefs)
+ {
+ break;
+ }
+ }
+ vboxNetFltWinSleep(2);
}
if(!vboxNetFltWinReferenceAdapt(pAdapt))
- return;
+ return;
#ifndef VBOXNETADP
/* the packets put to ReceiveQueue Array are currently not holding the references,
@@ -3609,7 +3616,7 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
if(Status != NDIS_STATUS_SUCCESS)
{
DBGPRINT(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
- Assert(0);
+ AssertFailed();
LogRel(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
}
}
@@ -3658,7 +3665,9 @@ int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
{
+#if !defined(VBOXNETADP) || !defined(VBOXNETFLT_NO_PACKET_QUEUE)
NDIS_STATUS Status;
+#endif
PVBOXNETFLTINS pInstance = pInfo->pNetFltIf;
PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
@@ -3668,10 +3677,13 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
if(vboxNetFltWinReferenceAdapt(pAdapt))
{
#ifndef VBOXNETADP
- Status = vboxNetFltWinGetMacAddress(pAdapt, &pInstance->u.s.Mac);
+ Status = vboxNetFltWinGetMacAddress(pAdapt, &pInstance->u.s.MacAddr);
if (Status == NDIS_STATUS_SUCCESS)
#endif
{
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ pInfo->Status = VINF_SUCCESS;
+#else
Status = vboxNetFltWinQuInitPacketQueue(pInstance);
if(Status == NDIS_STATUS_SUCCESS)
{
@@ -3681,6 +3693,7 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
{
pInfo->Status = VERR_GENERAL_FAILURE;
}
+#endif
}
#ifndef VBOXNETADP
else
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h
index 31d1cac7e..ae00a5a36 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFlt-win.h $ */
+/* $Id: VBoxNetFlt-win.h 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -210,6 +206,9 @@ DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo)
/** sets flags to the packet info */
#define SET_FLAGS_TO_INFO(_pPacketInfo, _fFlags) (ASMAtomicUoWriteU32((volatile uint32_t *)&(_pPacketInfo)->fFlags, (_fFlags)))
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pInstance, PVOID pvPacket, const UINT fFlags);
+#else
DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags);
#ifndef VBOX_NETFLT_ONDEMAND_BIND
@@ -218,6 +217,9 @@ DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance);
DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
#endif
+#endif /* #ifndef VBOXNETFLT_NO_PACKET_QUEUE */
+
+
#ifndef VBOXNETADP
/**
* searches the list entry in a single-linked list
@@ -426,13 +428,13 @@ extern RTMAC g_vboxNetFltWinVerifyMACGuest;
# define VBOXNETFLT_LBVERIFY(_pnf, _p) \
do { \
Assert(!vboxNetFltWinCheckMACs(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
- Assert(!vboxNetFltWinCheckMACs(_p, NULL, &(_pnf)->u.s.Mac)); \
+ Assert(!vboxNetFltWinCheckMACs(_p, NULL, &(_pnf)->u.s.MacAddr)); \
} while(0)
# define VBOXNETFLT_LBVERIFYSG(_pnf, _p) \
do { \
Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &g_vboxNetFltWinVerifyMACGuest)); \
- Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &(_pnf)->u.s.Mac)); \
+ Assert(!vboxNetFltWinCheckMACsSG(_p, NULL, &(_pnf)->u.s.MacAddr)); \
} while(0)
#else
@@ -483,44 +485,44 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState);
DECLINLINE(void) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns)
{
- ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
+ ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
}
DECLINLINE(void) vboxNetFltWinReferenceModePassThru(PVBOXNETFLTINS pIns)
{
- ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
+ ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
}
DECLINLINE(void) vboxNetFltWinIncReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
{
- ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, v);
+ ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, v);
}
DECLINLINE(void) vboxNetFltWinIncReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
{
- ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, v);
+ ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, v);
}
DECLINLINE(void) vboxNetFltWinDereferenceModeNetFlt(PVBOXNETFLTINS pIns)
{
- ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
+ ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
}
DECLINLINE(void) vboxNetFltWinDereferenceModePassThru(PVBOXNETFLTINS pIns)
{
- ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
+ ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
}
DECLINLINE(void) vboxNetFltWinDecReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
{
- Assert(v);
- ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, (uint32_t)(-((int32_t)v)));
+ Assert(v);
+ ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, (uint32_t)(-((int32_t)v)));
}
DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
{
- Assert(v);
- ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
+ Assert(v);
+ ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
}
DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
@@ -592,7 +594,7 @@ DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pS
DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
{
- Assert(v);
+ Assert(v);
ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
}
@@ -606,7 +608,7 @@ DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE p
DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
{
- Assert(v);
+ Assert(v);
if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
{
ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, v);
@@ -639,22 +641,22 @@ DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAd
pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
- if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
+ RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
+ if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
{
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
return NULL;
}
if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
{
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
return NULL;
}
vboxNetFltRetain((pNetFlt), true /* fBusy */);
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
return pNetFlt;
}
@@ -663,29 +665,29 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAP
{
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
#ifndef VBOXNETADP
if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
#else
if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
#endif
{
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
*pbNetFltActive = false;
return false;
}
- if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
+ if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
{
- vboxNetFltWinReferenceModePassThru(pNetFlt);
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ vboxNetFltWinReferenceModePassThru(pNetFlt);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
*pbNetFltActive = false;
return true;
}
vboxNetFltRetain((pNetFlt), true /* fBusy */);
- vboxNetFltWinReferenceModeNetFlt(pNetFlt);
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ vboxNetFltWinReferenceModeNetFlt(pNetFlt);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
*pbNetFltActive = true;
return true;
@@ -707,22 +709,22 @@ DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT
pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
- if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
+ RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
+ if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
{
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
return NULL;
}
if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v))
{
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
return NULL;
}
vboxNetFltRetain((pNetFlt), true /* fBusy */);
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
/* we have marked it as busy, so can do the res references outside the lock */
for(i = 0; i < v-1; i++)
@@ -745,32 +747,32 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PA
return false;
}
- RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp);
#ifndef VBOXNETADP
if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
#else
if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
#endif
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
*pbNetFltActive = false;
return false;
}
- if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
+ if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE)
{
- vboxNetFltWinIncReferenceModePassThru(pNetFlt, v);
+ vboxNetFltWinIncReferenceModePassThru(pNetFlt, v);
- RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp);
*pbNetFltActive = false;
return true;
}
vboxNetFltRetain(pNetFlt, true /* fBusy */);
- vboxNetFltWinIncReferenceModeNetFlt(pNetFlt, v);
+ vboxNetFltWinIncReferenceModeNetFlt(pNetFlt, v);
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
/* we have marked it as busy, so can do the res references outside the lock */
for(i = 0; i < v-1; i++)
@@ -793,14 +795,14 @@ DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_
vboxNetFltRelease(pNetFlt, true);
}
- vboxNetFltWinDecReferenceModeNetFlt(pNetFlt, n);
+ vboxNetFltWinDecReferenceModeNetFlt(pNetFlt, n);
}
DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
{
vboxNetFltRelease(pNetFlt, true);
- vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
+ vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
}
DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v)
@@ -836,7 +838,7 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
return false;
}
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
#ifdef VBOX_NETFLT_ONDEMAND_BIND
if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState))
#elif defined(VBOXNETADP)
@@ -845,11 +847,11 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
#endif
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
return true;
}
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
return false;
}
@@ -857,7 +859,7 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
{
PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
#ifdef VBOX_NETFLT_ONDEMAND_BIND
if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
#elif defined(VBOXNETADP)
@@ -866,11 +868,11 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
#endif
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
return true;
}
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
return false;
}
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc
index cad268553..69e252c59 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Sun Microsystems, Inc.
+ * Copyright (C) 2009 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -8,10 +8,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <windows.h>
@@ -29,7 +25,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0x0L
FILEOS VOS_NT_WINDOWS32
@@ -42,11 +38,11 @@ BEGIN
BEGIN
VALUE "CompanyName", VBOX_RC_COMPANY_NAME
VALUE "FileDescription", DESCRIPTION_STR
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
VALUE "InternalName", FILENAME_STR
VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
VALUE "OriginalFilename", FILENAME_STR
- VALUE "ProductName", "Sun VirtualBox\0"
+ VALUE "ProductName", "Sun VirtualBox\0"
VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf
index 53bf94320..b11c2b559 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf
@@ -3,7 +3,7 @@
;
;
-; Copyright (C) 2008 Sun Microsystems, Inc.
+; Copyright (C) 2008 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-; Clara, CA 95054 USA or visit http://www.sun.com if you need
-; additional information or have any questions.
-;
;
; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltA-win.asm b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltA-win.asm
deleted file mode 100644
index af47abbd7..000000000
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltA-win.asm
+++ /dev/null
@@ -1,33 +0,0 @@
-; $Id: VBoxNetFltA-win.asm $
-;; @file
-; VBoxNetFlt - Unwind Wrappers for 64-bit NT.
-;
-
-;
-; Copyright (C) 2008 Sun Microsystems, Inc.
-;
-; This file is part of VirtualBox Open Source Edition (OSE), as
-; available from http://www.virtualbox.org. This file is free software;
-; you can redistribute it and/or modify it under the terms of the GNU
-; General Public License (GPL) as published by the Free Software
-; Foundation, in version 2 as it comes in the "COPYING" file of the
-; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-;
-; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-; Clara, CA 95054 USA or visit http://www.sun.com if you need
-; additional information or have any questions.
-;
-
-%include "iprt/ntwrap.mac"
-
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortRetain
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortRelease
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortDisconnectAndRelease
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortSetActive
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortWaitForIdle
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortGetMacAddress
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortIsHostMac
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortIsPromiscuous
-NtWrapDyn2DrvFunctionWithAllRegParams netfltNtWrap, vboxNetFltPortXmit
-
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h
index 6cd331557..42792a985 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltCommon-win.h $ */
+/* $Id: VBoxNetFltCommon-win.h 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFltCommon.h - Network Filter Driver (Host), Windows Specific Code. Common headeer with commonly used defines and decls
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -26,15 +22,7 @@
#ifndef ___VBoxNetFltCommon_win_h___
#define ___VBoxNetFltCommon_win_h___
-#ifndef VBOX_NETFLT_ONDEMAND_BIND
-# define NDIS_MINIPORT_DRIVER
-# define NDIS50_MINIPORT 1
-#endif
-
-#define BINARY_COMPATIBLE 0
-#define NDIS_WDM 0
-#define NDIS50 1
-#define NTSTRSAFE_LIB
+//#define NTSTRSAFE_LIB
#ifdef DEBUG
//# define DEBUG_NETFLT_PACKETS
@@ -187,6 +175,7 @@ typedef struct VBOXNETFLTINS *PVBOXNETFLTINS;
* if clear the packet comes from the wire (underlying miniport) */
#define PACKET_SRC_HOST 0x00000002
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
/** flag specifying the packet was originated by our driver
* i.e. we could use it on our needs and should not return it
* we are enqueueing "our" packets on ProtocolReceive call-back when
@@ -197,6 +186,7 @@ typedef struct VBOXNETFLTINS *PVBOXNETFLTINS;
/** flag passed to vboxNetFltWinQuEnqueuePacket specifying that the packet should be copied
* this is supported for Ndis Packet only */
#define PACKET_COPY 0x00000008
+#endif
/** packet queue element containing the packet info */
typedef struct _PACKET_INFO
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c
index 40304dc7c..f55bb511c 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltMp-win.c $ */
+/* $Id: VBoxNetFltMp-win.c 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -30,17 +26,17 @@
#else
/** driver handle */
-static NDIS_HANDLE g_hDriverHandle = NULL;
+static NDIS_HANDLE g_hDriverHandle = NULL;
/** Ndis wrapper handle */
-static NDIS_HANDLE g_hNdisWrapperHandle;
+static NDIS_HANDLE g_hNdisWrapperHandle;
/** device handle for ioctl interface this is not used currently and should be removed soon */
-static NDIS_HANDLE g_hNdisDeviceHandle = NULL;
+static NDIS_HANDLE g_hNdisDeviceHandle = NULL;
/** device object used for ioctl interface this is not used currently and should be removed soon */
-static PDEVICE_OBJECT g_pControlDeviceObject = NULL;
+static PDEVICE_OBJECT g_pControlDeviceObject = NULL;
/** ioctl device ref count */
-static LONG g_cControlDeviceRefs = 0;
+static LONG g_cControlDeviceRefs = 0;
/** true if control device needs to be dereferenced before destroying */
-static bool g_bControlDeviceReferenced = false;
+static bool g_bControlDeviceReferenced = false;
enum _DEVICE_STATE
{
@@ -489,7 +485,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt)
* Set the flag that the miniport below is unbinding, so the request handlers will
* fail any request comming later
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
@@ -497,7 +493,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt)
vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing);
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
vboxNetFltWinWaitDereference(&pAdapt->MPState);
@@ -551,7 +547,7 @@ static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PADAPT pAdapt, NDIS_HANDLE hMi
{
rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData);
- Assert(RT_SUCCESS(rc));
+ AssertRC(rc);
if(RT_SUCCESS(rc))
{
break;
@@ -587,7 +583,7 @@ static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PADAPT pAdapt, NDIS_HANDLE hMi
vboxNetFltWinGenerateMACAddress(&mac);
}
- pThis->u.s.Mac = mac;
+ pThis->u.s.MacAddr = mac;
return NDIS_STATUS_SUCCESS;
}
@@ -803,7 +799,7 @@ vboxNetFltWinMpSendPackets(
)
{
PADAPT pAdapt = (PADAPT)fMiniportAdapterContext;
- NDIS_STATUS fStatus;
+ NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
UINT i;
PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
bool bNetFltActive;
@@ -817,13 +813,13 @@ vboxNetFltWinMpSendPackets(
uint32_t cPassThruRefs;
if(bNetFltActive)
{
- cNetFltRefs = cNumberOfPackets;
- cPassThruRefs = 0;
+ cNetFltRefs = cNumberOfPackets;
+ cPassThruRefs = 0;
}
else
{
- cPassThruRefs = cNumberOfPackets;
- cNetFltRefs = 0;
+ cPassThruRefs = cNumberOfPackets;
+ cNetFltRefs = 0;
}
for (i = 0; i < cNumberOfPackets; i++)
@@ -833,7 +829,12 @@ vboxNetFltWinMpSendPackets(
pPacket = pPacketArray[i];
if(!cNetFltRefs
- || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS)
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, PACKET_SRC_HOST)
+#else
+ || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS
+#endif
+ )
{
#ifndef VBOXNETADP
fStatus = vboxNetFltWinSendPassThru(pAdapt, pPacket);
@@ -862,8 +863,14 @@ vboxNetFltWinMpSendPackets(
}
else
{
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ NdisMSendComplete(pAdapt->hMiniportHandle,
+ pPacket,
+ NDIS_STATUS_SUCCESS);
+#else
cAdaptRefs--;
cNetFltRefs--;
+#endif
}
}
@@ -1004,11 +1011,11 @@ vboxNetFltWinMpQueryInformation(
/*
* If the miniport below is binding, fail the request
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_FAILURE;
break;
}
@@ -1020,7 +1027,7 @@ vboxNetFltWinMpQueryInformation(
&& (pAdapt->bStandingBy == FALSE))
{
pAdapt->bQueuedRequest = TRUE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_PENDING;
break;
}
@@ -1029,13 +1036,13 @@ vboxNetFltWinMpQueryInformation(
*/
if (pAdapt->bStandingBy == TRUE)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_FAILURE;
break;
}
pAdapt->bOutstandingRequests = TRUE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
{
bool fNetFltActive;
@@ -1053,14 +1060,14 @@ vboxNetFltWinMpQueryInformation(
vboxNetFltWinDereferenceNetFlt(pNetFlt);
vboxNetFltWinDereferenceAdapt(pAdapt);
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
pAdapt->bOutstandingRequests = FALSE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
break;
}
else if(fAdaptActive)
{
- pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU;
+ pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU;
/* we're cleaning it in RequestComplete */
}
}
@@ -1349,10 +1356,10 @@ vboxNetFltWinMpSetInformation(
/*
* If the miniport below is unbinding, fail the request
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_FAILURE;
break;
}
@@ -1365,7 +1372,7 @@ vboxNetFltWinMpSetInformation(
&& (pAdapt->bStandingBy == FALSE))
{
pAdapt->bQueuedRequest = TRUE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_PENDING;
break;
}
@@ -1374,18 +1381,18 @@ vboxNetFltWinMpSetInformation(
*/
if (pAdapt->bStandingBy == TRUE)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Status = NDIS_STATUS_FAILURE;
break;
}
pAdapt->bOutstandingRequests = TRUE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
{
/* need to disable cleaning promiscuous here ?? */
- bool fNetFltActive;
+ bool fNetFltActive;
const bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &fNetFltActive);
Assert(InformationBuffer);
@@ -1416,9 +1423,9 @@ vboxNetFltWinMpSetInformation(
vboxNetFltWinDereferenceNetFlt(pNetFlt);
vboxNetFltWinDereferenceAdapt(pAdapt);
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
pAdapt->bOutstandingRequests = FALSE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
break;
}
}
@@ -1862,7 +1869,7 @@ Notes: Read "Minimizing Miniport Driver Initialization Time" in the DDK
//
{
PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt));
- pInfo = &pNetFlt->u.s.Mac;
+ pInfo = &pNetFlt->u.s.MacAddr;
ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH;
}
break;
@@ -1876,7 +1883,7 @@ Notes: Read "Minimizing Miniport Driver Initialization Time" in the DDK
//
{
PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt));
- pInfo = &pNetFlt->u.s.Mac;
+ pInfo = &pNetFlt->u.s.MacAddr;
ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH;
}
break;
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h
index 82de0714a..317622957 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltMp-win.h $ */
+/* $Id: VBoxNetFltMp-win.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c
index 23191fef9..182e8fd5f 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltPt-win.c $ */
+/* $Id: VBoxNetFltPt-win.c 29108 2010-05-05 20:17:42Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -302,7 +298,7 @@ vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind)
* Set the flag that the miniport below is unbinding, so the request handlers will
* fail any request comming later
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
@@ -335,7 +331,7 @@ vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind)
}
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
if (CompleteRequest == TRUE)
{
@@ -581,15 +577,15 @@ vboxNetFltWinPtRequestComplete(
}
if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
{
- /* we're here _ONLY_ in the passthru mode */
- Assert(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU);
- if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU)
- {
- PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
- Assert(!pNetFltIf->fActive);
- vboxNetFltWinDereferenceModePassThru(pNetFltIf);
- vboxNetFltWinDereferenceAdapt(pAdapt);
- }
+ /* we're here _ONLY_ in the passthru mode */
+ Assert(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU);
+ if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU)
+ {
+ PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt);
+ Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
+ vboxNetFltWinDereferenceModePassThru(pNetFltIf);
+ vboxNetFltWinDereferenceAdapt(pAdapt);
+ }
if(Status == NDIS_STATUS_SUCCESS)
{
@@ -616,7 +612,7 @@ vboxNetFltWinPtRequestComplete(
Assert(Status == NDIS_STATUS_SUCCESS);
if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_NETFLT)
{
- Assert(pNetFltIf->fActive);
+ Assert(pNetFltIf->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
if(Status == NDIS_STATUS_SUCCESS)
{
pAdapt->fOurSetFilter = *((PULONG)pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer);
@@ -628,7 +624,7 @@ vboxNetFltWinPtRequestComplete(
}
else if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU)
{
- Assert(!pNetFltIf->fActive);
+ Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
if(Status == NDIS_STATUS_SUCCESS)
{
@@ -852,7 +848,7 @@ vboxNetFltWinPtQueueReceivedPacket(
Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
do{
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
Assert(pAdapt->cReceivedPacketCount < MAX_RECEIVE_PACKET_ARRAY_SIZE);
@@ -896,7 +892,7 @@ vboxNetFltWinPtQueueReceivedPacket(
DoIndicate = TRUE;
}
}
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
} while(0);
if(!bReturn)
@@ -987,6 +983,7 @@ static bool vboxNetFltWinPtTransferDataCompleteActive(IN PADAPT pAdapt,
/* 2. enqueue */
/* use the same packet info to put the packet in the processing packet queue */
#ifdef VBOX_NETFLT_ONDEMAND_BIND
+# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND"
PNDIS_BUFFER pBuffer;
PVOID pVA;
UINT cbLength;
@@ -995,7 +992,7 @@ static bool vboxNetFltWinPtTransferDataCompleteActive(IN PADAPT pAdapt,
NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL);
NdisQueryBufferSafe(pBuffer, &pVA, &cbLength, NormalPagePriority);
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.Mac) ?
+ fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ?
PACKET_MINE | PACKET_SRC_HOST : PACKET_MINE;
SET_FLAGS_TO_INFO(pInfo, fFlags);
@@ -1014,14 +1011,28 @@ static bool vboxNetFltWinPtTransferDataCompleteActive(IN PADAPT pAdapt,
pRecvRsvd->pBufToFree = NULL;
NdisSetPacketFlags(pPacket, 0);
-
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
+ {
+ /* drop it */
+ vboxNetFltWinFreeSGNdisPacket(pPacket, true);
+ vboxNetFltWinDereferenceAdapt(pAdapt);
+ }
+ else
+ {
+ NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1);
+ }
+ vboxNetFltWinDereferenceNetFlt(pNetFltIf);
+ break;
+# else
Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
-#endif
- if(Status == NDIS_STATUS_SUCCESS)
+ if (Status == NDIS_STATUS_SUCCESS)
{
break;
}
Assert(0);
+# endif
+#endif
}
}
else
@@ -1092,7 +1103,7 @@ vboxNetFltWinPtFlushReceiveQueue(
do
{
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
if (pAdapt->cReceivedPacketCount > 0)
{
@@ -1106,7 +1117,7 @@ vboxNetFltWinPtFlushReceiveQueue(
*/
pAdapt->cReceivedPacketCount = 0;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
if(!bReturn)
{
@@ -1135,7 +1146,7 @@ vboxNetFltWinPtFlushReceiveQueue(
}
/* we are here only in case pAdapt->cReceivedPacketCount == 0 */
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
} while (FALSE);
}
@@ -1379,20 +1390,56 @@ vboxNetFltWinPtReceiveActive(
/* enqueue SG */
#ifdef VBOX_NETFLT_ONDEMAND_BIND
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND"
+# endif
{
- uint32_t fFlags = MACS_EQUAL(((PRTNETETHERHDR)pRcvData)->SrcMac, pNetFlt->u.s.Mac) ?
+ uint32_t fFlags = MACS_EQUAL(((PRTNETETHERHDR)pRcvData)->SrcMac, pNetFlt->u.s.MacAddr) ?
PACKET_SG | PACKET_MINE | PACKET_SRC_HOST : PACKET_SG | PACKET_MINE;
Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, fFlags);
}
#else
+# ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pSG, PACKET_SG))
+ {
+ /* drop it */
+ vboxNetFltWinMemFree(pSG);
+ vboxNetFltWinDereferenceAdapt(pAdapt);
+ }
+ else
+ {
+ PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
+ pSG, /* PINTNETSG */
+ pSG, /* PVOID pBufToFree */
+ false, /* bool bToWire */
+ false); /* bool bCopyMemory */
+ Assert(pMyPacket);
+ if (pMyPacket)
+ {
+ NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
+
+ DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
+
+ LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
+ NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1);
+ }
+ else
+ {
+ vboxNetFltWinDereferenceAdapt(pAdapt);
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ vboxNetFltWinDereferenceNetFlt(pNetFlt);
+# else
Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
-#endif
if(Status != NDIS_STATUS_SUCCESS)
{
Assert(0);
vboxNetFltWinMemFree(pSG);
break;
}
+# endif
+#endif
}
else
#endif /* #ifndef DEBUG_NETFLT_RECV_TRANSFERDATA */
@@ -1571,7 +1618,7 @@ vboxNetFltWinPtReceive(
// break;
}
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pHeaderBuffer)->SrcMac, pNetFltIf->u.s.Mac) ?
+ fFlags = MACS_EQUAL(((PRTNETETHERHDR)pHeaderBuffer)->SrcMac, pNetFltIf->u.s.MacAddr) ?
PACKET_COPY | PACKET_SRC_HOST : PACKET_COPY;
Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, fFlags);
if(Status == NDIS_STATUS_SUCCESS)
@@ -1660,6 +1707,13 @@ vboxNetFltWinPtReceive(
{
VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
+ {
+ /* drop it */
+ break;
+ }
+#else
Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
Assert(Status == NDIS_STATUS_SUCCESS);
if(Status == NDIS_STATUS_SUCCESS)
@@ -1669,6 +1723,7 @@ vboxNetFltWinPtReceive(
bNetFltActive = false;
break;
}
+#endif
}
#ifndef VBOX_LOOPBACK_USEFLAGS
else if(vboxNetFltWinLbIsFromIntNet(pLb))
@@ -1693,11 +1748,13 @@ vboxNetFltWinPtReceive(
Assert(fAdaptActive);
} while(FALSE);
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
if(Status == NDIS_STATUS_SUCCESS || Status == NDIS_STATUS_NOT_ACCEPTED
-#ifndef VBOX_LOOPBACK_USEFLAGS
+# ifndef VBOX_LOOPBACK_USEFLAGS
|| pLb
-#endif
+# endif
)
+#endif
{
break;
}
@@ -1911,7 +1968,7 @@ vboxNetFltWinPtReceivePacket(
break;
}
- fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.Mac) ? PACKET_SRC_HOST : 0;
+ fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ? PACKET_SRC_HOST : 0;
Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, bResources ? fFlags | PACKET_COPY : fFlags);
if(Status == NDIS_STATUS_SUCCESS)
@@ -1977,7 +2034,9 @@ vboxNetFltWinPtReceivePacket(
if(!pLb)
#endif
{
+#ifndef VBOXNETFLT_NO_PACKET_QUEUE
NDIS_STATUS fStatus;
+#endif
bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
@@ -1987,6 +2046,15 @@ vboxNetFltWinPtReceivePacket(
* we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */
Assert(!bResources);
+#ifdef VBOXNETFLT_NO_PACKET_QUEUE
+ if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
+ {
+ /* drop it */
+ cRefCount = 0;
+ break;
+ }
+
+#else
fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
if(fStatus == NDIS_STATUS_SUCCESS)
{
@@ -2007,6 +2075,7 @@ vboxNetFltWinPtReceivePacket(
{
Assert(0);
}
+#endif
}
#ifndef VBOX_LOOPBACK_USEFLAGS
else if(vboxNetFltWinLbIsFromIntNet(pLb))
@@ -2115,23 +2184,23 @@ DECLHIDDEN(bool) vboxNetFltWinPtCloseAdapter(PADAPT pAdapt, PNDIS_STATUS pStatus
PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
if(pAdapt->bClosingAdapter)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Assert(0);
return false;
}
if (pAdapt->hBindingHandle == NULL)
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
Assert(0);
return false;
}
pAdapt->bClosingAdapter = true;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
/*
* Close the binding below. and wait for it to complete
@@ -2180,7 +2249,7 @@ vboxNetFltWinPtPnPNetEventSetPower(
/*
* Set the Internal Device State, this blocks all new sends or receives
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
vboxNetFltWinSetPowerState(&pAdapt->PTState, *pDeviceState);
@@ -2196,7 +2265,7 @@ vboxNetFltWinPtPnPNetEventSetPower(
{
pAdapt->bStandingBy = TRUE;
}
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
#ifndef VBOX_NETFLT_ONDEMAND_BIND
vboxNetFltWinPtFlushReceiveQueue(pAdapt, false);
@@ -2221,16 +2290,16 @@ vboxNetFltWinPtPnPNetEventSetPower(
/*
* If the below miniport is going to low power state, complete the queued request
*/
- RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
if (pAdapt->bQueuedRequest)
{
pAdapt->bQueuedRequest = FALSE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE);
}
else
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
}
#endif
@@ -2258,7 +2327,7 @@ vboxNetFltWinPtPnPNetEventSetPower(
}
#ifdef VBOX_NETFLT_ONDEMAND_BIND
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
#else
/*
* The device below is being turned on. If we had a request
@@ -2271,7 +2340,7 @@ vboxNetFltWinPtPnPNetEventSetPower(
pAdapt->bQueuedRequest = FALSE;
pAdapt->bOutstandingRequests = TRUE;
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
NdisRequest(&Status,
pAdapt->hBindingHandle,
@@ -2287,7 +2356,7 @@ vboxNetFltWinPtPnPNetEventSetPower(
}
else
{
- RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
+ RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
}
#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h
index 7958f683b..68dacbe72 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h
@@ -1,10 +1,10 @@
-/* $Id: VBoxNetFltPt-win.h $ */
+/* $Id: VBoxNetFltPt-win.h 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf
index 9e06cba75..2678d9506 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf
@@ -3,7 +3,7 @@
;
;
-; Copyright (C) 2008 Sun Microsystems, Inc.
+; Copyright (C) 2008 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;
-; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
-; Clara, CA 95054 USA or visit http://www.sun.com if you need
-; additional information or have any questions.
-;
;
; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp
index 377742520..ec102391d 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp
@@ -1,10 +1,10 @@
-/* $Id: WinNetConfig.cpp $ */
+/* $Id: WinNetConfig.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* VBoxNetCfgWin - Briefly describe this file, optionally with a longer description in a separate paragraph.
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
@@ -1752,7 +1748,7 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPWSTR pPnPId, VBOXNETCF
winEr = GetLastError();
if(winEr != ERROR_INSUFFICIENT_BUFFER)
{
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr);
+ Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr);
hr = HRESULT_FROM_WIN32(winEr);
break;
}
@@ -1774,7 +1770,7 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPWSTR pPnPId, VBOXNETCF
))
{
winEr = GetLastError();
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr);
+ Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr);
hr = HRESULT_FROM_WIN32(winEr);
break;
}
@@ -1808,9 +1804,9 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPWSTR pPnPId, VBOXNETCF
}
else
{
- DWORD winEr = GetLastError();
- Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetClassDevsExW failed winErr(%d)\n", winEr);
- hr = HRESULT_FROM_WIN32(winEr);
+ DWORD winEr = GetLastError();
+ Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetClassDevsExW failed winErr(%d)\n", winEr);
+ hr = HRESULT_FROM_WIN32(winEr);
}
return hr;
@@ -2310,6 +2306,159 @@ static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority (IN INetCfg *pNc
return true;
}
+static BOOL vboxNetCfgWinListUpperBindings (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext)
+{
+ INetCfgComponentBindings *pNccb = NULL;
+ IEnumNetCfgBindingPath *pEnumNccbp;
+ GUID *pGuid = (GUID*)pContext;
+ HRESULT hr;
+ LPWSTR pszwCompDisplayName;
+
+ hr = pNcc->GetDisplayName(&pszwCompDisplayName);
+ Assert(hr == S_OK);
+ if ( hr == S_OK )
+ {
+ Log(L" enumerating bindings for component (%s)\n", pszwCompDisplayName);
+ /* Get component's binding. */
+ hr = pNcc->QueryInterface( IID_INetCfgComponentBindings,
+ (PVOID *)&pNccb );
+ Assert(hr == S_OK);
+ if ( hr == S_OK )
+ {
+ /* Get binding path enumerator reference. */
+ hr = pNccb->EnumBindingPaths(EBP_ABOVE, &pEnumNccbp);
+ Assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ INetCfgBindingPath *pNccbp;
+ hr = pEnumNccbp->Reset();
+ Assert(hr == S_OK);
+ do
+ {
+ hr = VBoxNetCfgWinGetNextBindingPath(pEnumNccbp, &pNccbp);
+ Assert(hr == S_OK || hr == S_FALSE);
+ if(hr == S_OK)
+ {
+ LPWSTR pszwPathToken;
+ hr = pNccbp->GetPathToken(&pszwPathToken);
+ Assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ Log(L" enumerating bp (%s), enabled(0x%x)\n", pszwPathToken, pNccbp->IsEnabled());
+ IEnumNetCfgBindingInterface *pEnumNcbi;
+ hr = VBoxNetCfgWinGetBindingInterfaceEnum(pNccbp, &pEnumNcbi);
+ Assert(hr == S_OK);
+ if ( hr == S_OK )
+ {
+ INetCfgBindingInterface *pNcbi;
+ hr = pEnumNcbi->Reset();
+ Assert(hr == S_OK);
+ do
+ {
+ hr = VBoxNetCfgWinGetNextBindingInterface(pEnumNcbi, &pNcbi);
+ Assert(hr == S_OK || hr == S_FALSE);
+ if(hr == S_OK)
+ {
+ LPWSTR pszwInterfaceName;
+ hr = pNcbi->GetName(&pszwInterfaceName);
+ if(hr == S_OK)
+ {
+ Log(L" enumerating bi (%s)\n", pszwInterfaceName);
+ INetCfgComponent * pNccBoud;
+ hr = pNcbi->GetUpperComponent(&pNccBoud);
+ Assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ LPWSTR pszwDisplayName;
+ hr = pNccBoud->GetDisplayName(&pszwDisplayName);
+ Assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ Log(L" name (%s)\n", pszwDisplayName);
+ CoTaskMemFree(pszwDisplayName);
+ }
+ else
+ {
+ Log(L" ERROR getting name (0x%x)\n", hr);
+ }
+
+ VBoxNetCfgWinReleaseRef(pNccBoud);
+ }
+ VBoxNetCfgWinReleaseRef(pNcbi);
+ }
+ else
+ {
+ Log(L" ERROR getting bi name (0x%x)\n", hr);
+ }
+ }
+ else
+ {
+ if(hr == S_FALSE)
+ {
+ hr = S_OK;
+ break;
+ }
+ else
+ {
+ Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingInterface failed, hr (0x%x)\n", hr);
+ }
+ break;
+ }
+ } while(true);
+ VBoxNetCfgWinReleaseRef(pEnumNcbi);
+ }
+ else
+ {
+ Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetBindingInterfaceEnum failed, hr (0x%x)\n", hr);
+ }
+ CoTaskMemFree(pszwPathToken);
+ }
+ else
+ {
+ Log(L" ERROR getting bp name (0x%x)\n", hr);
+ }
+
+ VBoxNetCfgWinReleaseRef(pNccbp);
+ }
+ else
+ {
+ if(hr = S_FALSE)
+ {
+ hr = S_OK;
+ break;
+ }
+ else
+ {
+ Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingPath failed, hr (0x%x)\n", hr);
+ }
+ break;
+ }
+ } while(true);
+
+ VBoxNetCfgWinReleaseRef(pEnumNccbp);
+ }
+ else
+ {
+ Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: EnumBindingPaths failed, hr (0x%x)\n", hr);
+ }
+
+ VBoxNetCfgWinReleaseRef( pNccb );
+ }
+ else
+ {
+ Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr);
+ }
+
+ CoTaskMemFree(pszwCompDisplayName);
+ }
+ else
+ {
+ Log(L" ERROR getting component name (0x%x)\n", hr);
+ }
+
+ return true;
+}
+
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface (LPCWSTR pInfPath, bool bIsInfPathFile, /* <- input params */
GUID *pGuid, BSTR *lppszName, BSTR *pErrMsg) /* <- output params */
{
@@ -2770,6 +2919,68 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface (LPCWSTR
#undef SetErrBreak
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumUpperBindings ()
+{
+ INetCfg *pNc;
+ LPWSTR lpszApp = NULL;
+ HRESULT hr = VBoxNetCfgWinQueryINetCfgEx( FALSE,
+ L"VirtualBox Host-Only Creation",
+ 30000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec, */
+ &pNc, /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */
+ &lpszApp );
+ Assert(hr == S_OK);
+ if(hr == S_OK)
+ {
+ Log(L"Enumerating Net\n");
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
+ &GUID_DEVCLASS_NET,
+ vboxNetCfgWinListUpperBindings,
+ NULL);
+ Assert(hr == S_OK);
+
+ Log(L"Enumerating NetService\n");
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
+ &GUID_DEVCLASS_NETSERVICE,
+ vboxNetCfgWinListUpperBindings,
+ NULL);
+ Assert(hr == S_OK);
+
+ Log(L"Enumerating NetTrans\n");
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
+ &GUID_DEVCLASS_NETTRANS,
+ vboxNetCfgWinListUpperBindings,
+ NULL);
+ Assert(hr == S_OK);
+
+ Log(L"Enumerating NetClient\n");
+ hr = vboxNetCfgWinEnumNetCfgComponents(pNc,
+ &GUID_DEVCLASS_NETCLIENT,
+ vboxNetCfgWinListUpperBindings,
+ NULL);
+ Assert(hr == S_OK);
+
+ if(hr == S_OK)
+ {
+ hr = pNc->Apply();
+ Assert(hr == S_OK);
+ }
+
+ VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
+ }
+ else if(hr == NETCFG_E_NO_WRITE_LOCK && lpszApp)
+ {
+ Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: app %s is holding the lock, failed\n", lpszApp);
+ CoTaskMemFree(lpszApp);
+ }
+ else
+ {
+ Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: VBoxNetCfgWinQueryINetCfgEx failed, hr 0x%x\n", hr);
+ }
+
+ return hr;
+}
+
+
#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network"
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName (PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf)
{
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp
index 84e3f289a..b5c57ea36 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -8,10 +8,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Sample Notify Object
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h
index 36815dea8..ae772727c 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -8,10 +8,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*
* Based in part on Microsoft DDK sample code for Sample Notify Object
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc
index af11aa993..c7741a505 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Sun Microsystems, Inc.
+ * Copyright (C) 2009 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -8,10 +8,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
#include <windows.h>
#include <VBox/version.h>
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl
index 6b9e9a115..90f752f1c 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl
@@ -1,13 +1,18 @@
-/* $Id: VBoxNetFltNotifyn.idl $ */
+/* $Id: VBoxNetFltNotifyn.idl 29200 2010-05-07 12:14:18Z vboxsync $ */
/** @file
* VBoxNetFltNotify.idl - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
*/
/*
- * Copyright (C) 2008 Sun Microsystems, Inc.
+ * Copyright (C) 2008 Oracle Corporation
*
- * Sun Microsystems, Inc. confidential
- * All rights reserved
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*
* Based in part on Microsoft DDK sample code for Sample Notify Object
@@ -15,7 +20,7 @@
*
* Microsoft Windows
* Copyright (C) Microsoft Corporation, 1992-2001.
- *
+ *
*----------------------------------------------------------------------------
*/
#include <netcfgn.idl>