VBoxNetFlt.c revision 47a160d35dbc42c8c817c9b48be21dca11d329d6
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * VBoxNetFlt - Network Filter Driver (Host), Common Code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * available from http://www.virtualbox.org. This file is free software;
c74832c7184337c330041742d88e6dacaa07b378vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c74832c7184337c330041742d88e6dacaa07b378vboxsync * General Public License (GPL) as published by the Free Software
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c74832c7184337c330041742d88e6dacaa07b378vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
c74832c7184337c330041742d88e6dacaa07b378vboxsync * additional information or have any questions.
c74832c7184337c330041742d88e6dacaa07b378vboxsync/** @page pg_netflt VBoxNetFlt - Network Interface Filter
c74832c7184337c330041742d88e6dacaa07b378vboxsync * This is a kernel module that attaches to a real interface on the host
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * and filters and injects packets.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * In the big picture we're one of the three trunk interface on the internal
c74832c7184337c330041742d88e6dacaa07b378vboxsync * network, the one named "NIC Filter Driver": @image html Networking_Overview.gif
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @section sec_netflt_msc Locking / Sequence Diagrams
c74832c7184337c330041742d88e6dacaa07b378vboxsync * This secion contains a few sequence diagrams describing the problematic
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * transitions of a host interface filter instance.
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * The thing that makes it all a bit problematic is that multiple events may
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * happen at the same time, and that we have to be very careful to avoid
c74832c7184337c330041742d88e6dacaa07b378vboxsync * deadlocks caused by mixing our locks with the ones in the host kernel.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * The main events are receive, send, async send completion, disappearance of
c74832c7184337c330041742d88e6dacaa07b378vboxsync * the host networking interface and it's reappearance. The latter two events
c74832c7184337c330041742d88e6dacaa07b378vboxsync * are can be caused by driver unloading/loading or the device being physical
c74832c7184337c330041742d88e6dacaa07b378vboxsync * unplugged (e.g. a USB network device).
c74832c7184337c330041742d88e6dacaa07b378vboxsync * The strategy for dealing with these issues are:
c74832c7184337c330041742d88e6dacaa07b378vboxsync * - Use a simple state machine.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * - Require the user (IntNet) to serialize all its calls to us,
c74832c7184337c330041742d88e6dacaa07b378vboxsync * while at the same time not owning any lock used by any of the
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * the callbacks we might call on receive and async send completion.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * - Make sure we're 100% idle before disconnecting, and have a
c74832c7184337c330041742d88e6dacaa07b378vboxsync * disconnected status on both sides to fend off async calls.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * - Protect the host specific interface handle and the state variables
c74832c7184337c330041742d88e6dacaa07b378vboxsync * using a spinlock.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @subsection subsec_netflt_msc_dis_rel Disconnect from the network and release
c74832c7184337c330041742d88e6dacaa07b378vboxsync * VM, IntNet, NetFlt, Kernel, Wire;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt=>Kernel [label="pkt0 to wire", linecolor="green", textcolor="green"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Kernel->Wire [label="pkt0 to wire", linecolor="green", textcolor="green"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * --- [label="Suspending the trunk interface"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Lock Network"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Wire->Kernel [label="pkt1 - racing us", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Kernel=>>NetFlt [label="pkt1 - racing us", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt=>>IntNet [label="pkt1 recv - blocks", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Mark Trunk Suspended"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Unlock Network"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>NetFlt [label="pfnSetActive(false)"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt=>NetFlt [label="Mark inactive (atomic)"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet<<NetFlt;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>NetFlt [label="pfnWaitForIdle(forever)"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>>NetFlt [label="pkt1 to host", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt=>>Kernel [label="pkt1 to host", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Kernel<-Wire [label="pkt0 on wire", linecolor="green", textcolor="green"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt<<Kernel [label="pkt0 on wire", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * IntNet<<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * IntNet<<=IntNet [label="Lock Net, free SG, Unlock Net", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * NetFlt<-NetFlt [label="idle", linecolor="green", textcolor="green"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * IntNet<<NetFlt [label="idle (pfnWaitForIdle)"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * Wire->Kernel [label="pkt2", linecolor="red", textcolor="red"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * Kernel=>>NetFlt [label="pkt2", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>>Kernel [label="pkt2 to host", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * VM->IntNet [label="pkt3", linecolor="green", textcolor="green"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>IntNet [label="Route packet -> drop", linecolor="green", textcolor="green" ];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * --- [label="The trunk interface is idle now, disconnect it"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Lock Network"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Unlink Trunk"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Unlock Network"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>NetFlt [label="pfnDisconnectAndRelease"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * NetFlt=>Kernel [label="iflt_detach"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * NetFlt<<=Kernel [label="iff_detached"];
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * NetFlt>>Kernel [label="iff_detached"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * NetFlt<<Kernel [label="iflt_detach"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Release"];
0c34933fc8f84dd5183d1897881bbc7683d24541vboxsync * IntNet<<NetFlt [label="pfnDisconnectAndRelease"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Removal
c74832c7184337c330041742d88e6dacaa07b378vboxsync * The ifnet_t (pIf) is a tricky customer as any reference to it can potentially
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * race the filter detaching. The simple way of solving it on Darwin is to guard
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * all access to the pIf member with a spinlock. The other host systems will
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * probably have similar race conditions, so the spinlock is a generic thing.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * VM, IntNet, NetFlt, Kernel;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="ifnet_reference w/ spinlock", linecolor="green", textcolor="green" ];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt<<Kernel [label="ifnet_reference", linecolor="green", textcolor="green" ];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="pkt0 to wire (blocks)", linecolor="green", textcolor="green" ];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * --- [label="The host interface is being disconnected"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * Kernel->NetFlt [label="iff_detached"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="ifnet_release w/ spinlock"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt<<Kernel [label="ifnet_release"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="fDisconnectedFromHost=true"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt>>Kernel [label="iff_detached"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt<<Kernel [label="dropped", linecolor="green", textcolor="green"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Acquire spinlock", linecolor="green", textcolor="green"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * NetFlt<<Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="pIf=NULL", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * NetFlt=>NetFlt [label="Release spinlock", linecolor="green", textcolor="green"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
a6e58d30b4d856cf924fda15cd743fed386fff93vboxsync * IntNet<<NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Rediscovery
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * The rediscovery is performed when we receive a send request and a certain
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * period have elapsed since the last attempt, i.e. we're polling it. We
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync * synchronize the rediscovery with disconnection from the internal network
c74832c7184337c330041742d88e6dacaa07b378vboxsync * by means of the pfnWaitForIdle call, so no special handling is required.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * VM2, VM1, IntNet, NetFlt, Kernel, Wire;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * --- [label="Rediscovery conditions are not met"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * VM1->IntNet [label="pkt0"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>IntNet [label="Lock Network"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>IntNet [label="Unlock Network"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>NetFlt [label="pkt0 to wire"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet<<NetFlt [label="pkt0 to wire (dropped)"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * --- [label="Rediscovery conditions"];
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * VM1->IntNet [label="pkt1"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Lock Network"];
509c0d9c2c05b40f3f07f79e44c06c9395c1b293vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Unlock Network"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>NetFlt [label="pkt1 to wire"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="fRediscoveryPending=true w/ spinlock"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="ifnet_find_by_name"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt<<Kernel [label="ifnet_find_by_name (success)"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * VM2->IntNet [label="pkt2", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="red", textcolor="red"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet=>NetFlt [label="pkt2 to wire", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="!pIf || fRediscoveryPending (w/ spinlock)", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet<<NetFlt [label="pkt2 to wire (dropped)", linecolor="red", textcolor="red"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="iflt_attach"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt<<Kernel [label="iflt_attach (success)"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Acquire spinlock"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * NetFlt=>NetFlt [label="Set pIf and update flags"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>NetFlt [label="Release spinlock"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt=>Kernel [label="pkt1 to wire"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Kernel->Wire [label="pkt1 to wire"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * NetFlt<<Kernel [label="pkt1 to wire"];
c74832c7184337c330041742d88e6dacaa07b378vboxsync * IntNet<<NetFlt [label="pkt1 to wire"];
4fbca3751fe239da5934c23a783c3422618336e8vboxsync/*******************************************************************************
4fbca3751fe239da5934c23a783c3422618336e8vboxsync* Header Files *
4fbca3751fe239da5934c23a783c3422618336e8vboxsync*******************************************************************************/
c74832c7184337c330041742d88e6dacaa07b378vboxsync/*******************************************************************************
c74832c7184337c330041742d88e6dacaa07b378vboxsync* Defined Constants And Macros *
c74832c7184337c330041742d88e6dacaa07b378vboxsync*******************************************************************************/
c74832c7184337c330041742d88e6dacaa07b378vboxsync ( (PVBOXNETFLTINS)((uint8_t *)pIfPort - RT_OFFSETOF(VBOXNETFLTINS, MyPort)) )
c74832c7184337c330041742d88e6dacaa07b378vboxsyncAssertCompileMemberSize(VBOXNETFLTINS, enmState, sizeof(uint32_t));
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Sets the enmState member atomically.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Used for all updates.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pThis The instance.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param enmNewState The new value.
c74832c7184337c330041742d88e6dacaa07b378vboxsyncDECLINLINE(void) vboxNetFltSetState(PVBOXNETFLTINS pThis, VBOXNETFTLINSSTATE enmNewState)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, enmNewState);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Gets the enmState member atomically.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Used for all reads.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns The enmState value.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pThis The instance.
c74832c7184337c330041742d88e6dacaa07b378vboxsyncDECLINLINE(VBOXNETFTLINSSTATE) vboxNetFltGetState(PVBOXNETFLTINS pThis)
c74832c7184337c330041742d88e6dacaa07b378vboxsync return (VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Finds a instance by its name, the caller does the locking.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pGlobals The globals.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pszName The name of the instance.
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncstatic PVBOXNETFLTINS vboxNetFltFindInstanceLocked(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Finds a instance by its name, will request the mutex.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * No reference to the instance is retained, we're assuming the caller to
c74832c7184337c330041742d88e6dacaa07b378vboxsync * already have one but just for some reason doesn't have the pointer to it.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pGlobals The globals.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pszName The name of the instance.
c74832c7184337c330041742d88e6dacaa07b378vboxsyncDECLHIDDEN(PVBOXNETFLTINS) vboxNetFltFindInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
c74832c7184337c330041742d88e6dacaa07b378vboxsync int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync pRet = vboxNetFltFindInstanceLocked(pGlobals, pszName);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Unlinks an instance from the chain.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pGlobals The globals.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pToUnlink The instance to unlink.
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncstatic void vboxNetFltUnlinkLocked(PVBOXNETFLTGLOBALS pGlobals, PVBOXNETFLTINS pToUnlink)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * Performs interface rediscovery if it was disconnected from the host.
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * @returns true if successfully rediscovered and connected, false if not.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pThis The instance.
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsyncstatic bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Rediscovered already? Time to try again?
4fbca3751fe239da5934c23a783c3422618336e8vboxsync fRediscovered = !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync && !ASMAtomicUoReadBool(&pThis->fRediscoveryPending)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync && Now - ASMAtomicUoReadU64(&pThis->NanoTSLastRediscovery) > UINT64_C(5000000000); /* 5 sec */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync ASMAtomicWriteBool(&pThis->fRediscoveryPending, true);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Call the OS specific code to do the job.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Update the state when the call returns, that is everything except for
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * the fDisconnectedFromHost flag which the OS specific code shall set.
c74832c7184337c330041742d88e6dacaa07b378vboxsync fRediscovered = vboxNetFltOsMaybeRediscovered(pThis);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(!fRediscovered || !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost));
4fbca3751fe239da5934c23a783c3422618336e8vboxsync ASMAtomicUoWriteU64(&pThis->NanoTSLastRediscovery, RTTimeNanoTS());
4fbca3751fe239da5934c23a783c3422618336e8vboxsync ASMAtomicWriteBool(&pThis->fRediscoveryPending, false);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync# if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync# define NETFLT_DECL_CALLBACK(type) DECLASM(DECLHIDDEN(type))
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortXmit)(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous)(PINTNETTRUNKIFPORT pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortGetMacAddress)(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsHostMac)(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortWaitForIdle)(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortSetActive)(PINTNETTRUNKIFPORT pIfPort, bool fActive);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease)(PINTNETTRUNKIFPORT pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRetain)(PINTNETTRUNKIFPORT pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRelease)(PINTNETTRUNKIFPORT pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync# define NETFLT_DECL_CALLBACK(type) static DECLCALLBACK(type)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @copydoc INTNETTRUNKIFPORT::pfnXmit
c74832c7184337c330041742d88e6dacaa07b378vboxsyncNETFLT_DECL_CALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Input validation.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Do a busy retain and then make sure we're connected to the interface
c74832c7184337c330041742d88e6dacaa07b378vboxsync * before invoking the OS specific code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync if ( !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost)
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @copydoc INTNETTRUNKIFPORT::pfnIsPromiscuous
c74832c7184337c330041742d88e6dacaa07b378vboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsPromiscuous(PINTNETTRUNKIFPORT pIfPort)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Input validation.
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Ask the OS specific code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @copydoc INTNETTRUNKIFPORT::pfnGetMacAddress
c74832c7184337c330041742d88e6dacaa07b378vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortGetMacAddress(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac)
c74832c7184337c330041742d88e6dacaa07b378vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Input validation.
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Forward the question to the OS specific code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @copydoc INTNETTRUNKIFPORT::pfnIsHostMac
c74832c7184337c330041742d88e6dacaa07b378vboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsHostMac(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac)
c74832c7184337c330041742d88e6dacaa07b378vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Input validation.
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Ask the OS specific code.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Input validation.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Go to sleep on the semaphore after checking the busy count.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync rc = RTSemEventWait(pThis->hEventIdle, cMillies); /** @todo make interruptible? */
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @copydoc INTNETTRUNKIFPORT::pfnSetActive
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Input validation.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, false);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * We're assuming that the caller is serializing the calls, so we don't
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * have to be extremely careful here. Just update first and then call
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * the OS specific code, the update must be serialized for various reasons.
6b98f92a0c2c5dd90d8496ee553e5763c4debd49vboxsync * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
6b98f92a0c2c5dd90d8496ee553e5763c4debd49vboxsync * Serious paranoia.
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Disconnect and release it.
c74832c7184337c330041742d88e6dacaa07b378vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Disconnecting);
6dea6d87ed79bc0994d314fed1c90431091e8820vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Unconnected);
6b98f92a0c2c5dd90d8496ee553e5763c4debd49vboxsync * Destroy a device that has been disconnected from the switch.
6b98f92a0c2c5dd90d8496ee553e5763c4debd49vboxsync * @returns true if the instance is destroyed, false otherwise.
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync * @param pThis The instance to be destroyed. This is
b5d837811bf21f30a31748bbbcb28ee562bb2355vboxsync * no longer valid when this function returns.
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsyncstatic bool vboxNetFltDestroyInstance(PVBOXNETFLTINS pThis)
c74832c7184337c330041742d88e6dacaa07b378vboxsync uint32_t cRefs = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cRefs);
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync LogFlow(("vboxNetFltDestroyInstance: pThis=%p (%s)\n", pThis, pThis->szName));
e7925b345f17e5bd9f0c1cf3540b7d8573ec274fvboxsync * Validate the state.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Assert( vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Disconnecting
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync || vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Unconnected);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Disconnecting);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Make sure the state is 'disconnecting' / 'destroying' and let the OS
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * specific code do its part of the cleanup outside the mutex.
c74832c7184337c330041742d88e6dacaa07b378vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx); AssertRC(rc);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Destroying);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Disconnecting);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Unlink the instance and free up its resources.
c74832c7184337c330041742d88e6dacaa07b378vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx); AssertRC(rc);
c74832c7184337c330041742d88e6dacaa07b378vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Destroyed);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return true;
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Releases a reference to the specified instance.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * This method will destroy the instance when the count reaches 0.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * It will also take care of decrementing the counter and idle wakeup.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pThis The instance.
cad8876b46f9e366c4a1007a40c27ca1df078950vboxsync * @param fBusy Whether the busy counter should be decremented too.
c74832c7184337c330041742d88e6dacaa07b378vboxsyncDECLHIDDEN(void) vboxNetFltRelease(PVBOXNETFLTINS pThis, bool fBusy)
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * Paranoid Android.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
c74832c7184337c330041742d88e6dacaa07b378vboxsync Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Work the busy counter.
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync * The object reference counting.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * @copydoc INTNETTRUNKIFPORT::pfnRetain
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortRelease(PINTNETTRUNKIFPORT pIfPort)
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync * Retains a reference to the specified instance and a busy reference too.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pThis The instance.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param fBusy Whether the busy counter should be incremented as well.
c74832c7184337c330041742d88e6dacaa07b378vboxsyncDECLHIDDEN(void) vboxNetFltRetain(PVBOXNETFLTINS pThis, bool fBusy)
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * Paranoid Android.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
3e9c5c3e44de15c28695c7b570bc2551639187e3vboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync * Retain the object.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Work the busy counter.
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync * @copydoc INTNETTRUNKIFPORT::pfnRetain
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortRetain(PINTNETTRUNKIFPORT pIfPort)
4fbca3751fe239da5934c23a783c3422618336e8vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * Connects the instance to the specified switch port.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Called while owning the lock. We're ASSUMING that the internal
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * networking code is already owning an recursive mutex, so, there
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * will be no deadlocks when vboxNetFltOsConnectIt calls back into
c74832c7184337c330041742d88e6dacaa07b378vboxsync * it for setting preferences.
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync * @returns VBox status code.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pThis The instance.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param pSwitchPort The port on the internal network 'switch'.
4fbca3751fe239da5934c23a783c3422618336e8vboxsync * @param ppIfPort Where to return our port interface.
4fbca3751fe239da5934c23a783c3422618336e8vboxsyncstatic int vboxNetFltConnectIt(PVBOXNETFLTINS pThis, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort)
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Validate state.
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Unconnected);
120ee2736ed70b5ce8b0b4dd73cc4f8b4b9416c1vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Initializing);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync * Do the job.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Note that we're calling the os stuff while owning the semaphore here.
c74832c7184337c330041742d88e6dacaa07b378vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Connected);
c74832c7184337c330041742d88e6dacaa07b378vboxsync * Creates a new instance.
6f8a1ec7a08590986f176ea072ad499630fe5b6evboxsync * The new instance will be in the suspended state in a dynamic config and in
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * the inactive in a static one.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Called without owning the lock, but will request is several times.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @returns VBox status code.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pGlobals The globals.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pszName The instance name.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pSwitchPort The port on the switch that we're connected with (dynamic only).
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param fNoPromisc Do not attempt going into promiscuous mode.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param pvContext Context argument for vboxNetFltOsInitInstance.
c74832c7184337c330041742d88e6dacaa07b378vboxsync * @param ppIfPort Where to store the pointer to our port interface (dynamic only).
c74832c7184337c330041742d88e6dacaa07b378vboxsyncstatic int vboxNetFltNewInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName, PINTNETTRUNKSWPORT pSwitchPort,
c74832c7184337c330041742d88e6dacaa07b378vboxsync bool fNoPromisc, void *pvContext, PINTNETTRUNKIFPORT *ppIfPort)
f01175bdcb5e36a1a89fca88f45d7ee7fb034ed6vboxsync * Allocate and initialize a new instance before requesting the mutex.
c74832c7184337c330041742d88e6dacaa07b378vboxsync PVBOXNETFLTINS pNew = (PVBOXNETFLTINS)RTMemAllocZ(RT_OFFSETOF(VBOXNETFLTINS, szName[cchName + 1]));
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.u32Version = INTNETTRUNKIFPORT_VERSION;
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnRetain = NETFLT_CALLBACK(vboxNetFltPortRetain);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnRelease = NETFLT_CALLBACK(vboxNetFltPortRelease);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnDisconnectAndRelease= NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnSetActive = NETFLT_CALLBACK(vboxNetFltPortSetActive);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnWaitForIdle = NETFLT_CALLBACK(vboxNetFltPortWaitForIdle);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnGetMacAddress = NETFLT_CALLBACK(vboxNetFltPortGetMacAddress);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnIsHostMac = NETFLT_CALLBACK(vboxNetFltPortIsHostMac);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnIsPromiscuous = NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.pfnXmit = NETFLT_CALLBACK(vboxNetFltPortXmit);
c74832c7184337c330041742d88e6dacaa07b378vboxsync pNew->MyPort.u32VersionEnd = INTNETTRUNKIFPORT_VERSION;
f01175bdcb5e36a1a89fca88f45d7ee7fb034ed6vboxsync * Insert the instance into the chain, checking for
c74832c7184337c330041742d88e6dacaa07b378vboxsync * duplicates first of course (race).
#ifdef VBOXNETFLT_STATIC_CONFIG
return rc;
return rc;
return rc;
#ifdef VBOXNETFLT_STATIC_CONFIG
DECLHIDDEN(int) vboxNetFltSearchCreateInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName, PVBOXNETFLTINS *ppInstance, void *pvContext)
int rc;
while (pCur)
switch (enmState)
return VINF_ALREADY_INITIALIZED;
LogRel(("VBoxNetFlt: Huh? An instance of '%s' already exists! [pCur=%p cRefs=%d fDfH=%RTbool enmState=%d]\n",
return VERR_INTNET_FLT_IF_BUSY;
# ifdef RT_STRICT
return rc;
static DECLCALLBACK(int) vboxNetFltFactoryCreateAndConnect(PINTNETTRUNKFACTORY pIfFactory, const char *pszName,
PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, TrunkFactory));
int rc;
LogFlow(("vboxNetFltFactoryCreateAndConnect: pszName=%p:{%s} fFlags=%#x\n", pszName, pszName, fFlags));
if (pCur)
#ifdef VBOXNETFLT_STATIC_CONFIG
if (pCur)
return rc;
#ifdef VBOXNETFLT_STATIC_CONFIG
NULL,
ppIfPort);
return rc;
PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, TrunkFactory));
static DECLCALLBACK(void *) vboxNetFltQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, SupDrvFactory));
#ifdef LOG_ENABLED
return NULL;
return fRc;
int rc;
return VERR_WRONG_ORDER;
return VERR_WRONG_ORDER;
return rc;
int rc;
rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;