VirtualBox

Changeset 47499 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jul 31, 2013 5:36:16 PM (11 years ago)
Author:
vboxsync
Message:

Devices/Network: Temporarily disconnect network devices after the host resumed for NAT and bridged networks to let the guest pick up changed networks

Location:
trunk/src/VBox/Devices/Network
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r47459 r47499  
    64246424    PE1KSTATE pThis = RT_FROM_MEMBER(pInterface, E1KSTATE, INetworkConfig);
    64256425    bool fOldUp = !!(STATUS & STATUS_LU);
    6426     bool fNewUp = enmState == PDMNETWORKLINKSTATE_UP;
    6427 
     6426    bool fNewUp = enmState == PDMNETWORKLINKSTATE_UP || enmState == PDMNETWORKLINKSTATE_DOWN_RESUME;
     6427
     6428    /* old state was connected but STATUS not yet written by guest */
    64286429    if (   fNewUp != fOldUp
    6429         || (!fNewUp && pThis->fCableConnected)) /* old state was connected but STATUS not
    6430                                                   * yet written by guest */
     6430        || (!fNewUp && pThis->fCableConnected)
     6431        || (pThis->fCableConnected && enmState == PDMNETWORKLINKSTATE_DOWN_RESUME))
    64316432    {
    64326433        if (fNewUp)
     
    64496450            e1kRaiseInterrupt(pThis, VERR_SEM_BUSY, ICR_LSC);
    64506451        }
     6452
    64516453        if (pThis->pDrvR3)
    6452             pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, enmState);
     6454        {
     6455            /*
     6456             * Send a UP link state to the driver below if the network adapter is only
     6457             * temproarily disconnected due to resume event.
     6458             */
     6459            if (enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
     6460                pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, PDMNETWORKLINKSTATE_UP);
     6461            else
     6462                pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, enmState);
     6463        }
    64536464    }
    64546465    return VINF_SUCCESS;
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r46456 r47499  
    46664666    PPCNETSTATE pThis = RT_FROM_MEMBER(pInterface, PCNETSTATE, INetworkConfig);
    46674667    bool fLinkUp;
    4668     if (    enmState != PDMNETWORKLINKSTATE_DOWN
    4669         &&  enmState != PDMNETWORKLINKSTATE_UP)
    4670     {
    4671         AssertMsgFailed(("Invalid parameter enmState=%d\n", enmState));
    4672         return VERR_INVALID_PARAMETER;
    4673     }
     4668
     4669    AssertMsgReturn(enmState > PDMNETWORKLINKSTATE_INVALID && enmState <= PDMNETWORKLINKSTATE_DOWN_RESUME,
     4670                    ("Invalid link state: enmState=%d\n", enmState), VERR_INVALID_PARAMETER);
    46744671
    46754672    /* has the state changed? */
    4676     fLinkUp = enmState == PDMNETWORKLINKSTATE_UP;
    4677     if (pThis->fLinkUp != fLinkUp)
     4673    fLinkUp = enmState == PDMNETWORKLINKSTATE_UP || enmState == PDMNETWORKLINKSTATE_DOWN_RESUME;
     4674    if (   pThis->fLinkUp != fLinkUp
     4675        || enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
    46784676    {
    46794677        pThis->fLinkUp = fLinkUp;
    46804678        if (fLinkUp)
    46814679        {
    4682             /* connect  with a delay of 5 seconds */
     4680            /* Connect with a configured delay. */
    46834681            pThis->fLinkTempDown = true;
    46844682            pThis->cLinkDownReported = 0;
     
    46974695        Assert(!PDMCritSectIsOwner(&pThis->CritSect));
    46984696        if (pThis->pDrvR3)
    4699             pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, enmState);
     4697        {
     4698            /*
     4699             * Send a UP link state to the driver below if the network adapter is only
     4700             * temproarily disconnected due to resume event.
     4701             */
     4702            if (enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
     4703                pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, PDMNETWORKLINKSTATE_UP);
     4704            else
     4705                pThis->pDrvR3->pfnNotifyLinkChanged(pThis->pDrvR3, enmState);
     4706        }
    47004707    }
    47014708    return VINF_SUCCESS;
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r46904 r47499  
    998998    PVNETSTATE pThis = RT_FROM_MEMBER(pInterface, VNETSTATE, INetworkConfig);
    999999    bool fOldUp = !!(STATUS & VNET_S_LINK_UP);
    1000     bool fNewUp = enmState == PDMNETWORKLINKSTATE_UP;
    1001 
    1002     if (fNewUp != fOldUp)
     1000    bool fNewUp = enmState == PDMNETWORKLINKSTATE_UP || enmState == PDMNETWORKLINKSTATE_DOWN_RESUME;
     1001
     1002    if (   fNewUp != fOldUp
     1003        || enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
    10031004    {
    10041005        if (fNewUp)
     
    10151016        }
    10161017        if (pThis->pDrv)
    1017             pThis->pDrv->pfnNotifyLinkChanged(pThis->pDrv, enmState);
     1018        {
     1019            /*
     1020             * Send a UP link state to the driver below if the network adapter is only
     1021             * temproarily disconnected due to resume event.
     1022             */
     1023            if (enmState == PDMNETWORKLINKSTATE_DOWN_RESUME)
     1024                pThis->pDrv->pfnNotifyLinkChanged(pThis->pDrv, PDMNETWORKLINKSTATE_UP);
     1025            else
     1026                pThis->pDrv->pfnNotifyLinkChanged(pThis->pDrv, enmState);
     1027        }
    10181028    }
    10191029    return VINF_SUCCESS;
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r46904 r47499  
    10351035    LogFlow(("drvR3IntNetPowerResume\n"));
    10361036    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
     1037    VMRESUMEREASON enmReason = PDMDrvHlpVMGetResumeReason(pDrvIns);
     1038
    10371039    if (!pThis->fActivateEarlyDeactivateLate)
    10381040    {
     
    10421044        drvR3IntNetSetActive(pThis, true /* fActive */);
    10431045    }
    1044     if (   PDMDrvHlpVMTeleportedAndNotFullyResumedYet(pDrvIns)
    1045         && pThis->pIAboveConfigR3)
    1046     {
    1047         /*
    1048          * We've just been teleported and need to drop a hint to the switch
    1049          * since we're likely to have changed to a different port.  We just
    1050          * push out some ethernet frame that doesn't mean anything to anyone.
    1051          * For this purpose ethertype 0x801e was chosen since it was registered
    1052          * to Sun (dunno what it is/was used for though).
    1053          */
    1054         union
     1046
     1047    switch (enmReason)
     1048    {
     1049        case VMRESUMEREASON_HOST_RESUME:
    10551050        {
    1056             RTNETETHERHDR   Hdr;
    1057             uint8_t         ab[128];
    1058         } Frame;
    1059         RT_ZERO(Frame);
    1060         Frame.Hdr.DstMac.au16[0] = 0xffff;
    1061         Frame.Hdr.DstMac.au16[1] = 0xffff;
    1062         Frame.Hdr.DstMac.au16[2] = 0xffff;
    1063         Frame.Hdr.EtherType      = RT_H2BE_U16_C(0x801e);
    1064         int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3, &Frame.Hdr.SrcMac);
    1065         if (RT_SUCCESS(rc))
    1066             rc = drvR3IntNetResumeSend(pThis, &Frame, sizeof(Frame));
    1067         if (RT_FAILURE(rc))
    1068             LogRel(("IntNet#%u: Sending dummy frame failed: %Rrc\n", pDrvIns->iInstance, rc));
    1069     }
     1051            uint32_t u32TrunkType;
     1052            int rc = CFGMR3QueryU32(pDrvIns->pCfg, "TrunkType", &u32TrunkType);
     1053            AssertRC(rc);
     1054
     1055            /*
     1056             * Only do the disconnect for bridged networking. Host-only and
     1057             * internal networks are not affected by a host resume.
     1058             */
     1059            if (   RT_SUCCESS(rc)
     1060                && u32TrunkType == kIntNetTrunkType_NetFlt)
     1061            {
     1062                rc = pThis->pIAboveConfigR3->pfnSetLinkState(pThis->pIAboveConfigR3,
     1063                                                             PDMNETWORKLINKSTATE_DOWN_RESUME);
     1064                AssertRC(rc);
     1065            }
     1066            break;
     1067        }
     1068        case VMRESUMEREASON_TELEPORTED:
     1069        case VMRESUMEREASON_TELEPORT_FAILED:
     1070        {
     1071            if (   PDMDrvHlpVMTeleportedAndNotFullyResumedYet(pDrvIns)
     1072                   && pThis->pIAboveConfigR3)
     1073            {
     1074                /*
     1075                 * We've just been teleported and need to drop a hint to the switch
     1076                 * since we're likely to have changed to a different port.  We just
     1077                 * push out some ethernet frame that doesn't mean anything to anyone.
     1078                 * For this purpose ethertype 0x801e was chosen since it was registered
     1079                 * to Sun (dunno what it is/was used for though).
     1080                 */
     1081                union
     1082                {
     1083                    RTNETETHERHDR   Hdr;
     1084                    uint8_t         ab[128];
     1085                } Frame;
     1086                RT_ZERO(Frame);
     1087                Frame.Hdr.DstMac.au16[0] = 0xffff;
     1088                Frame.Hdr.DstMac.au16[1] = 0xffff;
     1089                Frame.Hdr.DstMac.au16[2] = 0xffff;
     1090                Frame.Hdr.EtherType      = RT_H2BE_U16_C(0x801e);
     1091                int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3,
     1092                                                           &Frame.Hdr.SrcMac);
     1093                if (RT_SUCCESS(rc))
     1094                    rc = drvR3IntNetResumeSend(pThis, &Frame, sizeof(Frame));
     1095                if (RT_FAILURE(rc))
     1096                    LogRel(("IntNet#%u: Sending dummy frame failed: %Rrc\n",
     1097                            pDrvIns->iInstance, rc));
     1098            }
     1099            break;
     1100        }
     1101        default: /* ignore every other resume reason else */
     1102            break;
     1103    } /* end of switch(enmReason) */
    10701104}
    10711105
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r45061 r47499  
    970970    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    971971    drvNATSetMac(pThis);
     972}
     973
     974
     975/**
     976 * @interface_method_impl{PDMDEVREG,pfnResume}
     977 */
     978static DECLCALLBACK(void) drvNATResume(PPDMDRVINS pDrvIns)
     979{
     980    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     981    VMRESUMEREASON enmReason = PDMDrvHlpVMGetResumeReason(pDrvIns);
     982
     983    switch (enmReason)
     984    {
     985        case VMRESUMEREASON_HOST_RESUME:
     986            /*
     987             * Host resumed from a suspend and the network might have changed.
     988             * Disconnect the guest from the network temporarily to let it pick up the changes.
     989             */
     990            pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig,
     991                                                  PDMNETWORKLINKSTATE_DOWN_RESUME);
     992            return;
     993        default: /* Ignore every other resume reason. */
     994            /* do nothing */
     995            return;
     996    }
    972997}
    973998
     
    14461471    NULL,
    14471472    /* pfnResume */
    1448     NULL,
     1473    drvNATResume,
    14491474    /* pfnAttach */
    14501475    NULL,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette