VirtualBox

Changeset 10843

Show
Ignore:
Timestamp:
07/23/08 23:49:52 (3 months ago)
Author:
vboxsync
Message:

intnet: Implemented activation on power on & resume, deactivation on power off and suspend, and setting/updating of the mac address.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/intnet.h

    r10819 r10843  
    733733 
    734734/** 
     735 * Request buffer for INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS. 
     736 * @see INTNETR0IfSetMacAddress. 
     737 */ 
     738typedef struct INTNETIFSETMACADDRESSREQ 
     739{ 
     740    /** The request header. */ 
     741    SUPVMMR0REQHDR  Hdr; 
     742    /** Alternative to passing the taking the session from the VM handle. 
     743     * Either use this member or use the VM handle, don't do both. */ 
     744    PSUPDRVSESSION  pSession; 
     745    /** Handle to the interface. */ 
     746    INTNETIFHANDLE  hIf; 
     747    /** The new MAC address. */ 
     748    PDMMAC          Mac; 
     749} INTNETIFSETMACADDRESSREQ; 
     750/** Pointer to an INTNETR0IfSetMacAddressReq / VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */ 
     751typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ; 
     752 
     753INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq); 
     754 
     755 
     756/** 
     757 * Request buffer for INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE. 
     758 * @see INTNETR0IfSetActive. 
     759 */ 
     760typedef struct INTNETIFSETACTIVEREQ 
     761{ 
     762    /** The request header. */ 
     763    SUPVMMR0REQHDR  Hdr; 
     764    /** Alternative to passing the taking the session from the VM handle. 
     765     * Either use this member or use the VM handle, don't do both. */ 
     766    PSUPDRVSESSION  pSession; 
     767    /** Handle to the interface. */ 
     768    INTNETIFHANDLE  hIf; 
     769    /** The new state. */ 
     770    bool            fActive; 
     771} INTNETIFSETACTIVEREQ; 
     772/** Pointer to an INTNETR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE request buffer. */ 
     773typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ; 
     774 
     775INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq); 
     776 
     777 
     778/** 
    735779 * Request buffer for INTNETR0IfSendReq / VMMR0_DO_INTNET_IF_SEND. 
    736780 * @see INTNETR0IfSend. 
     
    854898 * @param   fPromiscuous    Set if the interface should be in promiscuous mode, clear if not. 
    855899 */ 
    856 INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous); 
     900INTNETR0DECL(int) INTNETR0IfSetPromiscuousMode( PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous); 
     901INTNETR0DECL(int) INTNETR0IfSetMacAddress(      PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCPDMMAC pMac); 
     902INTNETR0DECL(int) INTNETR0IfSetActive(          PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive); 
    857903 
    858904/** 
  • trunk/include/VBox/vmm.h

    r10805 r10843  
    438438    /** Call INTNETR0IfSetPromiscuousMode(). */ 
    439439    VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE, 
     440    /** Call INTNETR0IfSetMacAddress(). */ 
     441    VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS, 
     442    /** Call INTNETR0IfSetActive(). */ 
     443    VMMR0_DO_INTNET_IF_SET_ACTIVE, 
    440444    /** Call INTNETR0IfSend(). */ 
    441445    VMMR0_DO_INTNET_IF_SEND, 
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r10762 r10843  
    7272    /** The network interface. */ 
    7373    PPDMINETWORKPORT        pPort; 
     74    /** The network config interface. 
     75     * Can (in theory at least) be NULL. */ 
     76    PPDMINETWORKCONFIG      pConfigIf; 
    7477    /** Pointer to the driver instance. */ 
    7578    PPDMDRVINS              pDrvIns; 
     
    111114/** Converts a pointer to DRVINTNET::INetworkConnector to a PDRVINTNET. */ 
    112115#define PDMINETWORKCONNECTOR_2_DRVINTNET(pInterface) ( (PDRVINTNET)((uintptr_t)pInterface - RT_OFFSETOF(DRVINTNET, INetworkConnector)) ) 
     116 
     117 
     118/** 
     119 * Updates the MAC address on the kernel side. 
     120 * 
     121 * @returns VBox status code. 
     122 * @param   pThis       The driver instance. 
     123 */ 
     124static int drvIntNetUpdateMacAddress(PDRVINTNET pThis) 
     125{ 
     126    if (!pThis->pConfigIf) 
     127        return VINF_SUCCESS; 
     128 
     129    INTNETIFSETMACADDRESSREQ SetMacAddressReq; 
     130    SetMacAddressReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 
     131    SetMacAddressReq.Hdr.cbReq = sizeof(SetMacAddressReq); 
     132    SetMacAddressReq.pSession = NIL_RTR0PTR; 
     133    SetMacAddressReq.hIf = pThis->hIf; 
     134    int rc = pThis->pConfigIf->pfnGetMac(pThis->pConfigIf, &SetMacAddressReq.Mac); 
     135    if (RT_SUCCESS(rc)) 
     136        rc = pThis->pDrvIns->pDrvHlp->pfnSUPCallVMMR0Ex(pThis->pDrvIns, VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS, 
     137                                                        &SetMacAddressReq, sizeof(SetMacAddressReq)); 
     138 
     139    Log(("drvIntNetUpdateMacAddress: %.*Rhxs rc=%Rrc\n", sizeof(SetMacAddressReq.Mac), &SetMacAddressReq.Mac, rc)); 
     140    return rc; 
     141} 
     142 
     143 
     144/** 
     145 * Sets the kernel interface active or inactive. 
     146 * 
     147 * Worker for poweron, poweroff, suspend and resume. 
     148 * 
     149 * @returns VBox status code. 
     150 * @param   pThis       The driver instance. 
     151 * @param   fActive     The new state. 
     152 */ 
     153static int drvIntNetSetActive(PDRVINTNET pThis, bool fActive) 
     154{ 
     155    if (!pThis->pConfigIf) 
     156        return VINF_SUCCESS; 
     157 
     158    INTNETIFSETACTIVEREQ SetActiveReq; 
     159    SetActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 
     160    SetActiveReq.Hdr.cbReq = sizeof(SetActiveReq); 
     161    SetActiveReq.pSession = NIL_RTR0PTR; 
     162    SetActiveReq.hIf = pThis->hIf; 
     163    SetActiveReq.fActive = fActive; 
     164    int rc = pThis->pDrvIns->pDrvHlp->pfnSUPCallVMMR0Ex(pThis->pDrvIns, VMMR0_DO_INTNET_IF_SET_ACTIVE, 
     165                                                        &SetActiveReq, sizeof(SetActiveReq)); 
     166 
     167    Log(("drvIntNetUpdateMacAddress: fActive=%d rc=%Rrc\n", fActive, rc)); 
     168    AssertRC(rc); 
     169    return rc; 
     170} 
    113171 
    114172 
     
    541599    PDRVINTNET pThis = PDMINS2DATA(pDrvIns, PDRVINTNET); 
    542600    if (!pThis->fActivateEarlyDeactivateLate) 
     601    { 
    543602        ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_SUSPENDED); 
     603        drvIntNetSetActive(pThis, false /* fActive */); 
     604    } 
    544605} 
    545606 
     
    558619        ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 
    559620        RTSemEventSignal(pThis->EventSuspended); 
     621        drvIntNetUpdateMacAddress(pThis); /* (could be a state restore) */ 
     622        drvIntNetSetActive(pThis, true /* fActive */); 
    560623    } 
    561624} 
     
    572635    PDRVINTNET pThis = PDMINS2DATA(pDrvIns, PDRVINTNET); 
    573636    if (!pThis->fActivateEarlyDeactivateLate) 
     637    { 
    574638        ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_SUSPENDED); 
     639        drvIntNetSetActive(pThis, false /* fActive */); 
     640    } 
    575641} 
    576642 
     
    589655        ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 
    590656        RTSemEventSignal(pThis->EventSuspended); 
     657        drvIntNetUpdateMacAddress(pThis); 
     658        drvIntNetSetActive(pThis, true /* fActive */); 
    591659    } 
    592660} 
     
    704772        return VERR_PDM_MISSING_INTERFACE_ABOVE; 
    705773    } 
     774    pThis->pConfigIf = (PPDMINETWORKCONFIG)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_NETWORK_CONFIG); 
    706775 
    707776    /* 
     
    887956        ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 
    888957        RTSemEventSignal(pThis->EventSuspended); 
     958        drvIntNetUpdateMacAddress(pThis); 
     959        drvIntNetSetActive(pThis, true /* fActive */); 
    889960    } 
    890961 
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r10819 r10843  
    11671167 
    11681168/** 
     1169 * Sets the MAC address of an interface. 
     1170 * 
     1171 * @returns VBox status code. 
     1172 * @param   pIntNet         The instance handle. 
     1173 * @param   hIf             The interface handle. 
     1174 * @param   pSession        The caller's session. 
     1175 * @param   pMAC            The new MAC address. 
     1176 */ 
     1177INTNETR0DECL(int) INTNETR0IfSetMacAddress(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCPDMMAC pMac) 
     1178{ 
     1179    LogFlow(("INTNETR0IfSetMacAddress: pIntNet=%p hIf=%RX32 pMac=%p:{%.6Rhxs}\n", pIntNet, hIf, pMac, pMac)); 
     1180 
     1181    /* 
     1182     * Validate & translate input. 
     1183     */ 
     1184    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 
     1185    AssertPtrReturn(pMac, VERR_INVALID_PARAMETER); 
     1186    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
     1187    if (!pIf) 
     1188    { 
     1189        Log(("INTNETR0IfSetMacAddress: returns VERR_INVALID_HANDLE\n")); 
     1190        return VERR_INVALID_HANDLE; 
     1191    } 
     1192 
     1193    /* 
     1194     * Grab the network semaphore and make the change. 
     1195     */ 
     1196    int rc; 
     1197    PINTNETNETWORK pNetwork = pIf->pNetwork; 
     1198    if (pNetwork) 
     1199    { 
     1200        rc = RTSemFastMutexRequest(pNetwork->FastMutex); 
     1201        if (RT_SUCCESS(rc)) 
     1202        { 
     1203            if (memcmp(&pIf->Mac, pMac, sizeof(pIf->Mac))) 
     1204            { 
     1205                Log(("INTNETR0IfSetMacAddress: hIf=%RX32: Changed from %.6Rhxs -> %.6Rhxs\n", 
     1206                     hIf, &pIf->Mac, pMac)); 
     1207                pIf->Mac = *pMac; 
     1208                pIf->fMacSet = true; 
     1209            } 
     1210 
     1211            rc = RTSemFastMutexRelease(pNetwork->FastMutex); 
     1212        } 
     1213    } 
     1214    else 
     1215        rc = VERR_WRONG_ORDER; 
     1216 
     1217    intnetR0IfRelease(pIf, pSession); 
     1218    return rc; 
     1219} 
     1220 
     1221 
     1222/** 
     1223 * VMMR0 request wrapper for INTNETR0IfSetMacAddress. 
     1224 * 
     1225 * @returns see INTNETR0IfSetMacAddress. 
     1226 * @param   pIntNet         The internal networking instance. 
     1227 * @param   pSession        The caller's session. 
     1228 * @param   pReq            The request packet. 
     1229 */ 
     1230INTNETR0DECL(int) INTNETR0IfSetMacAddressReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq) 
     1231{ 
     1232    if (RT_UNLIKELY(pReq->Hdr.cbReq != sizeof(*pReq))) 
     1233        return VERR_INVALID_PARAMETER; 
     1234    return INTNETR0IfSetMacAddress(pIntNet, pReq->hIf, pSession, &pReq->Mac); 
     1235} 
     1236 
     1237 
     1238/** 
    11691239 * Worker for intnetR0IfSetActive. 
    11701240 * 
     
    12561326        return VERR_WRONG_ORDER; 
    12571327    return intnetR0NetworkSetIfActive(pNetwork, pIf, fActive); 
     1328} 
     1329 
     1330 
     1331/** 
     1332 * Sets the active property of an interface. 
     1333 * 
     1334 * @returns VBox status code. 
     1335 * @param   pIntNet         The instance handle. 
     1336 * @param   hIf             The interface handle. 
     1337 * @param   pSession        The caller's session. 
     1338 * @param   fActive         The new state. 
     1339 */ 
     1340INTNETR0DECL(int) INTNETR0IfSetActive(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive) 
     1341{ 
     1342    LogFlow(("INTNETR0IfSetActive: pIntNet=%p hIf=%RX32 fActive=%RTbool\n", pIntNet, hIf, fActive)); 
     1343 
     1344    /* 
     1345     * Validate & translate input. 
     1346     */ 
     1347    AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 
     1348    PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 
     1349    if (!pIf) 
     1350    { 
     1351        Log(("INTNETR0IfSetActive: returns VERR_INVALID_HANDLE\n")); 
     1352        return VERR_INVALID_HANDLE; 
     1353    } 
     1354 
     1355    /* 
     1356     * Hand it to the network since it might involve the trunk 
     1357     * and things are tricky there wrt to locking order. 
     1358     */ 
     1359    int rc; 
     1360    PINTNETNETWORK pNetwork = pIf->pNetwork; 
     1361    if (pNetwork) 
     1362        rc = intnetR0NetworkSetIfActive(pNetwork, pIf, fActive); 
     1363    else 
     1364        rc = VERR_WRONG_ORDER; 
     1365 
     1366    intnetR0IfRelease(pIf, pSession); 
     1367    return rc; 
     1368} 
     1369 
     1370 
     1371/** 
     1372 * VMMR0 request wrapper for INTNETR0IfSetActive. 
     1373 * 
     1374 * @returns see INTNETR0IfSetActive. 
     1375 * @param   pIntNet         The internal networking instance. 
     1376 * @param   pSession        The caller's session. 
     1377 * @param   pReq            The request packet. 
     1378 */ 
     1379INTNETR0DECL(int) INTNETR0IfSetActiveReq(PINTNET pIntNet, PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq) 
     1380{ 
     1381    if (RT_UNLIKELY(pReq->Hdr.cbReq != sizeof(*pReq))) 
     1382        return VERR_INVALID_PARAMETER; 
     1383    return INTNETR0IfSetActive(pIntNet, pReq->hIf, pSession, pReq->fActive); 
    12581384} 
    12591385 
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r10806 r10843  
    670670DECLINLINE(bool) vmmR0IsValidSession(PVM pVM, PSUPDRVSESSION pClaimedSession, PSUPDRVSESSION pSession) 
    671671{ 
    672     /* Only one out of the two */ 
    673     if (pVM && pSession) 
     672    /* This must be set! */ 
     673    if (!pSession) 
     674        return false; 
     675 
     676    /* Only one out of the two. */ 
     677    if (pVM && pClaimedSession) 
    674678        return false; 
    675679    if (pVM) 
     
    909913                return VERR_NOT_SUPPORTED; 
    910914            return INTNETR0IfSetPromiscuousModeReq(g_pIntNet, pSession, (PINTNETIFSETPROMISCUOUSMODEREQ)pReqHdr); 
     915 
     916        case VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS: 
     917            if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETMACADDRESSREQ)pReqHdr)->pSession, pSession)) 
     918                return VERR_INVALID_PARAMETER; 
     919            if (!g_pIntNet) 
     920                return VERR_NOT_SUPPORTED; 
     921            return INTNETR0IfSetMacAddressReq(g_pIntNet, pSession, (PINTNETIFSETMACADDRESSREQ)pReqHdr); 
     922 
     923        case VMMR0_DO_INTNET_IF_SET_ACTIVE: 
     924            if (u64Arg || !pReqHdr || !vmmR0IsValidSession(pVM, ((PINTNETIFSETACTIVEREQ)pReqHdr)->pSession, pSession)) 
     925                return VERR_INVALID_PARAMETER; 
     926            if (!g_pIntNet) 
     927                return VERR_NOT_SUPPORTED; 
     928            return INTNETR0IfSetActiveReq(g_pIntNet, pSession, (PINTNETIFSETACTIVEREQ)pReqHdr); 
    911929 
    912930        case VMMR0_DO_INTNET_IF_SEND: 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy