summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostDrivers/VBoxNetAdp/freebsd
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostDrivers/VBoxNetAdp/freebsd')
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile54
-rw-r--r--src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c339
-rwxr-xr-xsrc/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp94
3 files changed, 487 insertions, 0 deletions
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile
new file mode 100644
index 00000000..013a223d
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/Makefile
@@ -0,0 +1,54 @@
+# $Id: Makefile $
+## @file
+# Makefile for the VirtualBox FreeBSD Host 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
+#
+
+KMOD = vboxnetadp
+
+CFLAGS += -DRT_OS_FREEBSD -DIN_RING0 -DIN_RT_R0 -DIN_SUP_R0 -DVBOX -DRT_WITH_VBOX -Iinclude -I. -Ir0drv -w -DVBOX_WITH_HARDENING -DVIMAGE
+
+.if (${MACHINE_ARCH} == "i386")
+ CFLAGS += -DRT_ARCH_X86
+.elif (${MACHINE_ARCH} == "amd64")
+ CFLAGS += -DRT_ARCH_AMD64
+.endif
+
+SRCS = \
+ VBoxNetAdp-freebsd.c \
+ VBoxNetAdp.c
+
+SRCS += device_if.h bus_if.h
+
+.include <bsd.kmod.mk>
+
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c
new file mode 100644
index 00000000..db5c0b64
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c
@@ -0,0 +1,339 @@
+/* $Id: VBoxNetAdp-freebsd.c $ */
+/** @file
+ * VBoxNetAdp - Virtual Network Adapter Driver (Host), FreeBSD Specific Code.
+ */
+
+/*-
+ * Copyright (c) 2009 Fredrik Lindberg <fli@shapeshifter.se>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <sys/param.h>
+#undef PVM
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/fcntl.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/ethernet.h>
+#include <net/bpf.h>
+
+#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
+#include <VBox/version.h>
+#include <iprt/errcore.h>
+#include <VBox/log.h>
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <iprt/spinlock.h>
+#include <iprt/process.h>
+#include <iprt/assert.h>
+#include <iprt/uuid.h>
+#include <iprt/alloc.h>
+#include <iprt/errcore.h>
+
+#define VBOXNETADP_OS_SPECFIC 1
+#include "../VBoxNetAdpInternal.h"
+
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 800500
+# include <sys/jail.h>
+# include <net/vnet.h>
+
+# define VBOXCURVNET_SET(arg) CURVNET_SET_QUIET(arg)
+# define VBOXCURVNET_SET_FROM_UCRED() VBOXCURVNET_SET(CRED_TO_VNET(curthread->td_ucred))
+# define VBOXCURVNET_RESTORE() CURVNET_RESTORE()
+
+#else /* !defined(__FreeBSD_version) || __FreeBSD_version < 800500 */
+
+# define VBOXCURVNET_SET(arg)
+# define VBOXCURVNET_SET_FROM_UCRED()
+# define VBOXCURVNET_RESTORE()
+
+#endif /* !defined(__FreeBSD_version) || __FreeBSD_version < 800500 */
+
+static int VBoxNetAdpFreeBSDCtrlioctl(struct cdev *, u_long, caddr_t, int flags,
+ struct thread *);
+static struct cdevsw vboxnetadp_cdevsw =
+{
+ .d_version = D_VERSION,
+ .d_ioctl = VBoxNetAdpFreeBSDCtrlioctl,
+ .d_read = (d_read_t *)nullop,
+ .d_write = (d_write_t *)nullop,
+ .d_name = VBOXNETADP_CTL_DEV_NAME,
+};
+
+static struct cdev *VBoxNetAdpFreeBSDcdev;
+
+static int VBoxNetAdpFreeBSDModuleEvent(struct module *, int, void *);
+static moduledata_t g_VBoxNetAdpFreeBSDModule = {
+ "vboxnetadp",
+ VBoxNetAdpFreeBSDModuleEvent,
+ NULL
+};
+
+/** Declare the module as a pseudo device. */
+DECLARE_MODULE(vboxnetadp, g_VBoxNetAdpFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(vboxnetadp, 1);
+MODULE_DEPEND(vboxnetadp, vboxdrv, 1, 1, 1);
+MODULE_DEPEND(vboxnetadp, vboxnetflt, 1, 1, 1);
+
+/**
+ * Module event handler
+ */
+static int
+VBoxNetAdpFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg)
+{
+ int rc = 0;
+
+ Log(("VBoxNetAdpFreeBSDModuleEvent\n"));
+
+ switch (enmEventType)
+ {
+ case MOD_LOAD:
+ rc = RTR0Init(0);
+ if (RT_FAILURE(rc))
+ {
+ Log(("RTR0Init failed %d\n", rc));
+ return RTErrConvertToErrno(rc);
+ }
+ rc = vboxNetAdpInit();
+ if (RT_FAILURE(rc))
+ {
+ RTR0Term();
+ Log(("vboxNetAdpInit failed %d\n", rc));
+ return RTErrConvertToErrno(rc);
+ }
+ /* Create dev node */
+ VBoxNetAdpFreeBSDcdev = make_dev(&vboxnetadp_cdevsw, 0,
+ UID_ROOT, GID_WHEEL, 0600, VBOXNETADP_CTL_DEV_NAME);
+
+ break;
+
+ case MOD_UNLOAD:
+ vboxNetAdpShutdown();
+ destroy_dev(VBoxNetAdpFreeBSDcdev);
+ RTR0Term();
+ break;
+ case MOD_SHUTDOWN:
+ case MOD_QUIESCE:
+ default:
+ return EOPNOTSUPP;
+ }
+
+ if (RT_SUCCESS(rc))
+ return 0;
+ return RTErrConvertToErrno(rc);
+}
+
+/**
+ * Device I/O Control entry point.
+ */
+static int
+VBoxNetAdpFreeBSDCtrlioctl(struct cdev *dev, u_long iCmd, caddr_t data, int flags, struct thread *td)
+{
+ PVBOXNETADP pAdp;
+ PVBOXNETADPREQ pReq = (PVBOXNETADPREQ)data;
+ struct ifnet *ifp;
+ int rc;
+
+ switch (iCmd)
+ {
+ case VBOXNETADP_CTL_ADD:
+ if ( !(iCmd & IOC_INOUT) /* paranoia*/
+ || IOCPARM_LEN(iCmd) < sizeof(*pReq))
+ return EINVAL;
+
+ rc = vboxNetAdpCreate(&pAdp,
+ pReq->szName[0] && RTStrEnd(pReq->szName, RT_MIN(IOCPARM_LEN(iCmd), sizeof(pReq->szName))) ?
+ pReq->szName : NULL);
+ if (RT_FAILURE(rc))
+ return EINVAL;
+
+ strncpy(pReq->szName, pAdp->szName, sizeof(pReq->szName) - 1);
+ pReq->szName[sizeof(pReq->szName) - 1] = '\0';
+ break;
+
+ case VBOXNETADP_CTL_REMOVE:
+ if (!RTStrEnd(pReq->szName, RT_MIN(sizeof(pReq->szName), IOCPARM_LEN(iCmd))))
+ return EINVAL;
+
+ pAdp = vboxNetAdpFindByName(pReq->szName);
+ if (!pAdp)
+ return EINVAL;
+
+ rc = vboxNetAdpDestroy(pAdp);
+ if (RT_FAILURE(rc))
+ return EINVAL;
+
+ break;
+
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * Initialize device, just set the running flag.
+ */
+static void VBoxNetAdpFreeBSDNetinit(void *priv)
+{
+ PVBOXNETADP pThis = priv;
+ struct ifnet *ifp = pThis->u.s.ifp;
+
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+}
+
+/**
+ * Transmit packets.
+ * netflt has already done everything for us so we just hand the
+ * packets to BPF and increment the packet stats.
+ */
+static void VBoxNetAdpFreeBSDNetstart(struct ifnet *ifp)
+{
+ PVBOXNETADP pThis = ifp->if_softc;
+ struct mbuf *m;
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
+ return;
+
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ {
+#if __FreeBSD_version >= 1100036
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+#else
+ ifp->if_opackets++;
+#endif
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ BPF_MTAP(ifp, m);
+ m_freem(m);
+ }
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+}
+
+/**
+ * Interface ioctl handling
+ */
+static int VBoxNetAdpFreeBSDNetioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ int error = 0;
+
+ switch (cmd)
+ {
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP)
+ {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ ifp->if_init(ifp->if_softc);
+ }
+ else
+ {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ }
+ break;
+ case SIOCGIFMEDIA:
+ {
+ struct ifmediareq *ifmr;
+ int count;
+
+ ifmr = (struct ifmediareq *)data;
+ count = ifmr->ifm_count;
+ ifmr->ifm_count = 1;
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+ ifmr->ifm_status |= IFM_ACTIVE;
+ ifmr->ifm_current = ifmr->ifm_active;
+ if (count >= 1)
+ {
+ int media = IFM_ETHER;
+ error = copyout(&media, ifmr->ifm_ulist, sizeof(int));
+ }
+ break;
+ }
+ default:
+ return ether_ioctl(ifp, cmd, data);
+ }
+ return error;
+}
+
+int vboxNetAdpOsInit(PVBOXNETADP pThis)
+{
+ pThis->u.s.ifp = NULL;
+ return VINF_SUCCESS;;
+}
+
+int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMac)
+{
+ struct ifnet *ifp;
+
+ VBOXCURVNET_SET_FROM_UCRED();
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ return VERR_NO_MEMORY;
+
+ if_initname(ifp, VBOXNETADP_NAME, pThis->iUnit);
+ ifp->if_softc = pThis;
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = VBoxNetAdpFreeBSDNetioctl;
+ ifp->if_start = VBoxNetAdpFreeBSDNetstart;
+ ifp->if_init = VBoxNetAdpFreeBSDNetinit;
+ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+ IFQ_SET_READY(&ifp->if_snd);
+ ether_ifattach(ifp, (void *)pMac);
+ ifp->if_baudrate = 0;
+
+ strncpy(pThis->szName, ifp->if_xname, VBOXNETADP_MAX_NAME_LEN);
+ pThis->u.s.ifp = ifp;
+ VBOXCURVNET_RESTORE();
+ return 0;
+}
+
+void vboxNetAdpOsDestroy(PVBOXNETADP pThis)
+{
+ struct ifnet *ifp;
+
+ ifp = pThis->u.s.ifp;
+ VBOXCURVNET_SET(ifp->if_vnet);
+ ether_ifdetach(ifp);
+ if_free(ifp);
+ VBOXCURVNET_RESTORE();
+}
diff --git a/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp
new file mode 100755
index 00000000..d90ced7b
--- /dev/null
+++ b/src/VBox/HostDrivers/VBoxNetAdp/freebsd/files_vboxnetadp
@@ -0,0 +1,94 @@
+#!/bin/sh
+# $Id: files_vboxnetadp $
+## @file
+# Shared file between Makefile.kmk and export_modules.sh.
+#
+
+#
+# Copyright (C) 2007-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/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/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-helpers.h=>include/iprt/x86-helpers.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/version.h=>include/VBox/version.h \
+ ${PATH_ROOT}/include/VBox/SUPDrvMangling.h=>include/VBox/SUPDrvMangling.h \
+ ${PATH_ROOT}/src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c=>VBoxNetAdp-freebsd.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/Runtime/r0drv/freebsd/the-freebsd-kernel.h=>r0drv/freebsd/the-freebsd-kernel.h \
+ ${PATH_OUT}/version-generated.h=>version-generated.h \
+ ${PATH_OUT}/product-generated.h=>product-generated.h \
+"
+