- Timestamp:
- Apr 7, 2010 5:22:17 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r27973 r28054 31 31 #include <VBox/pdmdrv.h> 32 32 #include <VBox/pdmnetifs.h> 33 #include <VBox/pdmnetinline.h> 33 34 #include <iprt/assert.h> 34 35 #include <iprt/file.h> … … 387 388 if (pSgBuf->pvAllocator) 388 389 { 390 Assert(!pSgBuf->pvUser); 389 391 slirp_ext_m_free(pThis->pNATState, (struct mbuf *)pSgBuf->pvAllocator); 390 392 pSgBuf->pvAllocator = NULL; 393 } 394 else if (pSgBuf->pvUser) 395 { 396 RTMemFree(pSgBuf->aSegs[0].pvSeg); 397 pSgBuf->aSegs[0].pvSeg = NULL; 398 RTMemFree(pSgBuf->pvUser); 399 pSgBuf->pvUser = NULL; 391 400 } 392 401 RTMemFree(pSgBuf); … … 406 415 { 407 416 struct mbuf *m = (struct mbuf *)pSgBuf->pvAllocator; 408 pSgBuf->pvAllocator = NULL; 409 slirp_input(pThis->pNATState, m, pSgBuf->cbUsed); 417 if (m) 418 { 419 /* 420 * A normal frame. 421 */ 422 pSgBuf->pvAllocator = NULL; 423 slirp_input(pThis->pNATState, m, pSgBuf->cbUsed); 424 } 425 else 426 { 427 /* 428 * GSO frame, need to segment it. 429 */ 430 /** @todo Make the NAT engine grok large frames? Could be more efficient... */ 431 uint8_t const *pbFrame = (uint8_t const *)pSgBuf->aSegs[0].pvSeg; 432 PCPDMNETWORKGSO pGso = (PCPDMNETWORKGSO)pSgBuf->pvUser; 433 uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, pSgBuf->cbUsed); Assert(cSegs > 1); 434 for (size_t iSeg = 0; iSeg < cSegs; iSeg++) 435 { 436 size_t cbSeg; 437 void *pvSeg; 438 m = slirp_ext_m_get(pThis->pNATState, pGso->cbHdrs + pGso->cbMaxSeg, &pvSeg, &cbSeg); 439 if (!m) 440 break; 441 442 uint32_t cbPayload; 443 uint32_t offPayload = PDMNetGsoCarveSegment(pGso, pbFrame, pSgBuf->cbUsed, 444 iSeg, cSegs, (uint8_t *)pvSeg, &cbPayload); 445 memcpy((uint8_t *)pvSeg + pGso->cbHdrs, pbFrame + offPayload, cbPayload); 446 447 slirp_input(pThis->pNATState, m, cbPayload + pGso->cbHdrs); 448 } 449 } 410 450 } 411 451 drvNATFreeSgBuf(pThis, pSgBuf); … … 421 461 { 422 462 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkUp); 423 AssertReturn(!pGso, VERR_NOT_IMPLEMENTED); /** @todo GSO buffer allocation. */424 463 425 464 /* … … 438 477 if (!pSgBuf) 439 478 return VERR_NO_MEMORY; 440 pSgBuf->pvAllocator = slirp_ext_m_get(pThis->pNATState, cbMin, 441 &pSgBuf->aSegs[0].pvSeg, &pSgBuf->aSegs[0].cbSeg); 442 if (!pSgBuf->pvAllocator) 443 { 444 RTMemFree(pSgBuf); 445 /** @todo Implement the VERR_TRY_AGAIN sematics. */ 446 return VERR_NO_MEMORY; 479 if (!pGso) 480 { 481 pSgBuf->pvUser = NULL; 482 pSgBuf->pvAllocator = slirp_ext_m_get(pThis->pNATState, cbMin, 483 &pSgBuf->aSegs[0].pvSeg, &pSgBuf->aSegs[0].cbSeg); 484 if (!pSgBuf->pvAllocator) 485 { 486 RTMemFree(pSgBuf); 487 /** @todo Implement the VERR_TRY_AGAIN semantics. */ 488 return VERR_NO_MEMORY; 489 } 490 } 491 else 492 { 493 pSgBuf->pvUser = RTMemDup(pGso, sizeof(*pGso)); 494 pSgBuf->pvAllocator = NULL; 495 pSgBuf->aSegs[0].cbSeg = RT_ALIGN_Z(cbMin, 16); 496 pSgBuf->aSegs[0].pvSeg = RTMemAlloc(pSgBuf->aSegs[0].cbSeg); 497 if (!pSgBuf->pvUser || !pSgBuf->aSegs[0].pvSeg) 498 { 499 RTMemFree(pSgBuf->aSegs[0].pvSeg); 500 RTMemFree(pSgBuf->pvUser); 501 RTMemFree(pSgBuf); 502 /** @todo Implement the VERR_TRY_AGAIN semantics. */ 503 return VERR_NO_MEMORY; 504 } 447 505 } 448 506 … … 453 511 pSgBuf->cbUsed = 0; 454 512 pSgBuf->cbAvailable = pSgBuf->aSegs[0].cbSeg; 455 pSgBuf->pvUser = NULL;456 513 pSgBuf->cSegs = 1; 457 514 515 #if 1 /* poison */ 516 memset(pSgBuf->aSegs[0].pvSeg, 'F', pSgBuf->aSegs[0].cbSeg); 517 #endif 458 518 *ppSgBuf = pSgBuf; 459 519 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.