Index: /trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp	(revision 10710)
+++ /trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp	(revision 10711)
@@ -59,4 +59,6 @@
      * In promiscuous mode the interface will receive all packages except the one it's sending. */
     bool                    fPromiscuous;
+    /** Whether the interface is active or not. */
+    bool                    fActive;
     /** Number of yields done to try make the interface read pending data.
      * We will stop yeilding when this reaches a threshold assuming that the VM is paused or
@@ -139,4 +141,6 @@
     /** Network creation flags (INTNET_OPEN_FLAGS_*). */
     uint32_t                fFlags;
+    /** The number of active interfaces (excluding the trunk). */
+    uint32_t                cActiveIFs;
     /** The length of the network name. */
     uint8_t                 cchName;
@@ -208,8 +212,8 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-static PINTNETTRUNKIF intnetTrunkIfRetain(PINTNETTRUNKIF pThis);
-static void intnetTrunkIfRelease(PINTNETTRUNKIF pThis);
-static bool intnetTrunkIfOutLock(PINTNETTRUNKIF pThis);
-static void intnetTrunkIfOutUnlock(PINTNETTRUNKIF pThis);
+static PINTNETTRUNKIF intnetR0TrunkIfRetain(PINTNETTRUNKIF pThis);
+static void intnetR0TrunkIfRelease(PINTNETTRUNKIF pThis);
+static bool intnetR0TrunkIfOutLock(PINTNETTRUNKIF pThis);
+static void intnetR0TrunkIfOutUnlock(PINTNETTRUNKIF pThis);
 
 
@@ -228,5 +232,5 @@
  * @internal
  */
-DECLINLINE(PINTNETIF) intnetHandle2IFPtrLocked(PINTNETHT pHT, INTNETIFHANDLE hIF)
+DECLINLINE(PINTNETIF) intnetR0Handle2IFPtrLocked(PINTNETHT pHT, INTNETIFHANDLE hIF)
 {
     if (RT_LIKELY((hIF & INTNET_HANDLE_MAGIC) == INTNET_HANDLE_MAGIC))
@@ -250,10 +254,10 @@
  * @param   hIF         The interface handle to validate and translate.
  */
-DECLINLINE(PINTNETIF) intnetHandle2IFPtr(PINTNETHT pHT, INTNETIFHANDLE hIF)
+DECLINLINE(PINTNETIF) intnetR0Handle2IFPtr(PINTNETHT pHT, INTNETIFHANDLE hIF)
 {
     AssertPtr(pHT);
     RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
     RTSpinlockAcquire(pHT->Spinlock, &Tmp);
-    PINTNETIF pIF = intnetHandle2IFPtrLocked(pHT, hIF);
+    PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, hIF);
     RTSpinlockRelease(pHT->Spinlock, &Tmp);
 
@@ -270,5 +274,5 @@
  * @param   pIF         The interface which we're allocating a handle for.
  */
-static INTNETIFHANDLE intnetHandleAllocate(PINTNET pIntNet, PINTNETIF pIF)
+static INTNETIFHANDLE intnetR0HandleAllocate(PINTNET pIntNet, PINTNETIF pIF)
 {
     Assert(pIF);
@@ -355,5 +359,5 @@
  * @param   h           The handle we're freeing.
  */
-static PINTNETIF intnetHandleFree(PINTNETHT pHT, INTNETIFHANDLE h)
+static PINTNETIF intnetR0HandleFree(PINTNETHT pHT, INTNETIFHANDLE h)
 {
     RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
@@ -364,5 +368,5 @@
      * at the end of the free list.
      */
-    PINTNETIF pIF = intnetHandle2IFPtrLocked(pHT, h);
+    PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, h);
     if (pIF)
     {
@@ -395,5 +399,5 @@
  *                      ensuring that there is sufficient space for the frame.
  */
-static unsigned intnetRingReadFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, void *pvFrame)
+static unsigned intnetR0RingReadFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, void *pvFrame)
 {
     Assert(pRingBuf->offRead < pBuf->cbBuf);
@@ -415,5 +419,5 @@
     return cb;
 }
-#endif
+#endif /* IN_INTNET_TESTCASE */
 
 
@@ -427,5 +431,5 @@
  * @param   cbFrame     The size of the frame.
  */
-static int intnetRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame)
+static int intnetR0RingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame)
 {
     /*
@@ -530,8 +534,8 @@
  * @param   cbFrame     The size of the frame.
  */
-static void intnetIfSend(PINTNETIF pIf, const void *pvFrame, unsigned cbFrame)
-{
-    LogFlow(("intnetIfSend: pIf=%p:{.hIf=%RX32}\n", pIf, pIf->hIf));
-    int rc = intnetRingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pvFrame, cbFrame);
+static void intnetR0IfSend(PINTNETIF pIf, const void *pvFrame, unsigned cbFrame)
+{
+    LogFlow(("intnetR0IfSend: pIf=%p:{.hIf=%RX32}\n", pIf, pIf->hIf));
+    int rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pvFrame, cbFrame);
     if (RT_SUCCESS(rc))
     {
@@ -554,5 +558,5 @@
             RTSemEventSignal(pIf->Event);
             RTThreadYield();
-            rc = intnetRingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pvFrame, cbFrame);
+            rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pvFrame, cbFrame);
             if (RT_SUCCESS(rc))
             {
@@ -587,5 +591,5 @@
  * @param   cbFrame     The size of the frame.
  */
-static void intnetNetworkSend(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, const void *pvFrame, unsigned cbFrame)
+static void intnetR0NetworkSend(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, const void *pvFrame, unsigned cbFrame)
 {
     /*
@@ -632,5 +636,5 @@
         for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext)
             if (pIf != pIfSender)
-                intnetIfSend(pIf, pvFrame, cbFrame);
+                intnetR0IfSend(pIf, pvFrame, cbFrame);
     }
     else
@@ -647,5 +651,5 @@
                 ||  (   pIf->fPromiscuous
                      && pIf != pIfSender /* promiscuous mode: omit the sender */))
-                intnetIfSend(pIf, pvFrame, cbFrame);
+                intnetR0IfSend(pIf, pvFrame, cbFrame);
         }
     }
@@ -675,5 +679,5 @@
      */
     AssertReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
         return VERR_INVALID_HANDLE;
@@ -696,5 +700,5 @@
      */
     if (pvFrame && cbFrame)
-        intnetNetworkSend(pIf->pNetwork, pIf, pvFrame, cbFrame);
+        intnetR0NetworkSend(pIf->pNetwork, pIf, pvFrame, cbFrame);
 
     /*
@@ -709,5 +713,5 @@
             void *pvCurFrame = INTNETHdrGetFramePtr(pHdr, pIf->pIntBuf);
             if (pvCurFrame)
-                intnetNetworkSend(pIf->pNetwork, pIf, pvCurFrame, pHdr->cbFrame);
+                intnetR0NetworkSend(pIf->pNetwork, pIf, pvCurFrame, pHdr->cbFrame);
         }
         /* else: ignore the frame */
@@ -752,5 +756,5 @@
      */
     AssertReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
         return VERR_INVALID_HANDLE;
@@ -807,5 +811,5 @@
     *ppRing0Buf = NULL;
     AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
         return VERR_INVALID_HANDLE;
@@ -843,5 +847,5 @@
      */
     AssertReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
         return VERR_INVALID_HANDLE;
@@ -884,5 +888,5 @@
      */
     AssertReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
     {
@@ -894,5 +898,8 @@
      * Grab the network semaphore and make the change.
      */
-    int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex);
+    PINTNETNETWORK pNetwork = pIf->pNetwork;
+    if (!pNetwork)
+        return VERR_WRONG_ORDER;
+    int rc = RTSemFastMutexRequest(pNetwork->FastMutex);
     if (RT_FAILURE(rc))
         return rc;
@@ -905,5 +912,5 @@
     }
 
-    RTSemFastMutexRelease(pIf->pNetwork->FastMutex);
+    RTSemFastMutexRelease(pNetwork->FastMutex);
     return VINF_SUCCESS;
 }
@@ -922,4 +929,97 @@
         return VERR_INVALID_PARAMETER;
     return INTNETR0IfSetPromiscuousMode(pIntNet, pReq->hIf, pReq->fPromiscuous);
+}
+
+
+/**
+ * Worker for intnetR0IfSetActive.
+ *
+ * This function will update the active interface count on the network and
+ * activate or deactivate the trunk connection if necessary. Note that in
+ * order to do this it is necessary to abandond the network semaphore.
+ *
+ * @returns VBox status code.
+ * @param   pNetwork        The network.
+ * @param   fIf             The interface.
+ * @param   fActive         What to do.
+ */
+static int intnetR0NetworkSetIfActive(PINTNETNETWORK pNetwork, PINTNETIF pIf, bool fActive)
+{
+    /* quick santiy check */
+    AssertPtr(pNetwork);
+    AssertPtr(pIf);
+
+    /*
+     * If we've got a trunk, lock it now in case we need to call out, and
+     * then lock the network.
+     */
+    PINTNETTRUNKIF pTrunkIf = pNetwork->pTrunkIF;
+    if (pTrunkIf && !intnetR0TrunkIfOutLock(pTrunkIf))
+        return VERR_SEM_DESTROYED;
+
+    int rc = RTSemFastMutexRequest(pNetwork->FastMutex); AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        bool fNetworkLocked = true;
+
+        /*
+         * Make the change if necessary.
+         */
+        if (pIf->fActive != fActive)
+        {
+            pIf->fActive = fActive;
+
+            uint32_t const cActiveIFs = pNetwork->cActiveIFs;
+            Assert((int32_t)cActiveIFs + (fActive ? 1 : -1) >= 0);
+            pNetwork->cActiveIFs += fActive ? 1 : -1;
+
+            if (    pTrunkIf
+                &&  (   !pNetwork->cActiveIFs
+                     || !cActiveIFs))
+            {
+                /*
+                 * We'll have to change the trunk status, so, leave
+                 * the network semaphore so we don't create any deadlocks.
+                 */
+                int rc2 = RTSemFastMutexRelease(pNetwork->FastMutex); AssertRC(rc2);
+                fNetworkLocked = false;
+
+                if (pTrunkIf->pIfPort)
+                    pTrunkIf->pIfPort->pfnSetActive(pTrunkIf->pIfPort, fActive);
+            }
+        }
+
+        if (fNetworkLocked)
+            RTSemFastMutexRelease(pNetwork->FastMutex);
+    }
+    if (pTrunkIf)
+        intnetR0TrunkIfOutUnlock(pTrunkIf);
+    return rc;
+}
+
+
+/**
+ * Activates or deactivates a interface.
+ *
+ * This is used to enable and disable the trunk connection on demans as well as
+ * know when not to expect an interface to want to receive packets.
+ *
+ * @returns VBox status code.
+ * @param   pIf         The interface.
+ * @param   fActive     What to do.
+ */
+static int intnetR0IfSetActive(PINTNETIF pIf, bool fActive)
+{
+    /* quick sanity check */
+    AssertPtrReturn(pIf, VERR_INVALID_POINTER);
+
+    /*
+     * Hand it to the network since it might involve the trunk
+     * and things are tricky there wrt to locking order.
+     */
+    PINTNETNETWORK pNetwork = pIf->pNetwork;
+    if (!pNetwork)
+        return VERR_WRONG_ORDER;
+    return intnetR0NetworkSetIfActive(pNetwork, pIf, fActive);
 }
 
@@ -943,5 +1043,5 @@
      */
     AssertReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);
     if (!pIf)
     {
@@ -1015,5 +1115,5 @@
      */
     AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER);
-    PINTNETIF pIf = intnetHandleFree(&pIntNet->IfHandles, hIf);
+    PINTNETIF pIf = intnetR0HandleFree(&pIntNet->IfHandles, hIf);
     if (!pIf)
         return VERR_INVALID_HANDLE;
@@ -1052,7 +1152,7 @@
  * @param   pvUser2     Pointer to the INTNET instance data.
  */
-static DECLCALLBACK(void) intnetIfDestruct(void *pvObj, void *pvUser1, void *pvUser2)
-{
-    LogFlow(("intnetIfDestruct: pvObj=%p pvUser1=%p pvUser2=%p\n", pvObj, pvUser1, pvUser2));
+static DECLCALLBACK(void) intnetR0IfDestruct(void *pvObj, void *pvUser1, void *pvUser2)
+{
+    LogFlow(("intnetR0IfDestruct: pvObj=%p pvUser1=%p pvUser2=%p\n", pvObj, pvUser1, pvUser2));
     PINTNETIF pIf = (PINTNETIF)pvUser1;
     PINTNET   pIntNet = (PINTNET)pvUser2;
@@ -1065,8 +1165,8 @@
     INTNETIFHANDLE hIf = ASMAtomicXchgU32(&pIf->hIf, INTNET_HANDLE_INVALID);
     if (hIf != INTNET_HANDLE_INVALID)
-        intnetHandleFree(&pIntNet->IfHandles, hIf);
-
-    /*
-     * If we've got a network unlink ourselves from it.
+        intnetR0HandleFree(&pIntNet->IfHandles, hIf);
+
+    /*
+     * If we've got a network deactivate and unlink ourselves from it.
      * Because of cleanup order we might be an orphan now.
      */
@@ -1074,4 +1174,6 @@
     if (pNetwork)
     {
+        intnetR0IfSetActive(pIf, false);
+
         if (pNetwork->pIFs == pIf)
             pNetwork->pIFs = pIf->pNext;
@@ -1176,7 +1278,7 @@
  * @param   phIf        Where to store the interface handle.
  */
-static int intnetNetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv, PINTNETIFHANDLE phIf)
-{
-    LogFlow(("intnetNetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u phIf=%p\n",
+static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv, bool *pfCloseNetwork, PINTNETIFHANDLE phIf)
+{
+    LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u phIf=%p\n",
              pNetwork, pSession, cbSend, cbRecv, phIf));
 
@@ -1186,4 +1288,6 @@
     AssertPtr(pNetwork);
     AssertPtr(phIf);
+    AssertPtr(pfCloseNetwork);
+    *pfCloseNetwork = false;
 
     /*
@@ -1193,13 +1297,23 @@
     if (!pIf)
         return VERR_NO_MEMORY;
-
+    //pIf->pNext = NULL;
     memset(&pIf->Mac, 0xff, sizeof(pIf->Mac)); /* broadcast */
-    //pIf->fMacSet = 0;
+    //pIf->fMacSet = false;
+    //pIf->fPromiscuous = false;
+    //pIf->fActive = false;
+    //pIf->pIntBuf = 0;
+    //pIf->pIntBufR3 = NIL_RTR3PTR;
+    //pIf->pIntBufDefault = 0;
+    //pIf->pIntBufDefaultR3 = NIL_RTR3PTR;
+    //pIf->cYields = 0;
+    pIf->Event = NIL_RTSEMEVENT;
+    //pIf->cSleepers = 0;
+    pIf->hIf = INTNET_HANDLE_INVALID;
+    pIf->pNetwork = pNetwork;
+    pIf->pSession = pSession;
+    //pIf->pvObj = NULL;
     int rc = RTSemEventCreate(&pIf->Event);
     if (RT_SUCCESS(rc))
     {
-        pIf->pSession = pSession;
-        pIf->pNetwork = pNetwork;
-
         /*
          * Create the default buffer.
@@ -1240,12 +1354,16 @@
                  * Register the interface with the session.
                  */
-                pIf->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE, intnetIfDestruct, pIf, pNetwork->pIntNet);
+                pIf->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE, intnetR0IfDestruct, pIf, pNetwork->pIntNet);
                 if (pIf->pvObj)
                 {
-                    pIf->hIf = intnetHandleAllocate(pNetwork->pIntNet, pIf);
+                    pIf->hIf = intnetR0HandleAllocate(pNetwork->pIntNet, pIf);
                     if (pIf->hIf != INTNET_HANDLE_INVALID)
                     {
+                        /* auto activation */ /** @todo do this manually in the future, ditto for setting the MAC address. */
+                        rc = intnetR0IfSetActive(pIf, true /* activate */);
+                        AssertRC(rc);
+
                         *phIf = pIf->hIf;
-                        LogFlow(("intnetNetworkCreateIf: returns VINF_SUCCESS *phIf=%p\n", *phIf));
+                        LogFlow(("intnetR0NetworkCreateIf: returns VINF_SUCCESS *phIf=%p\n", *phIf));
                         return VINF_SUCCESS;
                     }
@@ -1253,11 +1371,13 @@
 
                     SUPR0ObjRelease(pIf->pvObj, pSession);
-                    LogFlow(("intnetNetworkCreateIf: returns %Rrc\n", rc));
+                    LogFlow(("intnetR0NetworkCreateIf: returns %Rrc\n", rc));
                     return rc;
                 }
+
                 rc = VERR_NO_MEMORY;
                 RTSemFastMutexDestroy(pNetwork->FastMutex);
                 pNetwork->FastMutex = NIL_RTSEMFASTMUTEX;
             }
+
             SUPR0MemFree(pIf->pSession, (RTHCUINTPTR)pIf->pIntBufDefault);
             pIf->pIntBufDefault = NULL;
@@ -1269,5 +1389,6 @@
     }
     RTMemFree(pIf);
-    LogFlow(("intnetNetworkCreateIf: returns %Rrc\n", rc));
+    LogFlow(("intnetR0NetworkCreateIf: returns %Rrc\n", rc));
+    *pfCloseNetwork = true;
     return rc;
 }
@@ -1278,5 +1399,5 @@
 
 /** @copydoc INTNETTRUNKSWPORT::pfnSetSGPhys */
-static DECLCALLBACK(bool) intnetTrunkIfPortSetSGPhys(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable)
+static DECLCALLBACK(bool) intnetR0TrunkIfPortSetSGPhys(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable)
 {
     PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort);
@@ -1287,5 +1408,5 @@
 
 /** @copydoc INTNETTRUNKSWPORT::pfnRecv */
-static DECLCALLBACK(bool) intnetTrunkIfPortRecv(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG, uint32_t fSrc)
+static DECLCALLBACK(bool) intnetR0TrunkIfPortRecv(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG, uint32_t fSrc)
 {
     PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort);
@@ -1308,5 +1429,5 @@
 
 /** @copydoc INTNETTRUNKSWPORT::pfnSGRetain */
-static DECLCALLBACK(void) intnetTrunkIfPortSGRetain(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG)
+static DECLCALLBACK(void) intnetR0TrunkIfPortSGRetain(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG)
 {
     PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort);
@@ -1325,5 +1446,5 @@
 
 /** @copydoc INTNETTRUNKSWPORT::pfnSGRelease */
-static DECLCALLBACK(void) intnetTrunkIfPortSGRelease(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG)
+static DECLCALLBACK(void) intnetR0TrunkIfPortSGRelease(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG)
 {
     PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort);
@@ -1355,5 +1476,5 @@
  * @remarks Any locks.
  */
-static PINTNETTRUNKIF intnetTrunkIfRetain(PINTNETTRUNKIF pThis)
+static PINTNETTRUNKIF intnetR0TrunkIfRetain(PINTNETTRUNKIF pThis)
 {
     if (pThis && pThis->pIfPort)
@@ -1368,5 +1489,5 @@
  * @param   pThis       The trunk.
  */
-static void intnetTrunkIfRelease(PINTNETTRUNKIF pThis)
+static void intnetR0TrunkIfRelease(PINTNETTRUNKIF pThis)
 {
     if (pThis && pThis->pIfPort)
@@ -1385,5 +1506,5 @@
  * @remarks No locks other than the create/destroy one.
  */
-static bool intnetTrunkIfOutLock(PINTNETTRUNKIF pThis)
+static bool intnetR0TrunkIfOutLock(PINTNETTRUNKIF pThis)
 {
     AssertPtrReturn(pThis, false);
@@ -1406,5 +1527,5 @@
  * @param   pThis       The trunk.
  */
-static void intnetTrunkIfOutUnlock(PINTNETTRUNKIF pThis)
+static void intnetR0TrunkIfOutUnlock(PINTNETTRUNKIF pThis)
 {
     if (pThis)
@@ -1424,10 +1545,10 @@
  * @remarks Caller may only own the create/destroy lock.
  */
-static void intnetTrunkIfActivate(PINTNETTRUNKIF pThis, bool fActive)
-{
-    if (intnetTrunkIfOutLock(pThis))
+static void intnetR0TrunkIfActivate(PINTNETTRUNKIF pThis, bool fActive)
+{
+    if (intnetR0TrunkIfOutLock(pThis))
     {
         pThis->pIfPort->pfnSetActive(pThis->pIfPort, fActive);
-        intnetTrunkIfOutUnlock(pThis);
+        intnetR0TrunkIfOutUnlock(pThis);
     }
 }
@@ -1443,5 +1564,5 @@
  *          create/destroy lock is fine though.
  */
-static void intnetTrunkIfDestroy(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork)
+static void intnetR0TrunkIfDestroy(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork)
 {
     /* assert sanity */
@@ -1459,5 +1580,5 @@
     if (pIfPort)
     {
-        intnetTrunkIfOutLock(pThis);
+        intnetR0TrunkIfOutLock(pThis);
 
         /* unset it */
@@ -1515,5 +1636,5 @@
  * @param   pSession    The session handle.
  */
-static int intnetNetworkCreateTrunkConnection(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession)
+static int intnetR0NetworkCreateTrunkIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession)
 {
     const char *pszName;
@@ -1552,8 +1673,8 @@
         return VERR_NO_MEMORY;
     pTrunkIF->SwitchPort.u32Version     = INTNETTRUNKSWPORT_VERSION;
-    pTrunkIF->SwitchPort.pfnSetSGPhys   = intnetTrunkIfPortSetSGPhys;
-    pTrunkIF->SwitchPort.pfnRecv        = intnetTrunkIfPortRecv;
-    pTrunkIF->SwitchPort.pfnSGRetain    = intnetTrunkIfPortSGRetain;
-    pTrunkIF->SwitchPort.pfnSGRelease   = intnetTrunkIfPortSGRelease;
+    pTrunkIF->SwitchPort.pfnSetSGPhys   = intnetR0TrunkIfPortSetSGPhys;
+    pTrunkIF->SwitchPort.pfnRecv        = intnetR0TrunkIfPortRecv;
+    pTrunkIF->SwitchPort.pfnSGRetain    = intnetR0TrunkIfPortSGRetain;
+    pTrunkIF->SwitchPort.pfnSGRelease   = intnetR0TrunkIfPortSGRelease;
     pTrunkIF->SwitchPort.u32VersionEnd  = INTNETTRUNKSWPORT_VERSION;
     //pTrunkIF->pIfPort = NULL;
@@ -1577,5 +1698,5 @@
                 Assert(pTrunkIF->pIfPort);
                 pNetwork->pTrunkIF = pTrunkIF;
-                LogFlow(("intnetNetworkCreateTrunkConnection: VINF_SUCCESS - pszName=%s szTrunk=%s Network=%s\n",
+                LogFlow(("intnetR0NetworkCreateTrunkIf: VINF_SUCCESS - pszName=%s szTrunk=%s Network=%s\n",
                          rc, pszName, pNetwork->szTrunk, pNetwork->szName));
                 return VINF_SUCCESS;
@@ -1586,5 +1707,5 @@
     }
     RTMemFree(pTrunkIF);
-    LogFlow(("intnetNetworkCreateTrunkConnection: %Rrc - pszName=%s szTrunk=%s Network=%s\n",
+    LogFlow(("intnetR0NetworkCreateTrunkIf: %Rrc - pszName=%s szTrunk=%s Network=%s\n",
              rc, pszName, pNetwork->szTrunk, pNetwork->szName));
     return rc;
@@ -1594,17 +1715,17 @@
 
 /**
- * Close a network which was opened/created using intnetOpenNetwork()/intnetCreateNetwork().
+ * Close a network which was opened/created using intnetR0OpenNetwork()/intnetR0CreateNetwork().
  *
  * @param   pNetwork    The network to close.
  * @param   pSession    The session handle.
  */
-static int intnetNetworkClose(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession)
-{
-    LogFlow(("intnetNetworkClose: pNetwork=%p pSession=%p\n", pNetwork, pSession));
+static int intnetR0NetworkClose(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession)
+{
+    LogFlow(("intnetR0NetworkClose: pNetwork=%p pSession=%p\n", pNetwork, pSession));
     AssertPtrReturn(pSession, VERR_INVALID_PARAMETER);
     AssertPtrReturn(pNetwork, VERR_INVALID_PARAMETER);
 
     int rc = SUPR0ObjRelease(pNetwork->pvObj, pSession);
-    LogFlow(("intnetNetworkClose: return %Rrc\n", rc));
+    LogFlow(("intnetR0NetworkClose: return %Rrc\n", rc));
     return rc;
 }
@@ -1619,7 +1740,7 @@
  * @param   pvUser2     Pointer to the INTNET instance data.
  */
-static DECLCALLBACK(void) intnetNetworkDestruct(void *pvObj, void *pvUser1, void *pvUser2)
-{
-    LogFlow(("intnetNetworkDestruct: pvObj=%p pvUser1=%p pvUser2=%p\n", pvObj, pvUser1, pvUser2));
+static DECLCALLBACK(void) intnetR0NetworkDestruct(void *pvObj, void *pvUser1, void *pvUser2)
+{
+    LogFlow(("intnetR0NetworkDestruct: pvObj=%p pvUser1=%p pvUser2=%p\n", pvObj, pvUser1, pvUser2));
     PINTNETNETWORK  pNetwork = (PINTNETNETWORK)pvUser1;
     PINTNET         pIntNet = (PINTNET)pvUser2;
@@ -1633,5 +1754,5 @@
      */
     if (pNetwork->pTrunkIF)
-        intnetTrunkIfActivate(pNetwork->pTrunkIF, false /* fActive */);
+        intnetR0TrunkIfActivate(pNetwork->pTrunkIF, false /* fActive */);
 
     /*
@@ -1681,5 +1802,5 @@
      */
     if (pTrunkIF)
-        intnetTrunkIfDestroy(pTrunkIF, pNetwork);
+        intnetR0TrunkIfDestroy(pTrunkIF, pNetwork);
 
     /*
@@ -1707,8 +1828,8 @@
  * @param   ppNetwork       Where to store the pointer to the network on success.
  */
-static int intnetOpenNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, INTNETTRUNKTYPE enmTrunkType,
-                             const char *pszTrunk, uint32_t fFlags, PINTNETNETWORK *ppNetwork)
-{
-    LogFlow(("intnetOpenNetwork: pIntNet=%p pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x ppNetwork=%p\n",
+static int intnetR0OpenNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, INTNETTRUNKTYPE enmTrunkType,
+                               const char *pszTrunk, uint32_t fFlags, PINTNETNETWORK *ppNetwork)
+{
+    LogFlow(("intnetR0OpenNetwork: pIntNet=%p pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x ppNetwork=%p\n",
              pIntNet, pSession, pszNetwork, pszNetwork, enmTrunkType, pszTrunk, pszTrunk, fFlags, ppNetwork));
 
@@ -1771,5 +1892,5 @@
                 rc = VERR_INTNET_INCOMPATIBLE_TRUNK;
 
-            LogFlow(("intnetOpenNetwork: returns %Rrc *ppNetwork=%p\n", rc, *ppNetwork));
+            LogFlow(("intnetR0OpenNetwork: returns %Rrc *ppNetwork=%p\n", rc, *ppNetwork));
             return rc;
         }
@@ -1777,5 +1898,5 @@
     }
 
-    LogFlow(("intnetOpenNetwork: returns VERR_NOT_FOUND\n"));
+    LogFlow(("intnetR0OpenNetwork: returns VERR_NOT_FOUND\n"));
     return VERR_NOT_FOUND;
 }
@@ -1799,8 +1920,8 @@
  *                          here should be dereferenced outside the INTNET::FastMutex.
  */
-static int intnetCreateNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, INTNETTRUNKTYPE enmTrunkType,
-                               const char *pszTrunk, uint32_t fFlags, PINTNETNETWORK *ppNetwork)
-{
-    LogFlow(("intnetCreateNetwork: pIntNet=%p pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x ppNetwork=%p\n",
+static int intnetR0CreateNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, INTNETTRUNKTYPE enmTrunkType,
+                                 const char *pszTrunk, uint32_t fFlags, PINTNETNETWORK *ppNetwork)
+{
+    LogFlow(("intnetR0CreateNetwork: pIntNet=%p pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x ppNetwork=%p\n",
              pIntNet, pSession, pszNetwork, pszNetwork, enmTrunkType, pszTrunk, pszTrunk, fFlags, ppNetwork));
 
@@ -1826,4 +1947,5 @@
         //pNew->pIFs = NULL;
         pNew->pIntNet = pIntNet;
+        //pNew->cActiveIFs = 0;
         pNew->fFlags = fFlags;
         size_t cchName = strlen(pszNetwork);
@@ -1838,5 +1960,5 @@
          * Register the object in the current session and link it into the network list.
          */
-        pNew->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_INTERNAL_NETWORK, intnetNetworkDestruct, pNew, pIntNet);
+        pNew->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_INTERNAL_NETWORK, intnetR0NetworkDestruct, pNew, pIntNet);
         if (pNew->pvObj)
         {
@@ -1855,11 +1977,9 @@
                  * Connect the trunk.
                  */
-#ifdef IN_RING0
-                rc = intnetNetworkCreateTrunkConnection(pNew, pSession);
-#endif
+                rc = intnetR0NetworkCreateTrunkIf(pNew, pSession);
                 if (RT_SUCCESS(rc))
                 {
                     *ppNetwork = pNew;
-                    LogFlow(("intnetCreateNetwork: returns VINF_SUCCESS *ppNetwork=%p\n", pNew));
+                    LogFlow(("intnetR0CreateNetwork: returns VINF_SUCCESS *ppNetwork=%p\n", pNew));
                     return VINF_SUCCESS;
                 }
@@ -1875,5 +1995,5 @@
 
             *ppNetwork = pNew;
-            LogFlow(("intnetCreateNetwork: returns %Rrc\n", rc));
+            LogFlow(("intnetR0CreateNetwork: returns %Rrc\n", rc));
             return rc;
         }
@@ -1884,5 +2004,5 @@
     }
     RTMemFree(pNew);
-    LogFlow(("intnetCreateNetwork: returns %Rrc\n", rc));
+    LogFlow(("intnetR0CreateNetwork: returns %Rrc\n", rc));
     return rc;
 }
@@ -1963,19 +2083,20 @@
      * Note that because of the destructors grabbing INTNET::FastMutex and us being required
      * to own this semaphore for the entire network opening / creation and interface creation
-     * sequence, intnetCreateNetwork will have to defer the network cleanup to us on failure.
+     * sequence, intnetR0CreateNetwork will have to defer the network cleanup to us on failure.
      */
     PINTNETNETWORK pNetwork = NULL;
-    rc = intnetOpenNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork);
+    rc = intnetR0OpenNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork);
     if (RT_SUCCESS(rc) || rc == VERR_NOT_FOUND)
     {
+        bool fCloseNetwork = true;
         if (rc == VERR_NOT_FOUND)
-            rc = intnetCreateNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork);
+            rc = intnetR0CreateNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork);
         if (RT_SUCCESS(rc))
-            rc = intnetNetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, phIf);
+            rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, &fCloseNetwork, phIf);
 
         RTSemFastMutexRelease(pIntNet->FastMutex);
 
-        if (RT_FAILURE(rc) && pNetwork)
-            intnetNetworkClose(pNetwork, pSession);
+        if (RT_FAILURE(rc) && pNetwork && fCloseNetwork)
+            intnetR0NetworkClose(pNetwork, pSession);
     }
     else
Index: /trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp	(revision 10710)
+++ /trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp	(revision 10711)
@@ -238,5 +238,5 @@
         int rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, abBuf, cb);
 #else
-        int rc = intnetRingWriteFrame(pArgs->pBuf, &pArgs->pBuf->Send, abBuf, cb);
+        int rc = intnetR0RingWriteFrame(pArgs->pBuf, &pArgs->pBuf->Send, abBuf, cb);
         if (RT_SUCCESS(rc))
             rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, NULL, 0);
@@ -315,5 +315,5 @@
         {
             uint8_t abBuf[16384];
-            unsigned cb = intnetRingReadFrame(pArgs->pBuf, &pArgs->pBuf->Recv, abBuf);
+            unsigned cb = intnetR0RingReadFrame(pArgs->pBuf, &pArgs->pBuf->Recv, abBuf);
             unsigned *puFrame = (unsigned *)&abBuf[sizeof(PDMMAC) * 2];
 
@@ -461,5 +461,5 @@
                                 g_cErrors++;
                             }
-                            unsigned cb = intnetRingReadFrame(pBuf1, &pBuf1->Recv, abBuf);
+                            unsigned cb = intnetR0RingReadFrame(pBuf1, &pBuf1->Recv, abBuf);
                             if (cb != sizeof(g_TestFrame0))
                             {
