Changeset 10663 in vbox for trunk/src/VBox
- Timestamp:
- Jul 15, 2008 2:38:39 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r10540 r10663 788 788 789 789 # 790 # Internal Networking - Ring-3 Testcase for the Ring-0 code (a bit hackish). 791 # 792 ifdef VBOX_WITH_TESTCASES 793 PROGRAMS += tstIntNet-1 794 tstIntNet-1_TEMPLATE = VBOXR3TSTEXE 795 tstIntNet-1_SOURCES = \ 796 Network/testcase/tstIntNet-1.cpp 797 endif 798 799 800 # 790 801 # EEPROM device unit test requires cppunit 791 802 # -
trunk/src/VBox/Devices/Network/DrvIntNet.cpp
r10451 r10663 704 704 OpenReq.Hdr.cbReq = sizeof(OpenReq); 705 705 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 706 OpenReq.pSession = NULL; 706 707 707 708 /** @cfgm{Network, string} -
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10559 r10663 1253 1253 1254 1254 1255 #ifdef IN_RING0 1256 1257 /** @copydoc INTNETTRUNKSWPORT::pfnSetSGPhys */ 1258 static DECLCALLBACK(bool) intnetTrunkIfPortSetSGPhys(PINTNETTRUNKSWPORT pIfPort, bool fEnable) 1259 { 1260 AssertMsgFailed(("Not implemented because it wasn't required on Darwin\n")); 1261 return false; 1262 } 1263 1264 1265 /** @copydoc INTNETTRUNKSWPORT::pfnRecv */ 1266 static DECLCALLBACK(bool) intnetTrunkIfPortRecv(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG, uint32_t fSrc) 1267 { 1268 return false; 1269 } 1270 1271 1272 /** @copydoc INTNETTRUNKSWPORT::pfnSGRetain */ 1273 static DECLCALLBACK(void) intnetTrunkIfPortSGRetain(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG) 1274 { 1275 1276 } 1277 1278 1279 /** @copydoc INTNETTRUNKSWPORT::pfnSGRelease */ 1280 static DECLCALLBACK(void) intnetTrunkIfPortSGRelease(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG) 1281 { 1282 1283 } 1284 1285 1255 1286 /** 1256 1287 * Creates the trunk connection (if any). … … 1272 1303 case kIntNetTrunkType_WhateverNone: 1273 1304 return VINF_SUCCESS; 1305 1306 /* Can't happen, but makes GCC happy. */ 1274 1307 default: 1275 1308 return VERR_NOT_IMPLEMENTED; 1276 1309 1310 /* 1311 * Translate enum to component factory name. 1312 */ 1277 1313 case kIntNetTrunkType_NetFlt: 1278 1314 pszName = "VBoxNetFlt"; … … 1286 1322 } 1287 1323 1288 #if 01289 1324 /* 1290 1325 * Allocate the trunk interface. … … 1326 1361 rc, pszName, pNetwork->szTrunk, pNetwork->szName)); 1327 1362 return rc; 1328 #else 1329 return VERR_NOT_IMPLEMENTED; 1330 #endif 1331 } 1363 } 1364 1365 #endif /* IN_RING0 */ 1332 1366 1333 1367 … … 1576 1610 * Connect the trunk. 1577 1611 */ 1612 #ifdef IN_RING0 1578 1613 rc = intnetNetworkCreateTrunkConnection(pNew, pSession); 1614 #endif 1579 1615 if (RT_SUCCESS(rc)) 1580 1616 { -
trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
r10593 r10663 1 /* $Id$ */ 1 2 /** @file 2 * 3 * VBox - Testcase for the Ring-0 part of internal networking. 3 * VBox - Testcase for internal networking, simple NetFlt trunk creation. 4 4 */ 5 5 … … 20 20 */ 21 21 22 23 22 /******************************************************************************* 24 23 * Header Files * 25 24 *******************************************************************************/ 26 #define IN_INTNET_TESTCASE27 #define IN_INTNET_R328 #include <VBox/cdefs.h>29 #undef INTNETR0DECL30 #define INTNETR0DECL INTNETR3DECL31 25 #include <VBox/intnet.h> 32 26 #include <VBox/sup.h> 27 #include <VBox/vmm.h> 33 28 #include <VBox/err.h> 29 #include <iprt/initterm.h> 30 #include <iprt/alloc.h> 31 #include <iprt/path.h> 34 32 #include <iprt/stream.h> 35 #include <iprt/alloc.h> 36 #include <iprt/runtime.h> 33 #include <iprt/string.h> 37 34 #include <iprt/thread.h> 38 #include <iprt/time.h> 39 #include <iprt/asm.h> 35 #include <iprt/param.h> 40 36 41 42 /*******************************************************************************43 * Structures and Typedefs *44 *******************************************************************************/45 /**46 * Security objectype.47 */48 typedef enum SUPDRVOBJTYPE49 {50 /** The usual invalid object. */51 SUPDRVOBJTYPE_INVALID = 0,52 /** Internal network. */53 SUPDRVOBJTYPE_INTERNAL_NETWORK,54 /** Internal network interface. */55 SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE,56 /** The first invalid object type in this end. */57 SUPDRVOBJTYPE_END,58 /** The usual 32-bit type size hack. */59 SUPDRVOBJTYPE_32_BIT_HACK = 0x7ffffff60 } SUPDRVOBJTYPE;61 62 /**63 * Object destructor callback.64 * This is called for reference counted objectes when the count reaches 0.65 *66 * @param pvObj The object pointer.67 * @param pvUser1 The first user argument.68 * @param pvUser2 The second user argument.69 */70 typedef DECLCALLBACK(void) FNSUPDRVDESTRUCTOR(void *pvObj, void *pvUser1, void *pvUser2);71 /** Pointer to a FNSUPDRVDESTRUCTOR(). */72 typedef FNSUPDRVDESTRUCTOR *PFNSUPDRVDESTRUCTOR;73 74 75 /**76 * Dummy77 */78 typedef struct OBJREF79 {80 PFNSUPDRVDESTRUCTOR pfnDestructor;81 void *pvUser1;82 void *pvUser2;83 uint32_t volatile cRefs;84 } OBJREF, *POBJREF;85 37 86 38 /******************************************************************************* 87 39 * Global Variables * 88 40 *******************************************************************************/ 89 /** The error count. */ 90 unsigned g_cErrors = 0; 91 92 /** Fake session handle. */ 93 const PSUPDRVSESSION g_pSession = (PSUPDRVSESSION)0xdeadface; 94 95 /** Testframe 0 */ 96 struct TESTFRAME 97 { 98 uint16_t au16[6]; 99 } g_TestFrame0 = { { /* dst:*/ 0xffff, 0xffff, 0xffff, /*src:*/0x8086, 0, 0} }, 100 g_TestFrame1 = { { /* dst:*/0, 0, 0, /*src:*/0x8086, 0, 1} }; 41 static int g_cErrors = 0; 101 42 102 43 103 INTNETR3DECL(void *) SUPR0ObjRegister(PSUPDRVSESSION pSession, SUPDRVOBJTYPE enmType, PFNSUPDRVDESTRUCTOR pfnDestructor, void *pvUser1, void *pvUser2)44 int main(int argc, char **argv) 104 45 { 105 if (pSession != g_pSession) 106 { 107 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 108 g_cErrors++; 109 return NULL; 110 } 111 POBJREF pRef = (POBJREF)RTMemAlloc(sizeof(OBJREF)); 112 if (!pRef) 113 return NULL; 114 pRef->cRefs = 1; 115 pRef->pfnDestructor = pfnDestructor; 116 pRef->pvUser1 = pvUser1; 117 pRef->pvUser2 = pvUser2; 118 return pRef; 119 } 120 121 INTNETR3DECL(int) SUPR0ObjAddRef(void *pvObj, PSUPDRVSESSION pSession) 122 { 123 if (pSession != g_pSession) 124 { 125 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 126 g_cErrors++; 127 return VERR_INVALID_PARAMETER; 128 } 129 POBJREF pRef = (POBJREF)pvObj; 130 ASMAtomicIncU32(&pRef->cRefs); 131 return VINF_SUCCESS; 132 } 133 134 INTNETR3DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession) 135 { 136 if (pSession != g_pSession) 137 { 138 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 139 g_cErrors++; 140 return VERR_INVALID_PARAMETER; 141 } 142 POBJREF pRef = (POBJREF)pvObj; 143 if (!ASMAtomicDecU32(&pRef->cRefs)) 144 { 145 pRef->pfnDestructor(pRef, pRef->pvUser1, pRef->pvUser2); 146 RTMemFree(pRef); 147 } 148 return VINF_SUCCESS; 149 } 150 151 INTNETR3DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName) 152 { 153 if (pSession != g_pSession) 154 { 155 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 156 g_cErrors++; 157 return VERR_INVALID_PARAMETER; 158 } 159 return VINF_SUCCESS; 160 } 161 162 INTNETR3DECL(int) SUPR0MemAlloc(PSUPDRVSESSION pSession, uint32_t cb, PRTR0PTR ppvR0, PRTR3PTR ppvR3) 163 { 164 if (pSession != g_pSession) 165 { 166 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 167 g_cErrors++; 168 return VERR_INVALID_PARAMETER; 169 } 170 void *pv = RTMemAlloc(cb); 171 if (!pv) 172 return VERR_NO_MEMORY; 173 *ppvR0 = (RTR0PTR)pv; 174 if (ppvR3) 175 *ppvR3 = pv; 176 return VINF_SUCCESS; 177 } 178 179 INTNETR3DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr) 180 { 181 if (pSession != g_pSession) 182 { 183 RTPrintf("tstIntNetR0: Invalid session pointer %p, %s!\n", pSession, __FUNCTION__); 184 g_cErrors++; 185 return VERR_INVALID_PARAMETER; 186 } 187 RTMemFree((void *)uPtr); 188 return VINF_SUCCESS; 189 } 190 191 192 193 /* ugly but necessary for making R0 code compilable for R3. */ 194 #undef LOG_GROUP 195 #include "../SrvIntNetR0.cpp" 196 197 typedef struct ARGS 198 { 199 PINTNET pIntNet; 200 PINTNETBUF pBuf; 201 INTNETIFHANDLE hIf; 202 PDMMAC Mac; 203 uint64_t u64Start; 204 uint64_t u64End; 205 } ARGS, *PARGS; 206 207 208 #define TEST_TRANSFER_SIZE (_1M*384) 209 210 /** 211 * Send thread. 212 * This is constantly broadcasting frames to the network. 213 */ 214 DECLCALLBACK(int) SendThread(RTTHREAD Thread, void *pvArg) 215 { 216 PARGS pArgs = (PARGS)pvArg; 46 /* 47 * Init the runtime, open the support driver and load VMMR0.r0. 48 */ 49 RTR3Init(false, 0); 50 RTPrintf("tstIntNet-1: TESTING...\n"); 217 51 218 52 /* 219 * Send 64 MB of data.53 * Open the session, load ring-0 and issue the request. 220 54 */ 221 uint8_t abBuf[4096] = {0}; 222 PPDMMAC pMacSrc = (PPDMMAC)&abBuf[0]; 223 PPDMMAC pMacDst = pMacSrc + 1; 224 *pMacSrc = pArgs->Mac; 225 *pMacDst = pArgs->Mac; 226 pMacDst->au16[2] = pArgs->Mac.au16[2] ? 0 : 1; 227 unsigned *puFrame = (unsigned *)(pMacDst + 1); 228 unsigned iFrame = 0; 229 unsigned cbSent = 0; 230 pArgs->u64Start = RTTimeNanoTS(); 231 for (; cbSent < TEST_TRANSFER_SIZE; iFrame++) 55 PSUPDRVSESSION pSession; 56 int rc = SUPInit(&pSession, 0); 57 if (RT_FAILURE(rc)) 232 58 { 233 const unsigned cb = iFrame % 1519 + 12 + sizeof(unsigned); 234 *puFrame = iFrame; 235 #if 0 236 int rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, abBuf, cb); 237 #else 238 int rc = intnetRingWriteFrame(pArgs->pBuf, &pArgs->pBuf->Send, abBuf, cb); 239 if (RT_SUCCESS(rc)) 240 rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, NULL, 0); 241 #endif 242 if (VBOX_FAILURE(rc)) 243 { 244 g_cErrors++; 245 RTPrintf("tstIntNetR0: Failed sending %d bytes, rc=%Vrc (%d)\n", cb, rc, INTNETRingGetWritable(&pArgs->pBuf->Send)); 246 } 247 cbSent += cb; 59 RTPrintf("tstIntNet-1: SUPInit -> %Rrc\n", rc); 60 return 1; 248 61 } 249 62 250 /* 251 * Termination frames. 252 */ 253 puFrame[0] = 0xffffdead; 254 puFrame[1] = 0xffffdead; 255 puFrame[2] = 0xffffdead; 256 puFrame[3] = 0xffffdead; 257 for (unsigned c = 0; c < 20; c++) 63 char szPath[RTPATH_MAX]; 64 rc = RTPathProgram(szPath, sizeof(szPath) - sizeof("/../VMMR0.r0")); 65 if (RT_FAILURE(rc)) 258 66 { 259 int rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, abBuf, sizeof(PDMMAC) * 2 + sizeof(unsigned) * 4); 260 if (VBOX_FAILURE(rc)) 261 { 262 g_cErrors++; 263 RTPrintf("tstIntNetR0: send failed, rc=%Vrc\n", rc); 264 } 265 RTThreadSleep(1); 67 RTPrintf("tstIntNet-1: RTPathProgram -> %Rrc\n", rc); 68 return 1; 266 69 } 267 70 268 RTPrintf("tstIntNetR0: sender thread %.6Rhxs terminating. iFrame=%d cbSent=%d\n", &pArgs->Mac, iFrame, cbSent); 269 return 0; 270 } 271 272 273 /** Ignore lost frames. It only makes things worse to bitch about it. */ 274 #define IGNORE_LOST_FRAMES 275 276 /** 277 * Receive thread. 278 * This is reading stuff from the network. 279 */ 280 DECLCALLBACK(int) ReceiveThread(RTTHREAD Thread, void *pvArg) 281 { 282 unsigned cbReceived = 0; 283 unsigned cLostFrames = 0; 284 unsigned iFrame = ~0; 285 PARGS pArgs = (PARGS)pvArg; 286 for (;;) 71 rc = SUPLoadVMM(strcat(szPath, "/../VMMR0.r0")); 72 if (RT_FAILURE(rc)) 287 73 { 288 /* 289 * Wait for data. 290 */ 291 int rc = INTNETR0IfWait(pArgs->pIntNet, pArgs->hIf, RT_INDEFINITE_WAIT); 292 switch (rc) 293 { 294 case VERR_INTERRUPTED: 295 case VINF_SUCCESS: 296 break; 297 case VERR_SEM_DESTROYED: 298 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating. cbReceived=%u cLostFrames=%u iFrame=%u\n", 299 &pArgs->Mac, cbReceived, cLostFrames, iFrame); 300 return VINF_SUCCESS; 301 302 default: 303 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs got odd return value %Vrc! cbReceived=%u cLostFrames=%u iFrame=%u\n", 304 &pArgs->Mac, rc, cbReceived, cLostFrames, iFrame); 305 g_cErrors++; 306 return rc; 307 } 308 309 /* 310 * Read data. 311 */ 312 while (INTNETRingGetReadable(&pArgs->pBuf->Recv)) 313 { 314 uint8_t abBuf[16384]; 315 unsigned cb = intnetRingReadFrame(pArgs->pBuf, &pArgs->pBuf->Recv, abBuf); 316 unsigned *puFrame = (unsigned *)&abBuf[sizeof(PDMMAC) * 2]; 317 318 /* check for termination frame. */ 319 if ( cb == sizeof(PDMMAC) * 2 + sizeof(unsigned) * 4 320 && puFrame[0] == 0xffffdead 321 && puFrame[1] == 0xffffdead 322 && puFrame[2] == 0xffffdead 323 && puFrame[3] == 0xffffdead) 324 { 325 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating. cbReceived=%u cLostFrames=%u iFrame=%u\n", 326 &pArgs->Mac, cbReceived, cLostFrames, iFrame); 327 pArgs->u64End = RTTimeNanoTS(); 328 return VINF_SUCCESS; 329 } 330 331 /* validate frame header */ 332 PPDMMAC pMacSrc = (PPDMMAC)&abBuf[0]; 333 PPDMMAC pMacDst = pMacSrc + 1; 334 if ( pMacDst->au16[0] != 0x8086 335 || pMacDst->au16[1] != 0 336 || pMacDst->au16[2] != pArgs->Mac.au16[2] 337 || pMacSrc->au16[0] != 0x8086 338 || pMacSrc->au16[1] != 0 339 || pMacSrc->au16[2] == pArgs->Mac.au16[2]) 340 { 341 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs received frame header: %.16Rhxs\n", 342 &pArgs->Mac, abBuf); 343 g_cErrors++; 344 } 345 346 /* frame stuff and stats. */ 347 int off = iFrame + 1 - *puFrame; 348 if (off) 349 { 350 if (off > 0) 351 { 352 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs: iFrame=%d *puFrame=%d off=%d\n", 353 &pArgs->Mac, iFrame, *puFrame, off); 354 g_cErrors++; 355 cLostFrames++; 356 } 357 else 358 { 359 cLostFrames += -off; 360 #ifndef IGNORE_LOST_FRAMES 361 if (off < 50) 362 { 363 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs: iFrame=%d *puFrame=%d off=%d\n", 364 &pArgs->Mac, iFrame, *puFrame, off); 365 g_cErrors++; 366 } 367 #endif 368 } 369 } 370 iFrame = *puFrame; 371 cbReceived += cb; 372 } 373 } 374 } 375 376 int main() 377 { 378 379 /* 380 * Init runtime and create an INTNET instance. 381 */ 382 RTR3Init(); 383 RTPrintf("tstIntNetR0: TESTING...\n"); 384 PINTNET pIntNet; 385 int rc = INTNETR0Create(&pIntNet); 386 if (VBOX_FAILURE(rc)) 387 { 388 RTPrintf("tstIntNetR0: INTNETR0Create failed, rc=%Vrc\n"); 74 RTPrintf("tstIntNet-1: SUPLoadVMM(\"%s\") -> %Rrc\n", szPath, rc); 389 75 return 1; 390 76 } 391 77 392 78 /* 393 * Create two interfaces. 79 * Create the request, picking the network and trunk names from argv[2] 80 * and argv[1] if present. 394 81 */ 395 INTNETIFHANDLE hIf0 = INTNET_HANDLE_INVALID; 396 rc = INTNETR0Open(pIntNet, g_pSession, "test", kIntNetTrunkType_None, "", 0, 1536*2 + 4, 0x8000, &hIf0); 397 if (VBOX_SUCCESS(rc)) 82 INTNETOPENREQ OpenReq; 83 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 84 OpenReq.Hdr.cbReq = sizeof(OpenReq); 85 OpenReq.pSession = pSession; /* later */ 86 if (argc >= 2) 87 strncpy(OpenReq.szNetwork, argv[2], sizeof(OpenReq.szNetwork)); 88 else 89 strncpy(OpenReq.szNetwork, "tstIntNet-1", sizeof(OpenReq.szNetwork)); 90 if (argc >= 2) 91 strncpy(OpenReq.szNetwork, argv[2], sizeof(OpenReq.szNetwork)); 92 else 93 #ifdef RT_OS_DARWIN 94 strncpy(OpenReq.szTrunk, "en0", sizeof(OpenReq.szTrunk)); 95 #elif defined(RT_OS_LINUX) 96 strncpy(OpenReq.szTrunk, "eth0", sizeof(OpenReq.szTrunk)); 97 #else 98 strncpy(OpenReq.szTrunk, "em0", sizeof(OpenReq.szTrunk)); 99 #endif 100 OpenReq.enmTrunkType = kIntNetTrunkType_NetFlt; 101 OpenReq.fFlags = 0; 102 OpenReq.cbSend = 0; 103 OpenReq.cbRecv = 0; 104 OpenReq.hIf = INTNET_HANDLE_INVALID; 105 106 /* 107 * Issue the request. 108 */ 109 RTPrintf("tstIntNet-1: attempting to open/create network \"%s\" with NetFlt trunk \"%s\"...\n", 110 OpenReq.szNetwork, OpenReq.szTrunk); 111 RTThreadSleep(250); 112 rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr); 113 if (RT_SUCCESS(rc)) 398 114 { 399 if (hIf0 != INTNET_HANDLE_INVALID) 400 { 401 INTNETIFHANDLE hIf1 = INTNET_HANDLE_INVALID; 402 rc = INTNETR0Open(pIntNet, g_pSession, "test", kIntNetTrunkType_None, NULL, 0, 1536*2 + 4, 0x8000, &hIf1); 403 if (VBOX_SUCCESS(rc)) 404 { 405 if (hIf1 != INTNET_HANDLE_INVALID) 406 { 407 PINTNETBUF pBuf0; 408 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf0, &pBuf0); 409 if (VBOX_FAILURE(rc) || !pBuf0) 410 { 411 RTPrintf("tstIntNetR0: INTNETIfGetRing0Buffer failed! pBuf0=%p rc=%Vrc\n", pBuf0, rc); 412 g_cErrors++; 413 } 414 PINTNETBUF pBuf1; 415 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf1, &pBuf1); 416 if (VBOX_FAILURE(rc)) 417 { 418 RTPrintf("tstIntNetR0: INTNETIfGetRing0Buffer failed! pBuf1=%p rc=%Vrc\n", pBuf1, rc); 419 g_cErrors++; 420 } 115 RTPrintf("tstIntNet-1: successfully opened/created \"%s\" with NetFlt trunk \"%s\" - hIf=%#x", 116 OpenReq.szNetwork, OpenReq.szTrunk, OpenReq.hIf); 421 117 422 /*423 * Test basic waiting.424 */425 rc = INTNETR0IfWait(pIntNet, hIf0, 1);426 if (rc != VERR_TIMEOUT)427 {428 RTPrintf("tstIntNetR0: INTNETIfWait returned %Vrc expected VERR_TIMEOUT (hIf0)\n", rc);429 g_cErrors++;430 }431 rc = INTNETR0IfWait(pIntNet, hIf1, 0);432 if (rc != VERR_TIMEOUT)433 {434 RTPrintf("tstIntNetR0: INTNETIfWait returned %Vrc expected VERR_TIMEOUT (hIf1)\n", rc);435 g_cErrors++;436 }437 438 /*439 * Send and receive.440 */441 rc = INTNETR0IfSend(pIntNet, hIf0, &g_TestFrame0, sizeof(g_TestFrame0));442 if (VBOX_SUCCESS(rc))443 {444 rc = INTNETR0IfWait(pIntNet, hIf0, 1);445 if (rc != VERR_TIMEOUT)446 {447 RTPrintf("tstIntNetR0: INTNETIfWait returned %Vrc expected VERR_TIMEOUT (hIf0, 2nd)\n", rc);448 g_cErrors++;449 }450 rc = INTNETR0IfWait(pIntNet, hIf1, 0);451 if (rc == VINF_SUCCESS)452 {453 /* receive it */454 uint8_t abBuf[sizeof(g_TestFrame0)];455 const unsigned cbExpect = RT_ALIGN(sizeof(g_TestFrame0) + sizeof(INTNETHDR), sizeof(INTNETHDR));456 if (INTNETRingGetReadable(&pBuf1->Recv) != cbExpect)457 {458 RTPrintf("tstIntNetR0: %d readable bytes, expected %d!\n", INTNETRingGetReadable(&pBuf1->Recv), cbExpect);459 g_cErrors++;460 }461 unsigned cb = intnetRingReadFrame(pBuf1, &pBuf1->Recv, abBuf);462 if (cb != sizeof(g_TestFrame0))463 {464 RTPrintf("tstIntNetR0: read %d frame bytes, expected %d!\n", cb, sizeof(g_TestFrame0));465 g_cErrors++;466 }467 else if (memcmp(abBuf, &g_TestFrame0, sizeof(g_TestFrame0)))468 {469 RTPrintf("tstIntNetR0: Got invalid data!\n"470 "received: %.*Rhxs\n"471 "expected: %.*Rhxs\n",472 cb, abBuf, sizeof(g_TestFrame0), &g_TestFrame0);473 g_cErrors++;474 }475 476 /*477 * Send a packet from If1 just to set its MAC address.478 */479 rc = INTNETR0IfSend(pIntNet, hIf1, &g_TestFrame1, sizeof(g_TestFrame1));480 if (VBOX_FAILURE(rc))481 {482 RTPrintf("tstIntNetR0: INTNETIfSend returned %Vrc! (hIf1)\n", rc);483 g_cErrors++;484 }485 486 487 /*488 * Start threaded testcase.489 * Give it 5 mins to finish.490 */491 if (!g_cErrors)492 {493 ARGS Args0 = {0};494 Args0.hIf = hIf0;495 Args0.pBuf = pBuf0;496 Args0.pIntNet = pIntNet;497 Args0.Mac.au16[0] = 0x8086;498 Args0.Mac.au16[1] = 0;499 Args0.Mac.au16[2] = 0;500 501 ARGS Args1 = {0};502 Args1.hIf = hIf1;503 Args1.pBuf = pBuf1;504 Args1.pIntNet = pIntNet;505 Args1.Mac.au16[0] = 0x8086;506 Args1.Mac.au16[1] = 0;507 Args1.Mac.au16[2] = 1;508 509 RTTHREAD ThreadRecv0 = NIL_RTTHREAD;510 RTTHREAD ThreadRecv1 = NIL_RTTHREAD;511 RTTHREAD ThreadSend0 = NIL_RTTHREAD;512 RTTHREAD ThreadSend1 = NIL_RTTHREAD;513 rc = RTThreadCreate(&ThreadRecv0, ReceiveThread, &Args0, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "RECV0");514 if (VBOX_SUCCESS(rc))515 rc = RTThreadCreate(&ThreadRecv1, ReceiveThread, &Args1, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "RECV1");516 if (VBOX_SUCCESS(rc))517 rc = RTThreadCreate(&ThreadSend0, SendThread, &Args0, 0, RTTHREADTYPE_EMULATION, RTTHREADFLAGS_WAITABLE, "SEND0");518 if (VBOX_SUCCESS(rc))519 rc = RTThreadCreate(&ThreadSend1, SendThread, &Args1, 0, RTTHREADTYPE_EMULATION, RTTHREADFLAGS_WAITABLE, "SEND1");520 if (VBOX_SUCCESS(rc))521 {522 int rc2 = VINF_SUCCESS;523 rc = RTThreadWait(ThreadSend0, 5*60*1000, &rc2);524 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here (2.6.23-gentoo-r3 amd64). See #3023.*/525 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--)526 {527 RTThreadSleep(1);528 rc = RTThreadWait(ThreadSend0, 1, &rc2);529 }530 #endif531 AssertRC(rc);532 if (VBOX_SUCCESS(rc))533 {534 ThreadSend0 = NIL_RTTHREAD;535 rc = RTThreadWait(ThreadSend1, 5*60*1000, RT_SUCCESS(rc2) ? &rc2 : NULL);536 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here (2.6.23-gentoo-r3 amd64). See #3023.*/537 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--)538 {539 RTThreadSleep(1);540 rc = RTThreadWait(ThreadSend1, 1, &rc2);541 }542 #endif543 AssertRC(rc);544 if (RT_SUCCESS(rc))545 ThreadSend1 = NIL_RTTHREAD;546 }547 if ( VBOX_SUCCESS(rc)548 && VBOX_SUCCESS(rc2))549 {550 /*551 * Wait a bit for the receivers to finish up.552 */553 unsigned cYields = 100000;554 while ( ( INTNETRingGetReadable(&pBuf0->Recv)555 || INTNETRingGetReadable(&pBuf1->Recv))556 && cYields-- > 0)557 RTThreadYield();558 559 uint64_t u64Elapsed = RT_MAX(Args0.u64End, Args1.u64End) - RT_MIN(Args0.u64Start, Args1.u64Start);560 uint64_t u64Speed = (uint64_t)((2 * TEST_TRANSFER_SIZE / 1024) / (u64Elapsed / 1000000000.0));561 RTPrintf("tstIntNetR0: transfered %d bytes in %RU64 ns (%RU64 KB/s)\n",562 2 * TEST_TRANSFER_SIZE, u64Elapsed, u64Speed);563 564 /*565 * Closing time...566 */567 rc = RTThreadWait(ThreadRecv0, 5000, &rc2);568 if (RT_SUCCESS(rc))569 ThreadRecv0 = NIL_RTTHREAD;570 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2))571 {572 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 0, rc=%Vrc, rc2=%Vrc\n", rc, rc2);573 g_cErrors++;574 }575 576 rc = RTThreadWait(ThreadRecv1, 5000, &rc2);577 if (RT_SUCCESS(rc))578 ThreadRecv1 = NIL_RTTHREAD;579 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2))580 {581 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 1, rc=%Vrc, rc2=%Vrc\n", rc, rc2);582 g_cErrors++;583 }584 585 rc = INTNETR0IfClose(pIntNet, hIf0);586 if (VBOX_SUCCESS(rc))587 {588 hIf0 = INTNET_HANDLE_INVALID;589 pBuf0 = NULL;590 }591 else592 {593 RTPrintf("tstIntNetR0: INTNETIfClose failed, rc=%Vrc! (hIf0)\n", rc);594 g_cErrors++;595 }596 597 rc = INTNETR0IfClose(pIntNet, hIf1);598 if (VBOX_SUCCESS(rc))599 {600 hIf1 = INTNET_HANDLE_INVALID;601 pBuf1 = NULL;602 }603 else604 {605 RTPrintf("tstIntNetR0: INTNETIfClose failed, rc=%Vrc! (hIf1)\n", rc);606 g_cErrors++;607 }608 609 610 /* check if the network still exist... */611 if (pIntNet->pNetworks)612 {613 RTPrintf("tstIntNetR0: The network wasn't deleted! (g_cErrors=%d)\n", g_cErrors);614 g_cErrors++;615 }616 }617 else618 {619 RTPrintf("tstIntNetR0: Waiting on senders failed, rc=%Vrc, rc2=%Vrc\n", rc, rc2);620 g_cErrors++;621 }622 623 /*624 * Give them a chance to complete...625 */626 RTThreadWait(ThreadRecv0, 5000, NULL);627 RTThreadWait(ThreadRecv1, 5000, NULL);628 RTThreadWait(ThreadSend0, 5000, NULL);629 RTThreadWait(ThreadSend1, 5000, NULL);630 631 }632 else633 {634 RTPrintf("tstIntNetR0: Failed to create threads, rc=%Vrc\n", rc);635 g_cErrors++;636 }637 }638 }639 else640 {641 RTPrintf("tstIntNetR0: INTNETIfWait returned %Vrc expected VINF_SUCCESS (hIf1)\n", rc);642 g_cErrors++;643 }644 }645 else646 {647 RTPrintf("tstIntNetR0: INTNETIfSend returned %Vrc! (hIf0)\n", rc);648 g_cErrors++;649 }650 }651 else652 {653 RTPrintf("tstIntNetR0: INTNETOpen returned invalid handle on success! (hIf1)\n");654 g_cErrors++;655 }656 657 if (hIf1 != INTNET_HANDLE_INVALID)658 rc = INTNETR0IfClose(pIntNet, hIf1);659 }660 else661 {662 RTPrintf("tstIntNetR0: INTNETOpen failed for the 2nd interface! rc=%Vrc\n", rc);663 g_cErrors++;664 }665 666 if (hIf0 != INTNET_HANDLE_INVALID)667 rc = INTNETR0IfClose(pIntNet, hIf0);668 }669 else670 {671 RTPrintf("tstIntNetR0: INTNETOpen returned invalid handle on success! (hIf0)\n");672 g_cErrors++;673 }674 118 } 675 119 else 676 120 { 677 RTPrintf(" tstIntNetR0: INTNETOpen failed for the 1st interface! rc=%Vrc\n", rc);121 RTPrintf("stdIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc); 678 122 g_cErrors++; 679 123 } 680 124 681 /* 682 * Destroy the service. 683 */ 684 INTNETR0Destroy(pIntNet); 125 SUPTerm(false /* not forced */); 685 126 686 127 /* … … 688 129 */ 689 130 if (!g_cErrors) 690 RTPrintf("tstIntNet R0: SUCCESS\n");131 RTPrintf("tstIntNet-1: SUCCESS\n"); 691 132 else 692 RTPrintf("tstIntNet R0: FAILURE - %d errors\n", g_cErrors);133 RTPrintf("tstIntNet-1: FAILURE - %d errors\n", g_cErrors); 693 134 694 135 return !!g_cErrors; -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r10450 r10663 856 856 */ 857 857 case VMMR0_DO_INTNET_OPEN: 858 if (!pVM || u64Arg) 858 { 859 PINTNETOPENREQ pReq = (PINTNETOPENREQ)pReqHdr; 860 if (u64Arg || !pReq || (pVM ? pReq->pSession != NULL : !pReq->pSession)) 859 861 return VERR_INVALID_PARAMETER; 860 862 if (!g_pIntNet) 861 863 return VERR_NOT_SUPPORTED; 862 return INTNETR0OpenReq(g_pIntNet, pVM->pSession, (PINTNETOPENREQ)pReqHdr); 864 return INTNETR0OpenReq(g_pIntNet, pVM ? pVM->pSession : pReq->pSession, pReq); 865 } 863 866 864 867 case VMMR0_DO_INTNET_IF_CLOSE:
Note:
See TracChangeset
for help on using the changeset viewer.