diff --git a/repos/ports/lib/mk/spec/x86_64/virtualbox6-devices.mk b/repos/ports/lib/mk/spec/x86_64/virtualbox6-devices.mk index 88b189a833..ca52f34ca9 100644 --- a/repos/ports/lib/mk/spec/x86_64/virtualbox6-devices.mk +++ b/repos/ports/lib/mk/spec/x86_64/virtualbox6-devices.mk @@ -41,7 +41,6 @@ SRC_CC += Devices/Network/DevEEPROM.cpp SRC_CC += Devices/Network/DevPCNet.cpp SRC_CC += Devices/Network/DrvNetShaper.cpp SRC_CC += Devices/Network/DrvNetSniffer.cpp -SRC_CC += Devices/Network/DrvTAP.cpp SRC_CC += Devices/Network/Pcap.cpp SRC_CC += Devices/Parallel/DevParallel.cpp SRC_CC += Devices/PC/ACPI/VBoxAcpi.cpp diff --git a/repos/ports/ports/virtualbox6.hash b/repos/ports/ports/virtualbox6.hash index 69f0a04f07..e1f92e75e6 100644 --- a/repos/ports/ports/virtualbox6.hash +++ b/repos/ports/ports/virtualbox6.hash @@ -1 +1 @@ -c9f6708c2753758e31b59eb38dc1abcca821a913 +53f753241f3d5253338f284aa833d7db04469026 diff --git a/repos/ports/src/virtualbox6/init.h b/repos/ports/src/virtualbox6/init.h index 920b7c2ef0..71eece96b9 100644 --- a/repos/ports/src/virtualbox6/init.h +++ b/repos/ports/src/virtualbox6/init.h @@ -19,4 +19,6 @@ namespace Genode { struct Env; } namespace Sup { void init(Genode::Env &); } +namespace Network { void init(Genode::Env &); } + #endif /* _INIT_H_ */ diff --git a/repos/ports/src/virtualbox6/main.cc b/repos/ports/src/virtualbox6/main.cc index 6902b03e1c..1c49d5c2b3 100644 --- a/repos/ports/src/virtualbox6/main.cc +++ b/repos/ports/src/virtualbox6/main.cc @@ -338,6 +338,8 @@ void Libc::Component::construct(Libc::Env &env) environ = envp; + Network::init(env); + /* sidestep 'rtThreadPosixSelectPokeSignal' */ uint32_t const fFlags = RTR3INIT_FLAGS_UNOBTRUSIVE; diff --git a/repos/ports/src/virtualbox6/network.cc b/repos/ports/src/virtualbox6/network.cc new file mode 100644 index 0000000000..cb49234e91 --- /dev/null +++ b/repos/ports/src/virtualbox6/network.cc @@ -0,0 +1,605 @@ +/** + * Genode network session driver, + * derived from src/VBox/Devices/Network/DrvTAP.cpp. + */ + +/* + * Copyright (C) 2014-2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* + * Copyright (C) 2006-2012 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#define LOG_GROUP LOG_GROUP_DRV_TUN +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "VBoxDD.h" + +#include +#include + +#include + +/* VBox Genode specific */ +#include +#include +#include "init.h" + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ + +struct Nic_client; + +/** + * Nic driver instance data. + * + * @implements PDMINETWORKUP + */ +typedef struct DRVNIC +{ + /** The network interface to Nic session. */ + PDMINETWORKUP INetworkUp; + /** The config port interface we're representing. */ + PDMINETWORKCONFIG INetworkConfig; + /** The network interface to VBox driver. */ + PPDMINETWORKDOWN pIAboveNet; + /** The config port interface we're attached to. */ + PPDMINETWORKCONFIG pIAboveConfig; + /** Pointer to the driver instance. */ + PPDMDRVINS pDrvIns; + /** Receiver thread that handles all signals. */ + PPDMTHREAD pThread; + /** Nic::Session client wrapper. */ + Nic_client *nic_client; +} DRVNIC, *PDRVNIC; + + +/** + * Return lock to synchronize the destruction of the + * PDRVNIC, i.e., the Nic_client. + */ +static Genode::Blockade &destruct_blockade() +{ + static Genode::Blockade blockade { }; + return blockade; +} + + +static Genode::Allocator & net_alloc() +{ + static Libc::Allocator alloc { }; + return alloc; +} + +static Genode::Env *env_ptr = nullptr; + +void Network::init(Genode::Env &env) +{ + env_ptr = &env; +} + +class Nic_client +{ + private: + + enum { + PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE, + BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE, + }; + + Nic::Packet_allocator *_tx_block_alloc; + Nic::Connection _nic; + + enum { NIC_EP_STACK = 32u << 10, }; + Genode::Entrypoint _ep; + pthread_t _pthread; + + Genode::Signal_handler _link_state_dispatcher; + Genode::Signal_handler _rx_packet_avail_dispatcher; + Genode::Signal_handler _rx_ready_to_ack_dispatcher; + Genode::Signal_handler _destruct_dispatcher; + + bool _link_up = false; + + /* VM <-> device driver (down) <-> nic_client (up) <-> nic session */ + PPDMINETWORKDOWN _down_rx; + PPDMINETWORKCONFIG _down_rx_config; + + void _handle_rx_packet_avail() + { + while (_nic.rx()->packet_avail() && _nic.rx()->ready_to_ack()) { + Nic::Packet_descriptor rx_packet = _nic.rx()->get_packet(); + + char *rx_content = _nic.rx()->packet_content(rx_packet); + + Libc::with_libc([&] () { + int rc = _down_rx->pfnWaitReceiveAvail(_down_rx, RT_INDEFINITE_WAIT); + if (RT_FAILURE(rc)) return; + + rc = _down_rx->pfnReceive(_down_rx, rx_content, rx_packet.size()); + AssertRC(rc); + }); + + _nic.rx()->acknowledge_packet(rx_packet); + } + } + + void _handle_rx_ready_to_ack() { _handle_rx_packet_avail(); } + + void _handle_link_state() + { + _link_up = _nic.link_state(); + + Libc::with_libc([&] () { + _down_rx_config->pfnSetLinkState(_down_rx_config, + _link_up ? PDMNETWORKLINKSTATE_UP + : PDMNETWORKLINKSTATE_DOWN); + }); + } + + void _handle_destruct() + { + _nic.link_state_sigh(Genode::Signal_context_capability()); + _nic.rx_channel()->sigh_packet_avail(Genode::Signal_context_capability()); + _nic.rx_channel()->sigh_ready_to_ack(Genode::Signal_context_capability()); + + destruct_blockade().wakeup(); + } + + void _tx_ack(bool block = false) + { + /* check for acknowledgements */ + while (_nic.tx()->ack_avail() || block) { + Nic::Packet_descriptor acked_packet = _nic.tx()->get_acked_packet(); + _nic.tx()->release_packet(acked_packet); + block = false; + } + } + + Nic::Packet_descriptor _alloc_tx_packet(Genode::size_t len) + { + while (true) { + try { + Nic::Packet_descriptor packet = _nic.tx()->alloc_packet(len); + return packet; + } catch (Nic::Session::Tx::Source::Packet_alloc_failed) { + _tx_ack(true); + } + } + } + + static Nic::Packet_allocator* _packet_allocator() + { + return new (net_alloc()) Nic::Packet_allocator(&net_alloc()); + } + + void _handle_pthread_registration() + { + Genode::Thread *myself = Genode::Thread::myself(); + if (!myself || Libc::pthread_create(&_pthread, *myself, &myself)) { + Genode::error("network will not work - thread for pthread " + "registration invalid"); + return; + } + } + + Genode::Signal_handler _pthread_reg_sigh { + _ep, *this, &Nic_client::_handle_pthread_registration }; + + public: + + Nic_client(Genode::Env &env, PDRVNIC drvtap, char const *label) + : + _tx_block_alloc(_packet_allocator()), + _nic(env, _tx_block_alloc, BUF_SIZE, BUF_SIZE, label), + _ep(env, NIC_EP_STACK, "nic_ep", Genode::Affinity::Location()), + _link_state_dispatcher(_ep, *this, &Nic_client::_handle_link_state), + _rx_packet_avail_dispatcher(_ep, *this, &Nic_client::_handle_rx_packet_avail), + _rx_ready_to_ack_dispatcher(_ep, *this, &Nic_client::_handle_rx_ready_to_ack), + _destruct_dispatcher(_ep, *this, &Nic_client::_handle_destruct), + _down_rx(drvtap->pIAboveNet), + _down_rx_config(drvtap->pIAboveConfig) + { + Genode::Signal_transmitter(_pthread_reg_sigh).submit(); + } + + ~Nic_client() + { + /* XXX Libc::pthread_free(&_pthread); */ + destroy(net_alloc(), _tx_block_alloc); + } + + void enable_signals() + { + _nic.link_state_sigh(_link_state_dispatcher); + _nic.rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher); + _nic.rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher); + + /* set initial link-state */ + _handle_link_state(); + } + + Genode::Signal_context_capability dispatcher() { return _destruct_dispatcher; } + Nic::Mac_address mac_address() { return _nic.mac_address(); } + + int send_packet(void *packet, uint32_t packet_len) + { + if (!_link_up) { return VERR_NET_DOWN; } + + Nic::Packet_descriptor tx_packet = _alloc_tx_packet(packet_len); + + char *tx_content = _nic.tx()->packet_content(tx_packet); + Genode::memcpy(tx_content, packet, packet_len); + + _nic.tx()->submit_packet(tx_packet); + _tx_ack(); + + return VINF_SUCCESS; + } +}; + + +/** Converts a pointer to Nic::INetworkUp to a PRDVNic. */ +#define PDMINETWORKUP_2_DRVNIC(pInterface) ( (PDRVNIC)((uintptr_t)pInterface - RT_OFFSETOF(DRVNIC, INetworkUp)) ) +#define PDMINETWORKCONFIG_2_DRVNIC(pInterface) ( (PDRVNIC)((uintptr_t)pInterface - RT_OFFSETOF(DRVNIC, INetworkConfig)) ) + + +/******************************************************************************* +* Internal Functions * +*******************************************************************************/ + +/** + * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit} + */ +static DECLCALLBACK(int) drvNicNetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread) +{ + return VINF_SUCCESS; +} + + +/** + * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} + */ +static DECLCALLBACK(int) drvNicNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, + PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf) +{ +// PDRVNIC pThis = PDMINETWORKUP_2_DRVNIC(pInterface); + + /* + * Allocate a scatter / gather buffer descriptor that is immediately + * followed by the buffer space of its single segment. The GSO context + * comes after that again. + */ + PPDMSCATTERGATHER pSgBuf = (PPDMSCATTERGATHER)RTMemAlloc(RT_ALIGN_Z(sizeof(*pSgBuf), 16) + + RT_ALIGN_Z(cbMin, 16) + + (pGso ? RT_ALIGN_Z(sizeof(*pGso), 16) : 0)); + if (!pSgBuf) + return VERR_NO_MEMORY; + + /* + * Initialize the S/G buffer and return. + */ + pSgBuf->fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1; + pSgBuf->cbUsed = 0; + pSgBuf->cbAvailable = RT_ALIGN_Z(cbMin, 16); + pSgBuf->pvAllocator = NULL; + if (!pGso) + pSgBuf->pvUser = NULL; + else + { + pSgBuf->pvUser = (uint8_t *)(pSgBuf + 1) + pSgBuf->cbAvailable; + *(PPDMNETWORKGSO)pSgBuf->pvUser = *pGso; + } + pSgBuf->cSegs = 1; + pSgBuf->aSegs[0].cbSeg = pSgBuf->cbAvailable; + pSgBuf->aSegs[0].pvSeg = pSgBuf + 1; + + *ppSgBuf = pSgBuf; + return VINF_SUCCESS; +} + + +/** + * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf} + */ +static DECLCALLBACK(int) drvNicNetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf) +{ +// PDRVNIC pThis = PDMINETWORKUP_2_DRVNIC(pInterface); + if (pSgBuf) + { + Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC); + pSgBuf->fFlags = 0; + RTMemFree(pSgBuf); + } + return VINF_SUCCESS; +} + + +/** + * @interface_method_impl{PDMINETWORKUP,pfnSendBuf} + */ +static DECLCALLBACK(int) drvNicNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread) +{ + PDRVNIC pThis = PDMINETWORKUP_2_DRVNIC(pInterface); + Nic_client *nic_client = pThis->nic_client; + + AssertPtr(pSgBuf); + Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC); + + /* Set an FTM checkpoint as this operation changes the state permanently. */ +// PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_NETWORK); + + int rc; + if (!pSgBuf->pvUser) + { + Log2(("drvNicSend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n" + "%.*Rhxd\n", pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, + pSgBuf->aSegs[0].pvSeg)); + + rc = nic_client->send_packet(pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed); + } + else + { + uint8_t abHdrScratch[256]; + uint8_t const *pbFrame = (uint8_t const *)pSgBuf->aSegs[0].pvSeg; + PCPDMNETWORKGSO pGso = (PCPDMNETWORKGSO)pSgBuf->pvUser; + uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, pSgBuf->cbUsed); + Assert(cSegs > 1); + rc = VINF_SUCCESS; + for (size_t iSeg = 0; iSeg < cSegs; iSeg++) + { + uint32_t cbSegFrame; + void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, + abHdrScratch, iSeg, cSegs, &cbSegFrame); + rc = nic_client->send_packet(pvSegFrame, cbSegFrame); + if (RT_FAILURE(rc)) + break; + } + } + + pSgBuf->fFlags = 0; + RTMemFree(pSgBuf); + + AssertRC(rc); + if (RT_FAILURE(rc)) + rc = rc == VERR_NO_MEMORY ? VERR_NET_NO_BUFFER_SPACE : VERR_NET_DOWN; + return rc; +} + + +/** + * @interface_method_impl{PDMINETWORKUP,pfnEndXmit} + */ +static DECLCALLBACK(void) drvNicNetworkUp_EndXmit(PPDMINETWORKUP pInterface) +{ +// PDRVNIC pThis = PDMINETWORKUP_2_DRVNIC(pInterface); +} + + +/** + * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} + */ +static DECLCALLBACK(void) drvNicNetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) +{ + LogFlow(("drvNicNetworkUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous)); + /* nothing to do */ +} + + +/** + * Notification on link status changes. + */ +static DECLCALLBACK(void) drvNicNetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) +{ + LogFlow(("drvNicNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); + /* + * At this point we could stop waiting for signals etc. but for now we just do nothing. + */ +} + + +static DECLCALLBACK(int) drvGetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac) +{ + PDRVNIC pThis = PDMINETWORKCONFIG_2_DRVNIC(pInterface); + Nic_client *nic_client = pThis->nic_client; + + static_assert (sizeof(*pMac) == sizeof(nic_client->mac_address()), + "should be equal"); + memcpy(pMac, nic_client->mac_address().addr, sizeof(*pMac)); + return VINF_SUCCESS; +} + + +/* -=-=-=-=- PDMIBASE -=-=-=-=- */ + +/** + * @interface_method_impl{PDMIBASE,pfnQueryInterface} + */ +static DECLCALLBACK(void *) drvNicQueryInterface(PPDMIBASE pInterface, const char *pszIID) +{ + PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); + PDRVNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVNIC); + + PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase); + PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp); + PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig); + return NULL; +} + + +/* -=-=-=-=- PDMDRVREG -=-=-=-=- */ + +static DECLCALLBACK(void) drvNicDestruct(PPDMDRVINS pDrvIns) +{ + PDRVNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVNIC); + Nic_client *nic_client = pThis->nic_client; + + if (!nic_client) + Genode::error("nic_client not valid at destruction time"); + + if (nic_client) + Genode::Signal_transmitter(nic_client->dispatcher()).submit(); + + /* wait until the recv thread exits */ + destruct_blockade().block(); + + if (nic_client) + destroy(net_alloc(), nic_client); +} + + +/** + * Construct a Nic network transport driver instance. + * + * @copydoc FNPDMDRVCONSTRUCT + */ +static DECLCALLBACK(int) drvNicConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) +{ + PDRVNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVNIC); + PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); + int rc; + + /* + * Init the static parts. + */ + pThis->pDrvIns = pDrvIns; + /* IBase */ + pDrvIns->IBase.pfnQueryInterface = drvNicQueryInterface; + /* INetwork */ + pThis->INetworkUp.pfnBeginXmit = drvNicNetworkUp_BeginXmit; + pThis->INetworkUp.pfnAllocBuf = drvNicNetworkUp_AllocBuf; + pThis->INetworkUp.pfnFreeBuf = drvNicNetworkUp_FreeBuf; + pThis->INetworkUp.pfnSendBuf = drvNicNetworkUp_SendBuf; + pThis->INetworkUp.pfnEndXmit = drvNicNetworkUp_EndXmit; + pThis->INetworkUp.pfnSetPromiscuousMode = drvNicNetworkUp_SetPromiscuousMode; + pThis->INetworkUp.pfnNotifyLinkChanged = drvNicNetworkUp_NotifyLinkChanged; + /* INetworkConfig - used on Genode to request Mac address of nic_session */ + pThis->INetworkConfig.pfnGetMac = drvGetMac; + + /* + * Check that no-one is attached to us. + */ + AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER, + ("Configuration error: Not possible to attach anything to" + " this driver!\n"), VERR_PDM_DRVINS_NO_ATTACH); + + /* + * Query the above network port interface. + */ + pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN); + if (!pThis->pIAboveNet) + return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, + N_("Configuration error: The above device/driver" + " didn't export the network port interface")); + pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG); + if (!pThis->pIAboveConfig) + return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, + N_("Configuration error: the above device/driver" + " didn't export the network config interface!\n")); + + uint64_t slot; + rc = CFGMR3QueryInteger(pCfg, "Slot", &slot); + if (RT_FAILURE(rc)) + return PDMDRV_SET_ERROR(pDrvIns, rc, + N_("Configuration error: Failed to retrieve the network interface slot")); + + Genode::String<9> label_string(slot); + + /* + * Setup Genode nic_session connection + */ + if (!env_ptr) + return VERR_HOSTIF_INIT_FAILED; + + try { + pThis->nic_client = new (net_alloc()) Nic_client(*env_ptr, pThis, label_string.string()); + } catch (...) { + return VERR_HOSTIF_INIT_FAILED; + } + + return 0; +} + + +static DECLCALLBACK(void) drvNicPowerOn(PPDMDRVINS pDrvIns) +{ + PDRVNIC pThis = PDMINS_2_DATA(pDrvIns, PDRVNIC); + + if (pThis && pThis->nic_client) + pThis->nic_client->enable_signals(); +} + +/** + * Nic network transport driver registration record. + */ +const PDMDRVREG g_DrvHostInterface = +{ + /* u32Version */ + PDM_DRVREG_VERSION, + /* szName */ + "HostInterface", + /* szRCMod */ + "", + /* szR0Mod */ + "", + /* pszDescription */ + "Genode Network Session Driver", + /* fFlags */ + PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT, + /* fClass. */ + PDM_DRVREG_CLASS_NETWORK, + /* cMaxInstances */ + ~0U, + /* cbInstance */ + sizeof(DRVNIC), + /* pfnConstruct */ + drvNicConstruct, + /* pfnDestruct */ + drvNicDestruct, + /* pfnRelocate */ + NULL, + /* pfnIOCtl */ + NULL, + drvNicPowerOn, + /* pfnReset */ + NULL, + /* pfnSuspend */ + NULL, + /* pfnResume */ + NULL, + /* pfnAttach */ + NULL, + /* pfnDetach */ + NULL, + /* pfnPowerOff */ + NULL, + /* pfnSoftReset */ + NULL, + /* u32EndVersion */ + PDM_DRVREG_VERSION +}; diff --git a/repos/ports/src/virtualbox6/patches/drvtap.patch b/repos/ports/src/virtualbox6/patches/drvtap.patch new file mode 100644 index 0000000000..ab802599d4 --- /dev/null +++ b/repos/ports/src/virtualbox6/patches/drvtap.patch @@ -0,0 +1,31 @@ +Disarm check for usable TUN/TAP file. On Genode the DrvTAP is implemented +by network.cc and uses Genode nic_session directly. + +--- a/src/virtualbox6/src/VBox/Main/src-client/ConsoleImpl2.cpp ++++ b/src/virtualbox6/src/VBox/Main/src-client/ConsoleImpl2.cpp +@@ -5255,18 +5255,24 @@ + "sure that these changes are permanent, especially if you are " + "using udev")); + default: ++#if 0 + AssertMsgFailed(("Could not attach to host interface! Bad!\n")); + return VMSetError(VMR3GetVM(mpUVM), VERR_HOSTIF_INIT_FAILED, RT_SRC_POS, N_( + "Failed to initialize Host Interface Networking")); ++#else ++ break; ++#endif + } + } + ++#if 0 + Assert((intptr_t)maTapFD[uInstance] >= 0); + if ((intptr_t)maTapFD[uInstance] >= 0) ++#endif + { + InsertConfigString(pLunL0, "Driver", "HostInterface"); + InsertConfigNode(pLunL0, "Config", &pCfg); +- InsertConfigInteger(pCfg, "FileHandle", (intptr_t)maTapFD[uInstance]); ++ InsertConfigInteger(pCfg, "Slot", uInstance); + } + + #elif defined(VBOX_WITH_NETFLT) diff --git a/repos/ports/src/virtualbox6/patches/series b/repos/ports/src/virtualbox6/patches/series index 72b8487e74..b37d452ab8 100644 --- a/repos/ports/src/virtualbox6/patches/series +++ b/repos/ports/src/virtualbox6/patches/series @@ -1 +1,2 @@ serial.patch +drvtap.patch diff --git a/repos/ports/src/virtualbox6/target.mk b/repos/ports/src/virtualbox6/target.mk index 7e5da19f84..73cee714a7 100644 --- a/repos/ports/src/virtualbox6/target.mk +++ b/repos/ports/src/virtualbox6/target.mk @@ -6,6 +6,7 @@ CC_WARN += -Wall SRC_CC := main.cc drivers.cc vcpu_gim.cc SRC_CC += libc.cc unimpl.cc dummies.cc pdm.cc devices.cc nem.cc dynlib.cc +SRC_CC += network.cc LIBS += base LIBS += stdcxx