VirtualBox

Changeset 55041 in vbox for trunk/src


Ignore:
Timestamp:
Mar 31, 2015 3:22:11 PM (10 years ago)
Author:
vboxsync
Message:

NDIS6/NetLwf: re-worked promiscuous mode handling (#7231)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp

    r53624 r55041  
    187187    /** MAC address of underlying adapter */
    188188    RTMAC MacAddr;
    189     /** Packet filter of underlying miniport */
    190     ULONG uPacketFilter;
    191189    /** Saved offload configuration */
    192190    NDIS_OFFLOAD SavedOffloadConfig;
     
    197195    /** true if the trunk expects data from us */
    198196    bool fActive;
     197    /** true if the host wants the adapter to be in promisc mode */
     198    bool fHostPromisc;
    199199} VBOXNETLWF_MODULE;
    200200typedef VBOXNETLWF_MODULE *PVBOXNETLWF_MODULE;
     
    470470}
    471471
     472void inline vboxNetLwfWinOverridePacketFiltersUp(PVBOXNETLWF_MODULE pModuleCtx, ULONG *pFilters)
     473{
     474    if (ASMAtomicReadBool(&pModuleCtx->fActive) && !ASMAtomicReadBool(&pModuleCtx->fHostPromisc))
     475        *pFilters &= ~NDIS_PACKET_TYPE_PROMISCUOUS;
     476}
     477
    472478NDIS_STATUS vboxNetLwfWinOidRequest(IN NDIS_HANDLE hModuleCtx,
    473479                                    IN PNDIS_OID_REQUEST pOidRequest)
     
    494500            && pOidRequest->DATA.SET_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER)
    495501        {
    496             ASMAtomicWriteU32((uint32_t*)&pModuleCtx->uPacketFilter, *(ULONG*)pOidRequest->DATA.SET_INFORMATION.InformationBuffer);
    497             Log((__FUNCTION__": updated cached packet filter value to:\n"));
     502            ASMAtomicWriteBool(&pModuleCtx->fHostPromisc, !!(*(ULONG*)pOidRequest->DATA.SET_INFORMATION.InformationBuffer & NDIS_PACKET_TYPE_PROMISCUOUS));
     503            Log((__FUNCTION__": host wanted to set packet filter value to:\n"));
     504            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pOidRequest->DATA.SET_INFORMATION.InformationBuffer);
     505            /* Keep adapter in promisc mode as long as we are active. */
     506            if (ASMAtomicReadBool(&pModuleCtx->fActive))
     507                *(ULONG*)pClone->DATA.SET_INFORMATION.InformationBuffer |= NDIS_PACKET_TYPE_PROMISCUOUS;
     508            Log5((__FUNCTION__": pass the following packet filters to miniport:\n"));
    498509            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pOidRequest->DATA.SET_INFORMATION.InformationBuffer);
    499510        }
     
    512523            pPrev = ASMAtomicXchgPtrT(&pModuleCtx->pPendingRequest, NULL, PNDIS_OID_REQUEST);
    513524            Assert(pPrev == pClone);
     525            Log5((__FUNCTION__": got the following packet filters from miniport:\n"));
     526            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pOidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
     527            /*
     528             * The host does not expect the adapter to be in promisc mode,
     529             * unless it enabled the mode. Let's not disillusion it.
     530             */
     531            if (   pOidRequest->RequestType == NdisRequestQueryInformation
     532                && pOidRequest->DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER)
     533                vboxNetLwfWinOverridePacketFiltersUp(pModuleCtx, (ULONG*)pOidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
     534            Log5((__FUNCTION__": reporting to the host the following packet filters:\n"));
     535            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pOidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
    514536            vboxNetLwfWinCopyOidRequestResults(pClone, pOidRequest);
    515537            NdisFreeCloneOidRequest(pModuleCtx->hFilter, pClone);
     
    538560        Assert(pPrev == pRequest);
    539561
     562        Log5((__FUNCTION__": completed rq type=%d oid=%x\n", pRequest->RequestType, pRequest->DATA.QUERY_INFORMATION.Oid));
    540563        vboxNetLwfWinCopyOidRequestResults(pRequest, pOriginal);
     564        if (   pRequest->RequestType == NdisRequestQueryInformation
     565            && pRequest->DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER)
     566        {
     567            Log5((__FUNCTION__": underlying miniport reports its packet filters:\n"));
     568            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
     569            vboxNetLwfWinOverridePacketFiltersUp(pModuleCtx, (ULONG*)pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
     570            Log5((__FUNCTION__": reporting the following packet filters to upper protocol:\n"));
     571            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
     572        }
    541573        NdisFreeCloneOidRequest(pModuleCtx->hFilter, pRequest);
    542574        NdisFOidRequestComplete(pModuleCtx->hFilter, pOriginal, Status);
     
    556588static bool vboxNetLwfWinIsPromiscuous(PVBOXNETLWF_MODULE pModuleCtx)
    557589{
    558     return !!(pModuleCtx->uPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS);
     590    return ASMAtomicReadBool(&pModuleCtx->fHostPromisc);
    559591}
    560592
     
    591623{
    592624    LogFlow(("==>"__FUNCTION__": module=%p %s\n", pModuleCtx, fPromisc ? "promiscuous" : "normal"));
     625    ULONG uFilter = 0;
    593626    VBOXNETLWF_OIDREQ Rq;
    594627    vboxNetLwfWinInitOidRequest(&Rq);
    595     ULONG uFilter = ASMAtomicReadU32((uint32_t*)&pModuleCtx->uPacketFilter);
     628    Rq.Request.RequestType = NdisRequestQueryInformation;
     629    Rq.Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
     630    Rq.Request.DATA.QUERY_INFORMATION.InformationBuffer = &uFilter;
     631    Rq.Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(uFilter);
     632    NDIS_STATUS Status = vboxNetLwfWinSyncOidRequest(pModuleCtx, &Rq);
     633    if (Status != NDIS_STATUS_SUCCESS)
     634    {
     635        Log((__FUNCTION__": vboxNetLwfWinSyncOidRequest(query, OID_GEN_CURRENT_PACKET_FILTER) failed with 0x%x\n", Status));
     636        return Status;
     637    }
     638    if (Rq.Request.DATA.QUERY_INFORMATION.BytesWritten != sizeof(uFilter))
     639    {
     640        Log((__FUNCTION__": vboxNetLwfWinSyncOidRequest(query, OID_GEN_CURRENT_PACKET_FILTER) failed to write neccessary amount (%d bytes), actually written %d bytes\n", sizeof(uFilter), Rq.Request.DATA.QUERY_INFORMATION.BytesWritten));
     641        return NDIS_STATUS_FAILURE;
     642    }
     643
     644    Log5((__FUNCTION__": OID_GEN_CURRENT_PACKET_FILTER query returned the following filters:\n"));
     645    vboxNetLwfWinDumpFilterTypes(uFilter);
     646
    596647    if (fPromisc)
     648    {
     649        /* If we about to go promiscuous, save the state before we change it. */
     650        ASMAtomicWriteBool(&pModuleCtx->fHostPromisc, !!(uFilter & NDIS_PACKET_TYPE_PROMISCUOUS));
    597651        uFilter |= NDIS_PACKET_TYPE_PROMISCUOUS;
     652    }
     653    else
     654    {
     655        /* Reset promisc only if it was not enabled before we had changed it. */
     656        if (!ASMAtomicReadBool(&pModuleCtx->fHostPromisc))
     657            uFilter &= ~NDIS_PACKET_TYPE_PROMISCUOUS;
     658    }
     659
     660    Log5((__FUNCTION__": OID_GEN_CURRENT_PACKET_FILTER about to set the following filters:\n"));
     661    vboxNetLwfWinDumpFilterTypes(uFilter);
     662
     663    NdisResetEvent(&Rq.Event); /* need to reset as it has been set by query op */
    598664    Rq.Request.RequestType = NdisRequestSetInformation;
    599665    Rq.Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
    600666    Rq.Request.DATA.SET_INFORMATION.InformationBuffer = &uFilter;
    601667    Rq.Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(uFilter);
    602     NDIS_STATUS Status = vboxNetLwfWinSyncOidRequest(pModuleCtx, &Rq);
     668    Status = vboxNetLwfWinSyncOidRequest(pModuleCtx, &Rq);
    603669    if (Status != NDIS_STATUS_SUCCESS)
    604670    {
     
    12711337{
    12721338    LogFlow(("==>"__FUNCTION__": module=%p\n", hModuleCtx));
    1273     PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx;
    1274     Log((__FUNCTION__"Status indication: %s\n", vboxNetLwfWinStatusToText(pIndication->StatusCode)));
     1339    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
     1340    Log((__FUNCTION__"Got status indication: %s\n", vboxNetLwfWinStatusToText(pIndication->StatusCode)));
    12751341    switch (pIndication->StatusCode)
    12761342    {
    12771343        case NDIS_STATUS_PACKET_FILTER:
     1344            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pIndication->StatusBuffer);
     1345            vboxNetLwfWinOverridePacketFiltersUp(pModuleCtx, (ULONG*)pIndication->StatusBuffer);
     1346            Log((__FUNCTION__"Reporting status: %s\n", vboxNetLwfWinStatusToText(pIndication->StatusCode)));
    12781347            vboxNetLwfWinDumpFilterTypes(*(ULONG*)pIndication->StatusBuffer);
    12791348            break;
     
    12831352            break;
    12841353    }
    1285     NdisFIndicateStatus(pModule->hFilter, pIndication);
     1354    NdisFIndicateStatus(pModuleCtx->hFilter, pIndication);
    12861355    LogFlow(("<=="__FUNCTION__"\n"));
    12871356}
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