Index: trunk/src/VBox/Devices/Network/DrvIntNet.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DrvIntNet.cpp	(revision 10819)
+++ trunk/src/VBox/Devices/Network/DrvIntNet.cpp	(revision 10843)
@@ -72,4 +72,7 @@
     /** The network interface. */
     PPDMINETWORKPORT        pPort;
+    /** The network config interface.
+     * Can (in theory at least) be NULL. */
+    PPDMINETWORKCONFIG      pConfigIf;
     /** Pointer to the driver instance. */
     PPDMDRVINS              pDrvIns;
@@ -111,4 +114,59 @@
 /** Converts a pointer to DRVINTNET::INetworkConnector to a PDRVINTNET. */
 #define PDMINETWORKCONNECTOR_2_DRVINTNET(pInterface) ( (PDRVINTNET)((uintptr_t)pInterface - RT_OFFSETOF(DRVINTNET, INetworkConnector)) )
+
+
+/**
+ * Updates the MAC address on the kernel side.
+ *
+ * @returns VBox status code.
+ * @param   pThis       The driver instance.
+ */
+static int drvIntNetUpdateMacAddress(PDRVINTNET pThis)
+{
+    if (!pThis->pConfigIf)
+        return VINF_SUCCESS;
+
+    INTNETIFSETMACADDRESSREQ SetMacAddressReq;
+    SetMacAddressReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+    SetMacAddressReq.Hdr.cbReq = sizeof(SetMacAddressReq);
+    SetMacAddressReq.pSession = NIL_RTR0PTR;
+    SetMacAddressReq.hIf = pThis->hIf;
+    int rc = pThis->pConfigIf->pfnGetMac(pThis->pConfigIf, &SetMacAddressReq.Mac);
+    if (RT_SUCCESS(rc))
+        rc = pThis->pDrvIns->pDrvHlp->pfnSUPCallVMMR0Ex(pThis->pDrvIns, VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS,
+                                                        &SetMacAddressReq, sizeof(SetMacAddressReq));
+
+    Log(("drvIntNetUpdateMacAddress: %.*Rhxs rc=%Rrc\n", sizeof(SetMacAddressReq.Mac), &SetMacAddressReq.Mac, rc));
+    return rc;
+}
+
+
+/**
+ * Sets the kernel interface active or inactive.
+ *
+ * Worker for poweron, poweroff, suspend and resume.
+ *
+ * @returns VBox status code.
+ * @param   pThis       The driver instance.
+ * @param   fActive     The new state.
+ */
+static int drvIntNetSetActive(PDRVINTNET pThis, bool fActive)
+{
+    if (!pThis->pConfigIf)
+        return VINF_SUCCESS;
+
+    INTNETIFSETACTIVEREQ SetActiveReq;
+    SetActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+    SetActiveReq.Hdr.cbReq = sizeof(SetActiveReq);
+    SetActiveReq.pSession = NIL_RTR0PTR;
+    SetActiveReq.hIf = pThis->hIf;
+    SetActiveReq.fActive = fActive;
+    int rc = pThis->pDrvIns->pDrvHlp->pfnSUPCallVMMR0Ex(pThis->pDrvIns, VMMR0_DO_INTNET_IF_SET_ACTIVE,
+                                                        &SetActiveReq, sizeof(SetActiveReq));
+
+    Log(("drvIntNetUpdateMacAddress: fActive=%d rc=%Rrc\n", fActive, rc));
+    AssertRC(rc);
+    return rc;
+}
 
 
@@ -541,5 +599,8 @@
     PDRVINTNET pThis = PDMINS2DATA(pDrvIns, PDRVINTNET);
     if (!pThis->fActivateEarlyDeactivateLate)
+    {
         ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_SUSPENDED);
+        drvIntNetSetActive(pThis, false /* fActive */);
+    }
 }
 
@@ -558,4 +619,6 @@
         ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING);
         RTSemEventSignal(pThis->EventSuspended);
+        drvIntNetUpdateMacAddress(pThis); /* (could be a state restore) */
+        drvIntNetSetActive(pThis, true /* fActive */);
     }
 }
@@ -572,5 +635,8 @@
     PDRVINTNET pThis = PDMINS2DATA(pDrvIns, PDRVINTNET);
     if (!pThis->fActivateEarlyDeactivateLate)
+    {
         ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_SUSPENDED);
+        drvIntNetSetActive(pThis, false /* fActive */);
+    }
 }
 
@@ -589,4 +655,6 @@
         ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING);
         RTSemEventSignal(pThis->EventSuspended);
+        drvIntNetUpdateMacAddress(pThis);
+        drvIntNetSetActive(pThis, true /* fActive */);
     }
 }
@@ -704,4 +772,5 @@
         return VERR_PDM_MISSING_INTERFACE_ABOVE;
     }
+    pThis->pConfigIf = (PPDMINETWORKCONFIG)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_NETWORK_CONFIG);
 
     /*
@@ -887,4 +956,6 @@
         ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING);
         RTSemEventSignal(pThis->EventSuspended);
+        drvIntNetUpdateMacAddress(pThis);
+        drvIntNetSetActive(pThis, true /* fActive */);
     }
 
Index: trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp	(revision 10819)
+++ trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp	(revision 10843)
@@ -1167,4 +1167,74 @@
 
 /**
+ * Sets the MAC address of an interface.
+ *
+ * @returns VBox status code.
+ * @param   pIntNet         The instance handle.
+ * @param   hIf             The interface handle.
+ * @param   pSession        The caller's session.
+ * @param   pMAC            The new MAC address.
+ */
+INTNETR0DECL(int) INTNETR0IfSetMacAddress(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCPDMMAC pMac)
+{
+    LogFlow(("INTNETR0IfSetMacAddress: pIntNet=%p hIf=%RX32 pMac=%p:{%.6Rhxs}\n", pIntNet, hIf, pMac, pMac));
+
+    /*
+     * Validate & translate input.
+     */
+    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pMac, VERR_INVALID_PARAMETER);
+    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession);
+    if (!pIf)
+    {
+        Log(("INTNETR0IfSetMacAddress: returns VERR_INVALID_HANDLE\n"));
+        return VERR_INVALID_HANDLE;
+    }
+
+    /*
+     * Grab the network semaphore and make the change.
+     */
+    int rc;
+    PINTNETNETWORK pNetwork = pIf->pNetwork;
+    if (pNetwork)
+    {
+        rc = RTSemFastMutexRequest(pNetwork->FastMutex);
+        if (RT_SUCCESS(rc))
+        {
+            if (memcmp(&pIf->Mac, pMac, sizeof(pIf->Mac)))
+            {
+                Log(("INTNETR0IfSetMacAddress: hIf=%RX32: Changed from %.6Rhxs -> %.6Rhxs\n",
+                     hIf, &pIf->Mac, pMac));
+                pIf->Mac = *pMac;
+                pIf->fMacSet = true;
+            }
+
+            rc = RTSemFastMutexRelease(pNetwork->FastMutex);
+        }
+    }
+    else
+        rc = VERR_WRONG_ORDER;
+
+    intnetR0IfRelease(pIf, pSession);
+    return rc;
+}
+
+
+/**
+ * VMMR0 request wrapper for INTNETR0IfSetMacAddress.
+ *
+ * @returns see INTNETR0IfSetMacAddress.
+ * @param   pIntNet         The internal networking instance.
+ * @param   pSession        The caller's session.
+ * @param   pReq            The request packet.
+ */
+INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq)
+{
+    if (RT_UNLIKELY(pReq->Hdr.cbReq != sizeof(*pReq)))
+        return VERR_INVALID_PARAMETER;
+    return INTNETR0IfSetMacAddress(pIntNet, pReq->hIf, pSession, &pReq->Mac);
+}
+
+
+/**
  * Worker for intnetR0IfSetActive.
  *
@@ -1256,4 +1326,60 @@
         return VERR_WRONG_ORDER;
     return intnetR0NetworkSetIfActive(pNetwork, pIf, fActive);
+}
+
+
+/**
+ * Sets the active property of an interface.
+ *
+ * @returns VBox status code.
+ * @param   pIntNet         The instance handle.
+ * @param   hIf             The interface handle.
+ * @param   pSession        The caller's session.
+ * @param   fActive         The new state.
+ */
+INTNETR0DECL(int) INTNETR0IfSetActive(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive)
+{
+    LogFlow(("INTNETR0IfSetActive: pIntNet=%p hIf=%RX32 fActive=%RTbool\n", pIntNet, hIf, fActive));
+
+    /*
+     * Validate & translate input.
+     */
+    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER);
+    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession);
+    if (!pIf)
+    {
+        Log(("INTNETR0IfSetActive: returns VERR_INVALID_HANDLE\n"));
+        return VERR_INVALID_HANDLE;
+    }
+
+    /*
+     * Hand it to the network since it might involve the trunk
+     * and things are tricky there wrt to locking order.
+     */
+    int rc;
+    PINTNETNETWORK pNetwork = pIf->pNetwork;
+    if (pNetwork)
+        rc = intnetR0NetworkSetIfActive(pNetwork, pIf, fActive);
+    else
+        rc = VERR_WRONG_ORDER;
+
+    intnetR0IfRelease(pIf, pSession);
+    return rc;
+}
+
+
+/**
+ * VMMR0 request wrapper for INTNETR0IfSetActive.
+ *
+ * @returns see INTNETR0IfSetActive.
+ * @param   pIntNet         The internal networking instance.
+ * @param   pSession        The caller's session.
+ * @param   pReq            The request packet.
+ */
+INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq)
+{
+    if (RT_UNLIKELY(pReq->Hdr.cbReq != sizeof(*pReq)))
+        return VERR_INVALID_PARAMETER;
+    return INTNETR0IfSetActive(pIntNet, pReq->hIf, pSession, pReq->fActive);
 }
 
