VirtualBox

Changeset 5719 in vbox


Ignore:
Timestamp:
Nov 13, 2007 11:05:17 AM (17 years ago)
Author:
vboxsync
Message:

Solaris crossbow: allow using existing interfaces.

Location:
trunk/src/VBox/Devices
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r5718 r5719  
    138138 VBoxDD_LIBS           += adm
    139139 ifdef VBOX_WITH_CROSSBOW
    140   VBoxDD_LIBS          += dladm # or maybe try libdladm.so.1 ?
     140  VBoxDD_LIBS          += dlpi
    141141 endif
    142142 ifdef VBOX_WITH_SUID_WRAPPER
     
    530530 ifdef VBOX_WITH_CROSSBOW
    531531  Drivers_DEFS += VBOX_WITH_CROSSBOW
    532   Drivers_INCS += \
    533         Network/solaris
    534532 endif
    535533 ifdef VBOX_WITH_SUID_WRAPPER
  • trunk/src/VBox/Devices/Network/DrvTAP.cpp

    r5701 r5719  
    5959# include <ctype.h>
    6060# include <stdlib.h>
     61# include <stdio.h>
    6162# ifdef VBOX_WITH_CROSSBOW
    62 #  include <limits.h>
    6363#  include <libdlpi.h>
    64 #  include <libdlvnic.h>
    6564# endif
    6665#else
     
    105104    char                   *pszDeviceName;
    106105#ifdef RT_OS_SOLARIS
    107     /** The actual TAP/VNIC device name. */
    108     char                   *pszDeviceNameActual;
    109106# ifdef VBOX_WITH_CROSSBOW
    110107    /** Crossbow: MAC address of the device. */
     
    112109    /** Crossbow: Handle of the NIC. */
    113110    dlpi_handle_t           pDeviceHandle;
    114     /** Crossbow: ID of the virtual NIC. */
    115     uint_t                  uDeviceID;
    116111# else
    117112    /** IP device file handle (/dev/udp). */
    118113    RTFILE                  IPFileDevice;
    119114# endif
     115    /** Whether device name is obtained from setup application. */
     116    bool                    fStatic;
    120117#endif
    121118    /** TAP setup application. */
     
    174171#ifdef RT_OS_SOLARIS
    175172# ifdef VBOX_WITH_CROSSBOW
    176 static int              SolarisCreateVNIC(PDRVTAP pData);
    177 static int              SolarisGetNIC(char *pszNICName, size_t cbSize);
    178 static int              SolarisOpenNIC(PDRVTAP pData, const char *pszNICName);
     173static int              SolarisOpenVNIC(PDRVTAP pData);
    179174static int              SolarisDLPIErr2VBoxErr(int rc);
    180175# else
    181 static int              SolarisTAPAttach(PPDMDRVINS pDrvIns);
     176static int              SolarisTAPAttach(PDRVTAP pData);
    182177# endif
    183178#endif
     
    509504static int drvTAPSetupApplication(PDRVTAP pData)
    510505{
     506    char szCommand[4096];
     507
     508#ifdef VBOX_WITH_CROSSBOW
     509    /* Convert MAC address bytes to string (required by Solaris' dladm). */
     510    char *pszHex = "0123456789abcdef";
     511    uint8_t *pMacAddr8 = pData->MacAddress.au8;
     512    char szMacAddress[3 * sizeof(PDMMAC)];
     513    for (unsigned int i = 0; i < sizeof(PDMMAC); i++)
     514    {
     515        szMacAddress[3 * i] = pszHex[((*pMacAddr8 >> 4) & 0x0f)];
     516        szMacAddress[3 * i + 1] = pszHex[(*pMacAddr8 & 0x0f)];
     517        szMacAddress[3 * i + 2] = ':';
     518        *pMacAddr8++;
     519    }
     520    szMacAddress[sizeof(szMacAddress) - 1] =  0;
     521
     522    RTStrPrintf(szCommand, sizeof(szCommand), "%s %s %s", pData->pszSetupApplication,
     523            szMacAddress, pData->fStatic ? pData->pszDeviceName : "");
     524#else
     525    RTStrPrintf(szCommand, sizeof(szCommand), "%s %s", pData->pszSetupApplication,
     526            pData->fStatic ? pData->pszDeviceName : "");
     527#endif
     528
     529    /* Pipe open the setup application. */
     530    Log2(("Starting TAP setup application: %s\n", szCommand));
     531    FILE* pfSetupHandle = popen(szCommand, "r");
     532    if (pfSetupHandle == 0)
     533    {
     534        LogRel(("TAP#%d: Failed to run TAP setup application: %s\n", pData->pDrvIns->iInstance,
     535              pData->pszSetupApplication, strerror(errno)));
     536        return VERR_HOSTIF_INIT_FAILED;
     537    }
     538    if (!pData->fStatic)
     539    {
     540        /* Obtain device name from setup application. */
     541        char acBuffer[64];
     542        size_t cBufSize;
     543        fgets(acBuffer, sizeof(acBuffer), pfSetupHandle);
     544        cBufSize = strlen(acBuffer);
     545        /* The script must return the name of the interface followed by a carriage return as the
     546          first line of its output.  We need a null-terminated string. */
     547        if ((cBufSize < 2) || (acBuffer[cBufSize - 1] != '\n'))
     548        {
     549            pclose(pfSetupHandle);
     550            LogRel(("The TAP interface setup script did not return the name of a TAP device.\n"));
     551            return VERR_HOSTIF_INIT_FAILED;
     552        }
     553        /* Overwrite the terminating newline character. */
     554        acBuffer[cBufSize - 1] = 0;
     555        RTStrAPrintf(&pData->pszDeviceName, "%s", acBuffer);
     556    }
     557    int rc = pclose(pfSetupHandle);
     558    if (!WIFEXITED(rc))
     559    {
     560        LogRel(("The TAP interface setup script terminated abnormally.\n"));
     561        return VERR_HOSTIF_INIT_FAILED;
     562    }
     563    if (WEXITSTATUS(rc) != 0)
     564    {
     565        LogRel(("The TAP interface setup script returned a non-zero exit code.\n"));
     566        return VERR_HOSTIF_INIT_FAILED;
     567    }
     568    return VINF_SUCCESS;
     569}
     570
     571
     572/**
     573 * Calls OS-specific TAP terminate application/script.
     574 *
     575 * @returns VBox error code.
     576 * @param   pData           The instance data.
     577 */
     578static int drvTAPTerminateApplication(PDRVTAP pData)
     579{
    511580    char *pszArgs[3];
    512     pszArgs[0] = pData->pszSetupApplication;
    513     pszArgs[1] = pData->pszDeviceNameActual;
     581    pszArgs[0] = pData->pszTerminateApplication;
     582    pszArgs[1] = pData->pszDeviceName;
    514583    pszArgs[2] = NULL;
    515584
    516     Log2(("Starting TAP setup application: %s %s\n", pData->pszSetupApplication, pData->pszDeviceNameActual));
     585    Log2(("Starting TAP terminate application: %s %s\n", pData->pszTerminateApplication, pData->pszDeviceName));
    517586    RTPROCESS pid = NIL_RTPROCESS;
    518587    int rc = RTProcCreate(pszArgs[0], pszArgs, RTENV_DEFAULT, 0, &pid);
     
    527596                return VINF_SUCCESS;
    528597
    529             LogRel(("TAP#%d: Error running TAP setup application: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication));
    530         }
    531         else
    532             LogRel(("TAP#%d: RTProcWait failed for: %s\n", pData->pDrvIns->iInstance, pData->pszSetupApplication));
    533     }
    534     else
    535     {
    536         /* Bad. RTProcCreate() failed! */
    537         LogRel(("TAP#%d: Failed to fork() process for running TAP setup application: %s\n", pData->pDrvIns->iInstance,
    538               pData->pszSetupApplication, strerror(errno)));
    539     }
    540 
    541     return VERR_HOSTIF_INIT_FAILED;
    542 }
    543 
    544 
    545 /**
    546  * Calls OS-specific TAP terminate application/script.
    547  *
    548  * @returns VBox error code.
    549  * @param   pData           The instance data.
    550  */
    551 static int drvTAPTerminateApplication(PDRVTAP pData)
    552 {
    553     char *pszArgs[3];
    554     pszArgs[0] = pData->pszTerminateApplication;
    555     pszArgs[1] = pData->pszDeviceNameActual;
    556     pszArgs[2] = NULL;
    557 
    558     Log2(("Starting TAP terminate application: %s %s\n", pData->pszTerminateApplication, pData->pszDeviceNameActual));
    559     RTPROCESS pid = NIL_RTPROCESS;
    560     int rc = RTProcCreate(pszArgs[0], pszArgs, RTENV_DEFAULT, 0, &pid);
    561     if (RT_SUCCESS(rc))
    562     {
    563         RTPROCSTATUS Status;
    564         rc = RTProcWait(pid, 0, &Status);
    565         if (RT_SUCCESS(rc))
    566         {
    567             if (    Status.iStatus == 0
    568                 &&  Status.enmReason == RTPROCEXITREASON_NORMAL)
    569                 return VINF_SUCCESS;
    570 
    571598            LogRel(("TAP#%d: Error running TAP terminate application: %s\n", pData->pDrvIns->iInstance, pData->pszTerminateApplication));
    572599        }
     
    589616# ifdef VBOX_WITH_CROSSBOW
    590617/**
    591  * Crossbow: create a virtual NIC.
     618 * Crossbow: Open & configure the virtual NIC.
    592619 *
    593620 * @returns VBox error code.
    594621 * @param   pData           The instance data.
    595622 */
    596 static int SolarisCreateVNIC(PDRVTAP pData)
    597 {
    598     /*
    599      * Get a physical NIC.
    600      */
    601     /** @todo r=bird: I'm I right in thinking that this just gets the name of the
    602      * last ethernet NIC and binds us to that? If so, this really needs to be
    603      * a user option. On OS/2 this is passed in as 'ConnectTo', using the same name
    604      * is possibly a good idea even if the type is different (we need string not integer). */
    605     char szNICName[_LIFNAMSIZ];
    606     int ret = SolarisGetNIC(szNICName, sizeof(szNICName));
    607     if (VBOX_FAILURE(ret))
    608          return VERR_HOSTIF_INIT_FAILED;
    609 
    610     /*
    611      * Setup VNIC parameters.
    612      */
    613     dladm_vnic_attr_sys_t VNICAttr;
    614     memset(&VNICAttr, 0, sizeof(VNICAttr));
    615     size_t cbDestSize = sizeof(VNICAttr.va_dev_name);
    616     if (strlcpy(VNICAttr.va_dev_name, szNICName, cbDestSize) >= cbDestSize)
    617         return VERR_BUFFER_OVERFLOW;
    618     Assert(sizeof(struct ether_addr) == sizeof(pData->MacAddress));
    619     memcpy(VNICAttr.va_mac_addr, &pData->MacAddress, ETHERADDRL);
    620     VNICAttr.va_mac_len = ETHERADDRL;
    621 
    622     uint_t VnicID;
    623     bool fAutoID = true;
    624 #if 0
    625     /* Disabled for now, since Crossbow does not entirely respect our own VNIC ID.*/
    626     if (pData->pszDeviceName)
    627     {
    628         size_t cch = strlen(pData->pszDeviceName);
    629         if (cch > 1 && isdigit(pData->pszDeviceName[cch - 1]) != 0)
    630         {
    631             VnicID = pData->pszDeviceName[cch - 1] - '0';
    632             fAutoID = false;
    633         }
    634     }
    635 #endif
    636 
    637     /*
    638      * Create the VNIC.
    639      */
    640 /** r=bird: The users should be able to create the vnic himself and pass it down. This would be the
    641  * same as the tapN interface name.  */
    642     uint32_t flags = DLADM_VNIC_OPT_TEMP;
    643     if (fAutoID)
    644         flags |= DLADM_VNIC_OPT_AUTOID;
    645 
    646     dladm_status_t rc = dladm_vnic_create(fAutoID ? 0 : VnicID, szNICName, VNIC_MAC_ADDR_TYPE_FIXED,
    647                            (uchar_t *)&pData->MacAddress, ETHERADDRL, &VnicID, flags);
    648     if (rc != DLADM_STATUS_OK)
    649         return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    650                            N_("dladm_vnic_create() failed. NIC %s probably incorrect."), szNICName);
    651 
    652     pData->pszDeviceNameActual = NULL;
    653     RTStrAPrintf(&pData->pszDeviceNameActual, "vnic%u", VnicID);
    654     pData->uDeviceID = VnicID;
    655 
    656     ret = SolarisOpenNIC(pData, szNICName);
    657     if (VBOX_FAILURE(ret))
    658         return ret;
    659     return VINF_SUCCESS;
    660 }
    661 
    662 
    663 /**
    664  * Crossbow: Obtain a physical NIC for binding the virtual NIC.
    665  *
    666  * @returns VBox error code.
    667  * @param   pszNICName      Where to store the NIC name.
    668  * @param   cchNICName      The size of the buffer buffer pszNICName points to.
    669  */
    670 static int SolarisGetNIC(char *pszNICName, size_t cchNICName)
    671 {
    672     /*
    673      * Try and obtain the a physical NIC to bind the VNIC to.
    674      */
    675     int InetSocket = socket(AF_INET, SOCK_DGRAM, 0);
    676     if (RT_UNLIKELY(InetSocket == -1))
    677     {
    678         LogRel(("SolarisGetNIC: Socket creation for AF_INET family failed.\n"));
    679         return VERR_HOSTIF_INIT_FAILED;
    680     }
    681 
    682     int rc;
    683     struct lifnum IfNum;
    684     IfNum.lifn_family = AF_UNSPEC;
    685     if (ioctl(InetSocket, SIOCGLIFNUM, &IfNum) >= 0)
    686     {
    687         caddr_t pBuf = (caddr_t)RTMemAlloc(IfNum.lifn_count * sizeof(struct lifreq));
    688         if (pBuf)
    689         {
    690             struct lifconf IfCfg;
    691             memset(&IfCfg, 0, sizeof(IfCfg));
    692             IfCfg.lifc_family = AF_UNSPEC;
    693             IfCfg.lifc_buf = pBuf;
    694             IfCfg.lifc_len = IfNum.lifn_count * sizeof(struct lifreq);
    695             if (ioctl(InetSocket, SIOCGLIFCONF, &IfCfg) >= 0)
    696             {
    697                 /*
    698                  * Loop through all NICs on the machine. We'll use the first ethernet NIC
    699                  * that is not a loopback interface for binding the VNIC.
    700                  */
    701                 rc = VERR_GENERAL_FAILURE;    /** @todo find a better return code. */
    702                 struct lifreq *paIf = IfCfg.lifc_req;
    703                 int iIf = IfCfg.lifc_len / sizeof(struct lifreq);
    704                 while (iIf-- > 0)
    705                     if (strncmp(paIf[iIf].lifr_name, "lo", 2) != 0)
    706                     {
    707                         dlpi_handle_t hNIC = NULL;
    708                         if (dlpi_open(paIf[iIf].lifr_name, &hNIC, DLPI_RAW) == DLPI_SUCCESS)
    709                         {
    710                             dlpi_info_t NICInfo;
    711                             int rc2 = dlpi_info(hNIC, &NICInfo, 0);
    712                             dlpi_close(hNIC);
    713                             if (    rc2 == DLPI_SUCCESS
    714                                 &&  NICInfo.di_mactype == DL_ETHER)
    715                             {
    716                                 size_t cch = strlen(paIf[iIf].lifr_name);
    717                                 if (cch < cchNICName)
    718                                 {
    719                                     memcpy(pszNICName, paIf[iIf].lifr_name, cch + 1);
    720                                     rc = VINF_SUCCESS;
    721                                 }
    722                                 else
    723                                     rc = VERR_BUFFER_OVERFLOW;
    724                                 break;
    725                             }
    726                         }
    727                     }
    728             }
    729             else
    730             {
    731                 LogRel(("SolarisGetNIC: SIOCGLIFCONF failed\n"));
    732                 rc = VERR_HOSTIF_INIT_FAILED;
    733             }
    734             RTMemFree(pBuf);
    735         }
    736         else
    737             rc = VERR_NO_MEMORY;
    738     }
    739     else
    740     {
    741         LogRel(("SolarisGetNIC: SIOCGLIFNUM failed\n"));
    742         rc = VERR_HOSTIF_INIT_FAILED;
    743     }
    744     close(InetSocket);
    745     return rc;
    746 }
    747 
    748 
    749 /**
    750  * Crossbow: Open & configure the physical NIC.
    751  *
    752  * @returns VBox error code.
    753  * @param   pData           The instance data.
    754  * @param   pszNICName      Name of the physical NIC.
    755  * @param   pEtherAddr      Ethernet address to use for the VNIC.
    756  */
    757 static int SolarisOpenNIC(PDRVTAP pData, const char *pszNICName)
     623static int SolarisOpenVNIC(PDRVTAP pData)
    758624{
    759625    /*
    760626     * Open & bind the NIC using the datalink provider routine.
    761627     */
    762     int rc = dlpi_open(pszNICName, &pData->pDeviceHandle, DLPI_RAW);
     628    int rc = dlpi_open(pData->pszDeviceName, &pData->pDeviceHandle, DLPI_RAW);
    763629    if (rc != DLPI_SUCCESS)
    764630        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    765                            N_("Failed to open VNIC in raw mode."));
    766 
    767     /*
    768      * If we decide to get NIC name directly from user/env var., we will
    769      * need to checks here to make sure the NIC has a ethernet address.
    770      */
    771     rc = dlpi_bind(pData->pDeviceHandle, DLPI_ANY_SAP, NULL);
     631                           N_("Failed to open VNIC \"%s\" in raw mode."), pData->pszDeviceName);
     632
     633    dlpi_info_t vnicInfo;
     634    rc = dlpi_info(pData->pDeviceHandle, &vnicInfo, 0);
    772635    if (rc == DLPI_SUCCESS)
    773636    {
    774         rc = dlpi_set_physaddr(pData->pDeviceHandle, DL_CURR_PHYS_ADDR, &pData->MacAddress, ETHERADDRL);
    775         if (rc == DLPI_SUCCESS)
     637        if (vnicInfo.di_mactype == DL_ETHER)
    776638        {
    777             rc = dlpi_promiscon(pData->pDeviceHandle, DL_PROMISC_SAP);
     639            rc = dlpi_bind(pData->pDeviceHandle, DLPI_ANY_SAP, NULL);
    778640            if (rc == DLPI_SUCCESS)
    779641            {
    780                 /* Need to use DL_PROMIS_PHYS (not multicast) as we cannot be sure what the guest needs. */
    781                 rc = dlpi_promiscon(pData->pDeviceHandle, DL_PROMISC_PHYS);
     642                rc = dlpi_set_physaddr(pData->pDeviceHandle, DL_CURR_PHYS_ADDR, &pData->MacAddress, ETHERADDRL);
    782643                if (rc == DLPI_SUCCESS)
    783644                {
    784                     pData->FileDevice = dlpi_fd(pData->pDeviceHandle);
    785                     if (pData->FileDevice >= 0)
     645                    rc = dlpi_promiscon(pData->pDeviceHandle, DL_PROMISC_SAP);
     646                    if (rc == DLPI_SUCCESS)
    786647                    {
    787                         Log(("SolarisOpenNIC: %s -> %d\n", pszNICName, pData->FileDevice));
    788                         return VINF_SUCCESS;
     648                        /* Need to use DL_PROMIS_PHYS (not multicast) as we cannot be sure what the guest needs. */
     649                        rc = dlpi_promiscon(pData->pDeviceHandle, DL_PROMISC_PHYS);
     650                        if (rc == DLPI_SUCCESS)
     651                        {
     652                            pData->FileDevice = dlpi_fd(pData->pDeviceHandle);
     653                            if (pData->FileDevice >= 0)
     654                            {
     655                                Log(("SolarisOpenVNIC: %s -> %d\n", pData->pszDeviceName, pData->FileDevice));
     656                                return VINF_SUCCESS;
     657                            }
     658
     659                            rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
     660                                                     N_("Failed to obtain file descriptor for VNIC."));
     661                        }
     662                        else
     663                            rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
     664                                                     N_("Failed to set appropriate promiscous mode."));
    789665                    }
    790 
    791                     rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    792                                              N_("Failed to obtain file descriptor for VNIC."));
     666                    else
     667                        rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
     668                                                 N_("Failed to activate promiscous mode for VNIC."));
    793669                }
    794670                else
    795671                    rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    796                                              N_("Failed to set appropriate promiscous mode."));
     672                                             N_("Failed to set physical address for VNIC."));
    797673            }
    798674            else
    799675                rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    800                                          N_("Failed to activate promiscous mode for VNIC."));
     676                                         N_("Failed to bind VNIC."));
    801677        }
    802678        else
    803679            rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    804                                      N_("Failed to set physical address for VNIC."));
     680                                         N_("VNIC type is not ethernet."));
    805681    }
    806682    else
    807683        rc = PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    808                                  N_("Failed to bind VNIC."));
     684                                         N_("Failed to obtain VNIC info."));
    809685    dlpi_close(pData->pDeviceHandle);
    810686    return rc;
    811 }
    812 
    813 
    814 /**
    815  * Crossbow: Delete the virtual NIC.
    816  *
    817  * @returns VBox error code.
    818  * @param   pData           The instance data.
    819  */
    820 static int SolarisDeleteVNIC(PDRVTAP pData)
    821 {
    822     if (pData->pszDeviceNameActual)
    823     {
    824         dladm_status_t rc = dladm_vnic_delete(pData->uDeviceID, DLADM_VNIC_OPT_TEMP);
    825         if (rc == DLADM_STATUS_OK)
    826             return VINF_SUCCESS;
    827     }
    828     return VERR_HOSTIF_TERM_FAILED;
    829687}
    830688
     
    876734 *
    877735 * @returns VBox error code.
    878  * @param   pDrvIns          The driver instance data.
    879  * @param   pszDevName       Pointer to device name.
    880  */
    881 static DECLCALLBACK(int) SolarisTAPAttach(PPDMDRVINS pDrvIns)
    882 {
    883     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
     736 * @param   pData            The instance data.
     737 */
     738static DECLCALLBACK(int) SolarisTAPAttach(PDRVTAP pData)
     739{
    884740    LogFlow(("SolarisTapAttach: pData=%p\n", pData));
    885741
     
    887743    int IPFileDes = open("/dev/udp", O_RDWR, 0);
    888744    if (IPFileDes < 0)
    889         return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     745        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    890746                                   N_("Failed to open /dev/udp. errno=%d"), errno);
    891747
    892748    int TapFileDes = open("/dev/tap", O_RDWR, 0);
    893749    if (TapFileDes < 0)
    894         return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     750        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    895751                                   N_("Failed to open /dev/tap for TAP. errno=%d"), errno);
    896752
     
    913769    {
    914770        close(TapFileDes);
    915         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     771        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    916772                                   N_("Failed to get new interface. errno=%d"), errno);
    917773    }
     
    919775    int InterfaceFD = open("/dev/tap", O_RDWR, 0);
    920776    if (!InterfaceFD)
    921         return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     777        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    922778                                   N_("Failed to open interface /dev/tap. errno=%d"), errno);
    923779
     
    925781    {
    926782        close(InterfaceFD);
    927         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     783        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    928784                                   N_("Failed to push IP. errno=%d"), errno);
    929785    }
     
    932788    memset(&ifReq, 0, sizeof(ifReq));
    933789    if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
    934         LogRel(("TAP#%d: Failed to get interface flags.\n", pDrvIns->iInstance));
    935 
    936     char szTmp[16];
    937     char *pszDevName = pData->pszDeviceName;
    938     if (!pData->pszDeviceName || !*pData->pszDeviceName)
    939     {
    940         RTStrPrintf(szTmp, sizeof(szTmp), "tap%d", iPPA);
    941         pszDevName = szTmp;
    942     }
     790        LogRel(("TAP#%d: Failed to get interface flags.\n", pData->pDrvIns->iInstance));
    943791
    944792    ifReq.lifr_ppa = iPPA;
    945     RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pszDevName);
     793    RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pData->pszDeviceName);
    946794
    947795    if (ioctl(InterfaceFD, SIOCSLIFNAME, &ifReq) == -1)
    948         LogRel(("TAP#%d: Failed to set PPA. errno=%d\n", pDrvIns->iInstance, errno));
     796        LogRel(("TAP#%d: Failed to set PPA. errno=%d\n", pData->pDrvIns->iInstance, errno));
    949797
    950798    if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
    951         LogRel(("TAP#%d: Failed to get interface flags after setting PPA. errno=%d\n", pDrvIns->iInstance, errno));
     799        LogRel(("TAP#%d: Failed to get interface flags after setting PPA. errno=%d\n", pData->pDrvIns->iInstance, errno));
    952800
    953801#ifdef VBOX_SOLARIS_TAP_ARP
    954802    /* Interface */
    955803    if (ioctl(InterfaceFD, I_PUSH, "arp") == -1)
    956         LogRel(("TAP#%d: Failed to push ARP to Interface FD. errno=%d\n", pDrvIns->iInstance, errno));
     804        LogRel(("TAP#%d: Failed to push ARP to Interface FD. errno=%d\n", pData->pDrvIns->iInstance, errno));
    957805
    958806    /* IP */
    959807    if (ioctl(IPFileDes, I_POP, NULL) == -1)
    960         LogRel(("TAP#%d: Failed I_POP from IP FD. errno=%d\n", pDrvIns->iInstance, errno));
     808        LogRel(("TAP#%d: Failed I_POP from IP FD. errno=%d\n", pData->pDrvIns->iInstance, errno));
    961809
    962810    if (ioctl(IPFileDes, I_PUSH, "arp") == -1)
    963         LogRel(("TAP#%d: Failed to push ARP to IP FD. errno=%d\n", pDrvIns->iInstance, errno));
     811        LogRel(("TAP#%d: Failed to push ARP to IP FD. errno=%d\n", pData->pDrvIns->iInstance, errno));
    964812
    965813    /* ARP */
    966814    int ARPFileDes = open("/dev/tap", O_RDWR, 0);
    967815    if (ARPFileDes < 0)
    968         LogRel(("TAP#%d: Failed to open for /dev/tap for ARP. errno=%d", pDrvIns->iInstance, errno));
     816        LogRel(("TAP#%d: Failed to open for /dev/tap for ARP. errno=%d", pData->pDrvIns->iInstance, errno));
    969817
    970818    if (ioctl(ARPFileDes, I_PUSH, "arp") == -1)
    971         LogRel(("TAP#%d: Failed to push ARP to ARP FD. errno=%d\n", pDrvIns->iInstance, errno));
     819        LogRel(("TAP#%d: Failed to push ARP to ARP FD. errno=%d\n", pData->pDrvIns->iInstance, errno));
    972820
    973821    ioIF.ic_cmd = SIOCSLIFNAME;
     
    976824    ioIF.ic_dp = (char *)&ifReq;
    977825    if (ioctl(ARPFileDes, I_STR, &ioIF) == -1)
    978         LogRel(("TAP#%d: Failed to set interface name to ARP.\n", pDrvIns->iInstance));
     826        LogRel(("TAP#%d: Failed to set interface name to ARP.\n", pData->pDrvIns->iInstance));
    979827#endif
    980828
     
    990838        close(ARPFileDes);
    991839#endif
    992         LogRel(("TAP#%d: Cannot link TAP device to IP.\n", pDrvIns->iInstance));
    993         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     840        LogRel(("TAP#%d: Cannot link TAP device to IP.\n", pData->pDrvIns->iInstance));
     841        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    994842                    N_("Failed to link TAP device to IP. Check TAP interface name. errno=%d"), errno);
    995843    }
     
    998846    int ARPMuxID = ioctl(IPFileDes, I_LINK, ARPFileDes);
    999847    if (ARPMuxID == -1)
    1000         LogRel(("TAP#%d: Failed to link TAP device to ARP\n", pDrvIns->iInstance));
     848        LogRel(("TAP#%d: Failed to link TAP device to ARP\n", pData->pDrvIns->iInstance));
    1001849
    1002850    close(ARPFileDes);
     
    1006854    /* Reuse ifReq */
    1007855    memset(&ifReq, 0, sizeof(ifReq));
    1008     RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pszDevName);
     856    RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pData->pszDeviceName);
    1009857    ifReq.lifr_ip_muxid  = IPMuxID;
    1010858#ifdef VBOX_SOLARIS_TAP_ARP
     
    1019867        ioctl(IPFileDes, I_PUNLINK, IPMuxID);
    1020868        close(IPFileDes);
    1021         LogRel(("TAP#%d: Failed to set Mux ID.\n", pDrvIns->iInstance));
    1022         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     869        LogRel(("TAP#%d: Failed to set Mux ID.\n", pData->pDrvIns->iInstance));
     870        return PDMDrvHlpVMSetError(pData->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    1023871                                   N_("Failed to set Mux ID. Check TAP interface name. errno=%d"), errno);
    1024872    }
     
    1026874    pData->FileDevice = (RTFILE)TapFileDes;
    1027875    pData->IPFileDevice = (RTFILE)IPFileDes;
    1028     pData->pszDeviceNameActual = RTStrDup(pszDevName);
    1029876
    1030877    return VINF_SUCCESS;
     
    1133980        drvTAPTerminateApplication(pData);
    1134981
    1135 # ifdef VBOX_WITH_CROSSBOW
    1136     /* Finally unregister the VNIC */
    1137     dlpi_close(pData->pDeviceHandle);
    1138     SolarisDeleteVNIC(pData);
    1139 # endif
    1140 
    1141     RTStrFree(pData->pszDeviceNameActual);
    1142982#endif  /* RT_OS_SOLARIS */
    1143983
     984#ifdef RT_OS_SOLARIS
     985    if (!pData->fStatic)
     986        RTStrFree(pData->pszDeviceName);    /* allocated by drvTAPSetupApplication */
     987    else
     988        MMR3HeapFree(pData->pszDeviceName);
     989#else
    1144990    MMR3HeapFree(pData->pszDeviceName);
     991#endif
    1145992    MMR3HeapFree(pData->pszSetupApplication);
    1146993    MMR3HeapFree(pData->pszTerminateApplication);
     
    11691016    pData->pszDeviceName                = NULL;
    11701017#ifdef RT_OS_SOLARIS
    1171     pData->pszDeviceNameActual          = NULL;
    11721018# ifdef VBOX_WITH_CROSSBOW
    11731019    pData->pDeviceHandle                = NULL;
    1174     pData->uDeviceID                    = 0;
    11751020# else
    11761021    pData->IPFileDevice                 = NIL_RTFILE;
    11771022# endif
     1023    pData->fStatic                      = true;
    11781024#endif
    11791025    pData->pszSetupApplication          = NULL;
     
    12451091    rc = CFGMR3QueryStringAlloc(pCfgHandle, "Device", &pData->pszDeviceName);
    12461092    if (VBOX_FAILURE(rc))
    1247         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1248                                 N_("Configuration error: Query for \"Device\" string failed!"));
    1249 
    1250     /*
    1251      * Do the setup.
    1252      */
    1253 # ifdef VBOX_WITH_CROSSBOW
    1254     rc = SolarisCreateVNIC(pData);
    1255 # else
    1256     rc = SolarisTAPAttach(pDrvIns);
    1257 # endif
    1258     if (VBOX_FAILURE(rc))
    1259         return rc;
    1260 
     1093        pData->fStatic = false;
     1094
     1095    /* Obtain the device name from the setup application (if none was specified). */
    12611096    if (pData->pszSetupApplication)
    12621097    {
     
    12661101                                       N_("Error running TAP setup application. rc=%d"), rc);
    12671102    }
     1103
     1104    /*
     1105     * Do the setup.
     1106     */
     1107# ifdef VBOX_WITH_CROSSBOW
     1108    rc = SolarisOpenVNIC(pData);
     1109# else
     1110    rc = SolarisTAPAttach(pData);
     1111# endif
     1112    if (VBOX_FAILURE(rc))
     1113        return rc;
    12681114
    12691115#else /* !RT_OS_SOLARIS */
  • trunk/src/VBox/Devices/Network/solaris/vnicinit_solaris.sh

    r5587 r5719  
    22
    33# VirtualBox VNIC setup script for Solaris hosts with Crossbow.
    4 # usage: ./vnicinit.sh vnicname
    5 #
    6 # format of VNIC interface names MUST be like [name][number]
    7 # example: vnic1, vnic2, vnic900 etc.
    84
    95if [ -z "$1" ]; then
    10     echo "Missing VNIC interface name."
     6    echo "Missing MAC address."
    117    echo
    12     echo "Usage: $0 vnicname"
     8    echo "Usage: $0 macaddress [vnicname]"
     9    echo "       A new VNIC is created if no vnicname is provided."
    1310    exit 1
    1411fi
    1512
    16 vnic_name=`echo $1 | /usr/xpg4/bin/tr -s [:upper:] [:lower:]`
    17 vnic_id=${vnic_name##*[a-z]}
    18 vnic_name=$1
     13vnic_id=0
     14vnic_name=""
     15mac=$1
     16
     17# Create the VNIC if required
     18if [ -z "$2" ]; then
     19    vnic_id=`/usr/lib/vna iprb0 $mac`
     20    if [ $? != 0 ]; then
     21        exit 1
     22    fi
     23    vnic_name=vnic${vnic_id}
     24else
     25    vnic_name=$2
     26    vnic_id=${vnic_name##*[a-z]}
     27fi
     28
    1929if [ ${vnic_id} -lt 10 ]; then
    2030    host_ip="192.168.1.10${vnic_id}"
     
    3545netmask="255.255.255.0"
    3646
    37 /sbin/ifconfig $vnic_name plumb
    38 /sbin/ifconfig $vnic_name $host_ip destination $guest_ip netmask $netmask up
     47if [ -z "$2" ]; then
     48    /sbin/ifconfig $vnic_name plumb
     49    /sbin/ifconfig $vnic_name $host_ip destination $guest_ip netmask $netmask up
     50#else
     51#   Do existing VNIC configuration here if needed...
     52fi
    3953
    40 # Output the VNIC name though not used by VirtualBox
    4154echo "$vnic_name"
    4255exit $?
  • trunk/src/VBox/Devices/Network/solaris/vnicterm_solaris.sh

    r5587 r5719  
    1515
    1616/sbin/ifconfig $1 unplumb
     17vnic_id=${1##*[a-z]}
     18/usr/lib/vna ${vnic_id}
    1719exit $?
    1820
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