summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostDrivers/VBoxNetAdp/linux
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/HostDrivers/VBoxNetAdp/linux
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/HostDrivers/VBoxNetAdp/linux')
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile78
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c583
-rwxr-xr-xsrc/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp112
4 files changed, 773 insertions, 0 deletions
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile b/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile
new file mode 100644
index 00000000..30aada92
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile
@@ -0,0 +1,78 @@
+# $Id: Makefile $
+## @file
+# Makefile for the VirtualBox Linux Host Virtual Network Adapter Driver.
+#
+
+#
+# Copyright (C) 2006-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+# Linux kbuild sets this to our source directory if we are called from there
+obj ?= $(CURDIR)
+include $(obj)/Makefile-header.gmk
+VBOXNETADP_DIR := $(VBOX_MODULE_SRC_DIR)
+
+# Allow building directly from the subdirectory without assuming the toplevel
+# makefile has done the copying. Not the default use case, but can be handy.
+ifndef KBUILD_EXTRA_SYMBOLS
+KBUILD_EXTRA_SYMBOLS=$(abspath $(VBOXNETADP_DIR)/../vboxdrv/Module.symvers)
+endif
+
+VBOXMOD_NAME = vboxnetadp
+VBOXMOD_OBJS = \
+ linux/VBoxNetAdp-linux.o \
+ VBoxNetAdp.o
+ifeq ($(VBOX_KBUILD_TARGET_ARCH),x86)
+VBOXMOD_OBJS += \
+ math/gcc/divdi3.o \
+ math/gcc/moddi3.o \
+ math/gcc/qdivrem.o \
+ math/gcc/udivdi3.o \
+ math/gcc/udivmoddi4.o \
+ math/gcc/divdi3.o \
+ math/gcc/umoddi3.o
+endif
+VBOXMOD_INCL = \
+ $(VBOXNETADP_DIR) \
+ $(VBOXNETADP_DIR)include \
+ $(VBOXNETADP_DIR)r0drv/linux
+VBOXMOD_DEFS = \
+ RT_OS_LINUX \
+ IN_RING0 \
+ IN_RT_R0 \
+ IN_SUP_R0 \
+ VBOX \
+ RT_WITH_VBOX \
+ VBOX_WITH_HARDENING \
+ VBOX_WITH_64_BITS_GUESTS # <-- must be consistent with Config.kmk!
+VBOXMOD_CFLAGS = -include $(VBOXNETADP_DIR)include/VBox/SUPDrvMangling.h -fno-pie -Wno-declaration-after-statement
+
+include $(obj)/Makefile-footer.gmk
+
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile.kup b/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/Makefile.kup
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c b/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c
new file mode 100644
index 00000000..0654e1d7
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c
@@ -0,0 +1,583 @@
+/* $Id: VBoxNetAdp-linux.c $ */
+/** @file
+ * VBoxNetAdp - Virtual Network Adapter Driver (Host), Linux Specific Code.
+ */
+
+/*
+ * Copyright (C) 2009-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "the-linux-kernel.h"
+#include "version-generated.h"
+#include "revision-generated.h"
+#include "product-generated.h"
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/miscdevice.h>
+
+#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
+#include <VBox/log.h>
+#include <iprt/errcore.h>
+#include <iprt/process.h>
+#include <iprt/initterm.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+
+/*
+#include <iprt/assert.h>
+#include <iprt/semaphore.h>
+#include <iprt/spinlock.h>
+#include <iprt/string.h>
+#include <iprt/uuid.h>
+#include <iprt/alloca.h>
+*/
+
+#define VBOXNETADP_OS_SPECFIC 1
+#include "../VBoxNetAdpInternal.h"
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#define VBOXNETADP_LINUX_NAME "vboxnet%d"
+#define VBOXNETADP_CTL_DEV_NAME "vboxnetctl"
+
+#define VBOXNETADP_FROM_IFACE(iface) ((PVBOXNETADP) ifnet_softc(iface))
+
+/** Set netdev MAC address. */
+#if RTLNX_VER_MIN(5,17,0)
+# define VBOX_DEV_ADDR_SET(dev, addr, len) dev_addr_mod(dev, 0, addr, len)
+#else /* < 5.17.0 */
+# define VBOX_DEV_ADDR_SET(dev, addr, len) memcpy(dev->dev_addr, addr, len)
+#endif
+
+
+/*********************************************************************************************************************************
+* Internal Functions *
+*********************************************************************************************************************************/
+static int __init VBoxNetAdpLinuxInit(void);
+static void __exit VBoxNetAdpLinuxUnload(void);
+
+static int VBoxNetAdpLinuxOpen(struct inode *pInode, struct file *pFilp);
+static int VBoxNetAdpLinuxClose(struct inode *pInode, struct file *pFilp);
+#if RTLNX_VER_MAX(2,6,36)
+static int VBoxNetAdpLinuxIOCtl(struct inode *pInode, struct file *pFilp,
+ unsigned int uCmd, unsigned long ulArg);
+#else /* >= 2,6,36 */
+static long VBoxNetAdpLinuxIOCtlUnlocked(struct file *pFilp,
+ unsigned int uCmd, unsigned long ulArg);
+#endif /* >= 2,6,36 */
+
+static void vboxNetAdpEthGetDrvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+#if RTLNX_VER_MIN(4,20,0)
+static int vboxNetAdpEthGetLinkSettings(struct net_device *pNetDev, struct ethtool_link_ksettings *pLinkSettings);
+#else /* < 4,20,0 */
+static int vboxNetAdpEthGetSettings(struct net_device *dev, struct ethtool_cmd *cmd);
+#endif /* < 4,20,0 */
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+module_init(VBoxNetAdpLinuxInit);
+module_exit(VBoxNetAdpLinuxUnload);
+
+MODULE_AUTHOR(VBOX_VENDOR);
+MODULE_DESCRIPTION(VBOX_PRODUCT " Network Adapter Driver");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING " r" RT_XSTR(VBOX_SVN_REV) " (" RT_XSTR(INTNETTRUNKIFPORT_VERSION) ")");
+#endif
+
+/**
+ * The (common) global data.
+ */
+static struct file_operations gFileOpsVBoxNetAdp =
+{
+ owner: THIS_MODULE,
+ open: VBoxNetAdpLinuxOpen,
+ release: VBoxNetAdpLinuxClose,
+#if RTLNX_VER_MAX(2,6,36)
+ ioctl: VBoxNetAdpLinuxIOCtl,
+#else /* RTLNX_VER_MIN(2,6,36) */
+ unlocked_ioctl: VBoxNetAdpLinuxIOCtlUnlocked,
+#endif /* RTLNX_VER_MIN(2,6,36) */
+};
+
+/** The miscdevice structure. */
+static struct miscdevice g_CtlDev =
+{
+ minor: MISC_DYNAMIC_MINOR,
+ name: VBOXNETADP_CTL_DEV_NAME,
+ fops: &gFileOpsVBoxNetAdp,
+# if RTLNX_VER_MAX(2,6,18)
+ devfs_name: VBOXNETADP_CTL_DEV_NAME
+# endif
+};
+
+# if RTLNX_VER_MIN(2,6,19)
+static const struct ethtool_ops gEthToolOpsVBoxNetAdp =
+# else
+static struct ethtool_ops gEthToolOpsVBoxNetAdp =
+# endif
+{
+ .get_drvinfo = vboxNetAdpEthGetDrvinfo,
+# if RTLNX_VER_MIN(4,20,0)
+ .get_link_ksettings = vboxNetAdpEthGetLinkSettings,
+# else
+ .get_settings = vboxNetAdpEthGetSettings,
+# endif
+ .get_link = ethtool_op_get_link,
+};
+
+
+struct VBoxNetAdpPriv
+{
+ struct net_device_stats Stats;
+};
+
+typedef struct VBoxNetAdpPriv VBOXNETADPPRIV;
+typedef VBOXNETADPPRIV *PVBOXNETADPPRIV;
+
+static int vboxNetAdpLinuxOpen(struct net_device *pNetDev)
+{
+ netif_start_queue(pNetDev);
+ return 0;
+}
+
+static int vboxNetAdpLinuxStop(struct net_device *pNetDev)
+{
+ netif_stop_queue(pNetDev);
+ return 0;
+}
+
+static int vboxNetAdpLinuxXmit(struct sk_buff *pSkb, struct net_device *pNetDev)
+{
+ PVBOXNETADPPRIV pPriv = netdev_priv(pNetDev);
+
+ /* Update the stats. */
+ pPriv->Stats.tx_packets++;
+ pPriv->Stats.tx_bytes += pSkb->len;
+#if RTLNX_VER_MAX(2,6,31)
+ /* Update transmission time stamp. */
+ pNetDev->trans_start = jiffies;
+#endif
+ /* Nothing else to do, just free the sk_buff. */
+ dev_kfree_skb(pSkb);
+ return 0;
+}
+
+static struct net_device_stats *vboxNetAdpLinuxGetStats(struct net_device *pNetDev)
+{
+ PVBOXNETADPPRIV pPriv = netdev_priv(pNetDev);
+ return &pPriv->Stats;
+}
+
+
+/* ethtool_ops::get_drvinfo */
+static void vboxNetAdpEthGetDrvinfo(struct net_device *pNetDev, struct ethtool_drvinfo *info)
+{
+ PVBOXNETADPPRIV pPriv = netdev_priv(pNetDev);
+ NOREF(pPriv);
+
+ RTStrPrintf(info->driver, sizeof(info->driver),
+ "%s", VBOXNETADP_NAME);
+
+ /*
+ * Would be nice to include VBOX_SVN_REV, but it's not available
+ * here. Use file's svn revision via svn keyword?
+ */
+ RTStrPrintf(info->version, sizeof(info->version),
+ "%s", VBOX_VERSION_STRING);
+
+ RTStrPrintf(info->fw_version, sizeof(info->fw_version),
+ "0x%08X", INTNETTRUNKIFPORT_VERSION);
+
+ RTStrPrintf(info->bus_info, sizeof(info->driver),
+ "N/A");
+}
+
+
+# if RTLNX_VER_MIN(4,20,0)
+/* ethtool_ops::get_link_ksettings */
+static int vboxNetAdpEthGetLinkSettings(struct net_device *pNetDev, struct ethtool_link_ksettings *pLinkSettings)
+{
+ /* We just need to set field we care for, the rest is done by ethtool_get_link_ksettings() helper in ethtool. */
+ ethtool_link_ksettings_zero_link_mode(pLinkSettings, supported);
+ ethtool_link_ksettings_zero_link_mode(pLinkSettings, advertising);
+ ethtool_link_ksettings_zero_link_mode(pLinkSettings, lp_advertising);
+ pLinkSettings->base.speed = SPEED_10;
+ pLinkSettings->base.duplex = DUPLEX_FULL;
+ pLinkSettings->base.port = PORT_TP;
+ pLinkSettings->base.phy_address = 0;
+ pLinkSettings->base.transceiver = XCVR_INTERNAL;
+ pLinkSettings->base.autoneg = AUTONEG_DISABLE;
+ return 0;
+}
+#else /* RTLNX_VER_MAX(4,20,0) */
+/* ethtool_ops::get_settings */
+static int vboxNetAdpEthGetSettings(struct net_device *pNetDev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = 0;
+ cmd->advertising = 0;
+#if RTLNX_VER_MIN(2,6,27)
+ ethtool_cmd_speed_set(cmd, SPEED_10);
+#else
+ cmd->speed = SPEED_10;
+#endif
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_TP;
+ cmd->phy_address = 0;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+ return 0;
+}
+#endif /* RTLNX_VER_MAX(4,20,0) */
+
+
+#if RTLNX_VER_MIN(2,6,29)
+static const struct net_device_ops vboxNetAdpNetdevOps = {
+ .ndo_open = vboxNetAdpLinuxOpen,
+ .ndo_stop = vboxNetAdpLinuxStop,
+ .ndo_start_xmit = vboxNetAdpLinuxXmit,
+ .ndo_get_stats = vboxNetAdpLinuxGetStats
+};
+#endif
+
+static void vboxNetAdpNetDevInit(struct net_device *pNetDev)
+{
+ PVBOXNETADPPRIV pPriv;
+
+ ether_setup(pNetDev);
+#if RTLNX_VER_MIN(2,6,29)
+ pNetDev->netdev_ops = &vboxNetAdpNetdevOps;
+#else /* RTLNX_VER_MAX(2,6,29) */
+ pNetDev->open = vboxNetAdpLinuxOpen;
+ pNetDev->stop = vboxNetAdpLinuxStop;
+ pNetDev->hard_start_xmit = vboxNetAdpLinuxXmit;
+ pNetDev->get_stats = vboxNetAdpLinuxGetStats;
+#endif /* RTLNX_VER_MAX(2,6,29) */
+#if RTLNX_VER_MIN(4,10,0)
+ pNetDev->max_mtu = 65536;
+ pNetDev->features = NETIF_F_TSO
+ | NETIF_F_TSO6
+ | NETIF_F_TSO_ECN
+ | NETIF_F_SG
+ | NETIF_F_HW_CSUM;
+#endif /* RTLNX_VER_MIN(4,10,0) */
+
+ pNetDev->ethtool_ops = &gEthToolOpsVBoxNetAdp;
+
+ pPriv = netdev_priv(pNetDev);
+ memset(pPriv, 0, sizeof(*pPriv));
+}
+
+
+int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMACAddress)
+{
+ int rc = VINF_SUCCESS;
+ struct net_device *pNetDev;
+
+ /* No need for private data. */
+ pNetDev = alloc_netdev(sizeof(VBOXNETADPPRIV),
+ pThis->szName[0] ? pThis->szName : VBOXNETADP_LINUX_NAME,
+#if RTLNX_VER_MIN(3,17,0)
+ NET_NAME_UNKNOWN,
+#endif
+ vboxNetAdpNetDevInit);
+ if (pNetDev)
+ {
+ int err;
+
+ if (pNetDev->dev_addr)
+ {
+ VBOX_DEV_ADDR_SET(pNetDev, pMACAddress, ETH_ALEN);
+ Log2(("vboxNetAdpOsCreate: pNetDev->dev_addr = %.6Rhxd\n", pNetDev->dev_addr));
+
+ /*
+ * We treat presence of VBoxNetFlt filter as our "carrier",
+ * see vboxNetFltSetLinkState().
+ *
+ * operstates.txt: "On device allocation, networking core
+ * sets the flags equivalent to netif_carrier_ok() and
+ * !netif_dormant()" - so turn carrier off here.
+ */
+ netif_carrier_off(pNetDev);
+
+ err = register_netdev(pNetDev);
+ if (!err)
+ {
+ strncpy(pThis->szName, pNetDev->name, sizeof(pThis->szName));
+ pThis->szName[sizeof(pThis->szName) - 1] = '\0';
+ pThis->u.s.pNetDev = pNetDev;
+ Log2(("vboxNetAdpOsCreate: pThis=%p pThis->szName = %p\n", pThis, pThis->szName));
+ return VINF_SUCCESS;
+ }
+ }
+ else
+ {
+ LogRel(("VBoxNetAdp: failed to set MAC address (dev->dev_addr == NULL)\n"));
+ err = EFAULT;
+ }
+ free_netdev(pNetDev);
+ rc = RTErrConvertFromErrno(err);
+ }
+ return rc;
+}
+
+void vboxNetAdpOsDestroy(PVBOXNETADP pThis)
+{
+ struct net_device *pNetDev = pThis->u.s.pNetDev;
+ AssertPtr(pThis->u.s.pNetDev);
+
+ pThis->u.s.pNetDev = NULL;
+ unregister_netdev(pNetDev);
+ free_netdev(pNetDev);
+}
+
+/**
+ * Device open. Called on open /dev/vboxnetctl
+ *
+ * @param pInode Pointer to inode info structure.
+ * @param pFilp Associated file pointer.
+ */
+static int VBoxNetAdpLinuxOpen(struct inode *pInode, struct file *pFilp)
+{
+ Log(("VBoxNetAdpLinuxOpen: pid=%d/%d %s\n", RTProcSelf(), current->pid, current->comm));
+
+#ifdef VBOX_WITH_HARDENING
+ /*
+ * Only root is allowed to access the device, enforce it!
+ */
+ if (!capable(CAP_SYS_ADMIN))
+ {
+ Log(("VBoxNetAdpLinuxOpen: admin privileges required!\n"));
+ return -EPERM;
+ }
+#endif
+
+ return 0;
+}
+
+
+/**
+ * Close device.
+ *
+ * @param pInode Pointer to inode info structure.
+ * @param pFilp Associated file pointer.
+ */
+static int VBoxNetAdpLinuxClose(struct inode *pInode, struct file *pFilp)
+{
+ Log(("VBoxNetAdpLinuxClose: pid=%d/%d %s\n",
+ RTProcSelf(), current->pid, current->comm));
+ pFilp->private_data = NULL;
+ return 0;
+}
+
+/**
+ * Device I/O Control entry point.
+ *
+ * @param pFilp Associated file pointer.
+ * @param uCmd The function specified to ioctl().
+ * @param ulArg The argument specified to ioctl().
+ */
+#if RTLNX_VER_MAX(2,6,36)
+static int VBoxNetAdpLinuxIOCtl(struct inode *pInode, struct file *pFilp,
+ unsigned int uCmd, unsigned long ulArg)
+#else /* RTLNX_VER_MIN(2,6,36) */
+static long VBoxNetAdpLinuxIOCtlUnlocked(struct file *pFilp,
+ unsigned int uCmd, unsigned long ulArg)
+#endif /* RTLNX_VER_MIN(2,6,36) */
+{
+ VBOXNETADPREQ Req;
+ PVBOXNETADP pAdp;
+ int rc;
+ char *pszName = NULL;
+
+ Log(("VBoxNetAdpLinuxIOCtl: param len %#x; uCmd=%#x; add=%#x\n", _IOC_SIZE(uCmd), uCmd, VBOXNETADP_CTL_ADD));
+ if (RT_UNLIKELY(_IOC_SIZE(uCmd) != sizeof(Req))) /* paranoia */
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: bad ioctl sizeof(Req)=%#x _IOC_SIZE=%#x; uCmd=%#x.\n", sizeof(Req), _IOC_SIZE(uCmd), uCmd));
+ return -EINVAL;
+ }
+
+ switch (uCmd)
+ {
+ case VBOXNETADP_CTL_ADD:
+ Log(("VBoxNetAdpLinuxIOCtl: _IOC_DIR(uCmd)=%#x; IOC_OUT=%#x\n", _IOC_DIR(uCmd), IOC_OUT));
+ if (RT_UNLIKELY(copy_from_user(&Req, (void *)ulArg, sizeof(Req))))
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x.\n", ulArg, uCmd));
+ return -EFAULT;
+ }
+ Log(("VBoxNetAdpLinuxIOCtl: Add %s\n", Req.szName));
+
+ if (Req.szName[0])
+ {
+ pAdp = vboxNetAdpFindByName(Req.szName);
+ if (pAdp)
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: '%s' already exists\n", Req.szName));
+ return -EINVAL;
+ }
+ pszName = Req.szName;
+ }
+ rc = vboxNetAdpCreate(&pAdp, pszName);
+ if (RT_FAILURE(rc))
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: vboxNetAdpCreate -> %Rrc\n", rc));
+ return -(rc == VERR_OUT_OF_RESOURCES ? ENOMEM : EINVAL);
+ }
+
+ Assert(strlen(pAdp->szName) < sizeof(Req.szName));
+ strncpy(Req.szName, pAdp->szName, sizeof(Req.szName) - 1);
+ Req.szName[sizeof(Req.szName) - 1] = '\0';
+
+ if (RT_UNLIKELY(copy_to_user((void *)ulArg, &Req, sizeof(Req))))
+ {
+ /* this is really bad! */
+ /** @todo remove the adapter again? */
+ printk(KERN_ERR "VBoxNetAdpLinuxIOCtl: copy_to_user(%#lx,,%#zx); uCmd=%#x!\n", ulArg, sizeof(Req), uCmd);
+ return -EFAULT;
+ }
+ Log(("VBoxNetAdpLinuxIOCtl: Successfully added '%s'\n", Req.szName));
+ break;
+
+ case VBOXNETADP_CTL_REMOVE:
+ if (RT_UNLIKELY(copy_from_user(&Req, (void *)ulArg, sizeof(Req))))
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x.\n", ulArg, uCmd));
+ return -EFAULT;
+ }
+ Log(("VBoxNetAdpLinuxIOCtl: Remove %s\n", Req.szName));
+
+ pAdp = vboxNetAdpFindByName(Req.szName);
+ if (!pAdp)
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: '%s' not found\n", Req.szName));
+ return -EINVAL;
+ }
+
+ rc = vboxNetAdpDestroy(pAdp);
+ if (RT_FAILURE(rc))
+ {
+ Log(("VBoxNetAdpLinuxIOCtl: vboxNetAdpDestroy('%s') -> %Rrc\n", Req.szName, rc));
+ return -EINVAL;
+ }
+ Log(("VBoxNetAdpLinuxIOCtl: Successfully removed '%s'\n", Req.szName));
+ break;
+
+ default:
+ printk(KERN_ERR "VBoxNetAdpLinuxIOCtl: unknown command %x.\n", uCmd);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int vboxNetAdpOsInit(PVBOXNETADP pThis)
+{
+ /*
+ * Init linux-specific members.
+ */
+ pThis->u.s.pNetDev = NULL;
+
+ return VINF_SUCCESS;
+}
+
+
+
+/**
+ * Initialize module.
+ *
+ * @returns appropriate status code.
+ */
+static int __init VBoxNetAdpLinuxInit(void)
+{
+ int rc;
+ /*
+ * Initialize IPRT.
+ */
+ rc = RTR0Init(0);
+ if (RT_SUCCESS(rc))
+ {
+ Log(("VBoxNetAdpLinuxInit\n"));
+
+ rc = vboxNetAdpInit();
+ if (RT_SUCCESS(rc))
+ {
+ rc = misc_register(&g_CtlDev);
+ if (rc)
+ {
+ printk(KERN_ERR "VBoxNetAdp: Can't register " VBOXNETADP_CTL_DEV_NAME " device! rc=%d\n", rc);
+ return rc;
+ }
+ LogRel(("VBoxNetAdp: Successfully started.\n"));
+ return 0;
+ }
+ else
+ LogRel(("VBoxNetAdp: failed to register vboxnet0 device (rc=%d)\n", rc));
+ }
+ else
+ LogRel(("VBoxNetAdp: failed to initialize IPRT (rc=%d)\n", rc));
+
+ return -RTErrConvertToErrno(rc);
+}
+
+
+/**
+ * Unload the module.
+ *
+ * @todo We have to prevent this if we're busy!
+ */
+static void __exit VBoxNetAdpLinuxUnload(void)
+{
+ Log(("VBoxNetAdpLinuxUnload\n"));
+
+ /*
+ * Undo the work done during start (in reverse order).
+ */
+
+ vboxNetAdpShutdown();
+ /* Remove control device */
+ misc_deregister(&g_CtlDev);
+
+ RTR0Term();
+
+ Log(("VBoxNetAdpLinuxUnload - done\n"));
+}
+
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp b/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp
new file mode 100755
index 00000000..3f028677
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/linux/files_vboxnetadp
@@ -0,0 +1,112 @@
+#!/bin/sh
+# $Id: files_vboxnetadp $
+## @files
+# Shared file between Makefile.kmk and export_modules.sh.
+#
+
+#
+# Copyright (C) 2009-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+VBOX_VBOXNETADP_SOURCES=" \
+ ${PATH_ROOT}/include/iprt/alloc.h=>include/iprt/alloc.h \
+ ${PATH_ROOT}/include/iprt/alloca.h=>include/iprt/alloca.h \
+ ${PATH_ROOT}/include/iprt/asm.h=>include/iprt/asm.h \
+ ${PATH_ROOT}/include/iprt/asm-amd64-x86.h=>include/iprt/asm-amd64-x86.h \
+ ${PATH_ROOT}/include/iprt/asm-math.h=>include/iprt/asm-math.h \
+ ${PATH_ROOT}/include/iprt/assert.h=>include/iprt/assert.h \
+ ${PATH_ROOT}/include/iprt/assertcompile.h=>include/iprt/assertcompile.h \
+ ${PATH_ROOT}/include/iprt/avl.h=>include/iprt/avl.h \
+ ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \
+ ${PATH_ROOT}/include/iprt/cpuset.h=>include/iprt/cpuset.h \
+ ${PATH_ROOT}/include/iprt/ctype.h=>include/iprt/ctype.h \
+ ${PATH_ROOT}/include/iprt/err.h=>include/iprt/err.h \
+ ${PATH_ROOT}/include/iprt/errcore.h=>include/iprt/errcore.h \
+ ${PATH_ROOT}/include/iprt/heap.h=>include/iprt/heap.h \
+ ${PATH_ROOT}/include/iprt/initterm.h=>include/iprt/initterm.h \
+ ${PATH_ROOT}/include/iprt/latin1.h=>include/iprt/latin1.h \
+ ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \
+ ${PATH_ROOT}/include/iprt/mangling.h=>include/iprt/mangling.h \
+ ${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \
+ ${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \
+ ${PATH_ROOT}/include/iprt/mp.h=>include/iprt/mp.h \
+ ${PATH_ROOT}/include/iprt/net.h=>include/iprt/net.h \
+ ${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \
+ ${PATH_ROOT}/include/iprt/power.h=>include/iprt/power.h \
+ ${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \
+ ${PATH_ROOT}/include/iprt/semaphore.h=>include/iprt/semaphore.h \
+ ${PATH_ROOT}/include/iprt/spinlock.h=>include/iprt/spinlock.h \
+ ${PATH_ROOT}/include/iprt/stdarg.h=>include/iprt/stdarg.h \
+ ${PATH_ROOT}/include/iprt/stdint.h=>include/iprt/stdint.h \
+ ${PATH_ROOT}/include/iprt/string.h=>include/iprt/string.h \
+ ${PATH_ROOT}/include/iprt/thread.h=>include/iprt/thread.h \
+ ${PATH_ROOT}/include/iprt/time.h=>include/iprt/time.h \
+ ${PATH_ROOT}/include/iprt/timer.h=>include/iprt/timer.h \
+ ${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \
+ ${PATH_ROOT}/include/iprt/uint64.h=>include/iprt/uint64.h \
+ ${PATH_ROOT}/include/iprt/uni.h=>include/iprt/uni.h \
+ ${PATH_ROOT}/include/iprt/utf16.h=>include/iprt/utf16.h \
+ ${PATH_ROOT}/include/iprt/uuid.h=>include/iprt/uuid.h \
+ ${PATH_ROOT}/include/iprt/x86.h=>include/iprt/x86.h \
+ ${PATH_ROOT}/include/iprt/x86-helpers.h=>include/iprt/x86-helpers.h \
+ ${PATH_ROOT}/include/iprt/linux/version.h=>include/iprt/linux/version.h \
+ ${PATH_ROOT}/include/iprt/nocrt/limits.h=>include/iprt/nocrt/limits.h \
+ ${PATH_ROOT}/include/VBox/cdefs.h=>include/VBox/cdefs.h \
+ ${PATH_ROOT}/include/VBox/err.h=>include/VBox/err.h \
+ ${PATH_ROOT}/include/VBox/log.h=>include/VBox/log.h \
+ ${PATH_ROOT}/include/VBox/intnet.h=>include/VBox/intnet.h \
+ ${PATH_ROOT}/include/VBox/vmm/stam.h=>include/VBox/vmm/stam.h \
+ ${PATH_ROOT}/include/VBox/sup.h=>include/VBox/sup.h \
+ ${PATH_ROOT}/include/VBox/types.h=>include/VBox/types.h \
+ ${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxNetAdp/linux/VBoxNetAdp-linux.c=>linux/VBoxNetAdp-linux.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdp.c=>VBoxNetAdp.c \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h=>VBoxNetAdpInternal.h \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile-footer.gmk=>Makefile-footer.gmk \
+ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile-header.gmk=>Makefile-header.gmk \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/divdi3.c=>math/gcc/divdi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/moddi3.c=>math/gcc/moddi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/qdivrem.c=>math/gcc/qdivrem.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/quad.h=>math/gcc/quad.h \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivdi3.c=>math/gcc/udivdi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/udivmoddi4.c=>math/gcc/udivmoddi4.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/math/gcc/umoddi3.c=>math/gcc/umoddi3.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
+ ${PATH_ROOT}/src/VBox/Runtime/include/internal/iprt.h=>include/internal/iprt.h \
+ ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \
+ ${PATH_OUT}/version-generated.h=>version-generated.h \
+ ${PATH_OUT}/revision-generated.h=>revision-generated.h \
+ ${PATH_OUT}/product-generated.h=>product-generated.h \
+"
+