VirtualBox

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


Ignore:
Timestamp:
Dec 16, 2022 1:59:53 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154904
Message:

Devices/Network/DevVirtioNet_1_0: Fixed broken network after loading a saved state (call to virtioNetConfigurePktHdr() was missing causing packet offsets to be incorrect and packet data to be grabled). Also implement the temporary link down after loading a saved state to accomodate for changed network topologies, bugref:8651

File:
1 edited

Legend:

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

    r97814 r97824  
    10901090    Log10(("\n"));
    10911091    return rc;
     1092}
     1093
     1094/**
     1095 * Takes down the link temporarily if its current status is up.
     1096 *
     1097 * This is used during restore and when replumbing the network link.
     1098 *
     1099 * The temporary link outage is supposed to indicate to the OS that all network
     1100 * connections have been lost and that it for instance is appropriate to
     1101 * renegotiate any DHCP lease.
     1102 *
     1103 * @param   pDevIns     The device instance.
     1104 * @param   pThis       The virtio-net shared instance data.
     1105 * @param   pThisCC     The virtio-net ring-3 instance data.
     1106 */
     1107static void virtioNetR3TempLinkDown(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC)
     1108{
     1109    if (IS_LINK_UP(pThis))
     1110    {
     1111        SET_LINK_DOWN(pThis);
     1112
     1113        /* Re-establish link in 5 seconds. */
     1114        int rc = PDMDevHlpTimerSetMillies(pDevIns, pThisCC->hLinkUpTimer, pThis->cMsLinkUpDelay);
     1115        AssertRC(rc);
     1116
     1117        LogFunc(("[%s] Link is down temporarily\n", pThis->szInst));
     1118    }
     1119}
     1120
     1121
     1122static void virtioNetConfigurePktHdr(PVIRTIONET pThis, uint32_t fLegacy)
     1123{
     1124    /* Calculate network packet header type and size based on what we know now */
     1125    pThis->cbPktHdr = sizeof(VIRTIONETPKTHDR);
     1126    if (!fLegacy)
     1127        /* Modern (e.g. >= VirtIO 1.0) device specification's pkt size rules */
     1128        if (FEATURE_ENABLED(MRG_RXBUF))
     1129            pThis->ePktHdrType = kVirtioNetModernPktHdrWithMrgRx;
     1130        else /* Modern guest driver with MRG_RX feature disabled */
     1131            pThis->ePktHdrType = kVirtioNetModernPktHdrWithoutMrgRx;
     1132    else
     1133    {
     1134        /* Legacy (e.g. < VirtIO 1.0) device specification's pkt size rules */
     1135        if (FEATURE_ENABLED(MRG_RXBUF))
     1136            pThis->ePktHdrType = kVirtioNetLegacyPktHdrWithMrgRx;
     1137        else /* Legacy guest with MRG_RX feature disabled */
     1138        {
     1139            pThis->ePktHdrType = kVirtioNetLegacyPktHdrWithoutMrgRx;
     1140            pThis->cbPktHdr -= RT_SIZEOFMEMB(VIRTIONETPKTHDR, uNumBuffers);
     1141        }
     1142    }
    10921143}
    10931144
     
    12351286 *        and thus supports both legacy and modern guest virtio drivers.
    12361287 */
    1237 static DECLCALLBACK(int) virtioNetR3ModernDeviceLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1288static DECLCALLBACK(int) virtioNetR3ModernLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    12381289{
    12391290    PVIRTIONET     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
     
    13751426    pThis->virtioNetConfig.uStatus = pThis->Virtio.fDeviceStatus; /* reflects state to guest driver */
    13761427    pThis->fVirtioReady = pThis->Virtio.fDeviceStatus & VIRTIO_STATUS_DRIVER_OK;
    1377 
     1428    virtioNetConfigurePktHdr(pThis, pThis->Virtio.fLegacyDriver);
    13781429    return rc;
     1430}
     1431
     1432/**
     1433 * @callback_method_impl{FNSSMDEVLOADDONE, Link status adjustments after
     1434 *                      loading.}
     1435 */
     1436static DECLCALLBACK(int) virtioNetR3ModernLoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     1437{
     1438    PVIRTIONET     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
     1439    PVIRTIONETCC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
     1440    RT_NOREF(pSSM);
     1441
     1442    if (pThisCC->pDrv)
     1443        pThisCC->pDrv->pfnSetPromiscuousMode(pThisCC->pDrv, (pThis->fPromiscuous | pThis->fAllMulticast));
     1444
     1445    /*
     1446     * Indicate link down to the guest OS that all network connections have
     1447     * been lost, unless we've been teleported here.
     1448     */
     1449    if (!PDMDevHlpVMTeleportedAndNotFullyResumedYet(pDevIns))
     1450        virtioNetR3TempLinkDown(pDevIns, pThis, pThisCC);
     1451
     1452    return VINF_SUCCESS;
    13791453}
    13801454
     
    28742948
    28752949/**
    2876  * Takes down the link temporarily if its current status is up.
    2877  *
    2878  * This is used during restore and when replumbing the network link.
    2879  *
    2880  * The temporary link outage is supposed to indicate to the OS that all network
    2881  * connections have been lost and that it for instance is appropriate to
    2882  * renegotiate any DHCP lease.
    2883  *
    2884  * @param   pDevIns     The device instance.
    2885  * @param   pThis       The virtio-net shared instance data.
    2886  * @param   pThisCC     The virtio-net ring-3 instance data.
    2887  */
    2888 static void virtioNetR3TempLinkDown(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC)
    2889 {
    2890     if (IS_LINK_UP(pThis))
    2891     {
    2892         SET_LINK_DOWN(pThis);
    2893 
    2894         /* Re-establish link in 5 seconds. */
    2895         int rc = PDMDevHlpTimerSetMillies(pDevIns, pThisCC->hLinkUpTimer, pThis->cMsLinkUpDelay);
    2896         AssertRC(rc);
    2897 
    2898         LogFunc(("[%s] Link is down temporarily\n", pThis->szInst));
    2899     }
    2900 }
    2901 
    2902 /**
    29032950 * @interface_method_impl{PDMINETWORKCONFIG,pfnSetLinkState}
    29042951 */
     
    29522999            pThis->fCableConnected = true;
    29533000            SET_LINK_UP(pThis);
    2954             virtioCoreNotifyConfigChanged(&pThis->Virtio);
    29553001        }
    29563002        else /* Link requested to be brought down */
     
    29613007            pThis->fCableConnected = false;
    29623008            SET_LINK_DOWN(pThis);
    2963             virtioCoreNotifyConfigChanged(&pThis->Virtio);
    29643009        }
    29653010        if (pThisCC->pDrv)
     
    30803125}
    30813126
    3082 static void virtioNetConfigurePktHdr(PVIRTIONET pThis, uint32_t fLegacy)
    3083 {
    3084     /* Calculate network packet header type and size based on what we know now */
    3085     pThis->cbPktHdr = sizeof(VIRTIONETPKTHDR);
    3086     if (!fLegacy)
    3087         /* Modern (e.g. >= VirtIO 1.0) device specification's pkt size rules */
    3088         if (FEATURE_ENABLED(MRG_RXBUF))
    3089             pThis->ePktHdrType = kVirtioNetModernPktHdrWithMrgRx;
    3090         else /* Modern guest driver with MRG_RX feature disabled */
    3091             pThis->ePktHdrType = kVirtioNetModernPktHdrWithoutMrgRx;
    3092     else
    3093     {
    3094         /* Legacy (e.g. < VirtIO 1.0) device specification's pkt size rules */
    3095         if (FEATURE_ENABLED(MRG_RXBUF))
    3096             pThis->ePktHdrType = kVirtioNetLegacyPktHdrWithMrgRx;
    3097         else /* Legacy guest with MRG_RX feature disabled */
    3098         {
    3099             pThis->ePktHdrType = kVirtioNetLegacyPktHdrWithoutMrgRx;
    3100             pThis->cbPktHdr -= RT_SIZEOFMEMB(VIRTIONETPKTHDR, uNumBuffers);
    3101         }
    3102     }
    3103 }
    31043127
    31053128/**
     
    35953618     * Register saved state.
    35963619     */
    3597     rc = PDMDevHlpSSMRegister(pDevIns, VIRTIONET_SAVEDSTATE_VERSION, sizeof(*pThis),
    3598                               virtioNetR3ModernSaveExec, virtioNetR3ModernDeviceLoadExec);
     3620    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIONET_SAVEDSTATE_VERSION, sizeof(*pThis), NULL,
     3621                                NULL, NULL, NULL, /** @todo r=aeichner Teleportation? */
     3622                                NULL, virtioNetR3ModernSaveExec, NULL,
     3623                                NULL, virtioNetR3ModernLoadExec, virtioNetR3ModernLoadDone);
    35993624    AssertRCReturn(rc, rc);
    36003625    /*
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