VirtualBox

Changeset 18859 in vbox for trunk/src


Ignore:
Timestamp:
Apr 10, 2009 8:24:55 AM (16 years ago)
Author:
vboxsync
Message:

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

Location:
trunk/src
Files:
4 edited

Legend:

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

    r18803 r18859  
    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

    r18803 r18859  
    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

    r18803 r18859  
    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;
  • trunk/src/apps/adpctl/VBoxNetAdpCtl.cpp

    r18803 r18859  
    3131#include <unistd.h>
    3232#include <sys/wait.h>
     33#include <sys/ioctl.h>
     34#include <fcntl.h>
     35
     36/* @todo Error codes must be moved to some header file */
     37#define ADPCTLERR_NO_CTL_DEV 3
     38#define ADPCTLERR_IOCTL_FAILED 4
     39
     40/* @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */
     41#define VBOXNETADP_CTL_DEV_NAME    "/dev/vboxnetctl"
     42#define VBOXNETADP_NAME            "vboxnet"
     43#define VBOXNETADP_MAX_NAME_LEN    32
     44#define VBOXNETADP_CTL_ADD    _IOR('v', 1, VBOXNETADPREQ)
     45#define VBOXNETADP_CTL_REMOVE _IOW('v', 2, VBOXNETADPREQ)
     46typedef struct VBoxNetAdpReq
     47{
     48    char szName[VBOXNETADP_MAX_NAME_LEN];
     49} VBOXNETADPREQ;
     50typedef VBOXNETADPREQ *PVBOXNETADPREQ;
     51
    3352
    3453#define VBOXADPCTL_IFCONFIG_PATH "/sbin/ifconfig"
     
    4362{
    4463    fprintf(stderr, "Usage: VBoxNetAdpCtl <adapter> <address> ([netmask <address>] | remove)\n");
     64    fprintf(stderr, "     | VBoxNetAdpCtl add\n");
     65    fprintf(stderr, "     | VBoxNetAdpCtl <adapter> remove\n");
    4566}
    4667
     
    131152}
    132153
     154int doIOCtl(unsigned long uCmd, void *pData)
     155{
     156    int fd = open(VBOXNETADP_CTL_DEV_NAME, O_RDWR);
     157    if (fd == -1)
     158    {
     159        perror("VBoxNetAdpCtl: failed to open " VBOXNETADP_CTL_DEV_NAME);
     160        return ADPCTLERR_NO_CTL_DEV;
     161    }
     162
     163    int rc = ioctl(fd, uCmd, pData);
     164    if (rc == -1)
     165    {
     166        perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME);
     167        rc = ADPCTLERR_IOCTL_FAILED;
     168    }
     169   
     170    close(fd);
     171 
     172    return rc;
     173}
    133174
    134175int main(int argc, char *argv[])
     
    141182    int rc = EXIT_SUCCESS;
    142183    bool fRemove = false;
     184    VBOXNETADPREQ Req;
    143185
    144186    switch (argc)
     
    170212            pszAdapterName = argv[1];
    171213            pszAddress = argv[2];
    172             break;
     214            if (strcmp("remove", pszAddress) == 0)
     215            {
     216                strncpy(Req.szName, pszAdapterName, sizeof(Req.szName));
     217                return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req);
     218            }
     219            break;
     220        case 2:
     221            if (strcmp("add", argv[1]) == 0)
     222            {
     223                rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req);
     224                if (rc == 0)
     225                    puts(Req.szName);
     226                return rc;
     227            }
     228            /* Fall through */
    173229        default:
    174230            fprintf(stderr, "Invalid number of arguments.\n\n");
     
    179235    }
    180236
    181     if (strcmp("vboxnet0", pszAdapterName))
     237    if (strncmp("vboxnet", pszAdapterName, 7))
    182238    {
    183239        fprintf(stderr, "Setting configuration for %s is not supported.\n", pszAdapterName);
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