VBoxNetFlt.c revision ddf5c3bc368adfbecd8cc147963fe94d49e6e68d
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VBoxNetFlt - Network Filter Driver (Host), Common Code.
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * Sun Microsystems, Inc. confidential
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * All rights reserved
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync/** @page pg_netflt VBoxNetFlt - Network Interface Filter
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * This is a kernel module that attaches to a real interface on the host
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * and filters and injects packets.
154e1d5579ca6c8bee571a8d1ced5d76a0234030vboxsync * In the big picture we're one of the three trunk interface on the internal
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * network, the one named "NIC Filter Driver": @image html Networking_Overview.gif
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @section sec_netflt_msc Locking / Sequence Diagrams
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * This secion contains a few sequence diagrams describing the problematic
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * transitions of a host interface filter instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * The thing that makes it all a bit problematic is that multiple events may
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * happen at the same time, and that we have to be very careful to avoid
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * deadlocks caused by mixing our locks with the ones in the host kernel.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * The main events are receive, send, async send completion, disappearance of
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * the host networking interface and it's reappearance. The latter two events
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * are can be caused by driver unloading/loading or the device being physical
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * unplugged (e.g. a USB network device).
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * The strategy for dealing with these issues are:
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * - Use a simple state machine.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * - Require the user (IntNet) to serialize all its calls to us,
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * while at the same time not owning any lock used by any of the
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * the callbacks we might call on receive and async send completion.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * - Make sure we're 100% idle before disconnecting, and have a
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * disconnected status on both sides to fend off async calls.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * - Protect the host specific interface handle and the state variables
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * using a spinlock.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @subsection subsec_netflt_msc_dis_rel Disconnect from the network and release
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM, IntNet, NetFlt, Kernel, Wire;
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="pkt0 to wire", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel->Wire [label="pkt0 to wire", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * --- [label="Suspending the trunk interface"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Wire->Kernel [label="pkt1 - racing us", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel=>>NetFlt [label="pkt1 - racing us", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>>IntNet [label="pkt1 recv - blocks", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Mark Trunk Suspended"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pfnSetActive(false)"];
8e2b54cb9fc2bee03d7c6e63b808e153ee5497e7vboxsync * NetFlt=>NetFlt [label="Mark inactive (atomic)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt;
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pfnWaitForIdle(forever)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>>NetFlt [label="pkt1 to host", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>>Kernel [label="pkt1 to host", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel<-Wire [label="pkt0 on wire", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="pkt0 on wire", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<=IntNet [label="Lock Net, free SG, Unlock Net", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<-NetFlt [label="idle", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="idle (pfnWaitForIdle)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Wire->Kernel [label="pkt2", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel=>>NetFlt [label="pkt2", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>>Kernel [label="pkt2 to host", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM->IntNet [label="pkt3", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> drop", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * --- [label="The trunk interface is idle now, disconnect it"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlink Trunk"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pfnDisconnectAndRelease"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="iflt_detach"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<=Kernel [label="iff_detached"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt>>Kernel [label="iff_detached"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="iflt_detach"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Release"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="pfnDisconnectAndRelease"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Removal
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * The ifnet_t (pIf) is a tricky customer as any reference to it can potentially
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * race the filter detaching. The simple way of solving it on Darwin is to guard
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * all access to the pIf member with a spinlock. The other host systems will
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * probably have similar race conditions, so the spinlock is a generic thing.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM, IntNet, NetFlt, Kernel;
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="ifnet_reference w/ spinlock", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="ifnet_reference", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="pkt0 to wire (blocks)", linecolor="green", textcolor="green" ];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * --- [label="The host interface is being disconnected"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel->NetFlt [label="iff_detached"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="ifnet_release w/ spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="ifnet_release"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="fDisconnectedFromHost=true"];
8e2b54cb9fc2bee03d7c6e63b808e153ee5497e7vboxsync * NetFlt>>Kernel [label="iff_detached"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="dropped", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Acquire spinlock", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="pIf=NULL", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Release spinlock", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Rediscovery
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * The rediscovery is performed when we receive a send request and a certain
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * period have elapsed since the last attempt, i.e. we're polling it. We
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * synchronize the rediscovery with disconnection from the internal network
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * by means of the pfnWaitForIdle call, so no special handling is required.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM2, VM1, IntNet, NetFlt, Kernel, Wire;
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * --- [label="Rediscovery conditions are not met"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM1->IntNet [label="pkt0"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pkt0 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="pkt0 to wire (dropped)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * --- [label="Rediscovery conditions"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM1->IntNet [label="pkt1"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pkt1 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="fRediscoveryPending=true w/ spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="ifnet_find_by_name"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="ifnet_find_by_name (success)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * VM2->IntNet [label="pkt2", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet=>NetFlt [label="pkt2 to wire", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="!pIf || fRediscoveryPending (w/ spinlock)", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="pkt2 to wire (dropped)", linecolor="red", textcolor="red"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="iflt_attach"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="iflt_attach (success)"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Acquire spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Set pIf and update flags"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>NetFlt [label="Release spinlock"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt=>Kernel [label="pkt1 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Kernel->Wire [label="pkt1 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * NetFlt<<Kernel [label="pkt1 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * IntNet<<NetFlt [label="pkt1 to wire"];
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync/*******************************************************************************
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync* Header Files *
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync*******************************************************************************/
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync# error "The static setup needs a full check up wrt assumptions and incomplete code."
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync/*******************************************************************************
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync* Defined Constants And Macros *
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync*******************************************************************************/
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync ( (PVBOXNETFLTINS)((uint8_t *)pIfPort - RT_OFFSETOF(VBOXNETFLTINS, MyPort)) )
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Finds a instance by its name, the caller does the locking.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pGlobals The globals.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pszName The name of the instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncstatic PVBOXNETFLTINS vboxNetFltFindInstanceLocked(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Finds a instance by its name, will request the mutex.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pGlobals The globals.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pszName The name of the instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncDECLHIDDEN(PVBOXNETFLTINS) vboxNetFltFindInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync pRet = vboxNetFltFindInstanceLocked(pGlobals, pszName);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Unlinks an instance from the chain.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pGlobals The globals.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pToUnlink The instance to unlink.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncstatic void vboxNetFltUnlinkLocked(PVBOXNETFLTGLOBALS pGlobals, PVBOXNETFLTINS pToUnlink)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncAssertCompileMemberSize(VBOXNETFLTINS, enmState, sizeof(uint32_t));
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Sets the enmState member atomically.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Used for all updates.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pThis The instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param enmNewState The new value.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncDECLINLINE(void) vboxNetFltSetState(PVBOXNETFLTINS pThis, VBOXNETFTLINSSTATE enmNewState)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, enmNewState);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Gets the enmState member atomically.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Used for all reads.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @returns The enmState value.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pThis The instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncDECLINLINE(VBOXNETFTLINSSTATE) vboxNetFltGetState(PVBOXNETFLTINS pThis)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync return (VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Performs interface rediscovery if it was disconnected from the host.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @returns true if successfully rediscovered and connected, false if not.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * @param pThis The instance.
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsyncstatic bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Rediscovered already? Time to try again?
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync fRediscovered = !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync && !ASMAtomicUoReadBool(&pThis->fRediscoveryPending)
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync && Now - ASMAtomicUoReadU64(&pThis->NanoTSLastRediscovery) > UINT64_C(5000000000); /* 5 sec */
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync ASMAtomicWriteBool(&pThis->fRediscoveryPending, true);
19c976d0829db79a6f0aa68fbcc9c9bb8f0e5126vboxsync * Call the OS specific code to do the job.
if (fDoIt)
if (fRediscovered)
return fRediscovered;
#ifdef RT_WITH_W64_UNWIND_HACK
NETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortXmit)(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst);
NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous)(PINTNETTRUNKIFPORT pIfPort);
NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortGetMacAddress)(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac);
NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsHostMac)(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac);
NETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortWaitForIdle)(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies);
NETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortSetActive)(PINTNETTRUNKIFPORT pIfPort, bool fActive);
NETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease)(PINTNETTRUNKIFPORT pIfPort);
NETFLT_DECL_CALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
int rc;
return rc;
int rc;
return rc;
return !fActive;
int rc;
#ifdef VBOXNETFLT_STATIC_CONFIG
if (fBusy)
if (!cRefs)
if (!cRefs)
if (fBusy)
static int vboxNetFltConnectIt(PVBOXNETFLTINS pThis, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort)
int rc;
#ifdef VBOXNETFLT_STATIC_CONFIG
return rc;
static int vboxNetFltNewInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort)
int rc;
if (!pNew)
return VERR_INTNET_FLT_IF_FAILED;
#ifdef VBOXNETFLT_STATIC_CONFIG
return rc;
return rc;
return rc;
static DECLCALLBACK(int) vboxNetFltFactoryCreateAndConnect(PINTNETTRUNKFACTORY pIfFactory, const char *pszName,
PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, TrunkFactory));
int rc;
if (pCur)
#ifdef VBOXNETFLT_STATIC_CONFIG
return rc;
#ifdef VBOXNETFLT_STATIC_CONFIG
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 VINF_SUCCESS;
rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
return rc;
return rc;