diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Devices/Network/SrvIntNetR0.cpp | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-master.tar.gz |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Devices/Network/SrvIntNetR0.cpp')
-rw-r--r-- | src/VBox/Devices/Network/SrvIntNetR0.cpp | 351 |
1 files changed, 317 insertions, 34 deletions
diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp index a6d4772c..10274be5 100644 --- a/src/VBox/Devices/Network/SrvIntNetR0.cpp +++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -838,6 +838,22 @@ DECLINLINE(PINTNETMACTABENTRY) intnetR0NetworkFindMacAddrEntry(PINTNETNETWORK pN /** + * Checks if the IPv6 address is a good interface address. + * @returns true/false. + * @param addr The address, network endian. + */ +DECLINLINE(bool) intnetR0IPv6AddrIsGood(RTNETADDRIPV6 addr) +{ + return !( ( addr.QWords.qw0 == 0 && addr.QWords.qw1 == 0) /* :: */ + || ( (addr.Words.w0 & RT_H2BE_U16(0xff00)) == RT_H2BE_U16(0xff00)) /* multicast */ + || ( addr.Words.w0 == 0 && addr.Words.w1 == 0 + && addr.Words.w2 == 0 && addr.Words.w3 == 0 + && addr.Words.w4 == 0 && addr.Words.w5 == 0 + && addr.Words.w6 == 0 && addr.Words.w7 == RT_H2BE_U16(0x0001))); /* ::1 */ +} + + +/** * Checks if the IPv4 address is a broadcast address. * @returns true/false. * @param Addr The address, network endian. @@ -1070,8 +1086,12 @@ static void intnetR0IfAddrCacheDeleteIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, switch (enmAddrType) { case kIntNetAddrType_IPv4: - Log(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n", - pIf->hIf, &pIf->MacAddr, iEntry, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg)); + Log(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv4 deleted #%d %RTnaipv4 %s\n", + pIf->hIf, &pIf->MacAddr, iEntry, pAddr->IPv4, pszMsg)); + break; + case kIntNetAddrType_IPv6: + Log(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv6 deleted #%d %RTnaipv6 %s\n", + pIf->hIf, &pIf->MacAddr, iEntry, pAddr->IPv6, pszMsg)); break; default: Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 MAC=%.6Rhxs type=%d #%d %.*Rhxs %s\n", @@ -1247,8 +1267,12 @@ static void intnetR0IfAddrCacheAddIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCR switch (enmAddrType) { case kIntNetAddrType_IPv4: - Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n", - pIf->hIf, &pIf->MacAddr, pCache->cEntries, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg)); + Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %RTnaipv4 %s\n", + pIf->hIf, &pIf->MacAddr, pCache->cEntries, pAddr->IPv4, pszMsg)); + break; + case kIntNetAddrType_IPv6: + Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv6 added #%d %RTnaipv6 %s\n", + pIf->hIf, &pIf->MacAddr, pCache->cEntries, pAddr->IPv6, pszMsg)); break; default: Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs type=%d added #%d %.*Rhxs %s\n", @@ -2333,13 +2357,6 @@ static void intnetR0TrunkIfSnoopAddr(PINTNETNETWORK pNetwork, PCINTNETSG pSG, ui break; } - case RTNET_ETHERTYPE_IPV6: - { - /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might - * need to be edited. Check out how NDP works... */ - break; - } - case RTNET_ETHERTYPE_ARP: intnetR0TrunkIfSnoopArp(pNetwork, pSG); break; @@ -2347,6 +2364,41 @@ static void intnetR0TrunkIfSnoopAddr(PINTNETNETWORK pNetwork, PCINTNETSG pSG, ui } #endif /* INTNET_WITH_DHCP_SNOOPING */ +/** + * Deals with an IPv6 packet. + * + * This will fish out the source IP address and add it to the cache. + * Then it will look for DHCPRELEASE requests (?) and anything else + * that we might find useful later. + * + * @param pIf The interface that's sending the frame. + * @param pIpHdr Pointer to the IPv4 header in the frame. + * @param cbPacket The size of the packet, or more correctly the + * size of the frame without the ethernet header. + * @param fGso Set if this is a GSO frame, clear if regular. + */ +static void intnetR0IfSnoopIPv6SourceAddr(PINTNETIF pIf, PCRTNETIPV6 pIpHdr, uint32_t cbPacket, bool fGso) +{ + /* + * Check the header size first to prevent access invalid data. + */ + if (cbPacket < RTNETIPV6_MIN_LEN) + return; + + /* + * If the source address is good (not multicast) and + * not already in the address cache of the sender, add it. + */ + RTNETADDRU Addr; + Addr.IPv6 = pIpHdr->ip6_src; + + if ( intnetR0IPv6AddrIsGood(Addr.IPv6) && (pIpHdr->ip6_hlim == 0xff) + && intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(Addr.IPv6)) < 0) + { + intnetR0IfAddrCacheAddIt(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, "if/ipv6"); + } +} + /** * Deals with an IPv4 packet. @@ -2497,13 +2549,11 @@ static void intnetR0IfSnoopAddr(PINTNETIF pIf, uint8_t const *pbFrame, uint32_t case RTNET_ETHERTYPE_IPV4: intnetR0IfSnoopIPv4SourceAddr(pIf, (PCRTNETIPV4)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso); break; -#if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */ + case RTNET_ETHERTYPE_IPV6: - /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might - * need to be edited. Check out how NDP works... */ - intnetR0IfSnoopIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso, pfSgFlags); + intnetR0IfSnoopIPv6SourceAddr(pIf, (PCRTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso); break; -#endif + #if 0 /** @todo IntNet: implement IPX for wireless MAC sharing? */ case RTNET_ETHERTYPE_IPX_1: case RTNET_ETHERTYPE_IPX_2: @@ -2636,6 +2686,10 @@ static int intnetR0TrunkIfSendGsoFallback(PINTNETTRUNKIF pThis, PINTNETIF pIfSen INTNETSG SG; } u; + /** @todo We have to adjust MSS so it does not exceed the value configured for + * the host's interface. + */ + /* * Carve out the frame segments with the header and frame in different * scatter / gather segments. @@ -2687,6 +2741,43 @@ DECLINLINE(bool) intnetR0TrunkIfCanHandleGsoFrame(PINTNETTRUNKIF pThis, PINTNETS /** + * Calculates the checksum of a full ipv6 frame. + * + * @returns 16-bit hecksum value. + * @param pIpHdr The IPv6 header (network endian (big)). + * @param bProtocol The protocol number. This can be the same as the + * ip6_nxt field, but doesn't need to be. + * @param cbPkt The packet size (host endian of course). This can + * be the same as the ip6_plen field, but as with @a + * bProtocol it won't be when extension headers are + * present. For UDP this will be uh_ulen converted to + * host endian. + */ +static uint16_t computeIPv6FullChecksum(PCRTNETIPV6 pIpHdr) +{ + uint16_t const *data; + int len = RT_BE2H_U16(pIpHdr->ip6_plen); + uint32_t sum = RTNetIPv6PseudoChecksum(pIpHdr); + + /* add the payload */ + data = (uint16_t *) (pIpHdr + 1); + while(len > 1) + { + sum += *(data); + data++; + len -= 2; + } + + if(len > 0) + sum += *((uint8_t *) data); + + while(sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + + return (uint16_t) ~sum; +} + +/** * Sends a frame down the trunk. * * @param pThis The trunk. @@ -2765,9 +2856,51 @@ static void intnetR0TrunkIfSend(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork, P pArp->ar_tha = pThis->MacAddr; } } - //else if (pSG->fFlags & INTNETSG_FLAGS_ICMPV6_NDP) - //{ /// @todo move the editing into a different function - //} + else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6)) + { + /* + * IPV6 ICMP Neighbor Discovery : replace + * 1) the advertised source mac address in outgoing neighbor sollicitations + * with the HW MAC address of the trunk interface, + * 2) the advertised target mac address in outgoing neighbor advertisements + * with the HW mac address of the trunk interface. + * + * Note that this only applies to traffic going out on the trunk. Incoming + * NS/NA will never advertise any VM mac address, so we do not need to touch + * them. Other VMs on this bridge as well as the host will see and use the VM's + * actual mac addresses. + * + */ + + PRTNETIPV6 pIPv6 = (PRTNETIPV6)(pEthHdr + 1); + PRTNETNDP pNd = (PRTNETNDP)(pIPv6 + 1); + PRTNETNDP_SLLA_OPT pLLAOpt = (PRTNETNDP_SLLA_OPT)(pNd + 1); + + /* make sure we have enough bytes to work with */ + if(pSG->cbTotal >= (RTNETIPV6_MIN_LEN + RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN) && + /* ensure the packet came from our LAN (not gone through any router) */ + pIPv6->ip6_hlim == 0xff && + /* protocol has to be icmpv6 */ + pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 && + /* we either have a sollicitation with source link layer addr. opt, or */ + ((pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE && + pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 && + pLLAOpt->type == RTNETIPV6_ICMP_ND_SLLA_OPT) || + /* an advertisement with target link layer addr. option */ + ((pNd->icmp6_type == RTNETIPV6_ICMP_NA_TYPE && + pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 && + pLLAOpt->type == RTNETIPV6_ICMP_ND_TLLA_OPT)) ) && + pLLAOpt->len == RTNETIPV6_ICMP_ND_LLA_LEN) + { + /* swap the advertised VM MAC address with the trunk's */ + pLLAOpt->slla = pThis->MacAddr; + + /* recompute the checksum since we changed the packet */ + pNd->icmp6_cksum = 0; + pNd->icmp6_cksum = computeIPv6FullChecksum(pIPv6); + } + + } } /* @@ -2791,6 +2924,124 @@ static void intnetR0TrunkIfSend(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork, P /** + * Work around the issue with WiFi routers that replace IPv6 multicast + * Ethernet addresses with unicast ones. We check IPv6 destination address + * to determine if the packet originally had a multicast address, and if so + * we restore the original address and treat the modified packet as being a + * broadcast. + * + * @param pNetwork The network the frame is being sent to. + * @param pSG Pointer to the gather list for the frame. + * @param pEthHdr Pointer to the ethernet header. + */ +static bool intnetR0NetworkDetectAndFixNdBroadcast(PINTNETNETWORK pNetwork, PINTNETSG pSG, PRTNETETHERHDR pEthHdr) +{ + if (RT_BE2H_U16(pEthHdr->EtherType) != RTNET_ETHERTYPE_IPV6) + return false; + /* + * Check the minimum size and get a linear copy of the thing to work on, + * using the temporary buffer if necessary. + */ + if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) + + sizeof(RTNETNDP))) + return false; + uint8_t bTmp[sizeof(RTNETIPV6) + sizeof(RTNETNDP)]; + PRTNETIPV6 pIPv6 = (PRTNETIPV6)((uint8_t *)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR)); + if ( pSG->cSegsUsed != 1 + && pSG->aSegs[0].cb < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) + + sizeof(RTNETNDP)) + { + Log6(("fw: Copying IPv6 pkt %u\n", sizeof(RTNETIPV6))); + if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), sizeof(RTNETIPV6) + + sizeof(RTNETNDP), bTmp)) + return false; + pIPv6 = (PRTNETIPV6)bTmp; + } + + PCRTNETNDP pNd = (PCRTNETNDP) (pIPv6 + 1); + + /* Check IPv6 destination address if it is a multicast address. */ + static uint8_t auSolicitedNodeMulticastPrefix[] = + { + 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xff + }; + if (memcmp(pIPv6->ip6_dst.au8, auSolicitedNodeMulticastPrefix, + sizeof(auSolicitedNodeMulticastPrefix)) == 0) + { + /* + * The original must have been composed of 0x3333 followed by the last + * four bytes of the solicited-node multicast address. + */ + if (pSG->aSegs[0].cb < sizeof(RTNETETHERHDR)) + { + RTMAC DstMac; + DstMac.au16[0] = 0x3333; + DstMac.au16[1] = pIPv6->ip6_dst.au16[6]; + DstMac.au16[2] = pIPv6->ip6_dst.au16[7]; + return intnetR0SgWritePart(pSG, RT_OFFSETOF(RTNETETHERHDR, DstMac), sizeof(RTMAC), &DstMac); + } + pEthHdr = (PRTNETETHERHDR)pSG->aSegs[0].pv; + pEthHdr->DstMac.au16[0] = 0x3333; + pEthHdr->DstMac.au16[1] = pIPv6->ip6_dst.au16[6]; + pEthHdr->DstMac.au16[2] = pIPv6->ip6_dst.au16[7]; + return true; + } + + return false; +} + + +/** + * Snoops a multicast ICMPv6 ND DAD from the wire via the trunk connection. + * + * @param pNetwork The network the frame is being sent to. + * @param pSG Pointer to the gather list for the frame. + * @param pEthHdr Pointer to the ethernet header. + */ +static void intnetR0NetworkSnoopNAFromWire(PINTNETNETWORK pNetwork, PINTNETSG pSG, PRTNETETHERHDR pEthHdr) +{ + /* + * Check the minimum size and get a linear copy of the thing to work on, + * using the temporary buffer if necessary. + */ + if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) + + sizeof(RTNETNDP))) + return; + PRTNETIPV6 pIPv6 = (PRTNETIPV6)((uint8_t *)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR)); + if ( pSG->cSegsUsed != 1 + && pSG->aSegs[0].cb < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) + + sizeof(RTNETNDP)) + { + Log6(("fw: Copying IPv6 pkt %u\n", sizeof(RTNETIPV6))); + if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), sizeof(RTNETIPV6) + + sizeof(RTNETNDP), pNetwork->pbTmp)) + return; + pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP; + pIPv6 = (PRTNETIPV6)pNetwork->pbTmp; + } + + PCRTNETNDP pNd = (PCRTNETNDP) (pIPv6 + 1); + + /* + * a multicast NS with :: as source address means a DAD packet. + * if it comes from the wire and we have the DAD'd address in our cache, + * flush the entry as the address is being acquired by someone else on + * the network. + */ + if ( pIPv6->ip6_hlim == 0xff + && pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 + && pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE + && pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 + && pIPv6->ip6_src.QWords.qw0 == 0 + && pIPv6->ip6_src.QWords.qw1 == 0) + { + + intnetR0NetworkAddrCacheDelete(pNetwork, (PCRTNETADDRU) &pNd->target_address, + kIntNetAddrType_IPv6, sizeof(RTNETADDRIPV6), "tif/ip6"); + } +} +/** * Edits an ARP packet arriving from the wire via the trunk connection. * * @param pNetwork The network the frame is being sent to. @@ -3019,7 +3270,7 @@ DECLINLINE(bool) intnetR0NetworkIsContextOk(PINTNETNETWORK pNetwork, PINTNETIF p if ((fTrunkDst & pTrunk->fNoPreemptDsts) == fTrunkDst) return true; - /* ASSUMES: That a preemption test detects HWACCM contexts. (Will work on + /* ASSUMES: That a preemption test detects HM contexts. (Will work on non-preemptive systems as well.) */ if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) return true; @@ -3043,7 +3294,7 @@ DECLINLINE(bool) intnetR0NetworkIsContextOkForBroadcast(PINTNETNETWORK pNetwork, if (fSrc) return true; - /* ASSUMES: That a preemption test detects HWACCM contexts. (Will work on + /* ASSUMES: That a preemption test detects HM contexts. (Will work on non-preemptive systems as well.) */ if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) return true; @@ -3097,6 +3348,17 @@ static INTNETSWDECISION intnetR0NetworkSharedMacFixAndSwitchBroadcast(PINTNETNET return INTNETSWDECISION_BAD_CONTEXT; /* + * Check for ICMPv6 Neighbor Advertisements coming from the trunk. + * If we see an advertisement for an IP in our cache, we can safely remove + * it as the IP has probably moved. + */ + if ( (fSrc & INTNETTRUNKDIR_WIRE) + && RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_IPV6 + && pSG->GsoCtx.u8Type == PDMNETWORKGSOTYPE_INVALID) + intnetR0NetworkSnoopNAFromWire(pNetwork, pSG, pEthHdr); + + + /* * Check for ARP packets from the wire since we'll have to make * modification to them if we're sharing the MAC address with the host. */ @@ -3174,8 +3436,7 @@ static INTNETSWDECISION intnetR0NetworkSharedMacFixAndSwitchUnicast(PINTNETNETWO Log6(("intnetshareduni: IPv4 %d.%d.%d.%d\n", Addr.au8[0], Addr.au8[1], Addr.au8[2], Addr.au8[3])); break; -#if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */ - case RTNET_ETHERTYPE_IPV6 + case RTNET_ETHERTYPE_IPV6: if (RT_UNLIKELY(!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR) + RT_OFFSETOF(RTNETIPV6, ip6_dst), sizeof(Addr.IPv6), &Addr))) { Log(("intnetshareduni: failed to read ip6_dst! cbTotal=%#x\n", pSG->cbTotal)); @@ -3184,7 +3445,6 @@ static INTNETSWDECISION intnetR0NetworkSharedMacFixAndSwitchUnicast(PINTNETNETWO enmAddrType = kIntNetAddrType_IPv6; cbAddr = sizeof(Addr.IPv6); break; -#endif #if 0 /** @todo IntNet: implement IPX for wireless MAC sharing? */ case RTNET_ETHERTYPE_IPX_1: case RTNET_ETHERTYPE_IPX_2: @@ -3400,7 +3660,12 @@ static INTNETSWDECISION intnetR0NetworkSend(PINTNETNETWORK pNetwork, PINTNETIF p if (intnetR0IsMacAddrMulticast(&EthHdr.DstMac)) enmSwDecision = intnetR0NetworkSharedMacFixAndSwitchBroadcast(pNetwork, fSrc, pIfSender, pSG, &EthHdr, pDstTab); else if (fSrc & INTNETTRUNKDIR_WIRE) - enmSwDecision = intnetR0NetworkSharedMacFixAndSwitchUnicast(pNetwork, pSG, &EthHdr, pDstTab); + { + if (intnetR0NetworkDetectAndFixNdBroadcast(pNetwork, pSG, &EthHdr)) + enmSwDecision = intnetR0NetworkSharedMacFixAndSwitchBroadcast(pNetwork, fSrc, pIfSender, pSG, &EthHdr, pDstTab); + else + enmSwDecision = intnetR0NetworkSharedMacFixAndSwitchUnicast(pNetwork, pSG, &EthHdr, pDstTab); + } else enmSwDecision = intnetR0NetworkSwitchUnicast(pNetwork, fSrc, pIfSender, &EthHdr.DstMac, pDstTab); } @@ -3482,8 +3747,8 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession) PINTNETHDR pHdr; while ((pHdr = IntNetRingGetNextFrameToRead(&pIf->pIntBuf->Send)) != NULL) { - uint16_t const u16Type = pHdr->u16Type; - if (u16Type == INTNETHDR_TYPE_FRAME) + uint8_t const u8Type = pHdr->u8Type; + if (u8Type == INTNETHDR_TYPE_FRAME) { /* Send regular frame. */ void *pvCurFrame = IntNetHdrGetFramePtr(pHdr, pIf->pIntBuf); @@ -3492,7 +3757,7 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession) intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame, false /*fGso*/, (uint16_t *)&Sg.fFlags); enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &Sg, pDstTab); } - else if (u16Type == INTNETHDR_TYPE_GSO) + else if (u8Type == INTNETHDR_TYPE_GSO) { /* Send GSO frame if sane. */ PPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, pIf->pIntBuf); @@ -3514,7 +3779,7 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession) /* Unless it's a padding frame, we're getting babble from the producer. */ else { - if (u16Type != INTNETHDR_TYPE_PADDING) + if (u8Type != INTNETHDR_TYPE_PADDING) STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatBadFrames); /* ignore */ enmSwDecision = INTNETSWDECISION_DROP; } @@ -3617,7 +3882,7 @@ INTNETR0DECL(int) IntNetR0IfGetBufferPtrs(INTNETIFHANDLE hIf, PSUPDRVSESSI intnetR0IfRelease(pIf, pSession); LogFlow(("IntNetR0IfGetBufferPtrs: returns %Rrc *ppRing3Buf=%p *ppRing0Buf=%p\n", - rc, ppRing3Buf ? *ppRing3Buf : NULL, ppRing0Buf ? *ppRing0Buf : NULL)); + rc, ppRing3Buf ? *ppRing3Buf : NIL_RTR3PTR, ppRing0Buf ? *ppRing0Buf : NIL_RTR0PTR)); return rc; } @@ -4996,6 +5261,13 @@ static int intnetR0NetworkCreateTrunkIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION */ case kIntNetTrunkType_None: case kIntNetTrunkType_WhateverNone: +#ifdef VBOX_WITH_NAT_SERVICE + /* + * Well, here we don't want load anything special, + * just communicate between processes via internal network. + */ + case kIntNetTrunkType_SrvNat: +#endif return VINF_SUCCESS; /* Can't happen, but makes GCC happy. */ @@ -5015,9 +5287,11 @@ static int intnetR0NetworkCreateTrunkIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pszName = "VBoxNetAdp"; #endif /* VBOXNETADP_DO_NOT_USE_NETFLT */ break; +#ifndef VBOX_WITH_NAT_SERVICE case kIntNetTrunkType_SrvNat: pszName = "VBoxSrvNat"; break; +#endif } /* @@ -5476,9 +5750,12 @@ static int intnetR0OpenNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const c * about the trunk setup and security. */ int rc; - if ( enmTrunkType == kIntNetTrunkType_WhateverNone - || ( pCur->enmTrunkType == enmTrunkType - && !strcmp(pCur->szTrunk, pszTrunk))) + if ( enmTrunkType == kIntNetTrunkType_WhateverNone +#ifdef VBOX_WITH_NAT_SERVICE + || enmTrunkType == kIntNetTrunkType_SrvNat /* @todo: what does it mean */ +#endif + || ( pCur->enmTrunkType == enmTrunkType + && !strcmp(pCur->szTrunk, pszTrunk))) { rc = intnetR0CheckOpenNetworkFlags(pCur, fFlags); if (RT_SUCCESS(rc)) @@ -5574,6 +5851,9 @@ static int intnetR0CreateNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE; if ( enmTrunkType == kIntNetTrunkType_WhateverNone +#ifdef VBOX_WITH_NAT_SERVICE + || enmTrunkType == kIntNetTrunkType_SrvNat /* simialar security */ +#endif || enmTrunkType == kIntNetTrunkType_None) fDefFlags |= INTNET_OPEN_FLAGS_ACCESS_RESTRICTED; else @@ -5739,6 +6019,9 @@ INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork, { case kIntNetTrunkType_None: case kIntNetTrunkType_WhateverNone: +#ifdef VBOX_WITH_NAT_SERVICE + case kIntNetTrunkType_SrvNat: +#endif if (*pszTrunk) return VERR_INVALID_PARAMETER; break; |