VBoxNetFlt.c revision c0fa9ee5c9cb7a79ac0f20d8009f75148bd9195f
8ad79874169cc981a694a15e8a806b9a39133673vboxsync/* $Id$ */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/** @file
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VBoxNetFlt - Network Filter Driver (Host), Common Code.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync/*
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * available from http://www.virtualbox.org. This file is free software;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * General Public License (GPL) as published by the Free Software
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * additional information or have any questions.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/** @page pg_netflt VBoxNetFlt - Network Interface Filter
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This is a kernel module that attaches to a real interface on the host
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * and filters and injects packets.
258511aa4b33ed962c316ae5934e400edf09d3d6vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * In the big picture we're one of the three trunk interface on the internal
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * network, the one named "NIC Filter Driver": @image html Networking_Overview.gif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @section sec_netflt_msc Locking / Sequence Diagrams
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This secion contains a few sequence diagrams describing the problematic
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * transitions of a host interface filter instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * The thing that makes it all a bit problematic is that multiple events may
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * happen at the same time, and that we have to be very careful to avoid
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * deadlocks caused by mixing our locks with the ones in the host kernel.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * The main events are receive, send, async send completion, disappearance of
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * the host networking interface and it's reappearance. The latter two events
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * are can be caused by driver unloading/loading or the device being physical
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * unplugged (e.g. a USB network device).
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * The strategy for dealing with these issues are:
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * - Use a simple state machine.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * - Require the user (IntNet) to serialize all its calls to us,
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * while at the same time not owning any lock used by any of the
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * the callbacks we might call on receive and async send completion.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * - Make sure we're 100% idle before disconnecting, and have a
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * disconnected status on both sides to fend off async calls.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * - Protect the host specific interface handle and the state variables
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * using a spinlock.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @subsection subsec_netflt_msc_dis_rel Disconnect from the network and release
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @msc
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM, IntNet, NetFlt, Kernel, Wire;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="pkt0 to wire", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Kernel->Wire [label="pkt0 to wire", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * --- [label="Suspending the trunk interface"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Lock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Wire->Kernel [label="pkt1 - racing us", linecolor="red", textcolor="red"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Kernel=>>NetFlt [label="pkt1 - racing us", linecolor="red", textcolor="red"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>>IntNet [label="pkt1 recv - blocks", linecolor="red", textcolor="red"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Mark Trunk Suspended"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>NetFlt [label="pfnSetActive(false)"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Mark inactive (atomic)"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet<<NetFlt;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>NetFlt [label="pfnWaitForIdle(forever)"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>>NetFlt [label="pkt1 to host", linecolor="red", textcolor="red"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>>Kernel [label="pkt1 to host", linecolor="red", textcolor="red"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Kernel<-Wire [label="pkt0 on wire", linecolor="green", textcolor="green"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt<<Kernel [label="pkt0 on wire", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<<=IntNet [label="Lock Net, free SG, Unlock Net", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<-NetFlt [label="idle", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<<NetFlt [label="idle (pfnWaitForIdle)"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Wire->Kernel [label="pkt2", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Kernel=>>NetFlt [label="pkt2", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>>Kernel [label="pkt2 to host", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM->IntNet [label="pkt3", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Route packet -> drop", linecolor="green", textcolor="green" ];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * --- [label="The trunk interface is idle now, disconnect it"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Lock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlink Trunk"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>NetFlt [label="pfnDisconnectAndRelease"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>Kernel [label="iflt_detach"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt<<=Kernel [label="iff_detached"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt>>Kernel [label="iff_detached"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="iflt_detach"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Release"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet<<NetFlt [label="pfnDisconnectAndRelease"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @endmsc
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Removal
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * The ifnet_t (pIf) is a tricky customer as any reference to it can potentially
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * race the filter detaching. The simple way of solving it on Darwin is to guard
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * all access to the pIf member with a spinlock. The other host systems will
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * probably have similar race conditions, so the spinlock is a generic thing.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync * @msc
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * VM, IntNet, NetFlt, Kernel;
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM->IntNet [label="pkt0", linecolor="green", textcolor="green"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="ifnet_reference w/ spinlock", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="ifnet_reference", linecolor="green", textcolor="green" ];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>Kernel [label="pkt0 to wire (blocks)", linecolor="green", textcolor="green" ];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * --- [label="The host interface is being disconnected"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Kernel->NetFlt [label="iff_detached"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="ifnet_release w/ spinlock"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="ifnet_release"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>NetFlt [label="fDisconnectedFromHost=true"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt>>Kernel [label="iff_detached"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt<<Kernel [label="dropped", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Acquire spinlock", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt<<Kernel [label="ifnet_release", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="pIf=NULL", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Release spinlock", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<=NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet>>NetFlt [label="pfnSGRelease", linecolor="green", textcolor="green"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet<<NetFlt [label="pkt0 to wire", linecolor="green", textcolor="green"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @endmsc
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @subsection subsec_netflt_msc_hif_rm Host Interface Rediscovery
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * The rediscovery is performed when we receive a send request and a certain
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * period have elapsed since the last attempt, i.e. we're polling it. We
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * synchronize the rediscovery with disconnection from the internal network
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * by means of the pfnWaitForIdle call, so no special handling is required.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @msc
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM2, VM1, IntNet, NetFlt, Kernel, Wire;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * --- [label="Rediscovery conditions are not met"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * VM1->IntNet [label="pkt0"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Lock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>NetFlt [label="pkt0 to wire"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet<<NetFlt [label="pkt0 to wire (dropped)"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
91fdb167bd5c9417d9507c1317ae121864fdc9cbvboxsync * --- [label="Rediscovery conditions"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM1->IntNet [label="pkt1"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Lock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Route packet -> wire"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>IntNet [label="Unlock Network"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * IntNet=>NetFlt [label="pkt1 to wire"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Read pIf(==NULL) w/ spinlock"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="fRediscoveryPending=true w/ spinlock"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="ifnet_find_by_name"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="ifnet_find_by_name (success)"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * VM2->IntNet [label="pkt2", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Lock Network", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Route packet -> wire", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>IntNet [label="Unlock Network", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet=>NetFlt [label="pkt2 to wire", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="!pIf || fRediscoveryPending (w/ spinlock)", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<<NetFlt [label="pkt2 to wire (dropped)", linecolor="red", textcolor="red"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>Kernel [label="iflt_attach"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="iflt_attach (success)"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Acquire spinlock"];
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>NetFlt [label="Set pIf and update flags"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt=>NetFlt [label="Release spinlock"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * NetFlt=>Kernel [label="pkt1 to wire"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Kernel->Wire [label="pkt1 to wire"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * NetFlt<<Kernel [label="pkt1 to wire"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * IntNet<<NetFlt [label="pkt1 to wire"];
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * @endmsc
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/*******************************************************************************
b2640405e06105d868b5fc8f7b676bb680884380vboxsync* Header Files *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync*******************************************************************************/
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync#include "VBoxNetFltInternal.h"
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync#include <VBox/sup.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/log.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <VBox/err.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <iprt/assert.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <iprt/mem.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <iprt/string.h>
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync#include <iprt/spinlock.h>
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync#include <iprt/semaphore.h>
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#include <iprt/time.h>
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync#include <iprt/uuid.h>
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync/*******************************************************************************
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync* Defined Constants And Macros *
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync*******************************************************************************/
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#define IFPORT_2_VBOXNETFLTINS(pIfPort) \
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync ( (PVBOXNETFLTINS)((uint8_t *)pIfPort - RT_OFFSETOF(VBOXNETFLTINS, MyPort)) )
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync/**
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * Finds a instance by its name, the caller does the locking.
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync *
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * @param pGlobals The globals.
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * @param pszName The name of the instance.
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync */
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsyncstatic PVBOXNETFLTINS vboxNetFltFindInstanceLocked(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync{
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync PVBOXNETFLTINS pCur;
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync if (!strcmp(pszName, pCur->szName))
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync return pCur;
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync return NULL;
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync}
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync/**
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync * Finds a instance by its name, will request the mutex.
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns Pointer to the instance by the given name. NULL if not found.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @param pGlobals The globals.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pszName The name of the instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsyncDECLHIDDEN(PVBOXNETFLTINS) vboxNetFltFindInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName)
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync{
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync PVBOXNETFLTINS pRet;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertRCReturn(rc, NULL);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
04ae74690b2f07a5cb3490babe3fd5e0cbdda226vboxsync pRet = vboxNetFltFindInstanceLocked(pGlobals, pszName);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemFastMutexRelease(pGlobals->hFastMtx);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertRC(rc);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync return pRet;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Unlinks an instance from the chain.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync *
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param pGlobals The globals.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param pToUnlink The instance to unlink.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncstatic void vboxNetFltUnlinkLocked(PVBOXNETFLTGLOBALS pGlobals, PVBOXNETFLTINS pToUnlink)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if (pGlobals->pInstanceHead == pToUnlink)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync pGlobals->pInstanceHead = pToUnlink->pNext;
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync else
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync {
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync PVBOXNETFLTINS pCur;
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync for (pCur = pGlobals->pInstanceHead; pCur; pCur = pCur->pNext)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if (pCur->pNext == pToUnlink)
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync {
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync pCur->pNext = pToUnlink->pNext;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync break;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync }
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync Assert(pCur);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync }
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync pToUnlink->pNext = NULL;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncAssertCompileMemberSize(VBOXNETFLTINS, enmState, sizeof(uint32_t));
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Sets the enmState member atomically.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync *
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync * Used for all updates.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync *
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param pThis The instance.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param enmNewState The new value.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncDECLINLINE(void) vboxNetFltSetState(PVBOXNETFLTINS pThis, VBOXNETFTLINSSTATE enmNewState)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, enmNewState);
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Gets the enmState member atomically.
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync *
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsync * Used for all reads.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync *
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @returns The enmState value.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param pThis The instance.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
0c6fd0fa9727d13b7ba687dd94169ce829723522vboxsyncDECLINLINE(VBOXNETFTLINSSTATE) vboxNetFltGetState(PVBOXNETFLTINS pThis)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync return (VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Performs interface rediscovery if it was disconnected from the host.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync *
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @returns true if successfully rediscovered and connected, false if not.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @param pThis The instance.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncstatic bool vboxNetFltMaybeRediscovered(PVBOXNETFLTINS pThis)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync uint64_t Now = RTTimeNanoTS();
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync bool fRediscovered;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync bool fDoIt;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync /*
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Rediscovered already? Time to try again?
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync fRediscovered = !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync fDoIt = !fRediscovered
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync && !ASMAtomicUoReadBool(&pThis->fRediscoveryPending)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync && Now - ASMAtomicUoReadU64(&pThis->NanoTSLastRediscovery) > UINT64_C(5000000000); /* 5 sec */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if (fDoIt)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync ASMAtomicWriteBool(&pThis->fRediscoveryPending, true);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync RTSpinlockRelease(pThis->hSpinlock, &Tmp);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync /*
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Call the OS specific code to do the job.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Update the state when the call returns, that is everything except for
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * the fDisconnectedFromHost flag which the OS specific code shall set.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if (fDoIt)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync {
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync fRediscovered = vboxNetFltOsMaybeRediscovered(pThis);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync Assert(!fRediscovered || !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost));
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync ASMAtomicUoWriteU64(&pThis->NanoTSLastRediscovery, RTTimeNanoTS());
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync ASMAtomicWriteBool(&pThis->fRediscoveryPending, false);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync if (fRediscovered)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync vboxNetFltPortOsSetActive(pThis, pThis->fActive);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync }
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync return fRediscovered;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync#ifdef RT_WITH_W64_UNWIND_HACK
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# define NETFLT_DECL_CALLBACK(type) DECLASM(DECLHIDDEN(type))
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# define NETFLT_CALLBACK(_n) netfltNtWrap##_n
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortXmit)(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous)(PINTNETTRUNKIFPORT pIfPort);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortGetMacAddress)(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortIsHostMac)(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(int) NETFLT_CALLBACK(vboxNetFltPortWaitForIdle)(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies);
8ad79874169cc981a694a15e8a806b9a39133673vboxsyncNETFLT_DECL_CALLBACK(bool) NETFLT_CALLBACK(vboxNetFltPortSetActive)(PINTNETTRUNKIFPORT pIfPort, bool fActive);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease)(PINTNETTRUNKIFPORT pIfPort);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRetain)(PINTNETTRUNKIFPORT pIfPort);
8ad79874169cc981a694a15e8a806b9a39133673vboxsyncNETFLT_DECL_CALLBACK(void) NETFLT_CALLBACK(vboxNetFltPortRelease)(PINTNETTRUNKIFPORT pIfPort);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# else
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# error "UNSUPPORTED (RT_WITH_W64_UNWIND_HACK)"
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync# endif
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync#else
8ad79874169cc981a694a15e8a806b9a39133673vboxsync# define NETFLT_DECL_CALLBACK(type) static DECLCALLBACK(type)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync# define NETFLT_CALLBACK(_n) _n
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync#endif
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync/**
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @copydoc INTNETTRUNKIFPORT::pfnXmit
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(int) vboxNetFltPortXmit(PINTNETTRUNKIFPORT pIfPort, PINTNETSG pSG, uint32_t fDst)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync int rc = VINF_SUCCESS;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync /*
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Input validation.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertPtr(pThis);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync AssertPtr(pSG);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync Assert(pThis->fActive);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync /*
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Do a busy retain and then make sure we're connected to the interface
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * before invoking the OS specific code.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync vboxNetFltRetain(pThis, true /* fBusy */);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync if ( !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost)
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync || vboxNetFltMaybeRediscovered(pThis))
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync rc = vboxNetFltPortOsXmit(pThis, pSG, fDst);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync vboxNetFltRelease(pThis, true /* fBusy */);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync return rc;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @copydoc INTNETTRUNKIFPORT::pfnIsPromiscuous
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsPromiscuous(PINTNETTRUNKIFPORT pIfPort)
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync /*
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * Input validation.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertPtr(pThis);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync Assert(pThis->fActive);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync /*
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * Ask the OS specific code.
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync return vboxNetFltPortOsIsPromiscuous(pThis);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync}
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * @copydoc INTNETTRUNKIFPORT::pfnGetMacAddress
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortGetMacAddress(PINTNETTRUNKIFPORT pIfPort, PRTMAC pMac)
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync /*
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * Input validation.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync AssertPtr(pThis);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->fActive);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync /*
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync * Forward the question to the OS specific code.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync vboxNetFltPortOsGetMacAddress(pThis, pMac);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync}
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync/**
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @copydoc INTNETTRUNKIFPORT::pfnIsHostMac
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortIsHostMac(PINTNETTRUNKIFPORT pIfPort, PCRTMAC pMac)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync /*
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync * Input validation.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync AssertPtr(pThis);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->fActive);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync /*
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Ask the OS specific code.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync return vboxNetFltPortOsIsHostMac(pThis, pMac);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync}
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync/**
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsyncNETFLT_DECL_CALLBACK(int) vboxNetFltPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync{
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync int rc;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync /*
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync * Input validation.
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertPtr(pThis);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, VERR_INVALID_STATE);
4b79f1e3db952307a2b19933efb97ccb871157cfvboxsync AssertReturn(!pThis->fActive, VERR_INVALID_STATE);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync /*
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * Go to sleep on the semaphore after checking the busy count.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync */
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync vboxNetFltRetain(pThis, false /* fBusy */);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync rc = VINF_SUCCESS;
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync while (pThis->cBusy && RT_SUCCESS(rc))
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync rc = RTSemEventWait(pThis->hEventIdle, cMillies); /** @todo make interruptible? */
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync vboxNetFltRelease(pThis, false /* fBusy */);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync return rc;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync}
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync/**
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync * @copydoc INTNETTRUNKIFPORT::pfnSetActive
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsyncNETFLT_DECL_CALLBACK(bool) vboxNetFltPortSetActive(PINTNETTRUNKIFPORT pIfPort, bool fActive)
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync{
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
92de700c41f3803fd020736400a84b4105590eb6vboxsync /*
92de700c41f3803fd020736400a84b4105590eb6vboxsync * Input validation.
92de700c41f3803fd020736400a84b4105590eb6vboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync AssertPtr(pThis);
3a828bb90d1afb1dc3184bd90192750a87562d2dvboxsync AssertPtr(pThis->pGlobals);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync AssertReturn(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected, false);
3a828bb90d1afb1dc3184bd90192750a87562d2dvboxsync
92de700c41f3803fd020736400a84b4105590eb6vboxsync /*
92de700c41f3803fd020736400a84b4105590eb6vboxsync * We're assuming that the caller is serializing the calls, so we don't
92de700c41f3803fd020736400a84b4105590eb6vboxsync * have to be extremely careful here. Just update first and then call
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * the OS specific code, the update must be serialized for various reasons.
92de700c41f3803fd020736400a84b4105590eb6vboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync if (ASMAtomicReadBool(&pThis->fActive) != fActive)
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync {
92de700c41f3803fd020736400a84b4105590eb6vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
92de700c41f3803fd020736400a84b4105590eb6vboxsync RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync ASMAtomicWriteBool(&pThis->fActive, fActive);
92de700c41f3803fd020736400a84b4105590eb6vboxsync RTSpinlockRelease(pThis->hSpinlock, &Tmp);
92de700c41f3803fd020736400a84b4105590eb6vboxsync
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync vboxNetFltPortOsSetActive(pThis, fActive);
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync }
eb4f1fa4c357485330370c0eaba27e5a2af7d9c4vboxsync else
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync fActive = !fActive;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync return !fActive;
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync}
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync/**
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Serious paranoia.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertPtr(pThis);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync AssertPtr(pThis->pGlobals);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->szName[0]);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Connected);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->fActive);
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync Assert(!pThis->fRediscoveryPending);
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync Assert(!pThis->cBusy);
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Disconnect and release it.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync */
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Disconnecting);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync RTSpinlockRelease(pThis->hSpinlock, &Tmp);
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltOsDisconnectIt(pThis);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync pThis->pSwitchPort = NULL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Unconnected);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSpinlockRelease(pThis->hSpinlock, &Tmp);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltRelease(pThis, false /* fBusy */);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * Destroy a device that has been disconnected from the switch.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @return true iff the instance is destroyed, false otherwise
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @param pThis The instance to be destroyed. This is
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * no longer valid when this function returns.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsyncstatic bool vboxNetFltCheckDestroyInstance(PVBOXNETFLTINS pThis)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync PVBOXNETFLTGLOBALS pGlobals = pThis->pGlobals;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync int rc;
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync uint32_t cRefs = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cRefs);
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync LogFlow(("vboxNetFltCheckDestroyInstance: pThis=%p (%s)\n", pThis, pThis->szName));
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync /*
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync * Validate the state.
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync */
0c802efc285bf77b849eaf660a9c18a0e7f62445vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
8ad79874169cc981a694a15e8a806b9a39133673vboxsync Assert( vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Disconnecting
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync || vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Unconnected);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Disconnecting);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->fActive);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->fRediscoveryPending);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->cRefs);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync Assert(!pThis->cBusy);
ce95f18112057771f68abe58df709edd7c467db1vboxsync Assert(!pThis->pSwitchPort);
ce95f18112057771f68abe58df709edd7c467db1vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Make sure the state is 'disconnecting' and let the OS specific code
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * do its part of the cleanup outside the mutex.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx); AssertRC(rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if(cRefs != 0)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(cRefs < UINT32_MAX / 2);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return false;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Destroying);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltOsDeleteInstance(pThis);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Unlink the instance and free up its resources.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx); AssertRC(rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Destroyed);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltUnlinkLocked(pGlobals, pThis);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemEventDestroy(pThis->hEventIdle);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pThis->hEventIdle = NIL_RTSEMEVENT;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync RTSpinlockDestroy(pThis->hSpinlock);
083344b49cc7370da15d3cb7e3a9c9cb2d8dfbb0vboxsync pThis->hSpinlock = NIL_RTSPINLOCK;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTMemFree(pThis);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return true;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Releases a reference to the specified instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This method will destroy the instance when the count reaches 0.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * It will also take care of decrementing the counter and idle wakeup.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @param pThis The instance.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @param fBusy Whether the busy counter should be decremented too.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncDECLHIDDEN(void) vboxNetFltRelease(PVBOXNETFLTINS pThis, bool fBusy)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync uint32_t cRefs;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Paranoid Android.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertPtr(pThis);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertPtr(pThis->pGlobals);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->szName[0]);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Work the busy counter.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (fBusy)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync cRefs = ASMAtomicDecU32(&pThis->cBusy);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!cRefs)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = RTSemEventSignal(pThis->hEventIdle);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertRC(rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync else
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(cRefs < UINT32_MAX / 2);
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync }
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * The object reference counting.
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync */
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync cRefs = ASMAtomicDecU32(&pThis->cRefs);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!cRefs)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltCheckDestroyInstance(pThis);
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync else
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync Assert(cRefs < UINT32_MAX / 2);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @copydoc INTNETTRUNKIFPORT::pfnRetain
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortRelease(PINTNETTRUNKIFPORT pIfPort)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync vboxNetFltRelease(pThis, false /* fBusy */);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Retains a reference to the specified instance and a busy reference too.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pThis The instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param fBusy Whether the busy counter should be incremented as well.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncDECLHIDDEN(void) vboxNetFltRetain(PVBOXNETFLTINS pThis, bool fBusy)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync uint32_t cRefs;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Paranoid Android.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertPtr(pThis);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert( vboxNetFltGetState(pThis) > kVBoxNetFltInsState_Invalid
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && vboxNetFltGetState(pThis) < kVBoxNetFltInsState_Destroyed);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertPtr(pThis->pGlobals);
8f5194f08a06cabef528366bdaa64a74be8adb0dvboxsync Assert(pThis->hEventIdle != NIL_RTSEMEVENT);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync Assert(pThis->hSpinlock != NIL_RTSPINLOCK);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pThis->szName[0]);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Retain the object.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync cRefs = ASMAtomicIncU32(&pThis->cRefs);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(cRefs > 1 && cRefs < UINT32_MAX / 2);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Work the busy counter.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (fBusy)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync cRefs = ASMAtomicIncU32(&pThis->cBusy);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(cRefs > 0 && cRefs < UINT32_MAX / 2);
8f5194f08a06cabef528366bdaa64a74be8adb0dvboxsync }
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync NOREF(cRefs);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @copydoc INTNETTRUNKIFPORT::pfnRetain
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncNETFLT_DECL_CALLBACK(void) vboxNetFltPortRetain(PINTNETTRUNKIFPORT pIfPort)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXNETFLTINS pThis = IFPORT_2_VBOXNETFLTINS(pIfPort);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltRetain(pThis, false /* fBusy */);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Connects the instance to the specified switch port.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Called while owning the lock. We're ASSUMING that the internal
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * networking code is already owning an recursive mutex, so, there
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * will be no deadlocks when vboxNetFltOsConnectIt calls back into
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * it for setting preferences.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns VBox status code.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pThis The instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pSwitchPort The port on the internal network 'switch'.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @param ppIfPort Where to return our port interface.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic int vboxNetFltConnectIt(PVBOXNETFLTINS pThis, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Validate state.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->fActive);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->fRediscoveryPending);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(!pThis->cBusy);
4f01a090c00f35e11528b7fa7bcdf629399af9e9vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
4f01a090c00f35e11528b7fa7bcdf629399af9e9vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Unconnected);
e1d63281b1a65b419caf27e7b0712b2594b0c938vboxsync#else
e1d63281b1a65b419caf27e7b0712b2594b0c938vboxsync Assert(vboxNetFltGetState(pThis) == kVBoxNetFltInsState_Initializing);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Do the job.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Note that we're calling the os stuff while owning the semaphore here.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pThis->pSwitchPort = pSwitchPort;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxNetFltOsConnectIt(pThis);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
8ad79874169cc981a694a15e8a806b9a39133673vboxsync vboxNetFltSetState(pThis, kVBoxNetFltInsState_Connected);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *ppIfPort = &pThis->MyPort;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync }
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync else
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync pThis->pSwitchPort = NULL;
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync Assert(!pThis->fActive);
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync return rc;
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync}
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync/**
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * Creates a new instance.
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync *
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * The new instance will be in the suspended state in a dynamic config and in
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * the inactive in a static one.
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync *
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * Called without owning the lock, but will request is several times.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync *
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * @returns VBox status code.
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * @param pGlobals The globals.
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * @param pszName The instance name.
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync * @param pSwitchPort The port on the switch that we're connected with (dynamic only).
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync * @param ppIfPort Where to store the pointer to our port interface (dynamic only).
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync * @param fNoPromisc Do not attempt going into promiscuous mode.
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync */
147b6ddff14ec450da8593696cf60c4258d61613vboxsyncstatic int vboxNetFltNewInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName, PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort, bool fNoPromisc
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync , void * pContext
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync#endif
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync )
2906c2554adf12dac04c4bdd7e44ec9f960f0390vboxsync{
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync /*
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync * Allocate and initialize a new instance before requesting the mutex.
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync */
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync int rc;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync size_t const cchName = strlen(pszName);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync PVBOXNETFLTINS pNew = (PVBOXNETFLTINS)RTMemAllocZ(RT_OFFSETOF(VBOXNETFLTINS, szName[cchName + 1]));
2906c2554adf12dac04c4bdd7e44ec9f960f0390vboxsync if (!pNew)
c676658a234a45bfe783320e8a13f6fd4f0425dbvboxsync return VERR_INTNET_FLT_IF_FAILED;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->pNext = NULL;
c676658a234a45bfe783320e8a13f6fd4f0425dbvboxsync pNew->MyPort.u32Version = INTNETTRUNKIFPORT_VERSION;
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pNew->MyPort.pfnRetain = NETFLT_CALLBACK(vboxNetFltPortRetain);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pNew->MyPort.pfnRelease = NETFLT_CALLBACK(vboxNetFltPortRelease);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pNew->MyPort.pfnDisconnectAndRelease= NETFLT_CALLBACK(vboxNetFltPortDisconnectAndRelease);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnSetActive = NETFLT_CALLBACK(vboxNetFltPortSetActive);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnWaitForIdle = NETFLT_CALLBACK(vboxNetFltPortWaitForIdle);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnGetMacAddress = NETFLT_CALLBACK(vboxNetFltPortGetMacAddress);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnIsHostMac = NETFLT_CALLBACK(vboxNetFltPortIsHostMac);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnIsPromiscuous = NETFLT_CALLBACK(vboxNetFltPortIsPromiscuous);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.pfnXmit = NETFLT_CALLBACK(vboxNetFltPortXmit);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->MyPort.u32VersionEnd = INTNETTRUNKIFPORT_VERSION;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->pSwitchPort = NULL;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->pGlobals = pGlobals;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->hSpinlock = NIL_RTSPINLOCK;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->enmState = kVBoxNetFltInsState_Initializing;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->fActive = false;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->fDisconnectedFromHost = false;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->fRediscoveryPending = false;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->fDisablePromiscuous = fNoPromisc;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->NanoTSLastRediscovery = INT64_MAX;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->cRefs = 1;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->cBusy = 0;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pNew->hEventIdle = NIL_RTSEMEVENT;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync memcpy(pNew->szName, pszName, cchName + 1);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync rc = RTSpinlockCreate(&pNew->hSpinlock);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemEventCreate(&pNew->hEventIdle);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxNetFltOsPreInitInstance(pNew);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
8ad79874169cc981a694a15e8a806b9a39133673vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Insert the instance into the chain, checking for
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * duplicates first of course (race).
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!vboxNetFltFindInstanceLocked(pGlobals, pszName))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pNew->pNext = pGlobals->pInstanceHead;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pGlobals->pInstanceHead = pNew;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Call the OS specific initialization code.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxNetFltOsInitInstance(pNew
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync , pContext
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
8ad79874169cc981a694a15e8a806b9a39133673vboxsync );
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRequest(pGlobals->hFastMtx);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
8ad79874169cc981a694a15e8a806b9a39133673vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync pNew->enmState = kVBoxNetFltInsState_Unconnected;
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(!pSwitchPort);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *ppIfPort = &pNew->MyPort;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Connect it as well, the OS specific bits has to be done outside
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * the lock as they may call back to into intnet.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxNetFltConnectIt(pNew, pSwitchPort, ppIfPort);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *ppIfPort = &pNew->MyPort;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* Bail out (failed). */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltOsDeleteInstance(pNew);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync vboxNetFltUnlinkLocked(pGlobals, pNew);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
8ad79874169cc981a694a15e8a806b9a39133673vboxsync else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = VERR_INTNET_FLT_IF_BUSY;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemEventDestroy(pNew->hEventIdle);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSpinlockDestroy(pNew->hSpinlock);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTMemFree(pNew);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
ce95f18112057771f68abe58df709edd7c467db1vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
ce95f18112057771f68abe58df709edd7c467db1vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
ce95f18112057771f68abe58df709edd7c467db1vboxsync * searches for the NetFlt instance by its name and creates the new one if not found
ce95f18112057771f68abe58df709edd7c467db1vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @return VINF_SUCCESS if new instance was created, VINF_ALREADY_INITIALIZED if an instanmce already exists,
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * VERR_xxx in case of a failure
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsyncDECLHIDDEN(int) vboxNetFltSearchCreateInstance(PVBOXNETFLTGLOBALS pGlobals, const char *pszName, PVBOXNETFLTINS *ppInstance, void * pContext)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PINTNETTRUNKIFPORT pIfPort;
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync int rc;
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync AssertRCReturn(rc, rc);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync
6724f34fdfee01d77d13f23d907d7b79d80e435dvboxsync *ppInstance = vboxNetFltFindInstanceLocked(pGlobals, pszName);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync if(*ppInstance)
6724f34fdfee01d77d13f23d907d7b79d80e435dvboxsync {
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync VBOXNETFTLINSSTATE enmState = vboxNetFltGetState(*ppInstance);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync if(enmState != kVBoxNetFltInsState_Destroying && enmState != kVBoxNetFltInsState_Destroyed)
6724f34fdfee01d77d13f23d907d7b79d80e435dvboxsync {
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync vboxNetFltRetain(*ppInstance, false);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync return VINF_ALREADY_INITIALIZED;
ce95f18112057771f68abe58df709edd7c467db1vboxsync }
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync /*wait for the instance to be removed from the list */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *ppInstance = NULL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync do
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
ce95f18112057771f68abe58df709edd7c467db1vboxsync
ce95f18112057771f68abe58df709edd7c467db1vboxsync RTSemEventWait(pGlobals->hTimerEvent, 2);
ce95f18112057771f68abe58df709edd7c467db1vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertRCReturn(rc, rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync } while(vboxNetFltFindInstanceLocked(pGlobals, pszName));
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync }
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync rc = vboxNetFltNewInstance(pGlobals, pszName, NULL, &pIfPort, false, pContext);
5ea88591f1ca09476c7e97c758f9c52e1dbb6626vboxsync if(RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *ppInstance = IFPORT_2_VBOXNETFLTINS(pIfPort);
ce95f18112057771f68abe58df709edd7c467db1vboxsync else
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync *ppInstance = NULL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
ce95f18112057771f68abe58df709edd7c467db1vboxsync return rc;
ce95f18112057771f68abe58df709edd7c467db1vboxsync}
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync#endif
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync/**
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @copydoc INTNETTRUNKFACTORY::pfnCreateAndConnect
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync */
8ad79874169cc981a694a15e8a806b9a39133673vboxsyncstatic DECLCALLBACK(int) vboxNetFltFactoryCreateAndConnect(PINTNETTRUNKFACTORY pIfFactory, const char *pszName,
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT *ppIfPort, bool fNoPromisc)
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync{
6de26a0709c5a075db3c7532e7702444cd35afd6vboxsync PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, TrunkFactory));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXNETFLTINS pCur;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync LogFlow(("vboxNetFltFactoryCreateAndConnect: pszName=%p:{%s}\n", pszName, pszName));
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync Assert(pGlobals->cFactoryRefs > 0);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Static: Find instance, check if busy, connect if not.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Dynamic: Check for duplicate / busy interface instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertRCReturn(rc, rc);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync pCur = vboxNetFltFindInstanceLocked(pGlobals, pszName);
46ff7af86c9b48efa8270af373c8d5dcfa7d05c5vboxsync if (pCur)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync switch (vboxNetFltGetState(pCur))
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync {
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync case kVBoxNetFltInsState_Unconnected:
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync /* instance can be destroyed when it is neither used by the IntNet nor by the ndis filter driver mechanism
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync * (i.e. the driver is not bound to the specified adapter)*/
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync /* Prevent setting promiscuous mode for WiFi adapters. */
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync pCur->fDisablePromiscuous = fNoPromisc;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync LogAleksey(("fNoPromisc=%d\n", pCur->fDisablePromiscuous));
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync vboxNetFltRetain(pCur, false /* fBusy */); /** @todo who releases this on failure? */
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = vboxNetFltConnectIt(pCur, pSwitchPort, ppIfPort);
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync break;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync case kVBoxNetFltInsState_Connected:
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertFailed();
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = VERR_INTNET_FLT_IF_BUSY;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync break;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync case kVBoxNetFltInsState_Disconnecting:
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync AssertFailed();
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = VERR_INTNET_FLT_IF_BUSY;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync break;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync default:
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync /** @todo what? */
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = VERR_INTNET_FLT_IF_BUSY;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync break;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync }
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync#else
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = VERR_INTNET_FLT_IF_BUSY;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync#endif
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync LogFlow(("vboxNetFltFactoryCreateAndConnect: returns %Rrc\n", rc));
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync return rc;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync }
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync rc = VERR_INTNET_FLT_IF_NOT_FOUND;
7796e8b1dcbbe95e91b6f56842324ef07d99f977vboxsync#else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Dynamically create a new instance.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = vboxNetFltNewInstance(pGlobals, pszName, pSwitchPort, ppIfPort, fNoPromisc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync LogFlow(("vboxNetFltFactoryCreateAndConnect: returns %Rrc\n", rc));
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @copydoc INTNETTRUNKFACTORY::pfnRelease
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic DECLCALLBACK(void) vboxNetFltFactoryRelease(PINTNETTRUNKFACTORY pIfFactory)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, TrunkFactory));
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int32_t cRefs = ASMAtomicDecS32(&pGlobals->cFactoryRefs);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(cRefs >= 0); NOREF(cRefs);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync LogFlow(("vboxNetFltFactoryRelease: cRefs=%d (new)\n", cRefs));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Implements the SUPDRV component factor interface query method.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns Pointer to an interface. NULL if not supported.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync *
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * @param pSupDrvFactory Pointer to the componet factory registration structure.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * @param pSession The session - unused.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * @param pszInterfaceUuid The factory interface id.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncstatic DECLCALLBACK(void *) vboxNetFltQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid)
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync{
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync PVBOXNETFLTGLOBALS pGlobals = (PVBOXNETFLTGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXNETFLTGLOBALS, SupDrvFactory));
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Convert the UUID strings and compare them.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTUUID UuidReq;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
8ad79874169cc981a694a15e8a806b9a39133673vboxsync if (!RTUuidCompareStr(&UuidReq, INTNETTRUNKFACTORY_UUID_STR))
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync {
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync ASMAtomicIncS32(&pGlobals->cFactoryRefs);
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync return &pGlobals->TrunkFactory;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef LOG_ENABLED
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* log legacy queries */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* else if (!RTUuidCompareStr(&UuidReq, INTNETTRUNKFACTORY_V1_UUID_STR))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxNetFlt: V1 factory query\n"));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxNetFlt: unknown factory interface query (%s)\n", pszInterfaceUuid));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
8ad79874169cc981a694a15e8a806b9a39133673vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync else
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Log(("VBoxNetFlt: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return NULL;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Checks whether the VBoxNetFlt wossname can be unloaded.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This will return false if someone is currently using the module.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns true if it's relatively safe to unload it, otherwise false.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @param pGlobals Pointer to the globals.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncDECLHIDDEN(bool) vboxNetFltCanUnload(PVBOXNETFLTGLOBALS pGlobals)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync bool fRc = !pGlobals->pInstanceHead
b2640405e06105d868b5fc8f7b676bb680884380vboxsync && pGlobals->cFactoryRefs <= 0;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexRelease(pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertRC(rc);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync return fRc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * tries to deinitialize Idc
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * we separate the globals settings "base" which is actually
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * "general" globals settings except for Idc, and idc.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * thus it's not possible to make idc initialization from the driver startup routine for it,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * though the "base is still needed for the driver to functions".
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pGlobals
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * @return VINF_SUCCESS on succes, VERR_WRONG_ORDER if we're busy.
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncDECLHIDDEN(int) vboxNetFltTryDeleteIdc(PVBOXNETFLTGLOBALS pGlobals)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * Check before trying to deregister the factory.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!vboxNetFltCanUnload(pGlobals))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return VERR_WRONG_ORDER;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Disconnect from SUPDRV and check that nobody raced us,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * reconnect if that should happen.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync AssertRC(rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (!vboxNetFltCanUnload(pGlobals))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync AssertRC(rc);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return VERR_WRONG_ORDER;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync SUPR0IdcClose(&pGlobals->SupDrvIDC);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * performs "base" globals deinitialization
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * we separate the globals settings "base" which is actually
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync * "general" globals settings except for Idc, and idc.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * thus it's not possible to make idc initialization from the driver startup routine for it,
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * though the "base is still needed for the driver to functions".
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @param pGlobals
ce95f18112057771f68abe58df709edd7c467db1vboxsync * @return none
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync */
ce95f18112057771f68abe58df709edd7c467db1vboxsyncDECLHIDDEN(void) vboxNetFltDeleteGlobalsBase(PVBOXNETFLTGLOBALS pGlobals)
ce95f18112057771f68abe58df709edd7c467db1vboxsync{
ce95f18112057771f68abe58df709edd7c467db1vboxsync /*
ce95f18112057771f68abe58df709edd7c467db1vboxsync * Release resources.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync */
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync RTSemFastMutexDestroy(pGlobals->hFastMtx);
ce95f18112057771f68abe58df709edd7c467db1vboxsync pGlobals->hFastMtx = NIL_RTSEMFASTMUTEX;
ce95f18112057771f68abe58df709edd7c467db1vboxsync
ce95f18112057771f68abe58df709edd7c467db1vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync RTSemEventDestroy(pGlobals->hTimerEvent);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync pGlobals->hTimerEvent = NIL_RTSEMEVENT;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#endif
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Called by the native part when the OS wants the driver to unload.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns VINF_SUCCESS on succes, VERR_WRONG_ORDER if we're busy.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @param pGlobals Pointer to the globals.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsyncDECLHIDDEN(int) vboxNetFltTryDeleteGlobals(PVBOXNETFLTGLOBALS pGlobals)
8ad79874169cc981a694a15e8a806b9a39133673vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = vboxNetFltTryDeleteIdc(pGlobals);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if(RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync vboxNetFltDeleteGlobalsBase(pGlobals);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * performs the "base" globals initialization
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * we separate the globals initialization to globals "base" initialization which is actually
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * "general" globals initialization except for Idc not being initialized, and idc initialization.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * thus it's not possible to make idc initialization from the driver startup routine for it.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync *
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * @returns VBox status code.
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync * @param pGlobals Pointer to the globals. */
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsyncDECLHIDDEN(int) vboxNetFltInitGlobalsBase(PVBOXNETFLTGLOBALS pGlobals)
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync{
eafe2940026f325feeaa433c9ea44823431ec5ffvboxsync /*
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * Initialize the common portions of the structure.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync */
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc = RTSemFastMutexCreate(&pGlobals->hFastMtx);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
b2640405e06105d868b5fc8f7b676bb680884380vboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync rc = RTSemEventCreate(&pGlobals->hTimerEvent);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
ce95f18112057771f68abe58df709edd7c467db1vboxsync {
ce95f18112057771f68abe58df709edd7c467db1vboxsync#endif
ce95f18112057771f68abe58df709edd7c467db1vboxsync pGlobals->pInstanceHead = NULL;
ce95f18112057771f68abe58df709edd7c467db1vboxsync
ce95f18112057771f68abe58df709edd7c467db1vboxsync pGlobals->TrunkFactory.pfnRelease = vboxNetFltFactoryRelease;
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pGlobals->TrunkFactory.pfnCreateAndConnect = vboxNetFltFactoryCreateAndConnect;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync strcpy(pGlobals->SupDrvFactory.szName, "VBoxNetFlt");
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync pGlobals->SupDrvFactory.pfnQueryFactoryInterface = vboxNetFltQueryFactoryInterface;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync return rc;
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync#ifdef VBOXNETFLT_STATIC_CONFIG
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync RTSemFastMutexDestroy(pGlobals->hFastMtx);
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync#endif
cf2d13234ccc8755e2610badbdab5dc0b7bfb1dcvboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
b2640405e06105d868b5fc8f7b676bb680884380vboxsync}
8ad79874169cc981a694a15e8a806b9a39133673vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync/**
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync * performs the Idc initialization
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * we separate the globals initialization to globals "base" initialization which is actually
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * "general" globals initialization except for Idc not being initialized, and idc initialization.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync * thus it's not possible to make idc initialization from the driver startup routine for it.
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync *
b2640405e06105d868b5fc8f7b676bb680884380vboxsync * @returns VBox status code.
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * @param pGlobals Pointer to the globals. */
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsyncDECLHIDDEN(int) vboxNetFltInitIdc(PVBOXNETFLTGLOBALS pGlobals)
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync{
b2640405e06105d868b5fc8f7b676bb680884380vboxsync int rc;
8ad79874169cc981a694a15e8a806b9a39133673vboxsync /*
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync * Establish a connection to SUPDRV and register our component factory.
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync */
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync if (RT_SUCCESS(rc))
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync {
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync if (RT_SUCCESS(rc))
8ad79874169cc981a694a15e8a806b9a39133673vboxsync {
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync Log(("VBoxNetFlt: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync return rc;
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync }
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync /* bail out. */
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync LogRel(("VBoxNetFlt: Failed to register component factory, rc=%Rrc\n", rc));
b2640405e06105d868b5fc8f7b676bb680884380vboxsync SUPR0IdcClose(&pGlobals->SupDrvIDC);
8ad79874169cc981a694a15e8a806b9a39133673vboxsync }
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync return rc;
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync}
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync/**
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync * Called by the native driver/kext module initialization routine.
b2640405e06105d868b5fc8f7b676bb680884380vboxsync *
8ad79874169cc981a694a15e8a806b9a39133673vboxsync * It will initialize the common parts of the globals, assuming the caller
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync * has already taken care of the OS specific bits.
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync *
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync * @returns VBox status code.
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync * @param pGlobals Pointer to the globals.
b394f699c1a81998b6216e59bac82704a937e4f5vboxsync */
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsyncDECLHIDDEN(int) vboxNetFltInitGlobals(PVBOXNETFLTGLOBALS pGlobals)
b2640405e06105d868b5fc8f7b676bb680884380vboxsync{
8ad79874169cc981a694a15e8a806b9a39133673vboxsync /*
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync * Initialize the common portions of the structure.
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync */
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync int rc = vboxNetFltInitGlobalsBase(pGlobals);
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync if (RT_SUCCESS(rc))
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync {
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync rc = vboxNetFltInitIdc(pGlobals);
b4a81d521ea7f88aca6f77b2725541e58a2dc018vboxsync if (RT_SUCCESS(rc))
b2640405e06105d868b5fc8f7b676bb680884380vboxsync {
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync return rc;
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync /* bail out. */
5b9474ab4fc24402eb9e352fb2845b036f0736b6vboxsync vboxNetFltDeleteGlobalsBase(pGlobals);
b2640405e06105d868b5fc8f7b676bb680884380vboxsync }
b2640405e06105d868b5fc8f7b676bb680884380vboxsync
b2640405e06105d868b5fc8f7b676bb680884380vboxsync return rc;
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync}
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync
5a9cd9ff1147e9845e0d3fc020973df2d3e66daavboxsync