summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Network/DrvIntNet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Network/DrvIntNet.cpp')
-rw-r--r--src/VBox/Devices/Network/DrvIntNet.cpp106
1 files changed, 70 insertions, 36 deletions
diff --git a/src/VBox/Devices/Network/DrvIntNet.cpp b/src/VBox/Devices/Network/DrvIntNet.cpp
index 2abed09a..d85afd35 100644
--- a/src/VBox/Devices/Network/DrvIntNet.cpp
+++ b/src/VBox/Devices/Network/DrvIntNet.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -462,12 +462,12 @@ PDMBOTHCBDECL(int) drvIntNetUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGAT
#endif
Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
- Assert( pHdr->u16Type == INTNETHDR_TYPE_FRAME
- || pHdr->u16Type == INTNETHDR_TYPE_GSO);
+ Assert( pHdr->u8Type == INTNETHDR_TYPE_FRAME
+ || pHdr->u8Type == INTNETHDR_TYPE_GSO);
Assert(PDMCritSectIsOwner(&pThis->XmitLock));
/** @todo LATER: try unalloc the frame. */
- pHdr->u16Type = INTNETHDR_TYPE_PADDING;
+ pHdr->u8Type = INTNETHDR_TYPE_PADDING;
IntNetRingCommitFrame(&pThis->CTX_SUFF(pBuf)->Send, pHdr);
#ifdef IN_RING3
@@ -702,9 +702,9 @@ static int drvR3IntNetRecvRun(PDRVINTNET pThis)
}
Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offReadX, pHdr));
- uint16_t u16Type = pHdr->u16Type;
- if ( ( u16Type == INTNETHDR_TYPE_FRAME
- || u16Type == INTNETHDR_TYPE_GSO)
+ uint8_t u8Type = pHdr->u8Type;
+ if ( ( u8Type == INTNETHDR_TYPE_FRAME
+ || u8Type == INTNETHDR_TYPE_GSO)
&& !pThis->fLinkDown)
{
/*
@@ -714,7 +714,7 @@ static int drvR3IntNetRecvRun(PDRVINTNET pThis)
int rc = pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, 0);
if (rc == VINF_SUCCESS)
{
- if (u16Type == INTNETHDR_TYPE_FRAME)
+ if (u8Type == INTNETHDR_TYPE_FRAME)
{
/*
* Normal frame.
@@ -813,7 +813,7 @@ static int drvR3IntNetRecvRun(PDRVINTNET pThis)
/*
* NIC is going down, likely because the VM is being reset. Skip the frame.
*/
- AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
+ AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
IntNetRingSkipFrame(pRingBuf);
}
else
@@ -830,7 +830,7 @@ static int drvR3IntNetRecvRun(PDRVINTNET pThis)
/*
* Link down or unknown frame - skip to the next frame.
*/
- AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
+ AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
IntNetRingSkipFrame(pRingBuf);
STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
}
@@ -1034,6 +1034,8 @@ static DECLCALLBACK(void) drvR3IntNetResume(PPDMDRVINS pDrvIns)
{
LogFlow(("drvR3IntNetPowerResume\n"));
PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
+ VMRESUMEREASON enmReason = PDMDrvHlpVMGetResumeReason(pDrvIns);
+
if (!pThis->fActivateEarlyDeactivateLate)
{
ASMAtomicXchgSize(&pThis->enmRecvState, RECVSTATE_RUNNING);
@@ -1041,32 +1043,64 @@ static DECLCALLBACK(void) drvR3IntNetResume(PPDMDRVINS pDrvIns)
drvR3IntNetUpdateMacAddress(pThis); /* (could be a state restore) */
drvR3IntNetSetActive(pThis, true /* fActive */);
}
- if ( PDMDrvHlpVMTeleportedAndNotFullyResumedYet(pDrvIns)
- && pThis->pIAboveConfigR3)
+
+ switch (enmReason)
{
- /*
- * We've just been teleported and need to drop a hint to the switch
- * since we're likely to have changed to a different port. We just
- * push out some ethernet frame that doesn't mean anything to anyone.
- * For this purpose ethertype 0x801e was chosen since it was registered
- * to Sun (dunno what it is/was used for though).
- */
- union
+ case VMRESUMEREASON_HOST_RESUME:
{
- RTNETETHERHDR Hdr;
- uint8_t ab[128];
- } Frame;
- RT_ZERO(Frame);
- Frame.Hdr.DstMac.au16[0] = 0xffff;
- Frame.Hdr.DstMac.au16[1] = 0xffff;
- Frame.Hdr.DstMac.au16[2] = 0xffff;
- Frame.Hdr.EtherType = RT_H2BE_U16_C(0x801e);
- int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3, &Frame.Hdr.SrcMac);
- if (RT_SUCCESS(rc))
- rc = drvR3IntNetResumeSend(pThis, &Frame, sizeof(Frame));
- if (RT_FAILURE(rc))
- LogRel(("IntNet#%u: Sending dummy frame failed: %Rrc\n", pDrvIns->iInstance, rc));
- }
+ uint32_t u32TrunkType;
+ int rc = CFGMR3QueryU32(pDrvIns->pCfg, "TrunkType", &u32TrunkType);
+ AssertRC(rc);
+
+ /*
+ * Only do the disconnect for bridged networking. Host-only and
+ * internal networks are not affected by a host resume.
+ */
+ if ( RT_SUCCESS(rc)
+ && u32TrunkType == kIntNetTrunkType_NetFlt)
+ {
+ rc = pThis->pIAboveConfigR3->pfnSetLinkState(pThis->pIAboveConfigR3,
+ PDMNETWORKLINKSTATE_DOWN_RESUME);
+ AssertRC(rc);
+ }
+ break;
+ }
+ case VMRESUMEREASON_TELEPORTED:
+ case VMRESUMEREASON_TELEPORT_FAILED:
+ {
+ if ( PDMDrvHlpVMTeleportedAndNotFullyResumedYet(pDrvIns)
+ && pThis->pIAboveConfigR3)
+ {
+ /*
+ * We've just been teleported and need to drop a hint to the switch
+ * since we're likely to have changed to a different port. We just
+ * push out some ethernet frame that doesn't mean anything to anyone.
+ * For this purpose ethertype 0x801e was chosen since it was registered
+ * to Sun (dunno what it is/was used for though).
+ */
+ union
+ {
+ RTNETETHERHDR Hdr;
+ uint8_t ab[128];
+ } Frame;
+ RT_ZERO(Frame);
+ Frame.Hdr.DstMac.au16[0] = 0xffff;
+ Frame.Hdr.DstMac.au16[1] = 0xffff;
+ Frame.Hdr.DstMac.au16[2] = 0xffff;
+ Frame.Hdr.EtherType = RT_H2BE_U16_C(0x801e);
+ int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3,
+ &Frame.Hdr.SrcMac);
+ if (RT_SUCCESS(rc))
+ rc = drvR3IntNetResumeSend(pThis, &Frame, sizeof(Frame));
+ if (RT_FAILURE(rc))
+ LogRel(("IntNet#%u: Sending dummy frame failed: %Rrc\n",
+ pDrvIns->iInstance, rc));
+ }
+ break;
+ }
+ default: /* ignore every other resume reason else */
+ break;
+ } /* end of switch(enmReason) */
}
@@ -1660,7 +1694,7 @@ static DECLCALLBACK(int) drvR3IntNetConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
/* Temporary hack: attach to a network with the name 'if=en0' and you're hitting the wire. */
if ( !OpenReq.szTrunk[0]
&& OpenReq.enmTrunkType == kIntNetTrunkType_None
- && !strncmp(pThis->szNetwork, "if=en", sizeof("if=en") - 1)
+ && !strncmp(pThis->szNetwork, RT_STR_TUPLE("if=en"))
&& RT_C_IS_DIGIT(pThis->szNetwork[sizeof("if=en") - 1])
&& !pThis->szNetwork[sizeof("if=en")])
{
@@ -1670,7 +1704,7 @@ static DECLCALLBACK(int) drvR3IntNetConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg
/* Temporary hack: attach to a network with the name 'wif=en0' and you're on the air. */
if ( !OpenReq.szTrunk[0]
&& OpenReq.enmTrunkType == kIntNetTrunkType_None
- && !strncmp(pThis->szNetwork, "wif=en", sizeof("wif=en") - 1)
+ && !strncmp(pThis->szNetwork, RT_STR_TUPLE("wif=en"))
&& RT_C_IS_DIGIT(pThis->szNetwork[sizeof("wif=en") - 1])
&& !pThis->szNetwork[sizeof("wif=en")])
{