VirtualBox

Changeset 18802 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 7, 2009 11:06:41 AM (16 years ago)
Author:
vboxsync
Message:

2957: Dynamic add/remove via /dev/vboxnetctl ioctls.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h

    r17256 r18802  
    4242# define VBOXNETADP_DETACH_TIMEOUT 500
    4343#endif
     44
     45#define VBOXNETADP_CTL_DEV_NAME    "vboxnetctl"
     46#define VBOXNETADP_CTL_ADD    _IOR('v', 1, VBOXNETADPREQ)
     47#define VBOXNETADP_CTL_REMOVE _IOW('v', 2, VBOXNETADPREQ)
     48
     49typedef struct VBoxNetAdpReq
     50{
     51    char szName[VBOXNETADP_MAX_NAME_LEN];
     52} VBOXNETADPREQ;
     53typedef VBOXNETADPREQ *PVBOXNETADPREQ;
    4454
    4555/**
     
    6575*/
    6676
    67 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT
    6877enum VBoxNetAdpState
    6978{
    7079    kVBoxNetAdpState_Invalid,
    7180    kVBoxNetAdpState_Transitional,
     81#ifdef VBOXANETADP_DO_NOT_USE_NETFLT
    7282    kVBoxNetAdpState_Available,
    7383    kVBoxNetAdpState_Connected,
    74     kVBoxNetAdpState_Active
     84#endif /* VBOXANETADP_DO_NOT_USE_NETFLT */
     85    kVBoxNetAdpState_Active,
     86    kVBoxNetAdpState_U32Hack = 0xFFFFFFFF
    7587};
    7688typedef enum VBoxNetAdpState VBOXNETADPSTATE;
    77 #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */
    7889
    7990struct VBoxNetAdapter
     
    8596    /* --- Protected with spinlock. --- */
    8697
     98#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    8799    /** Denotes availability of this slot in adapter array. */
    88100    VBOXNETADPSTATE   enmState;
     101#ifdef VBOXANETADP_DO_NOT_USE_NETFLT
    89102
    90103    /* --- Unprotected. Atomic access. --- */
  • trunk/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp

    r17256 r18802  
    5757#include <sys/errno.h>
    5858#include <sys/param.h>
     59#include <sys/conf.h>
     60#include <miscfs/devfs/devfs.h>
    5961
    6062#define VBOXNETADP_OS_SPECFIC 1
     
    7476#define VBOXNETADP_FROM_IFACE(iface) ((PVBOXNETADP) ifnet_softc(iface))
    7577
     78/* debug printf */
     79#if defined(RT_OS_WINDOWS)
     80# define OSDBGPRINT(a) DbgPrint a
     81#elif defined(RT_OS_LINUX)
     82# define OSDBGPRINT(a) printk a
     83#elif defined(RT_OS_DARWIN)
     84# define OSDBGPRINT(a) printf a
     85#elif defined(RT_OS_OS2)
     86# define OSDBGPRINT(a) SUPR0Printf a
     87#elif defined(RT_OS_FREEBSD)
     88# define OSDBGPRINT(a) printf a
     89#elif defined(RT_OS_SOLARIS)
     90# define OSDBGPRINT(a) SUPR0Printf a
     91#else
     92# define OSDBGPRINT(a)
     93#endif
     94
    7695/*******************************************************************************
    7796*   Internal Functions                                                         *
     
    82101__END_DECLS
    83102
     103static int VBoxNetAdpDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
     104static int VBoxNetAdpDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
     105static int VBoxNetAdpDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
     106
    84107/*******************************************************************************
    85108*   Global Variables                                                           *
     
    105128
    106129#else /* !VBOXANETADP_DO_NOT_USE_NETFLT */
     130
     131static int   g_nCtlDev = -1; /* Major dev number */
     132static void *g_hCtlDev = 0;  /* FS dev handle */
     133
     134/**
     135 * The character device switch table for the driver.
     136 */
     137static struct cdevsw    g_ChDev =
     138{
     139    /*.d_open     = */VBoxNetAdpDarwinOpen,
     140    /*.d_close    = */VBoxNetAdpDarwinClose,
     141    /*.d_read     = */eno_rdwrt,
     142    /*.d_write    = */eno_rdwrt,
     143    /*.d_ioctl    = */VBoxNetAdpDarwinIOCtl,
     144    /*.d_stop     = */eno_stop,
     145    /*.d_reset    = */eno_reset,
     146    /*.d_ttys     = */NULL,
     147    /*.d_select   = */eno_select,
     148    /*.d_mmap     = */eno_mmap,
     149    /*.d_strategy = */eno_strat,
     150    /*.d_getc     = */eno_getc,
     151    /*.d_putc     = */eno_putc,
     152    /*.d_type     = */0
     153};
    107154
    108155/**
     
    128175    pMac->au8[5] = pThis->uUnit;
    129176}
     177
    130178#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    131179
     
    619667}
    620668#else /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    621 VBOXNETADP g_vboxnet0;
     669//VBOXNETADP g_vboxnet0;
     670VBOXNETADP g_aAdapters[VBOXNETADP_MAX_INSTANCES];
    622671
    623672#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
     673
    624674
    625675
     
    634684    rc = RTSemEventCreate(&pThis->u.s.hEvtDetached);
    635685    if (RT_FAILURE(rc))
     686    {
     687        OSDBGPRINT(("vboxNetAdpOsCreate: failed to create semaphore (rc=%d).\n", rc));
    636688        return rc;
     689    }
    637690
    638691    mac.sdl_len = sizeof(mac);
     
    688741        Log(("vboxNetAdpDarwinRegisterDevice: Failed to allocate interface (err=%d).\n", err));
    689742
     743    RTSemEventDestroy(pThis->u.s.hEvtDetached);
     744    pThis->u.s.hEvtDetached = NIL_RTSEMEVENT;
     745
    690746    return RTErrConvertFromErrno(err);
    691747}
     
    727783}
    728784
     785int vboxNetAdpCreate (PVBOXNETADP *ppNew)
     786{
     787    int rc;
     788    unsigned i;
     789    for (i = 0; i < RT_ELEMENTS(g_aAdapters); i++)
     790    {
     791        PVBOXNETADP pThis = &g_aAdapters[i];
     792
     793        if (ASMAtomicCmpXchgU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Transitional, kVBoxNetAdpState_Invalid))
     794        {
     795            /* Found an empty slot -- use it. */
     796            Log(("vboxNetAdpCreate: found empty slot: %d\n", i));
     797            RTMAC Mac;
     798            vboxNetAdpComposeMACAddress(pThis, &Mac);
     799            rc = vboxNetAdpOsCreate(pThis, &Mac);
     800            if (RT_SUCCESS(rc))
     801            {
     802                *ppNew = pThis;
     803                ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Active);
     804            }
     805            else
     806            {
     807                ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Invalid);
     808                Log(("vboxNetAdpCreate: vboxNetAdpOsCreate failed with '%Rrc'.\n", rc));
     809            }
     810            return rc;
     811        }
     812    }
     813    Log(("vboxNetAdpCreate: no empty slots!\n"));
     814
     815    /* All slots in adapter array are busy. */
     816    return VERR_OUT_OF_RESOURCES;
     817}
     818
     819int vboxNetAdpDestroy (PVBOXNETADP pThis)
     820{
     821    int rc = VINF_SUCCESS;
     822
     823    if (!ASMAtomicCmpXchgU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Transitional, kVBoxNetAdpState_Active))
     824        return VERR_INTNET_FLT_IF_BUSY;
     825
     826    vboxNetAdpOsDestroy(pThis);
     827
     828    ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Invalid);
     829
     830    return rc;
     831}
     832
     833/**
     834 * Device open. Called on open /dev/vboxnetctl
     835 *
     836 * @param   pInode      Pointer to inode info structure.
     837 * @param   pFilp       Associated file pointer.
     838 */
     839static int VBoxNetAdpDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
     840{
     841    char szName[128];
     842    szName[0] = '\0';
     843    proc_name(proc_pid(pProcess), szName, sizeof(szName));
     844    Log(("VBoxNetAdpDarwinOpen: pid=%d '%s'\n", proc_pid(pProcess), szName));
     845    return 0;
     846}
     847
     848/**
     849 * Close device.
     850 */
     851static int VBoxNetAdpDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
     852{
     853    Log(("VBoxNetAdpDarwinClose: pid=%d\n", proc_pid(pProcess)));
     854    return 0;
     855}
     856
     857/**
     858 * Device I/O Control entry point.
     859 *
     860 * @returns Darwin for slow IOCtls and VBox status code for the fast ones.
     861 * @param   Dev         The device number (major+minor).
     862 * @param   iCmd        The IOCtl command.
     863 * @param   pData       Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)).
     864 * @param   fFlags      Flag saying we're a character device (like we didn't know already).
     865 * @param   pProcess    The process issuing this request.
     866 */
     867static int VBoxNetAdpDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
     868{
     869    int rc = VINF_SUCCESS;
     870    uint32_t cbReq = IOCPARM_LEN(iCmd);
     871    PVBOXNETADPREQ pReq = (PVBOXNETADPREQ)pData;
     872
     873    Log(("VBoxNetAdpDarwinIOCtl: param len %#x; iCmd=%#lx\n", cbReq, iCmd));
     874    switch (IOCBASECMD(iCmd))
     875    {
     876        case IOCBASECMD(VBOXNETADP_CTL_ADD):
     877            if ((IOC_DIRMASK & iCmd) == IOC_OUT)
     878            {
     879                PVBOXNETADP pNew;
     880                rc = vboxNetAdpCreate(&pNew);
     881                if (RT_SUCCESS(rc))
     882                {
     883                    if (cbReq < sizeof(VBOXNETADPREQ))
     884                    {
     885                        OSDBGPRINT(("VBoxNetAdpDarwinIOCtl: param len %#x < req size %#x; iCmd=%#lx\n", cbReq, sizeof(VBOXNETADPREQ), iCmd));
     886                        return EINVAL;
     887                    }
     888                    strncpy(pReq->szName, pNew->szName, sizeof(pReq->szName));
     889                }
     890            }
     891            break;
     892
     893        case IOCBASECMD(VBOXNETADP_CTL_REMOVE):
     894            for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++)
     895            {
     896                PVBOXNETADP pThis = &g_aAdapters[i];
     897                rc = VERR_NOT_FOUND;
     898                if (strncmp(pThis->szName, pReq->szName, VBOXNETADP_MAX_NAME_LEN) == 0)
     899                    if (ASMAtomicReadU32((uint32_t volatile *)&pThis->enmState) == kVBoxNetAdpState_Active)
     900                    {
     901                        rc = vboxNetAdpDestroy(pThis);
     902                        break;
     903                    }
     904            }
     905            break;
     906        default:
     907            OSDBGPRINT(("VBoxNetAdpDarwinIOCtl: unknown command %x.\n", IOCBASECMD(iCmd)));
     908            rc = VERR_INVALID_PARAMETER;
     909            break;
     910    }
     911
     912    return RT_SUCCESS(rc) ? 0 : EINVAL;
     913}
     914
    729915int  vboxNetAdpOsInit(PVBOXNETADP pThis)
    730916{
     
    732918     * Init the darwin specific members.
    733919     */
     920    pThis->enmState = kVBoxNetAdpState_Invalid;
    734921    pThis->u.s.pIface = NULL;
    735922    pThis->u.s.hEvtDetached = NIL_RTSEMEVENT;
     
    764951        rc = vboxNetAdpInitGlobals(&g_VBoxNetAdpGlobals);
    765952#else /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    766         RTMAC Mac;
    767         vboxNetAdpOsInit(&g_vboxnet0);
    768         vboxNetAdpComposeMACAddress(&g_vboxnet0, &Mac);
    769         rc = vboxNetAdpOsCreate(&g_vboxnet0, &Mac);
     953        for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++)
     954        {
     955            g_aAdapters[i].uUnit = i;
     956            vboxNetAdpOsInit(&g_aAdapters[i]);
     957        }
     958
     959        PVBOXNETADP pVboxnet0;
     960        rc = vboxNetAdpCreate(&pVboxnet0);
     961        if (RT_SUCCESS(rc))
     962        {
     963            g_nCtlDev = cdevsw_add(-1, &g_ChDev);
     964            if (g_nCtlDev < 0)
     965            {
     966                LogRel(("VBoxAdp: failed to register control device."));
     967                rc = VERR_CANT_CREATE;
     968            }
     969            else
     970            {
     971                g_hCtlDev = devfs_make_node(makedev(g_nCtlDev, 0), DEVFS_CHAR,
     972                                            UID_ROOT, GID_WHEEL, 0600, VBOXNETADP_CTL_DEV_NAME);
     973                if (!g_hCtlDev)
     974                {
     975                    LogRel(("VBoxAdp: failed to create FS node for control device."));
     976                    rc = VERR_CANT_CREATE;
     977                }
     978            }
     979        }
     980
    770981#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    771982        if (RT_SUCCESS(rc))
     
    8131024    memset(&g_VBoxNetAdpGlobals, 0, sizeof(g_VBoxNetAdpGlobals));
    8141025#else /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    815     vboxNetAdpOsDestroy(&g_vboxnet0);
     1026    /* Remove virtual adapters */
     1027    for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++)
     1028        vboxNetAdpDestroy(&g_aAdapters[i]);
     1029    /* Remove control device */
     1030    devfs_remove(g_hCtlDev);
     1031    cdevsw_remove(g_nCtlDev, &g_ChDev);
    8161032#endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */
    8171033
  • trunk/src/VBox/Runtime/VBox/log-vbox.cpp

    r18602 r18802  
    419419# endif
    420420# if defined(DEBUG_aleksey)  /* Guest ring-0 as well */
    421         RTLogGroupSettings(pLogger, "+net_tap_drv.e.l.f+net_flt_drv.e.l.f+srv_intnet.e.l.f");
     421        RTLogGroupSettings(pLogger, "+net_adp_drv.e.l.f+net_flt_drv.e.l.f+srv_intnet.e.l.f");
    422422        RTLogFlags(pLogger, "enabled unbuffered");
    423423        pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette