Index: src/apps/Makefile.kmk =================================================================== --- src/apps/Makefile.kmk (revision 22813) +++ src/apps/Makefile.kmk (working copy) @@ -32,7 +32,7 @@ include $(PATH_SUB_CURRENT)/tunctl/Makefile.kmk endif endif -if1of ($(KBUILD_TARGET),darwin solaris linux) +if1of ($(KBUILD_TARGET),darwin solaris linux freebsd) ifneq ($(wildcard $(PATH_SUB_CURRENT)/adpctl),) include $(PATH_SUB_CURRENT)/adpctl/Makefile.kmk endif Index: src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c =================================================================== --- src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c (revision 0) +++ src/VBox/HostDrivers/VBoxNetAdp/freebsd/VBoxNetAdp-freebsd.c (revision 0) @@ -0,0 +1,280 @@ +/** @file + * VBoxNetAdp - Virtual Network Adapter Driver (Host), FreeBSD Specific Code. + */ + +/*- + * Copyright (c) 2009 Fredrik Lindberg + * + * 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 +#undef PVM +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_GROUP LOG_GROUP_NET_ADP_DRV +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VBOXNETADP_OS_SPECFIC 1 +#include "../VBoxNetAdpInternal.h" + +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, ng_vboxnetflt, 1, 1, 1); + +/** + * Module event handler + */ +static int +VBoxNetAdpFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg) +{ + int rc = 0; + + Log(("VBoxNetFltFreeBSDModuleEvent\n")); + + switch (enmEventType) + { + case MOD_LOAD: + rc = RTR0Init(0); + if (!RT_SUCCESS(rc)) { + Log(("RTR0Init failed %d\n", rc)); + return RTErrConvertToErrno(rc); + } + rc = vboxNetAdpInit(); + if (!RT_SUCCESS(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); + + RTR0Term(); + break; + + case MOD_UNLOAD: + vboxNetAdpShutdown(); + destroy_dev(VBoxNetAdpFreeBSDcdev); + 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 cmd, caddr_t data, int flags, struct thread *td) +{ + PVBOXNETADP pAdp = NULL; + PVBOXNETADPREQ pReq = (PVBOXNETADPREQ)data; + struct ifnet *ifp; + int rc; + + switch (cmd) { + case VBOXNETADP_CTL_ADD: + if (!(cmd & IOC_OUT)) + return (EINVAL); + + rc = vboxNetAdpCreate(&pAdp); + if (!RT_SUCCESS(rc)) + return (EINVAL); + + strncpy(pReq->szName, pAdp->szName, sizeof(pReq->szName)); + break; + case VBOXNETADP_CTL_REMOVE: + pAdp = vboxNetAdpFindByName(pReq->szName); + if (pAdp) + rc = vboxNetAdpDestroy(pAdp); + else + return (EINVAL); + + if (!RT_SUCCESS(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 aldready 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)) { + ifp->if_opackets++; + 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) +{ + + 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; + default: + return ether_ioctl(ifp, cmd, data); + } + return 0; +} + +int vboxNetAdpOsInit(PVBOXNETADP pThis) +{ + + pThis->u.s.ifp = NULL; + return VINF_SUCCESS;; +} + +int vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMac) +{ + struct ifnet *ifp; + + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + return VERR_NO_MEMORY; + + if_initname(ifp, VBOXNETADP_NAME, pThis->uUnit); + 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; + return 0; +} + +void vboxNetAdpOsDestroy(PVBOXNETADP pThis) +{ + struct ifnet *ifp; + + ifp = pThis->u.s.ifp; + ether_ifdetach(ifp); + if_free(ifp); +} Index: src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h =================================================================== --- src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h (revision 22813) +++ src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h (working copy) @@ -147,6 +147,11 @@ /** Pointer to Linux network device structure. */ struct net_device *pNetDev; /** @} */ +# elif defined(RT_OS_FREEBSD) + /** @name FreeBSD instance data. + * @{ */ + struct ifnet *ifp; + /** @} */ # else # error PORTME # endif Index: src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk =================================================================== --- src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk (revision 22813) +++ src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk (working copy) @@ -23,7 +23,7 @@ include $(KBUILD_PATH)/subheader.kmk -if1of ($(KBUILD_TARGET), solaris darwin linux) +if1of ($(KBUILD_TARGET), solaris darwin linux freebsd) # # VBoxNetAdp - Virtual Network Adapter # Note! On Solaris the name has to be <= 8 chars long. @@ -34,6 +34,7 @@ VBoxNetAdp_INST = $(INST_VBOXNETADP)$(if $(eq $(KBUILD_TARGET),darwin),Contents/MacOS/) VBoxNetAdp_NAME.solaris = vboxnet VBoxNetAdp_NAME.linux = vboxnetadp +VBoxNetAdp_NAME.freebsd = vboxnetadp VBoxNetAdp_NOINST.linux = true VBoxNetAdp_DEPS.solaris += $(VBOX_SVN_REV_KMK) VBoxNetAdp_DEFS = IN_RT_R0 VBOX_SVN_REV=$(VBOX_SVN_REV) IN_SUP_STATIC @@ -51,6 +52,9 @@ VBoxNetAdp_SOURCES.linux = \ linux/VBoxNetAdp-linux.c \ VBoxNetAdp.c +VBoxNetAdp_SOURCES.freebsd = \ + freebsd/VBoxNetAdp-freebsd.c \ + VBoxNetAdp.c VBoxNetAdp_SOURCES = #VBoxNetAdp_SOURCES = \ # VBoxNetAdp.c