VirtualBox

Changeset 54902 in vbox


Ignore:
Timestamp:
Mar 23, 2015 11:05:58 AM (10 years ago)
Author:
vboxsync
Message:

solaris/VBoxNetFltBow: Fix using VNIC templates when lower-mac has a vanity name.
Better handling with conflicting VNIC names while we dynamically create VNICs.
Simplified instance-number bumping - got rid of semfastmutex for this.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r54887 r54902  
    16861686/** Failed to create a virtual network interface instance. */
    16871687#define VERR_INTNET_FLT_VNIC_CREATE_FAILED          (-3605)
     1688/** Failed to retreive a virtual network interface link ID. */
     1689#define VERR_INTNET_FLT_VNIC_LINK_ID_NOT_FOUND      (-3606)
     1690/** Failed to initialize a virtual network interface instance. */
     1691#define VERR_INTNET_FLT_VNIC_INIT_FAILED            (-3607)
     1692/** Failed to open a virtual network interface instance. */
     1693#define VERR_INTNET_FLT_VNIC_OPEN_FAILED            (-3608)
     1694/** Failed to retreive underlying (lower mac) link. */
     1695#define VERR_INTNET_FLT_LOWER_LINK_INFO_NOT_FOUND   (-3609)
     1696/** Failed to open underlying link instance. */
     1697#define VERR_INTNET_FLT_LOWER_LINK_OPEN_FAILED      (-3610)
     1698/** Failed to get underlying link ID. */
     1699#define VERR_INTNET_FLT_LOWER_LINK_ID_NOT_FOUND     (-3611)
    16881700/** @} */
    16891701
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c

    r50718 r54902  
    245245/** Global Device handle we only support one instance. */
    246246static dev_info_t *g_pVBoxNetFltSolarisDip = NULL;
    247 /** Global Mutex (actually an rw lock). */
    248 static RTSEMFASTMUTEX g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
    249247/** The (common) global data. */
    250248static VBOXNETFLTGLOBALS g_VBoxNetFltSolarisGlobals;
     
    293291    {
    294292        /*
    295          * Initialize Solaris specific globals here.
     293         * Initialize the globals and connect to the support driver.
     294         *
     295         * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
     296         * for establishing the connect to the support driver.
    296297         */
    297         rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx);
     298        memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
     299        rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
    298300        if (RT_SUCCESS(rc))
    299301        {
    300             /*
    301              * Initialize the globals and connect to the support driver.
    302              *
    303              * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
    304              * for establishing the connect to the support driver.
    305              */
    306             memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals));
    307             rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals);
    308             if (RT_SUCCESS(rc))
    309             {
    310                 rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
    311                 if (!rc)
    312                     return rc;
    313 
    314                 LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
    315                 vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
    316             }
    317             else
    318                 LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
    319 
    320             RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
    321             g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
    322         }
     302            rc = mod_install(&g_VBoxNetFltSolarisModLinkage);
     303            if (!rc)
     304                return rc;
     305
     306            LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
     307            vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals);
     308        }
     309        else
     310            LogRel((DEVICE_NAME ":failed to initialize globals.\n"));
    323311
    324312        RTR0Term();
     
    349337    rc = mod_remove(&g_VBoxNetFltSolarisModLinkage);
    350338    if (!rc)
    351     {
    352         if (g_VBoxNetFltSolarisMtx != NIL_RTSEMFASTMUTEX)
    353         {
    354             RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx);
    355             g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;
    356         }
    357 
    358339        RTR0Term();
    359     }
    360340
    361341    return rc;
     
    871851        {
    872852            LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC mac_client_set_resources failed. rc=%d\n", rc));
    873             rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
     853            rc = VERR_INTNET_FLT_VNIC_INIT_FAILED;
    874854        }
    875855
     
    880860        LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
    881861
    882     return rc;
     862    return VERR_INTNET_FLT_VNIC_OPEN_FAILED;
     863}
     864
     865
     866
     867/**
     868 * Get the underlying link name for a VNIC (template).
     869 *
     870 * @return VBox status code.
     871 * @param   hVNICMacHandle      The handle to the VNIC.
     872 * @param   pszLowerLinkName    Where to store the lower-mac linkname, must be
     873 *                              at least MAXLINKNAMELEN in size.
     874 */
     875LOCAL int vboxNetFltSolarisGetLowerLinkName(mac_handle_t hVNICMacHandle, char *pszLowerLinkName)
     876{
     877    Assert(mac_is_vnic(hVNICMacHandle));
     878    mac_handle_t hPhysLinkHandle = mac_get_lower_mac_handle(hVNICMacHandle);
     879    if (RT_LIKELY(hPhysLinkHandle))
     880    {
     881        datalink_id_t PhysLinkId;
     882        const char *pszMacName = mac_name(hPhysLinkHandle);
     883        int rc = vboxNetFltSolarisGetLinkId(pszMacName, &PhysLinkId);
     884        if (RT_SUCCESS(rc))
     885        {
     886            rc = dls_mgmt_get_linkinfo(PhysLinkId, pszLowerLinkName, NULL /*class*/, NULL /*media*/, NULL /*flags*/);
     887            if (RT_LIKELY(!rc))
     888                return VINF_SUCCESS;
     889
     890            LogRel((DEVICE_NAME ":vboxNetFltSolarisGetLowerLinkName failed to get link info. pszMacName=%s pszLowerLinkName=%s\n",
     891                    pszMacName, pszLowerLinkName));
     892            return VERR_INTNET_FLT_LOWER_LINK_INFO_NOT_FOUND;
     893        }
     894
     895        LogRel((DEVICE_NAME ":vboxNetFltSolarisGetLowerLinkName failed to get link id. pszMacName=%s pszLowerLinkName=%s\n",
     896                pszMacName, pszLowerLinkName));
     897        return VERR_INTNET_FLT_LOWER_LINK_ID_NOT_FOUND;
     898    }
     899
     900    LogRel((DEVICE_NAME ":vboxNetFltSolarisGetLowerLinkName failed to get lower-mac. pszLowerLinkName=%s\n", pszLowerLinkName));
     901    return VERR_INTNET_FLT_LOWER_LINK_OPEN_FAILED;
    883902}
    884903
     
    917936             * Get the underlying linkname.
    918937             */
    919             mac_handle_t hPhysLinkHandle = mac_get_lower_mac_handle(hInterface);
    920             if (RT_LIKELY(hPhysLinkHandle))
     938            AssertCompile(sizeof(pVNICTemplate->szLinkName) >= MAXLINKNAMELEN);
     939            rc = vboxNetFltSolarisGetLowerLinkName(hInterface, pVNICTemplate->szLinkName);
     940            if (RT_SUCCESS(rc))
    921941            {
    922                 const char *pszLinkName = mac_name(hPhysLinkHandle);
    923                 rc = RTStrCopy(pVNICTemplate->szLinkName, sizeof(pVNICTemplate->szLinkName), pszLinkName);
    924                 if (RT_SUCCESS(rc))
     942                /*
     943                 * Now open the VNIC template to retrieve the VLAN Id & resources.
     944                 */
     945                mac_client_handle_t hClient;
     946                rc = mac_client_open(hInterface, &hClient,
     947                                     NULL,                                   /* name of this client */
     948                                     MAC_OPEN_FLAGS_USE_DATALINK_NAME |      /* client name same as underlying NIC */
     949                                     MAC_OPEN_FLAGS_MULTI_PRIMARY            /* allow multiple primary unicasts */
     950                                     );
     951                if (RT_LIKELY(!rc))
    925952                {
    926                     /*
    927                      * Now open the VNIC template to retrieve the VLAN Id & resources.
    928                      */
    929                     mac_client_handle_t hClient;
    930                     rc = mac_client_open(hInterface, &hClient,
    931                                          NULL,                                   /* name of this client */
    932                                          MAC_OPEN_FLAGS_USE_DATALINK_NAME |      /* client name same as underlying NIC */
    933                                          MAC_OPEN_FLAGS_MULTI_PRIMARY            /* allow multiple primary unicasts */
    934                                          );
    935                     if (RT_LIKELY(!rc))
    936                     {
    937                         pVNICTemplate->uVLANId = mac_client_vid(hClient);
    938                         mac_client_get_resources(hClient, &pVNICTemplate->Resources);
    939                         mac_client_close(hClient, 0 /* fFlags */);
    940                         mac_close(hInterface);
    941 
    942                         Log((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate successfully init. VNIC template. szLinkName=%s\n",
    943                                     pVNICTemplate->szLinkName));
    944                         return VINF_SUCCESS;
    945                     }
    946                     else
    947                     {
    948                         LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open VNIC template. rc=%d\n", rc));
    949                         rc = VERR_INTNET_FLT_IF_FAILED;
    950                     }
     953                    pVNICTemplate->uVLANId = mac_client_vid(hClient);
     954                    mac_client_get_resources(hClient, &pVNICTemplate->Resources);
     955                    mac_client_close(hClient, 0 /* fFlags */);
     956                    mac_close(hInterface);
     957
     958                    LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate successfully init. VNIC template. szLinkName=%s "
     959                            "VLAN Id=%u\n", pVNICTemplate->szLinkName, pVNICTemplate->uVLANId));
     960                    return VINF_SUCCESS;
    951961                }
    952962                else
    953963                {
    954                     LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to copy link name of underlying interface"
    955                             ". rc=%d\n", rc));
     964                    LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open VNIC template. rc=%d\n", rc));
     965                    rc = VERR_INTNET_FLT_IF_FAILED;
    956966                }
    957967            }
    958968            else
    959             {
    960                 LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get lower handle for VNIC template '%s'.\n",
     969                LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get lower linkname for VNIC template '%s'.\n",
    961970                        pThis->szName));
    962                 rc = VERR_INTNET_FLT_IF_FAILED;
    963             }
    964971
    965972            mac_close(hInterface);
     
    11441151
    11451152    /*
     1153     * Make sure the dynamic VNIC we're creating doesn't already exists, if so pick a new instance.
     1154     * This is to avoid conflicts with users manually creating VNICs whose name starts with VBOXBOW_VNIC_NAME.
     1155     */
     1156    do
     1157    {
     1158        AssertCompile(sizeof(pVNIC->szName) > sizeof(VBOXBOW_VNIC_NAME "18446744073709551615" /* UINT64_MAX */));
     1159        RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXBOW_VNIC_NAME, g_VBoxNetFltSolarisVNICId);
     1160        mac_handle_t hTmpMacHandle;
     1161        rc = mac_open_by_linkname(pVNIC->szName, &hTmpMacHandle);
     1162        if (rc)
     1163            break;
     1164        mac_close(hTmpMacHandle);
     1165        ASMAtomicIncU64(&g_VBoxNetFltSolarisVNICId);
     1166    } while (1);
     1167
     1168    /*
    11461169     * Create the VNIC under 'pszLinkName', which can be the one from the VNIC template or can
    11471170     * be a physical interface.
    11481171     */
    1149     rc = RTSemFastMutexRequest(g_VBoxNetFltSolarisMtx); AssertRC(rc);
    1150     RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXBOW_VNIC_NAME, g_VBoxNetFltSolarisVNICId);
    11511172    rc = vnic_create(pVNIC->szName, pszLinkName, &AddrType, &MacLen, GuestMac.au8, &MacSlot, 0 /* Mac-Prefix Length */, uVLANId,
    11521173                        fFlags, &pVNIC->hLinkId, &Diag, NULL /* Reserved */);
     
    11551176        pVNIC->fCreated = true;
    11561177        ASMAtomicIncU64(&g_VBoxNetFltSolarisVNICId);
    1157         RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
    11581178
    11591179        /*
     
    11701190            {
    11711191                Log((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC created VNIC '%s' over '%s' with random mac %.6Rhxs\n",
    1172                          pVNIC->szName, pszLinkName, &GuestMac));
     1192                     pVNIC->szName, pszLinkName, &GuestMac));
    11731193                *ppVNIC = pVNIC;
    11741194                return VINF_SUCCESS;
    11751195            }
    1176             else
    1177                 LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC vboxNetFltSolarisInitVNIC failed. rc=%d\n", rc));
    1178 
     1196
     1197            LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC vboxNetFltSolarisInitVNIC failed. rc=%d\n", rc));
    11791198            mac_close(pVNIC->hInterface);
    11801199            pVNIC->hInterface = NULL;
     
    11821201        else
    11831202        {
    1184             LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to open VNIC '%s' over '%s'. rc=%d\n", pVNIC->szName,
    1185                         pThis->szName, rc));
     1203            LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC logrel failed to open VNIC '%s' over '%s'. rc=%d\n", pVNIC->szName,
     1204                    pThis->szName, rc));
     1205            rc = VERR_INTNET_FLT_VNIC_LINK_ID_NOT_FOUND;
    11861206        }
    11871207
    11881208        vboxNetFltSolarisDestroyVNIC(pVNIC);
    1189         rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
    11901209    }
    11911210    else
    11921211    {
    1193         RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
    1194 
    11951212        LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create VNIC '%s' over '%s' rc=%d Diag=%d\n", pVNIC->szName,
    11961213                    pszLinkName, rc, Diag));
     
    16501667    Log((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface pThis=%p\n", pThis));
    16511668
     1669    /*
     1670     * It is possible we get called when vboxNetFltPortOsConnectInterface() didn't succeed
     1671     * in which case pvIfData will be NULL. See intnetR0NetworkCreateIf() pfnConnectInterface call
     1672     * through reference counting in SUPR0ObjRelease() for the "pIf" object.
     1673     */
    16521674    PVBOXNETFLTVNIC pVNIC = pvIfData;
    1653     AssertMsgReturn(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
    1654                     ("Invalid pvIfData=%p magic=%#x (expected %#x)\n", pvIfData,
    1655                      pVNIC ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC), VERR_INVALID_POINTER);
    1656 
    1657     /*
    1658      * If the underlying interface is a physical interface or a VNIC template, we need to delete the created VNIC.
    1659      */
    1660     if (   !pThis->u.s.fIsVNIC
    1661         || pThis->u.s.fIsVNICTemplate)
    1662     {
     1675    if (RT_LIKELY(pVNIC))
     1676    {
     1677        AssertMsgReturn(pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
     1678                        ("Invalid magic=%#x (expected %#x)\n", pVNIC->u32Magic, VBOXNETFLTVNIC_MAGIC), VERR_INVALID_POINTER);
     1679
    16631680        /*
    1664          * Remove the VNIC from the list, destroy and free it.
     1681         * If the underlying interface is a physical interface or a VNIC template, we need to delete the created VNIC.
    16651682         */
    1666         list_remove(&pThis->u.s.hVNICs, pVNIC);
    1667         Log((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
    1668         vboxNetFltSolarisDestroyVNIC(pVNIC);
    1669         vboxNetFltSolarisFreeVNIC(pVNIC);
     1683        if (   !pThis->u.s.fIsVNIC
     1684            || pThis->u.s.fIsVNICTemplate)
     1685        {
     1686            /*
     1687             * Remove the VNIC from the list, destroy and free it.
     1688             */
     1689            list_remove(&pThis->u.s.hVNICs, pVNIC);
     1690            Log((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
     1691            vboxNetFltSolarisDestroyVNIC(pVNIC);
     1692            vboxNetFltSolarisFreeVNIC(pVNIC);
     1693        }
    16701694    }
    16711695
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