Changeset 10733 in vbox for trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
- Timestamp:
- Jul 17, 2008 10:42:30 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10711 r10733 110 110 /** Whether to supply physical addresses with the outbound SGs. */ 111 111 bool volatile fPhysSG; 112 /** Set if the 'wire' is in promiscuous mode. 113 * The state of the 'host' is queried each time. */ 114 bool fPromiscuousWire; 112 115 } INTNETTRUNKIF; 113 116 /** Pointer to a trunk interface. */ … … 388 391 389 392 393 /** 394 * Initializes a scatter / gather buffer from a simple linear buffer. 395 * 396 * @returns Pointer to the start of the frame. 397 * @param pSG Pointer to the scatter / gather structure. 398 * (The pvOwnerData, fFlags, cUsers, and cSegsAlloc members are left untouched.) 399 * @param pvFrame Pointer to the frame 400 * @param cbFrame The size of the frame. 401 */ 402 DECLINLINE(void) intnetR0SgInitTemp(PINTNETSG pSG, void *pvFrame, uint32_t cbFrame) 403 { 404 pSG->pvOwnerData = NULL; 405 pSG->pvUserData = NULL; 406 pSG->pvUserData2 = NULL; 407 pSG->cbTotal = cbFrame; 408 pSG->cUsers = 1; 409 pSG->fFlags = INTNETSG_FLAGS_TEMP; 410 pSG->cSegsAlloc = 1; 411 pSG->cSegsUsed = 1; 412 pSG->aSegs[0].Phys = NIL_RTHCPHYS; 413 pSG->aSegs[0].pv = pvFrame; 414 pSG->aSegs[0].cb = cbFrame; 415 } 416 417 418 /** 419 * Initializes a scatter / gather buffer from a internal networking packet. 420 * 421 * @returns Pointer to the start of the frame. 422 * @param pSG Pointer to the scatter / gather structure. 423 * (The pvOwnerData, fFlags, cUsers, and cSegsAlloc members are left untouched.) 424 * @param pHdr Pointer to the packet header. 425 * @param pBuf The buffer the header is within. Only used in strict builds. 426 */ 427 DECLINLINE(void) intnetR0SgInitFromPkt(PINTNETSG pSG, PCINTNETHDR pPktHdr, PCINTNETBUF pBuf) 428 { 429 pSG->cSegsUsed = 1; 430 pSG->cbTotal = pSG->aSegs[0].cb = pPktHdr->cbFrame; 431 pSG->aSegs[0].pv = INTNETHdrGetFramePtr(pPktHdr, pBuf); 432 pSG->aSegs[0].Phys = NIL_RTHCPHYS; 433 } 434 435 390 436 #ifdef IN_INTNET_TESTCASE 391 437 /** … … 423 469 424 470 /** 471 * Reads an entire SG into a fittingly size buffer. 472 * 473 * @param pSG The SG list to read. 474 * @param pvBuf The buffer to read into (at least pSG->cbTotal in size). 475 */ 476 DECLINLINE(void) intnetR0SgRead(PCINTNETSG pSG, void *pvBuf) 477 { 478 if (pSG->cSegsUsed == 1) 479 { 480 Assert(pSG->cbTotal == pSG->aSegs[0].cb); 481 memcpy(pvBuf, pSG->aSegs[0].pv, pSG->cbTotal); 482 } 483 else 484 { 485 uint8_t *pbDst = (uint8_t *)pvBuf; 486 unsigned const cSegs = pSG->cSegsUsed; Assert(cSegs == pSG->cSegsUsed); 487 for (unsigned iSeg = 0; iSeg < cSegs; iSeg++) 488 { 489 uint32_t cbSeg = pSG->aSegs[iSeg].cb; 490 Assert(cbSeg <= pSG->cbTotal && (uintptr_t)(pbDst - (uint8_t *)pvBuf) + cbSeg <= pSG->cbTotal); 491 memcpy(pbDst, pSG->aSegs[iSeg].pv, cbSeg); 492 pbDst += cbSeg; 493 } 494 } 495 } 496 497 498 /** 425 499 * Writes a frame packet to the buffer. 426 500 * … … 428 502 * @param pBuf The buffer. 429 503 * @param pRingBuf The ring buffer to read from. 430 * @param pvFrame The frame to write. 431 * @param cbFrame The size of the frame. 432 */ 433 static int intnetR0RingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame) 504 * @param pSG The gatter list. 505 */ 506 static int intnetR0RingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, PCINTNETSG pSG) 434 507 { 435 508 /* 436 509 * Validate input. 437 510 */ 438 Assert (pBuf);439 Assert (pRingBuf);440 Assert (pvFrame);441 Assert( cbFrame>= sizeof(PDMMAC) * 2);511 AssertPtr(pBuf); 512 AssertPtr(pRingBuf); 513 AssertPtr(pSG); 514 Assert(pSG->cbTotal >= sizeof(PDMMAC) * 2); 442 515 uint32_t offWrite = pRingBuf->offWrite; 443 516 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR))); … … 445 518 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR))); 446 519 447 const uint32_t cb = RT_ALIGN_32( cbFrame, sizeof(INTNETHDR));520 const uint32_t cb = RT_ALIGN_32(pSG->cbTotal, sizeof(INTNETHDR)); 448 521 if (offRead <= offWrite) 449 522 { … … 455 528 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 456 529 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 457 pHdr->cbFrame = cbFrame;530 pHdr->cbFrame = pSG->cbTotal; 458 531 pHdr->offFrame = sizeof(INTNETHDR); 459 532 460 memcpy(pHdr + 1, pvFrame, cbFrame);533 intnetR0SgRead(pSG, pHdr + 1); 461 534 462 535 offWrite += cb + sizeof(INTNETHDR); … … 479 552 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart); 480 553 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 481 pHdr->cbFrame = cbFrame;554 pHdr->cbFrame = pSG->cbTotal; 482 555 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr; 483 556 484 memcpy(pvFrameOut, pvFrame, cbFrame);557 intnetR0SgRead(pSG, pvFrameOut); 485 558 486 559 offWrite = pRingBuf->offStart + cb; … … 497 570 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 498 571 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 499 pHdr->cbFrame = cbFrame;572 pHdr->cbFrame = pSG->cbTotal; 500 573 pHdr->offFrame = sizeof(INTNETHDR); 501 574 502 memcpy(pHdr + 1, pvFrame, cbFrame);575 intnetR0SgRead(pSG, pHdr + 1); 503 576 504 577 offWrite += cb + sizeof(INTNETHDR); … … 525 598 #pragma pack() 526 599 typedef INTNETETHERHDR *PINTNETETHERHDR; 600 typedef INTNETETHERHDR const *PCINTNETETHERHDR; 527 601 528 602 … … 531 605 * 532 606 * @param pIf The interface. 533 * @param pvFrame The frame data. 534 * @param cbFrame The size of the frame. 535 */ 536 static void intnetR0IfSend(PINTNETIF pIf, const void *pvFrame, unsigned cbFrame) 607 * @param pSG The gather buffer which data is being sent to the interface. 608 */ 609 static void intnetR0IfSend(PINTNETIF pIf, PINTNETSG pSG) 537 610 { 538 611 LogFlow(("intnetR0IfSend: pIf=%p:{.hIf=%RX32}\n", pIf, pIf->hIf)); 539 int rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, p vFrame, cbFrame);612 int rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pSG); 540 613 if (RT_SUCCESS(rc)) 541 614 { 542 615 pIf->cYields = 0; 543 616 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatRecvs); 544 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, cbFrame);617 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, pSG->cbTotal); 545 618 RTSemEventSignal(pIf->Event); 546 619 return; 547 620 } 548 621 622 /** @todo we'll have to drop this I'm afraid since it'll screw up the host networking otherwise... */ 549 623 /* 550 624 * Retry a few times, yielding the CPU in between. … … 558 632 RTSemEventSignal(pIf->Event); 559 633 RTThreadYield(); 560 rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, p vFrame, cbFrame);634 rc = intnetR0RingWriteFrame(pIf->pIntBuf, &pIf->pIntBuf->Recv, pSG); 561 635 if (RT_SUCCESS(rc)) 562 636 { 563 637 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatYieldsOk); 564 638 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatRecvs); 565 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, cbFrame);639 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, pSG->cbTotal); 566 640 RTSemEventSignal(pIf->Event); 567 641 return; … … 579 653 580 654 /** 655 * Sends a frame down the trunk. 656 * 657 * The caller must own the network mutex, might be abandond temporarily. 658 * The fTrunkLock parameter indicates whether the trunk lock is held. 659 * 660 * @param pThis The trunk. 661 * @param pNetwork The network the frame is being sent to. 662 * @param fDst The destination flags. 663 * @param pSG Pointer to the gather list. 664 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 665 */ 666 static void intnetR0TrunkIfSend(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork, uint32_t fDst, PINTNETSG pSG, bool fTrunkLocked) 667 { 668 Assert(fTrunkLocked); 669 /** @todo implement + move? */ 670 } 671 672 673 /** 674 * Sends a broadcast frame. 675 * 676 * The caller must own the network mutex, might be abandond temporarily. 677 * When pIfSender is not NULL, the caller must also own the trunk semaphore. 678 * 679 * @returns true if it's addressed to someone on the network, otherwise false. 680 * @param pNetwork The network the frame is being sent to. 681 * @param pIfSender The interface sending the frame. This is NULL if it's the trunk. 682 * @param fSrc The source flags. This 0 if it's not from the trunk. 683 * @param pSG Pointer to the gather list. 684 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 685 */ 686 static bool intnetR0NetworkSendBroadcast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, PINTNETSG pSG, bool fTrunkLocked) 687 { 688 /* 689 * This is a broadcast or multicast address. For the present we treat those 690 * two as the same - investigating multicast is left for later. 691 * 692 * Write the packet to all the interfaces and signal them. 693 */ 694 Log2(("Broadcast\n")); 695 for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext) 696 if (pIf != pIfSender) 697 intnetR0IfSend(pIf, pSG); 698 699 /* 700 * Unless the trunk is the origin, broadcast it to both the wire 701 * and the host as well. 702 */ 703 PINTNETTRUNKIF pTrunkIf = pNetwork->pTrunkIF; 704 if ( pIfSender 705 && pTrunkIf) 706 intnetR0TrunkIfSend(pTrunkIf, pNetwork, INTNETTRUNKDIR_HOST | INTNETTRUNKDIR_WIRE, pSG, fTrunkLocked); 707 return false; /* broadcast frames are never dropped */ 708 } 709 710 711 /** 712 * Sends a multicast frame. 713 * 714 * The caller must own the network mutex, might be abandond temporarily. 715 * 716 * @returns true if it's addressed to someone on the network, otherwise false. 717 * @param pNetwork The network the frame is being sent to. 718 * @param pIfSender The interface sending the frame. This is NULL if it's the trunk. 719 * @param fSrc The source flags. This 0 if it's not from the trunk. 720 * @param pSG Pointer to the gather list. 721 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 722 * @param pEthHdr Pointer to the ethernet header. 723 */ 724 static bool intnetR0NetworkSendMulticast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, PINTNETSG pSG, bool fTrunkLocked, PCINTNETETHERHDR pEthHdr) 725 { 726 /** @todo implement multicast */ 727 return intnetR0NetworkSendBroadcast(pNetwork, pIfSender, pSG, fTrunkLocked); 728 } 729 730 731 /** 732 * Sends a unicast frame. 733 * 734 * The caller must own the network mutex, might be abandond temporarily. 735 * 736 * @returns true if it's addressed to someone on the network, otherwise false. 737 * @param pNetwork The network the frame is being sent to. 738 * @param pIfSender The interface sending the frame. This is NULL if it's the trunk. 739 * @param fSrc The source flags. This 0 if it's not from the trunk. 740 * @param pSG Pointer to the gather list. 741 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 742 * @param pEthHdr Pointer to the ethernet header. 743 */ 744 static bool intnetR0NetworkSendUnicast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, PINTNETSG pSG, bool fTrunkLocked, PCINTNETETHERHDR pEthHdr) 745 { 746 /* 747 * Only send to the interfaces with matching a MAC address. 748 */ 749 Log2(("Dst=%.6Rhxs\n", &pEthHdr->MacDst)); 750 bool fExactIntNetRecipient = false; 751 for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext) 752 { 753 Log2(("Dst=%.6Rhxs ?==? %.6Rhxs\n", &pEthHdr->MacDst, &pIf->Mac)); 754 bool fIt = false; 755 if ( ( !pIf->fMacSet 756 || (fIt = !memcmp(&pIf->Mac, &pEthHdr->MacDst, sizeof(pIf->Mac))) ) 757 || ( pIf->fPromiscuous 758 && !(pNetwork->fFlags & (INTNET_OPEN_FLAGS_IGNORE_PROMISC | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC)) 759 && pIf != pIfSender /* promiscuous mode: omit the sender */)) 760 { 761 fExactIntNetRecipient |= fIt; 762 intnetR0IfSend(pIf, pSG); 763 } 764 } 765 766 /* 767 * Send it to the trunk? Only consider this if we didn't find an recipient 768 * or if the trunk is in some form or promiscuous mode. 769 */ 770 PINTNETTRUNKIF pTrunkIf = pNetwork->pTrunkIF; 771 if ( pIfSender 772 && pTrunkIf 773 && pTrunkIf->pIfPort) 774 { 775 uint32_t fDst = 0; 776 if ( pTrunkIf->fPromiscuousWire 777 && !(pNetwork->fFlags & (INTNET_OPEN_FLAGS_IGNORE_PROMISC | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC | INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE)) ) 778 fDst |= INTNETTRUNKDIR_WIRE; 779 if ( !(pNetwork->fFlags & (INTNET_OPEN_FLAGS_IGNORE_PROMISC | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC | INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_HOST | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_HOST)) 780 || pTrunkIf->pIfPort->pfnIsPromiscuous(pTrunkIf->pIfPort) ) 781 fDst |= INTNETTRUNKDIR_HOST; 782 else if ( !fExactIntNetRecipient /* if you have duplicate mac addresses, you're screwed. */ 783 && pTrunkIf->pIfPort->pfnIsHostMac(pTrunkIf->pIfPort, &pEthHdr->MacDst)) 784 fDst |= INTNETTRUNKDIR_HOST; 785 if (fDst) 786 intnetR0TrunkIfSend(pTrunkIf, pNetwork, fDst, pSG, fTrunkLocked); 787 } 788 789 return fExactIntNetRecipient; 790 } 791 792 793 /** 581 794 * Sends a frame. 582 795 * … … 586 799 * The caller must own the network mutex. 587 800 * 588 * @param pNetwork The network the frame is being sent to. 589 * @param pIfSender The interface sending the frame. 590 * @param pvFrame The frame data. 591 * @param cbFrame The size of the frame. 592 */ 593 static void intnetR0NetworkSend(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, const void *pvFrame, unsigned cbFrame) 594 { 801 * @returns true if it's addressed to someone on the network, otherwise false. 802 * @param pNetwork The network the frame is being sent to. 803 * @param pIfSender The interface sending the frame. This is NULL if it's the trunk. 804 * @param fSrc The source flags. This 0 if it's not from the trunk. 805 * @param pSG Pointer to the gather list. 806 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 807 */ 808 static bool intnetR0NetworkSend(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, PINTNETSG pSG, bool fTrunkLocked) 809 { 810 bool fRc = false; 811 595 812 /* 596 813 * Assert reality. 597 814 */ 598 Assert(pNetwork); 599 Assert(pIfSender); 815 AssertPtr(pNetwork); 816 AssertPtrNull(pIfSender); 817 Assert(pIfSender ? fSrc == 0 : fSrc != 0); 600 818 Assert(pNetwork == pIfSender->pNetwork); 601 Assert(pvFrame); 602 if (cbFrame < sizeof(PDMMAC) * 2) 603 return; 819 AssertPtr(pSG); 820 Assert(pSG->cSegsUsed >= 1); 821 Assert(pSG->cSegsUsed <= pSG->cSegsAlloc); 822 if (pSG->cbTotal < sizeof(INTNETETHERHDR)) 823 return fRc; 604 824 605 825 /* … … 607 827 */ 608 828 STAM_REL_COUNTER_INC(&pIfSender->pIntBuf->cStatSends); 609 STAM_REL_COUNTER_ADD(&pIfSender->pIntBuf->cbStatSend, cbFrame); 829 STAM_REL_COUNTER_ADD(&pIfSender->pIntBuf->cbStatSend, pSG->cbTotal); 830 831 /* 832 * Get the ethernet header (might theoretically involve multiple segments). 833 */ 834 INTNETETHERHDR EthHdr; 835 if (RT_LIKELY(pSG->aSegs[0].cb >= sizeof(EthHdr))) 836 EthHdr = *(PCINTNETETHERHDR)pSG->aSegs[0].pv; 837 else 838 { 839 uint8_t *pbDst = (uint8_t *)&EthHdr; 840 size_t cbLeft = sizeof(EthHdr); 841 for (unsigned iSeg = 0; cbLeft && iSeg < pSG->cSegsUsed; iSeg++) 842 { 843 size_t cb = RT_MIN(cbLeft, pSG->aSegs[iSeg].cb); 844 memcpy(pbDst, pSG->aSegs[iSeg].pv, cb); 845 pbDst += cb; 846 cbLeft -= cb; 847 } 848 AssertReturn(!cbLeft, false); 849 } 610 850 611 851 /* 612 852 * Inspect the header updating the mac address of the sender in the process. 613 853 */ 614 PINTNETETHERHDR pEthHdr = (PINTNETETHERHDR)pvFrame;615 if (memcmp(&pEthHdr->MacSrc, &pIfSender->Mac, sizeof(pIfSender->Mac)))854 if ( pIfSender 855 && memcmp(&EthHdr.MacSrc, &pIfSender->Mac, sizeof(pIfSender->Mac))) 616 856 { 617 857 /** @todo stats */ 618 Log2(("IF MAC: %.6Rhxs -> %.6Rhxs\n", &pIfSender->Mac, & pEthHdr->MacSrc));619 pIfSender->Mac = pEthHdr->MacSrc;858 Log2(("IF MAC: %.6Rhxs -> %.6Rhxs\n", &pIfSender->Mac, &EthHdr.MacSrc)); 859 pIfSender->Mac = EthHdr.MacSrc; 620 860 pIfSender->fMacSet = true; 621 861 } 622 862 623 if ( (pEthHdr->MacDst.au8[0] & 1) /* multicast address */ 624 || ( pEthHdr->MacDst.au16[0] == 0xffff /* broadcast address. s*/ 625 && pEthHdr->MacDst.au16[1] == 0xffff 626 && pEthHdr->MacDst.au16[2] == 0xffff) 627 ) 628 { 629 /* 630 * This is a broadcast or multicast address. For the present we treat those 631 * two as the same - investigating multicast is left for later. 632 * 633 * Write the packet to all the interfaces and signal them. 634 */ 635 Log2(("Broadcast\n")); 636 for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext) 637 if (pIf != pIfSender) 638 intnetR0IfSend(pIf, pvFrame, cbFrame); 639 } 863 /* 864 * Distribute the frame. 865 */ 866 if (RT_UNLIKELY(EthHdr.MacDst.au8[0] & 1)) /* multicast address */ 867 fRc = intnetR0NetworkSendMulticast(pNetwork, pIfSender, fSrc, pSG, fTrunkLocked, &EthHdr); 868 else if ( EthHdr.MacDst.au16[0] == 0xffff /* broadcast address. */ 869 && EthHdr.MacDst.au16[1] == 0xffff 870 && EthHdr.MacDst.au16[2] == 0xffff) 871 fRc = intnetR0NetworkSendBroadcast(pNetwork, pIfSender, pSG, fTrunkLocked); 640 872 else 641 { 642 /* 643 * Only send to the interfaces with matching a MAC address. 644 */ 645 Log2(("Dst=%.6Rhxs\n", &pEthHdr->MacDst)); 646 for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext) 647 { 648 Log2(("Dst=%.6Rhxs ?==? %.6Rhxs\n", &pEthHdr->MacDst, &pIf->Mac)); 649 if ( ( !pIf->fMacSet 650 || !memcmp(&pIf->Mac, &pEthHdr->MacDst, sizeof(pIf->Mac))) 651 || ( pIf->fPromiscuous 652 && pIf != pIfSender /* promiscuous mode: omit the sender */)) 653 intnetR0IfSend(pIf, pvFrame, cbFrame); 654 } 655 } 873 fRc = intnetR0NetworkSendUnicast(pNetwork, pIfSender, fSrc, pSG, fTrunkLocked, &EthHdr); 874 return fRc; 656 875 } 657 876 … … 668 887 * @param pIntNet The instance data. 669 888 * @param hIf The interface handle. 670 * @param pvFrame Pointer to the frame. 671 * @param cbFrame Size of the frame. 889 * @param pvFrame Pointer to the frame. Optional, please don't use. 890 * @param cbFrame Size of the frame. Optional, please don't use. 672 891 */ 673 892 INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, const void *pvFrame, unsigned cbFrame) … … 676 895 677 896 /* 678 * Validate input. 679 */ 897 * Validate input and translate the handle. 898 */ 899 /** @todo add an exctra reference to the interface! */ 680 900 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 681 901 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); … … 692 912 } 693 913 694 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 914 /* 915 * Lock the network. If there is a trunk retain it and grab its 916 * out-bound lock (this requires leaving the network lock first). 917 * Grabbing the out-bound lock here simplifies things quite a bit 918 * later on, so while this is excessive and a bit expensive it's 919 * not worth caring about right now. 920 */ 921 PINTNETNETWORK pNetwork = pIf->pNetwork; 922 int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 695 923 if (RT_FAILURE(rc)) 696 924 return rc; 925 PINTNETTRUNKIF pTrunkIf = intnetR0TrunkIfRetain(pNetwork->pTrunkIF); 926 if (pTrunkIf) 927 { 928 RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 929 930 if (!intnetR0TrunkIfOutLock(pTrunkIf)) 931 { 932 intnetR0TrunkIfRelease(pTrunkIf); 933 return VERR_SEM_DESTROYED; 934 } 935 936 rc = RTSemFastMutexRequest(pNetwork->FastMutex); 937 if (RT_FAILURE(rc)) 938 { 939 intnetR0TrunkIfOutUnlock(pTrunkIf); 940 intnetR0TrunkIfRelease(pTrunkIf); 941 return rc; 942 } 943 } 944 945 INTNETSG Sg; /** @todo this will have to be changed if we're going to use async sending 946 * with buffer sharing for some OS or service. Darwin copies everything so 947 * I won't bother allocating and managing SGs rigth now. Sorry. */ 697 948 698 949 /* … … 700 951 */ 701 952 if (pvFrame && cbFrame) 702 intnetR0NetworkSend(pIf->pNetwork, pIf, pvFrame, cbFrame); 953 { 954 intnetR0SgInitTemp(&Sg, (void *)pvFrame, cbFrame); 955 intnetR0NetworkSend(pIf->pNetwork, pIf, 0, &Sg, !!pTrunkIf); 956 } 703 957 704 958 /* … … 713 967 void *pvCurFrame = INTNETHdrGetFramePtr(pHdr, pIf->pIntBuf); 714 968 if (pvCurFrame) 715 intnetR0NetworkSend(pIf->pNetwork, pIf, pvCurFrame, pHdr->cbFrame); 969 { 970 intnetR0SgInitTemp(&Sg, pvCurFrame, pHdr->cbFrame); 971 intnetR0NetworkSend(pIf->pNetwork, pIf, 0, &Sg, !!pTrunkIf); 972 } 716 973 } 717 974 /* else: ignore the frame */ … … 721 978 } 722 979 723 return RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 980 /* 981 * Release the semaphore(s) and release references. 982 */ 983 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 984 if (pTrunkIf) 985 { 986 intnetR0TrunkIfOutUnlock(pTrunkIf); 987 intnetR0TrunkIfRelease(pTrunkIf); 988 } 989 990 return rc; 724 991 } 725 992 … … 1420 1687 1421 1688 /* 1422 * 1423 */ 1424 1425 1426 return false; 1689 * Lock the network and send the frame to it. 1690 */ 1691 int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 1692 AssertRCReturn(rc, false); 1693 1694 bool fRc; 1695 if (RT_LIKELY(pNetwork->cActiveIFs > 0)) 1696 fRc = intnetR0NetworkSend(pNetwork, NULL, fSrc, pSG, false /* fTrunkLocked */); 1697 else 1698 fRc = false; /* don't drop it */ 1699 1700 rc = RTSemFastMutexRelease(pNetwork->FastMutex); 1701 AssertRC(rc); 1702 1703 return fRc; 1427 1704 } 1428 1705 … … 1470 1747 * Retain the trunk interface. 1471 1748 * 1472 * @returns pThis .1749 * @returns pThis if retained. 1473 1750 * 1474 1751 * @param pThis The trunk. … … 1479 1756 { 1480 1757 if (pThis && pThis->pIfPort) 1758 { 1481 1759 pThis->pIfPort->pfnRetain(pThis->pIfPort); 1482 return pThis; 1760 return pThis; 1761 } 1762 return NULL; 1483 1763 } 1484 1764 … … 1681 1961 pTrunkIF->pNetwork = pNetwork; 1682 1962 //pTrunkIF->fPhysSG = false; 1963 //pTrunkIF->fPromiscuousWire = false; 1683 1964 int rc = RTSemFastMutexCreate(&pTrunkIF->FastMutex); 1684 1965 if (RT_SUCCESS(rc)) … … 1840 2121 Assert(enmTrunkType > kIntNetTrunkType_Invalid && enmTrunkType < kIntNetTrunkType_End); 1841 2122 AssertPtr(pszTrunk); 1842 Assert(!(fFlags & ~(INTNET_OPEN_FLAGS_ PUBLIC)));2123 Assert(!(fFlags & ~(INTNET_OPEN_FLAGS_MASK))); 1843 2124 AssertPtr(ppNetwork); 1844 2125 *ppNetwork = NULL; … … 1866 2147 && !strcmp(pCur->szTrunk, pszTrunk))) 1867 2148 { 1868 if (!((pCur->fFlags ^ fFlags) & (INTNET_OPEN_FLAGS_PUBLIC)))2149 if (!((pCur->fFlags ^ fFlags) & INTNET_OPEN_FLAGS_SECURITY_XOR_MASK)) 1869 2150 { 1870 2151 … … 1879 2160 rc = SUPR0ObjVerifyAccess(pCur->pvObj, pSession, pCur->szName); 1880 2161 if (RT_SUCCESS(rc)) 2162 { 2163 pCur->fFlags |= fFlags & INTNET_OPEN_FLAGS_SECURITY_OR_MASK; 2164 1881 2165 *ppNetwork = pCur; 2166 } 1882 2167 else 1883 2168 SUPR0ObjRelease(pCur->pvObj, pSession); … … 1932 2217 Assert(enmTrunkType > kIntNetTrunkType_Invalid && enmTrunkType < kIntNetTrunkType_End); 1933 2218 AssertPtr(pszTrunk); 1934 Assert(!(fFlags & ~ (INTNET_OPEN_FLAGS_PUBLIC)));2219 Assert(!(fFlags & ~INTNET_OPEN_FLAGS_MASK)); 1935 2220 AssertPtr(ppNetwork); 1936 2221 *ppNetwork = NULL; … … 2068 2353 } 2069 2354 2070 AssertMsgReturn(!(fFlags & ~ (INTNET_OPEN_FLAGS_PUBLIC)), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);2355 AssertMsgReturn(!(fFlags & ~INTNET_OPEN_FLAGS_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 2071 2356 AssertPtrReturn(phIf, VERR_INVALID_PARAMETER); 2072 2357
Note:
See TracChangeset
for help on using the changeset viewer.