VirtualBox

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


Ignore:
Timestamp:
Aug 19, 2024 2:05:15 PM (8 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164430
Message:

Devices/Network: cleaned up header file, memory leak fixes, search domains pushed to guest on host network change only. bugref:10268

Location:
trunk/src/VBox/Devices/Network
Files:
1 deleted
2 edited

Legend:

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

    r105353 r105726  
    10971097 * information ourselves.
    10981098 */
    1099 static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface)
    1100 {
     1099static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConf)
     1100{
     1101    RT_NOREF(pDnsConf);
    11011102    PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
    11021103    drvNATUpdateDNS(pThis, /* fFlapLink */ true);
  • trunk/src/VBox/Devices/Network/DrvNATlibslirp.cpp

    r105429 r105726  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_DRV_NAT
    33 
    34 #include "DrvNATlibslirp.h"
    35 
    36 
    37 /**
     33#define RTNET_INCL_IN_ADDR
     34#include "VBoxDD.h"
     35
     36#ifdef RT_OS_WINDOWS
     37# include <iprt/win/winsock2.h>
     38# include <iprt/win/ws2tcpip.h>
     39#endif
     40
     41#include <libslirp.h>
     42
     43#include <VBox/vmm/dbgf.h>
     44#include <VBox/vmm/pdmdrv.h>
     45#include <VBox/vmm/pdmnetifs.h>
     46#include <VBox/vmm/pdmnetinline.h>
     47
     48#ifndef RT_OS_WINDOWS
     49# include <unistd.h>
     50# include <fcntl.h>
     51# include <poll.h>
     52# include <errno.h>
     53#endif
     54#ifdef RT_OS_FREEBSD
     55# include <netinet/in.h>
     56#endif
     57
     58#ifdef RT_OS_WINDOWS
     59# include <iprt/win/winsock2.h>
     60# define inet_aton(x, y) inet_pton(2, x, y)
     61# define AF_INET6 23
     62#endif
     63
     64#include <iprt/assert.h>
     65#include <iprt/critsect.h>
     66#include <iprt/cidr.h>
     67#include <iprt/file.h>
     68#include <iprt/mem.h>
     69#include <iprt/net.h>
     70#include <iprt/pipe.h>
     71#include <iprt/string.h>
     72#include <iprt/stream.h>
     73#include <iprt/time.h>
     74#include <iprt/uuid.h>
     75
     76#include <iprt/asm.h>
     77
     78#include <iprt/semaphore.h>
     79#include <iprt/req.h>
     80#ifdef RT_OS_DARWIN
     81# include <SystemConfiguration/SystemConfiguration.h>
     82# include <CoreFoundation/CoreFoundation.h>
     83#endif
     84
     85#define COUNTERS_INIT
     86#include "slirp/counters.h"
     87#include "slirp/resolv_conf_parser.h"
     88
     89
     90/*********************************************************************************************************************************
     91*   Defined Constants And Macros                                                                                                 *
     92*********************************************************************************************************************************/
     93#define DRVNAT_MAXFRAMESIZE (16 * 1024)
     94#define DRVNAT_DEFAULT_TIMEOUT (3600*1000)
     95
     96/**
     97 * @todo: This is a bad hack to prevent freezing the guest during high network
     98 *        activity. Windows host only. This needs to be fixed properly.
     99 */
     100#define VBOX_NAT_DELAY_HACK
     101
     102#define GET_EXTRADATA(pdrvins, node, name, rc, type, type_name, var)                                  \
     103    do {                                                                                                \
     104        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var));                                               \
     105        if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND)                                      \
     106            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     107                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     108                                       (pdrvins)->iInstance);                                    \
     109    } while (0)
     110
     111#define GET_ED_STRICT(pdrvins, node, name, rc, type, type_name, var)                                  \
     112    do {                                                                                                \
     113        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var));                                               \
     114        if (RT_FAILURE((rc)))                                                                           \
     115            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     116                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     117                                       (pdrvins)->iInstance);                                     \
     118    } while (0)
     119
     120#define GET_EXTRADATA_N(pdrvins, node, name, rc, type, type_name, var, var_size)                      \
     121    do {                                                                                                \
     122        (rc) = (pdrvins)->pHlpR3->pfnCFGMQuery ## type((node), name, &(var), var_size);                                     \
     123        if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND)                                      \
     124            return PDMDrvHlpVMSetError((pdrvins), (rc), RT_SRC_POS, \
     125                                       N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
     126                                       (pdrvins)->iInstance);                                     \
     127    } while (0)
     128
     129#define GET_BOOL(rc, pdrvins, node, name, var) \
     130    GET_EXTRADATA(pdrvins, node, name, (rc), Bool, bolean, (var))
     131#define GET_STRING(rc, pdrvins, node, name, var, var_size) \
     132    GET_EXTRADATA_N(pdrvins, node, name, (rc), String, string, (var), (var_size))
     133#define GET_STRING_ALLOC(rc, pdrvins, node, name, var) \
     134    GET_EXTRADATA(pdrvins, node, name, (rc), StringAlloc, string, (var))
     135#define GET_S32(rc, pdrvins, node, name, var) \
     136    GET_EXTRADATA(pdrvins, node, name, (rc), S32, int, (var))
     137#define GET_S32_STRICT(rc, pdrvins, node, name, var) \
     138    GET_ED_STRICT(pdrvins, node, name, (rc), S32, int, (var))
     139
     140#define DO_GET_IP(rc, node, instance, status, x)                                \
     141    do {                                                                            \
     142        char    sz##x[32];                                                          \
     143        GET_STRING((rc), (node), (instance), #x, sz ## x[0],  sizeof(sz ## x));     \
     144        if (rc != VERR_CFGM_VALUE_NOT_FOUND)                                        \
     145            (status) = inet_aton(sz ## x, &x);                                      \
     146    } while (0)
     147
     148#define GETIP_DEF(rc, node, instance, x, def)           \
     149    do                                                      \
     150    {                                                       \
     151        int status = 0;                                     \
     152        DO_GET_IP((rc), (node), (instance),  status, x);    \
     153        if (status == 0 || rc == VERR_CFGM_VALUE_NOT_FOUND) \
     154            x.s_addr = def;                                 \
     155    } while (0)
     156
     157
     158/*********************************************************************************************************************************
     159*   Structures and Typedefs                                                                                                      *
     160*********************************************************************************************************************************/
     161/** Slirp Timer */
     162typedef struct slirpTimer
     163{
     164    struct slirpTimer *next;
     165    uint32_t uTimeExpire;
     166    SlirpTimerCb pHandler;
     167    void *opaque;
     168} SlirpTimer;
     169
     170/**
     171 * Main state of Libslirp NAT
     172 */
     173typedef struct SlirpState
     174{
     175    unsigned int nsock;
     176
     177    Slirp *pSlirp;
     178    struct pollfd *polls;
     179
     180    /** Num Polls (not bytes) */
     181    unsigned int uPollCap = 0;
     182
     183    SlirpTimer *pTimerHead;
     184} SlirpState;
     185typedef SlirpState *pSlirpState;
     186
     187/**
     188 * NAT network transport driver instance data.
     189 *
     190 * @implements  PDMINETWORKUP
     191 */
     192typedef struct DRVNAT
     193{
     194    /** The network interface. */
     195    PDMINETWORKUP           INetworkUp;
     196    /** The network NAT Engine configuration. */
     197    PDMINETWORKNATCONFIG    INetworkNATCfg;
     198    /** The port we're attached to. */
     199    PPDMINETWORKDOWN        pIAboveNet;
     200    /** The network config of the port we're attached to. */
     201    PPDMINETWORKCONFIG      pIAboveConfig;
     202    /** Pointer to the driver instance. */
     203    PPDMDRVINS              pDrvIns;
     204    /** Link state */
     205    PDMNETWORKLINKSTATE     enmLinkState;
     206    /** NAT state */
     207    pSlirpState             pNATState;
     208    /** TFTP directory prefix. */
     209    char                   *pszTFTPPrefix;
     210    /** Boot file name to provide in the DHCP server response. */
     211    char                   *pszBootFile;
     212    /** tftp server name to provide in the DHCP server response. */
     213    char                   *pszNextServer;
     214    /** Polling thread. */
     215    PPDMTHREAD              pSlirpThread;
     216    /** Queue for NAT-thread-external events. */
     217    RTREQQUEUE              hSlirpReqQueue;
     218    /** The guest IP for port-forwarding. */
     219    uint32_t                GuestIP;
     220    /** Link state set when the VM is suspended. */
     221    PDMNETWORKLINKSTATE     enmLinkStateWant;
     222
     223#ifndef RT_OS_WINDOWS
     224    /** The write end of the control pipe. */
     225    RTPIPE                  hPipeWrite;
     226    /** The read end of the control pipe. */
     227    RTPIPE                  hPipeRead;
     228# if HC_ARCH_BITS == 32
     229    uint32_t                u32Padding;
     230# endif
     231#else
     232    /** for external notification */
     233    HANDLE                  hWakeupEvent;
     234#endif
     235
     236#define DRV_PROFILE_COUNTER(name, dsc)     STAMPROFILE Stat ## name
     237#define DRV_COUNTING_COUNTER(name, dsc)    STAMCOUNTER Stat ## name
     238#include "slirp/counters.h"
     239    /** thread delivering packets for receiving by the guest */
     240    PPDMTHREAD              pRecvThread;
     241    /** event to wakeup the guest receive thread */
     242    RTSEMEVENT              EventRecv;
     243    /** Receive Req queue (deliver packets to the guest) */
     244    RTREQQUEUE              hRecvReqQueue;
     245
     246    /** makes access to device func RecvAvail and Recv atomical. */
     247    RTCRITSECT              DevAccessLock;
     248    /** Number of in-flight packets. */
     249    volatile uint32_t       cPkts;
     250
     251    /** Transmit lock taken by BeginXmit and released by EndXmit. */
     252    RTCRITSECT              XmitLock;
     253
     254#ifdef RT_OS_DARWIN
     255    /* Handle of the DNS watcher runloop source. */
     256    CFRunLoopSourceRef      hRunLoopSrcDnsWatcher;
     257#endif
     258} DRVNAT;
     259AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8);
     260/** Pointer to the NAT driver instance data. */
     261typedef DRVNAT *PDRVNAT;
     262
     263
     264/*********************************************************************************************************************************
     265*   Internal Functions                                                                                                           *
     266*********************************************************************************************************************************/
     267static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho);
     268static void drvNAT_UpdateTimeout(uint32_t *uTimeout, void *opaque);
     269static void drvNAT_CheckTimeout(void *opaque);
     270static DECLCALLBACK(int) drvNAT_AddPollCb(int iFd, int iEvents, void *opaque);
     271static DECLCALLBACK(int64_t) drvNAT_ClockGetNsCb(void *opaque);
     272static DECLCALLBACK(int) drvNAT_GetREventsCb(int idx, void *opaque);
     273
     274
     275
     276/*
    38277 * PDM Function Implementations
    39278 */
     
    499738         */
    500739#ifndef RT_OS_WINDOWS
    501         uint32_t uTimeout = 0;
     740        uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT;
    502741        pThis->pNATState->nsock = 1;
    503742
     
    548787
    549788#else /* RT_OS_WINDOWS */
    550         uint32_t uTimeout = 0;
     789        uint32_t uTimeout = DRVNAT_DEFAULT_TIMEOUT;
    551790        pThis->pNATState->nsock = 0;
    552791        slirp_pollfds_fill(pThis->pNATState->pSlirp, &uTimeout, drvNAT_AddPollCb /* SlirpAddPollCb */, pThis /* opaque */);
     
    7751014}
    7761015
     1016/**
     1017 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnRedirectRuleCommand}
     1018 */
    7771019static DECLCALLBACK(int) drvNATNetworkNatConfigRedirect(PPDMINETWORKNATCONFIG pInterface, bool fRemove,
    7781020                                                        bool fUdp, const char *pHostIp, uint16_t u16HostPort,
     
    8111053
    8121054/**
     1055 * @interface_method_impl{PDMINETWORKNATCONFIG,pfnNotifyDnsChanged}
     1056 */
     1057static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface, PCPDMINETWORKNATDNSCONFIG pDnsConf)
     1058{
     1059    PDRVNAT const      pThis     = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
     1060    SlirpState * const pNATState = pThis->pNATState;
     1061    AssertReturnVoid(pNATState);
     1062    AssertReturnVoid(pNATState->pSlirp);
     1063
     1064    slirp_set_vdomainname(pNATState->pSlirp, pDnsConf->szDomainName);
     1065    slirp_set_vdnssearch(pNATState->pSlirp, pDnsConf->papszSearchDomains);
     1066    /** @todo Convert the papszNameServers entries to IP address and tell about
     1067     *        the first IPv4 and IPv6 ones. */
     1068}
     1069
     1070
     1071/*
    8131072 * Libslirp Utility Functions
    8141073 */
     
    8221081 */
    8231082static void drvNAT_UpdateTimeout(uint32_t *uTimeout, void *opaque)
     1083{
     1084    PDRVNAT pThis = (PDRVNAT)opaque;
     1085    Assert(pThis);
     1086
     1087    uint32_t currTime = drvNAT_ClockGetNsCb(pThis) / (1000 * 1000);
     1088    SlirpTimer *pCurrent = pThis->pNATState->pTimerHead;
     1089    while (pCurrent != NULL)
     1090    {
     1091        if (pCurrent->uTimeExpire != 0)
     1092        {
     1093            int64_t diff = pCurrent->uTimeExpire - currTime;
     1094
     1095            if (diff < 0)
     1096                diff = 0;
     1097
     1098            if (diff < *uTimeout)
     1099                *uTimeout = diff;
     1100        }
     1101
     1102        pCurrent = pCurrent->next;
     1103    }
     1104}
     1105
     1106/**
     1107 * Check if timeout has passed in given list of Slirp timers.
     1108 *
     1109 * @param   opaque  Pointer to NAT State context.
     1110 *
     1111 * @thread  ?
     1112 */
     1113static void drvNAT_CheckTimeout(void *opaque)
    8241114{
    8251115    PDRVNAT pThis = (PDRVNAT)opaque;
     
    8301120    while (pCurrent != NULL)
    8311121    {
    832         if (pCurrent->uTimeExpire != -1)
    833         {
    834             int64_t diff = pCurrent->uTimeExpire - currTime;
    835 
    836             if (diff < 0)
    837                 diff = 0;
    838 
    839             if (diff < *uTimeout)
    840                 *uTimeout = diff;
    841         }
    842 
    843         pCurrent = pCurrent->next;
    844     }
    845 }
    846 
    847 /**
    848  * Check if timeout has passed in given list of Slirp timers.
    849  *
    850  * @param   opaque  Pointer to NAT State context.
    851  *
    852  * @thread  ?
    853  */
    854 static void drvNAT_CheckTimeout(void *opaque)
    855 {
    856     PDRVNAT pThis = (PDRVNAT)opaque;
    857     Assert(pThis);
    858 
    859     int64_t currTime = drvNAT_ClockGetNsCb(pThis) / (1000 * 1000);
    860     SlirpTimer *pCurrent = pThis->pNATState->pTimerHead;
    861     while (pCurrent != NULL)
    862     {
    863         if (pCurrent->uTimeExpire != -1)
     1122        if (pCurrent->uTimeExpire != 0)
    8641123        {
    8651124            int64_t diff = pCurrent->uTimeExpire - currTime;
    8661125            if (diff <= 0)
    8671126            {
    868                 pCurrent->uTimeExpire = -1;
     1127                pCurrent->uTimeExpire = 0;
    8691128                pCurrent->pHandler(pCurrent->opaque);
    8701129            }
     
    9291188}
    9301189
    931 /**
     1190
     1191/*
    9321192 * Libslirp Callbacks
    9331193 */
     
    10291289
    10301290    pNewTimer->next = pThis->pNATState->pTimerHead;
    1031     pNewTimer->uTimeExpire = -1;
     1291    pNewTimer->uTimeExpire = -1; /** @todo r=bird: uTimeExpire is unsigned, not signed. Visual C++ barfs at this mixup. */
    10321292    pNewTimer->pHandler = slirpTimeCb;
    10331293    pNewTimer->opaque = cb_opaque;
     
    10941354 * Registers poll. Unused function (other than logging).
    10951355 */
    1096 static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque) {
     1356static DECLCALLBACK(void) drvNAT_RegisterPoll(int fd, void *opaque)
     1357{
    10971358    RT_NOREF(fd, opaque);
    10981359    Log4(("Poll registered\n"));
     
    11021363 * Unregisters poll. Unused function (other than logging).
    11031364 */
    1104 static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque) {
     1365static DECLCALLBACK(void) drvNAT_UnregisterPoll(int fd, void *opaque)
     1366{
    11051367    RT_NOREF(fd, opaque);
    11061368    Log4(("Poll unregistered\n"));
     
    11271389        int cbNew = pThis->pNATState->uPollCap * 2 * sizeof(struct pollfd);
    11281390        struct pollfd *pvNew = (struct pollfd *)RTMemRealloc(pThis->pNATState->polls, cbNew);
    1129         if(pvNew)
     1391        if (pvNew)
    11301392        {
    11311393            pThis->pNATState->polls = pvNew;
     
    11821444    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    11831445
    1184     if (pThis->pNATState)
    1185     {
    1186         slirp_cleanup(pThis->pNATState->pSlirp);
     1446    SlirpState * const pNATState = pThis->pNATState;
     1447    if (pNATState)
     1448    {
     1449        slirp_cleanup(pNATState->pSlirp);
     1450
    11871451#ifdef VBOX_WITH_STATISTICS
    11881452# define DRV_PROFILE_COUNTER(name, dsc)     DEREGISTER_COUNTER(name, pThis)
     
    11901454# include "slirp/counters.h"
    11911455#endif
     1456        RTMemFree(pNATState->polls);
     1457        pNATState->polls = NULL;
     1458
     1459        RTMemFree(pNATState);
    11921460        pThis->pNATState = NULL;
    11931461    }
     
    12211489static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    12221490{
    1223     int rc = 0;
    1224 
    1225     /* Construct PDRVNAT */
    1226 
    12271491    RT_NOREF(fFlags);
    12281492    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    1229     PDRVNAT         pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     1493    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    12301494
    12311495    /*
     
    12331497     */
    12341498    pThis->pDrvIns                      = pDrvIns;
    1235     pThis->pNATState                    = (SlirpState *)RTMemAlloc(sizeof(SlirpState));
    1236     if(pThis->pNATState == NULL)
     1499
     1500    SlirpState * const pNATState = (SlirpState *)RTMemAllocZ(sizeof(*pNATState));
     1501    if (pNATState == NULL)
    12371502        return VERR_NO_MEMORY;
    1238     else
    1239     {
    1240         pThis->pNATState->nsock = 0;
    1241         pThis->pNATState->pTimerHead = NULL;
    1242         pThis->pNATState->polls = (struct pollfd *)RTMemAlloc(64 * sizeof(struct pollfd));
    1243         pThis->pNATState->uPollCap = 64;
    1244     }
     1503    pThis->pNATState                    = pNATState;
     1504    pNATState->nsock                    = 0;
     1505    pNATState->pTimerHead               = NULL;
     1506    pNATState->polls                    = (struct pollfd *)RTMemAllocZ(64 * sizeof(struct pollfd));
     1507    AssertReturn(pNATState->polls, VERR_NO_MEMORY);
     1508    pNATState->uPollCap                = 64;
     1509
    12451510    pThis->hSlirpReqQueue               = NIL_RTREQQUEUE;
    12461511    pThis->EventRecv                    = NIL_RTSEMEVENT;
     
    12601525    /* NAT engine configuration */
    12611526    pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfigRedirect;
    1262     pThis->INetworkNATCfg.pfnNotifyDnsChanged = NULL;
     1527    pThis->INetworkNATCfg.pfnNotifyDnsChanged    = drvNATNotifyDnsChanged;
    12631528
    12641529    /*
     
    12891554     * Get the configuration settings.
    12901555     */
     1556    int  rc;
    12911557    bool fPassDomain = true;
    12921558    GET_BOOL(rc, pDrvIns, pCfg, "PassDomain", fPassDomain);
     
    13351601
    13361602    RTNETADDRIPV4 Network, Netmask;
    1337 
    13381603    rc = RTCidrStrToIPv4(szNetwork, &Network, &Netmask);
    13391604    if (RT_FAILURE(rc))
     
    13441609    /* Construct Libslirp Config and Initialzie Slirp */
    13451610
    1346     LogFlow(("Here is what is coming out of the vbox config:\n \
    1347             Network: %lu\n \
    1348             Netmask: %lu\n", Network, Netmask));
    1349 
    1350 #ifndef RT_OS_WINDOWS
     1611    LogFlow(("Here is what is coming out of the vbox config:\n"
     1612             "  Network: %lu\n"
     1613             "  Netmask: %lu\n", Network, Netmask));
     1614
     1615#ifndef RT_OS_WINDOWS /** @todo r=bird: Why do we need special windows code here?!? */
    13511616    struct in_addr vnetwork = RTNetIPv4AddrHEToInAddr(&Network);
    13521617    struct in_addr vnetmask = RTNetIPv4AddrHEToInAddr(&Netmask);
     
    13711636#endif
    13721637
     1638    /** @todo r=bird: This is leaked.  It can be a stack structure since libslirp
     1639     *        only copies values from it and doesn't retain the pointer. */
    13731640    SlirpConfig *pSlirpCfg = new SlirpConfig { 0 };
    13741641
     
    13981665    pSlirpCfg->vdomainname = NULL;
    13991666
     1667    /** @todo r=bird: This is leaked.  It can be a static structure.   */
    14001668    SlirpCb *slirpCallbacks = (struct SlirpCb *)RTMemAlloc(sizeof(SlirpCb));
    14011669
     
    14321700
    14331701    rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pRecvThread, pThis, drvNATRecv,
    1434                                 drvNATRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATRX");
     1702                               drvNATRecvWakeup, 256 * _1K, RTTHREADTYPE_IO, "NATRX");
    14351703    AssertRCReturn(rc, rc);
    14361704
     
    14631731
    14641732    rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pSlirpThread, pThis, drvNATAsyncIoThread,
    1465                                 drvNATAsyncIoWakeup, 256 * _1K, RTTHREADTYPE_IO, "NAT");
     1733                               drvNATAsyncIoWakeup, 256 * _1K, RTTHREADTYPE_IO, "NAT");
    14661734    AssertRCReturn(rc, rc);
    14671735
Note: See TracChangeset for help on using the changeset viewer.

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