VirtualBox

Changeset 36730 in vbox


Ignore:
Timestamp:
Apr 19, 2011 2:31:40 PM (14 years ago)
Author:
vboxsync
Message:

Solaris/NetFltBow: support for VNIC templates and VLANs.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r36408 r36730  
    395395    (PFNRT)RTStrDupTag,
    396396    (PFNRT)RTStrFree,
     397    (PFNRT)RTStrCopy,
     398    (PFNRT)RTStrNCmp,
    397399    /* VBoxNetAdp */
    398400    (PFNRT)RTRandBytes,
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h

    r36121 r36730  
    180180            /** Whether the underlying interface is a VNIC or not. */
    181181            bool fIsVNIC;
     182            /** Whether the underlying interface is a VNIC template or not. */
     183            bool fIsVNICTemplate;
    182184            /** Handle to list of created VNICs. */
    183185            list_t hVNICs;
    184186            /** Instance number while creating VNICs. */
    185187            uint64_t uInstance;
    186             /** Pointer to the VNIC instance data. */
    187             void *pvVNIC;
    188188            /** The MAC address of the host interface. */
    189189            RTMAC MacAddr;
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c

    r36377 r36730  
    4646#include <sys/mac.h>
    4747#include <sys/strsun.h>
    48 #include <sys/sunddi.h>
    4948
    5049#include <sys/vnic_mgmt.h>
     
    5251#include <sys/mac_provider.h>
    5352#include <sys/dls.h>
     53#include <sys/dld.h>
     54#include <sys/cred.h>
    5455
    5556
     
    6465/** The module descriptions as seen in 'modinfo'. */
    6566#define DEVICE_DESC_DRV                 "VirtualBox NetBow"
    66 /** The dynamically created VNIC name */
     67/** The dynamically created VNIC name (hardcoded in NetIf-solaris.cpp).
     68 *  @todo move this define into a common header. */
    6769#define VBOXFLT_VNIC_NAME               "vboxvnic"
     70/** The VirtualBox VNIC template name (hardcoded in NetIf-solaris.cpp).
     71 *   *  @todo move this define into a common header. */
     72#define VBOXFLT_VNIC_TEMPLATE_NAME      "vboxvnic_template"
    6873/** Debugging switch for using symbols in kmdb */
    6974# define LOCAL                          static
     
    9297} VLANHEADER;
    9398typedef struct VLANHEADER *PVLANHEADER;
     99
     100/* Private: from sys/vlan.h */
     101#ifndef VLAN_ID_NONE
     102# define VLAN_ID_NONE           0
     103#endif
     104
     105/* Private: from sys/param.h */
     106#ifndef MAXLINKNAMESPECIFIER
     107# define MAXLINKNAMESPECIFIER   96 /* MAXLINKNAMELEN + ZONENAME_MAX */
     108#endif
     109
     110/* Private: from sys/mac_client_priv.h, mac client function prototypes. */
     111extern uint16_t mac_client_vid(mac_client_handle_t hClient);
     112extern void     mac_client_get_resources(mac_client_handle_t hClient, mac_resource_props_t *pResources);
     113extern int      mac_client_set_resources(mac_client_handle_t hClient, mac_resource_props_t *pResources);
    94114
    95115
     
    171191};
    172192
     193/*
     194 * VBOXNETFLTVNICTEMPLATE: VNIC template information.
     195 */
     196typedef struct VBOXNETFLTVNICTEMPLATE
     197{
     198    /** The name of link on which the VNIC template is created on. */
     199    char                        szLinkName[MAXNAMELEN];
     200    /** The VLAN Id (can be VLAN_ID_NONE). */
     201    uint16_t                    uVLANId;
     202    /** Resources (bandwidth, CPU bindings, flow priority etc.) */
     203    mac_resource_props_t        Resources;
     204} VBOXNETFLTVNICTEMPLATE;
     205typedef struct VBOXNETFLTVNICTEMPLATE *PVBOXNETFLTVNICTEMPLATE;
     206
    173207/**
    174208 * VBOXNETFLTVNIC: Per-VNIC instance data.
     
    176210typedef struct VBOXNETFLTVNIC
    177211{
    178     uint32_t             u32Magic;        /* Magic number (VBOXNETFLTVNIC_MAGIC) */
    179     bool                 fCreated;        /* Whether we created the VNIC or not */
    180     void                *pvIf;            /* The VirtualBox interface */
    181     mac_handle_t         hInterface;      /* The lower MAC handle */
    182     datalink_id_t        hLinkId;         /* The link ID */
    183     mac_client_handle_t  hClient;         /* Client handle */
    184     mac_unicast_handle_t hUnicast;        /* Unicast address handle  */
    185     mac_promisc_handle_t hPromiscuous;    /* Promiscuous handle */
    186     char                 szName[128];     /* The VNIC name */
    187     list_node_t          hNode;           /* Handle to the next VNIC in the list */
     212    /** Magic number (VBOXNETFLTVNIC_MAGIC). */
     213    uint32_t                    u32Magic;
     214    /** Whether we created the VNIC or not. */
     215    bool                        fCreated;
     216    /** Pointer to the VNIC template if any. */
     217    PVBOXNETFLTVNICTEMPLATE     pVNICTemplate;
     218    /** Pointer to the VirtualBox interface instance. */
     219    void                       *pvIf;
     220    /** The lower MAC handle. */
     221    mac_handle_t                hInterface;
     222    /** The VNIC link ID. */
     223    datalink_id_t               hLinkId;
     224    /** The MAC client handle */
     225    mac_client_handle_t         hClient;
     226    /** The unicast address handle.  */
     227    mac_unicast_handle_t        hUnicast;
     228    /** The promiscuous handle (currently unused). */
     229    mac_promisc_handle_t        hPromiscuous;
     230    /* The VNIC name. */
     231    char                        szName[MAXLINKNAMESPECIFIER];
     232    /** Handle to the next VNIC in the list. */
     233    list_node_t                 hNode;
    188234} VBOXNETFLTVNIC;
    189235typedef struct VBOXNETFLTVNIC *PVBOXNETFLTVNIC;
    190 
    191236
    192237/*******************************************************************************
     
    209254LOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback);
    210255LOCAL void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg);
    211 LOCAL void vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis);
     256LOCAL int vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis, mac_handle_t hInterface, bool fIsVNIC);
    212257LOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC);
     258LOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC, PVBOXNETFLTVNICTEMPLATE pVNICTemplate);
    213259LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void);
    214260LOCAL void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC);
    215261LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC);
    216262LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC);
     263LOCAL inline int vboxNetFltSolarisGetLinkId(const char *pszMacName, datalink_id_t *pLinkId);
    217264
    218265
     
    682729
    683730/**
    684  * Report capabilities and MAC address to IntNet.
     731 * Report capabilities and MAC address to IntNet after obtaining the MAC address
     732 * of the underlying interface for a VNIC or the current interface if it's a
     733 * physical/ether-stub interface.
    685734 *
    686735 * @param   pThis           The instance.
     736 * @param   hInterface      The Interface handle.
     737 * @param   fIsVNIC         Whether this interface handle corresponds to a VNIC
     738 *                          or not.
     739 *
    687740 * @remarks Retains the instance while doing it's job.
    688  */
    689 LOCAL void vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis)
     741 * @returns VBox status code.
     742 */
     743LOCAL int vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis, mac_handle_t hInterface, bool fIsVNIC)
    690744{
    691745    if (!pThis->u.s.fReportedInfo)
    692746    {
     747        mac_handle_t hLowerMac = NULL;
     748        if (!fIsVNIC)
     749            hLowerMac = hInterface;
     750        else
     751        {
     752            hLowerMac = mac_get_lower_mac_handle(hInterface);
     753            if (RT_UNLIKELY(!hLowerMac))
     754            {
     755                LogRel((DEVICE_NAME ":vboxNetFltSolarisReportInfo failed to get lower MAC handle for '%s'\n", pThis->szName));
     756                return VERR_INVALID_HANDLE;
     757            }
     758        }
     759
     760        mac_unicast_primary_get(hLowerMac, (uint8_t *)pThis->u.s.MacAddr.au8);
    693761        if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
    694762        {
    695763            Assert(pThis->pSwitchPort);
    696             LogFlow((DEVICE_NAME ":vboxNetFltSolarisInitVNIC phys mac %.6Rhxs\n", &pThis->u.s.MacAddr));
     764            LogFlow((DEVICE_NAME ":vboxNetFltSolarisReportInfo phys mac %.6Rhxs\n", &pThis->u.s.MacAddr));
    697765            pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
    698766            pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
     
    703771        }
    704772    }
    705 }
    706 
    707 
    708 /**
    709  * Initialize a VNIC.
     773    return VINF_SUCCESS;
     774}
     775
     776
     777/**
     778 * Initialize a VNIC, optionally from a template.
    710779 *
    711780 * @param   pThis           The instance.
    712781 * @param   pVNIC           Pointer to the VNIC.
    713  *
    714  * @returns Solaris error code (errno).
     782 * @param   pVNICTemplate   Pointer to the VNIC template initialize from, can be
     783 *                          NULL.
     784 *
     785 * @returns VBox status code.
    715786 */
    716787LOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC)
     
    722793    AssertReturn(pVNIC, VERR_INVALID_PARAMETER);
    723794    AssertReturn(pVNIC->hInterface, VERR_INVALID_POINTER);
    724     AssertReturn(pVNIC->hLinkId, VERR_INVALID_POINTER);
     795    AssertReturn(pVNIC->hLinkId != DATALINK_INVALID_LINKID, VERR_INVALID_HANDLE);
    725796    AssertReturn(!pVNIC->hClient, VERR_INVALID_HANDLE);
    726797
     
    732803    if (RT_LIKELY(!rc))
    733804    {
     805        if (pVNIC->pVNICTemplate)
     806            rc = mac_client_set_resources(pVNIC->hClient, &pVNIC->pVNICTemplate->Resources);
     807
     808        if (RT_LIKELY(!rc))
     809        {
     810            rc = vboxNetFltSolarisReportInfo(pThis, pVNIC->hInterface, true /* fIsVNIC */);
     811            if (RT_SUCCESS(rc))
     812            {
     813                LogFlow((DEVICE_NAME ":vboxNetFltSolarisInitVNIC pThis=%p szName=%s succeeded.\n", pThis, pThis->szName));
     814                return rc;
     815            }
     816            else
     817                LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to report info. rc=%d\n", rc));
     818        }
     819        else
     820        {
     821            LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC mac_client_set_resources failed. rc=%d\n", rc));
     822            rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
     823        }
     824
     825        mac_client_close(pVNIC->hClient, 0 /* flags */);
     826        pVNIC->hClient = NULL;
     827    }
     828    else
     829        LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
     830
     831    return rc;
     832}
     833
     834
     835/**
     836 * Initializes the VNIC template. This involves opening the template VNIC to
     837 * retreive info. like the VLAN Id, underlying MAC address etc.
     838 *
     839 * @param   pThis           The VM connection instance.
     840 * @param   pVNIC           Pointer to the VNIC.
     841 * @param   pVNICTemplate   Pointer to a VNIC template to initialize.
     842 *
     843 * @returns VBox status code.
     844 */
     845LOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC, PVBOXNETFLTVNICTEMPLATE pVNICTemplate)
     846{
     847    LogFlow((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate pThis=%p pVNIC=%p pVNICTemplate=%p\n", pThis, pVNIC, pVNICTemplate));
     848
     849    AssertReturn(pVNICTemplate, VERR_INVALID_PARAMETER);
     850    AssertReturn(pThis->u.s.fIsVNICTemplate == true, VERR_INVALID_STATE);
     851
     852    /*
     853     * Get the VNIC template's datalink ID.
     854     */
     855    datalink_id_t VNICLinkId;
     856    int rc = vboxNetFltSolarisGetLinkId(pThis->szName, &VNICLinkId);
     857    if (RT_SUCCESS(rc))
     858    {
    734859        /*
    735          * Set the RX callback.
     860         * Open the VNIC to obtain a MAC handle so as to retreive the VLAN ID.
    736861         */
    737         mac_diag_t Diag = MAC_DIAG_NONE;
    738         rc = mac_unicast_add_set_rx(pVNIC->hClient,
    739                                         NULL                        /* MAC address, use existing VNIC address */,
    740                                         MAC_UNICAST_PRIMARY |       /* Use Primary address of the VNIC */
    741                                             MAC_UNICAST_NODUPCHECK, /* Don't fail for conflicting MAC/VLAN-id combinations */
    742                                         &pVNIC->hUnicast,
    743                                         0                           /* VLAN-id */,
    744                                         &Diag,
    745                                         vboxNetFltSolarisRecv,      /* RX callback */
    746                                         pThis                       /* callback private data */
    747                                         );
    748         if (RT_LIKELY(!rc))
    749         {
    750             if (!pThis->u.s.fReportedInfo)
     862        mac_handle_t hInterface;
     863        rc = mac_open_by_linkid(VNICLinkId, &hInterface);
     864        if (!rc)
     865        {
     866            /*
     867             * Get the underlying linkname.
     868             */
     869            mac_handle_t hPhysLinkHandle = mac_get_lower_mac_handle(hInterface);
     870            if (RT_LIKELY(hPhysLinkHandle))
    751871            {
    752                 /*
    753                  * Obtain the MAC address of the underlying physical interface.
    754                  */
    755                 mac_handle_t hLowerMac = mac_get_lower_mac_handle(pVNIC->hInterface);
    756                 if (RT_LIKELY(hLowerMac))
     872                const char *pszLinkName = mac_name(hPhysLinkHandle);
     873                rc = RTStrCopy(pVNICTemplate->szLinkName, sizeof(pVNICTemplate->szLinkName), pszLinkName);
     874                if (RT_SUCCESS(rc))
    757875                {
    758                     mac_unicast_primary_get(hLowerMac, (uint8_t *)pThis->u.s.MacAddr.au8);
    759                     vboxNetFltSolarisReportInfo(pThis);
     876                    /*
     877                     * Now open the VNIC template to retrieve the VLAN Id & resources.
     878                     */
     879                    mac_client_handle_t hClient;
     880                    rc = mac_client_open(hInterface, &hClient,
     881                                         NULL,                                   /* name of this client */
     882                                         MAC_OPEN_FLAGS_USE_DATALINK_NAME |      /* client name same as underlying NIC */
     883                                         MAC_OPEN_FLAGS_MULTI_PRIMARY            /* allow multiple primary unicasts */
     884                                         );
     885                    if (RT_LIKELY(!rc))
     886                    {
     887                        pVNICTemplate->uVLANId = mac_client_vid(hClient);
     888                        mac_client_get_resources(hClient, &pVNICTemplate->Resources);
     889                        mac_client_close(hClient, 0 /* fFlags */);
     890                        mac_close(hInterface);
     891
     892                        LogFlow((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate successfully init. VNIC template. szLinkName=%s\n",
     893                                    pVNICTemplate->szLinkName));
     894                        return VINF_SUCCESS;
     895                    }
     896                    else
     897                    {
     898                        LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open VNIC template. rc=%d\n", rc));
     899                        rc = VERR_INTNET_FLT_IF_FAILED;
     900                    }
    760901                }
    761902                else
    762                 {
    763                     LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to get lower MAC handle for '%s'\n", pThis->szName));
    764                     rc = ENODEV;
    765                 }
     903                    LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to copy link name of underlying interface. rc=%d\n", rc));
    766904            }
    767 
    768             if (!rc)
     905            else
    769906            {
    770                 Assert(pVNIC->hClient);
    771                 Assert(pVNIC->hInterface);
    772                 Assert(pVNIC->hLinkId);
    773                 LogFlow((DEVICE_NAME ":vboxNetFltSolarisInitVNIC successfully initialized VNIC '%s'\n", pVNIC->szName));
    774                 return 0;
     907                LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get lower handle for VNIC template '%s'.\n", pThis->szName));
     908                rc = VERR_INTNET_FLT_IF_FAILED;
    775909            }
    776910
    777             mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
    778             mac_rx_clear(pVNIC->hClient);
    779             pVNIC->hUnicast = NULL;
     911            mac_close(hInterface);
    780912        }
    781913        else
    782             LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to set RX callback. rc=%d Diag=%d\n", rc, Diag));
    783 
    784         mac_client_close(pVNIC->hClient, 0 /* flags */);
    785         pVNIC->hClient = NULL;
     914        {
     915            LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to open by link ID. rc=%d\n", rc));
     916            rc = VERR_INTNET_FLT_IF_FAILED;
     917        }
    786918    }
    787919    else
    788         LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNIC failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
    789 
    790     return RTErrConvertFromErrno(rc);
     920        LogRel((DEVICE_NAME ":vboxNetFltSolarisInitVNICTemplate failed to get VNIC template link Id. rc=%d\n", rc));
     921
     922    return rc;
    791923}
    792924
     
    803935        return NULL;
    804936
    805     pVNIC->u32Magic     = VBOXNETFLTVNIC_MAGIC;
    806     pVNIC->fCreated     = false;
    807     pVNIC->pvIf         = NULL;
    808     pVNIC->hInterface   = NULL;
    809     pVNIC->hLinkId      = DATALINK_INVALID_LINKID;
    810     pVNIC->hClient      = NULL;
    811     pVNIC->hUnicast     = NULL;
    812     pVNIC->hPromiscuous = NULL;
     937    pVNIC->u32Magic        = VBOXNETFLTVNIC_MAGIC;
     938    pVNIC->fCreated        = false;
     939    pVNIC->pVNICTemplate   = NULL;
     940    pVNIC->pvIf            = NULL;
     941    pVNIC->hInterface      = NULL;
     942    pVNIC->hLinkId         = DATALINK_INVALID_LINKID;
     943    pVNIC->hClient         = NULL;
     944    pVNIC->hUnicast        = NULL;
     945    pVNIC->hPromiscuous    = NULL;
    813946    RT_ZERO(pVNIC->szName);
    814947    list_link_init(&pVNIC->hNode);
     
    8711004            pVNIC->fCreated = false;
    8721005        }
     1006
     1007        if (pVNIC->pVNICTemplate)
     1008        {
     1009            RTMemFree(pVNIC->pVNICTemplate);
     1010            pVNIC->pVNICTemplate = NULL;
     1011        }
    8731012    }
    8741013}
     
    8811020 * @param   ppVNIC          Where to store the created VNIC.
    8821021 *
    883  * @returns corresponding VBox error code.
     1022 * @returns VBox status code.
    8841023 */
    8851024LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC)
     
    8941033        return VERR_NO_MEMORY;
    8951034
    896     AssertCompile(sizeof(pVNIC->szName) > sizeof(VBOXFLT_VNIC_NAME) + 64);
    8971035    RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance);
    8981036
     
    9091047    AssertCompile(sizeof(RTMAC) <= MAXMACADDRLEN);
    9101048
     1049    const char *pszLinkName       = pThis->szName;
     1050    uint16_t uVLANId              = VLAN_ID_NONE;
    9111051    vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
    9121052    vnic_ioc_diag_t Diag          = VNIC_IOC_DIAG_NONE;
     
    9141054    int MacLen                    = sizeof(GuestMac);
    9151055    uint32_t fFlags               = 0;
    916 
    917     int rc = vnic_create(pVNIC->szName, pThis->szName, &AddrType, &MacLen, GuestMac.au8, &MacSlot, 0 /* Mac-Prefix Length */, 0 /* VLAN-ID */,
     1056    int rc                        = VERR_INVALID_STATE;
     1057
     1058    if (pThis->u.s.fIsVNICTemplate)
     1059    {
     1060        pVNIC->pVNICTemplate = RTMemAllocZ(sizeof(VBOXNETFLTVNICTEMPLATE));
     1061        if (RT_UNLIKELY(!pVNIC->pVNICTemplate))
     1062            return VERR_NO_MEMORY;
     1063
     1064        /*
     1065         * Initialize the VNIC template.
     1066         */
     1067        rc = vboxNetFltSolarisInitVNICTemplate(pThis, pVNIC, pVNIC->pVNICTemplate);
     1068        if (RT_FAILURE(rc))
     1069        {
     1070            LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to initialize VNIC from VNIC template. rc=%Rrc\n", rc));
     1071            vboxNetFltSolarisFreeVNIC(pVNIC);
     1072            return rc;
     1073        }
     1074
     1075        pszLinkName = pVNIC->pVNICTemplate->szLinkName;
     1076        uVLANId     = pVNIC->pVNICTemplate->uVLANId;
     1077#if 0
     1078        /*
     1079         * Required only if we're creating a VLAN interface & not a VNIC with a VLAN Id.
     1080         */
     1081        if (uVLANId != VLAN_ID_NONE)
     1082            fFlags |= MAC_VLAN;
     1083#endif
     1084        LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC pThis=%p VLAN Id=%u\n", pThis, uVLANId));
     1085    }
     1086
     1087    /*
     1088     * Create the VNIC under 'pszLinkName', which can be the one from the VNIC template or can
     1089     * be a physical interface.
     1090     */
     1091    rc = vnic_create(pVNIC->szName, pszLinkName, &AddrType, &MacLen, GuestMac.au8, &MacSlot, 0 /* Mac-Prefix Length */, uVLANId,
    9181092                        fFlags, &pVNIC->hLinkId, &Diag, NULL /* Reserved */);
    9191093    if (!rc)
     
    9271101        if (!rc)
    9281102        {
     1103            /*
     1104             * Initialize the VNIC from the physical interface or the VNIC template.
     1105             */
    9291106            rc = vboxNetFltSolarisInitVNIC(pThis, pVNIC);
    930             if (RT_LIKELY(!rc))
     1107            if (RT_SUCCESS(rc))
    9311108            {
    9321109                pThis->u.s.uInstance++;
    933                 LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s'\n", pVNIC->szName, pThis->szName));
     1110                LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s' with random mac %.6Rhxs\n",
     1111                         pVNIC->szName, pszLinkName, &GuestMac));
    9341112                *ppVNIC = pVNIC;
    9351113                return VINF_SUCCESS;
     
    9481126
    9491127        vboxNetFltSolarisDestroyVNIC(pVNIC);
    950         rc = VERR_OPEN_FAILED;
     1128        rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
    9511129    }
    9521130    else
    9531131    {
    9541132        LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create VNIC '%s' over '%s' rc=%d Diag=%d\n", pVNIC->szName,
    955                     pThis->szName, rc, Diag));
     1133                    pszLinkName, rc, Diag));
    9561134        rc = VERR_INTNET_FLT_VNIC_CREATE_FAILED;
    9571135    }
     
    9601138
    9611139    return rc;
     1140}
     1141
     1142
     1143/**
     1144 * Wrapper for getting the datalink ID given the MAC name.
     1145 *
     1146 * @param    pszMacName     The MAC name.
     1147 * @param    pLinkId        Where to store the datalink ID.
     1148 *
     1149 * @returns VBox status code.
     1150 */
     1151LOCAL inline int vboxNetFltSolarisGetLinkId(const char *pszMacName, datalink_id_t *pLinkId)
     1152{
     1153    /*
     1154     * dls_mgmt_get_linkid() requires to be in a state to answer upcalls. We should always use this
     1155     * first before resorting to other means to retrieve the MAC name.
     1156     */
     1157    int rc = dls_mgmt_get_linkid(pszMacName, pLinkId);
     1158    if (rc)
     1159        rc = dls_devnet_macname2linkid(pszMacName, pLinkId);
     1160
     1161    if (RT_LIKELY(!rc))
     1162        return VINF_SUCCESS;
     1163
     1164    LogRel((DEVICE_NAME ":vboxNetFltSolarisGetLinkId failed for '%s'. rc=%d\n", pszMacName, rc));
     1165    return RTErrConvertFromErrno(rc);
    9621166}
    9631167
     
    10481252        {
    10491253            /*
    1050              * This is NOT a VNIC. Just pretend success for now.
     1254             * Physical Interface: Just pretend success for now.
    10511255             * We will create a VNIC per VM interface later, see vboxNetFltPortOsConnectInterface().
    10521256             */
    10531257            pThis->u.s.fIsVNIC = false;
    1054             mac_unicast_primary_get(hInterface, pThis->u.s.MacAddr.au8);
    1055             vboxNetFltSolarisReportInfo(pThis);
     1258            vboxNetFltSolarisReportInfo(pThis, hInterface, pThis->u.s.fIsVNIC);
    10561259            mac_close(hInterface);
    10571260            return VINF_SUCCESS;
     
    10601263        pThis->u.s.fIsVNIC = true;
    10611264
     1265        if (RTStrNCmp(pThis->szName, VBOXFLT_VNIC_TEMPLATE_NAME, sizeof(VBOXFLT_VNIC_TEMPLATE_NAME) - 1) == 0)
     1266        {
     1267            /*
     1268             * VNIC Template: Just pretend success for now.
     1269             * We will create a VNIC per VM interface later, see vboxNetFltPortOsConnectInterface().
     1270             */
     1271            LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p VNIC template '%s' detected.\n", pThis, pThis->szName));
     1272            pThis->u.s.fIsVNICTemplate = true;
     1273            vboxNetFltSolarisReportInfo(pThis, hInterface, pThis->u.s.fIsVNIC);
     1274            mac_close(hInterface);
     1275            return VINF_SUCCESS;
     1276        }
     1277
     1278        /*
     1279         * VNIC: Alloc & init. the VNIC structure and use the VNIC directly.
     1280         */
    10621281        PVBOXNETFLTVNIC pVNIC = vboxNetFltSolarisAllocVNIC();
    10631282        if (RT_LIKELY(pVNIC))
     
    10691288             * Obtain the data link ID for this VNIC, it's needed for modifying the MAC address among other things.
    10701289             */
    1071             rc = dls_mgmt_get_linkid(pThis->szName, &pVNIC->hLinkId);
    1072             if (RT_LIKELY(!rc))
     1290            rc = vboxNetFltSolarisGetLinkId(pThis->szName, &pVNIC->hLinkId);
     1291            if (RT_SUCCESS(rc))
    10731292            {
    10741293                /*
     
    10911310        }
    10921311        else
     1312        {
    10931313            LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to allocate VNIC private data.\n"));
     1314            rc = VERR_NO_MEMORY;
     1315        }
    10941316
    10951317        mac_close(hInterface);
    10961318    }
    10971319    else
     1320    {
    10981321        LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to open link '%s'! rc=%d\n", pThis->szName, rc));
    1099 
    1100     return RTErrConvertFromErrno(rc);
     1322        rc = VERR_OPEN_FAILED;
     1323    }
     1324
     1325    return rc;
    11011326}
    11021327
     
    11071332     * Init. the solaris specific data.
    11081333     */
    1109     pThis->u.s.fIsVNIC = false;
     1334    pThis->u.s.fIsVNIC         = false;
     1335    pThis->u.s.fIsVNICTemplate = false;
    11101336    list_create(&pThis->u.s.hVNICs, sizeof(VBOXNETFLTVNIC), offsetof(VBOXNETFLTVNIC, hNode));
    1111     pThis->u.s.uInstance = 0;
    1112     pThis->u.s.pvVNIC = NULL;
    1113     bzero(&pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
    1114     pThis->u.s.fReportedInfo = false;
     1337    pThis->u.s.uInstance       = 0;
     1338    RT_ZERO(pThis->u.s.MacAddr);
     1339    pThis->u.s.fReportedInfo   = false;
    11151340    return VINF_SUCCESS;
    11161341}
     
    11651390void vboxNetFltPortOsNotifyMacAddress(PVBOXNETFLTINS pThis, void *pvIfData, PCRTMAC pMac)
    11661391{
    1167     LogFlow((DEVICE_NAME ":vboxNetFltPortOSNotifyMacAddress %s %.6Rhxs\n", pThis->szName, pMac));
     1392    LogFlow((DEVICE_NAME ":vboxNetFltPortOSNotifyMacAddress pszIf=%s pszVNIC=%s MAC=%.6Rhxs\n", pThis->szName,
     1393             ((PVBOXNETFLTVNIC)pvIfData)->szName, pMac));
    11681394
    11691395    /*
     
    11881414
    11891415    int rc = vnic_modify_addr(pVNIC->hLinkId, &AddrType, &MacLen, au8GuestMac, &MacSlot, 0 /* Mac-Prefix Length */, &Diag);
    1190     if (RT_UNLIKELY(rc))
    1191         LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed! rc=%d Diag=%d\n", rc, Diag));
    1192 }
     1416    if (RT_LIKELY(!rc))
     1417    {
     1418        /*
     1419         * Remove existing unicast address and the RX hook.
     1420         */
     1421        if (pVNIC->hUnicast)
     1422        {
     1423            mac_rx_clear(pVNIC->hClient);
     1424            mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
     1425            pVNIC->hUnicast = NULL;
     1426        }
     1427
     1428        /*
     1429         * Add the primary unicast address and set the RX hook.
     1430         */
     1431        mac_diag_t MacDiag = MAC_DIAG_NONE;
     1432        /* uint16_t uVLANId = pVNIC->pVNICTemplate ? pVNIC->pVNICTemplate->uVLANId : 0; */
     1433        rc = mac_unicast_add(pVNIC->hClient, NULL, MAC_UNICAST_PRIMARY, &pVNIC->hUnicast, 0 /* VLAN Id */, &MacDiag);
     1434        if (RT_LIKELY(!rc))
     1435        {
     1436            /*
     1437             * Set the RX receive function.
     1438             */
     1439            mac_rx_set(pVNIC->hClient, vboxNetFltSolarisRecv, pThis);
     1440            LogFlow((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress successfully added unicast address %.6Rhxs\n", pMac));
     1441        }
     1442        else
     1443            LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed to add primary unicast address. rc=%d Diag=%d\n", rc, MacDiag));
     1444    }
     1445    else
     1446    {
     1447        /*
     1448         * They really ought to use EEXIST, but I'm afraid this error comes from the VNIC device driver directly.
     1449         * Sequence: vnic_modify_addr()->mac_unicast_primary_set()->mac_update_macaddr() which uses a function pointer
     1450         * to the MAC driver (calls mac_vnic_unicast_set() in our case). Documented here if the error code should change we know
     1451         * where to look.
     1452         */
     1453        if (rc == ENOTSUP)
     1454        {
     1455            LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress: failed! a VNIC with mac %.6Rhxs probably already exists.",
     1456                    pMac, rc));
     1457            LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress: This NIC cannot establish connection. szName=%s szVNIC=%s\n",
     1458                    pThis->szName, pVNIC->szName));
     1459        }
     1460        else
     1461            LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed! mac %.6Rhxs rc=%d Diag=%d\n", pMac, rc, Diag));
     1462    }
     1463}
     1464
    11931465
    11941466
     
    12001472
    12011473    /*
    1202      * If the underlying interface is not a VNIC, we need to create
     1474     * If the underlying interface is a physical interface or a VNIC template, we need to create
    12031475     * a VNIC per guest NIC.
    12041476     */
    1205     if (!pThis->u.s.fIsVNIC)
     1477    if (   !pThis->u.s.fIsVNIC
     1478        || pThis->u.s.fIsVNICTemplate)
    12061479    {
    12071480        PVBOXNETFLTVNIC pVNIC = NULL;
     
    12191492             */
    12201493            list_insert_tail(&pThis->u.s.hVNICs, pVNIC);
    1221             LogFlow((DEVICE_NAME ":vboxNetFltPortOsConnectInterface successfully created VNIC '%s'.\n", pVNIC->szName));
    12221494            return VINF_SUCCESS;
    12231495        }
     
    12271499    else
    12281500    {
     1501        /*
     1502         * This is a VNIC passed to us, use it directly.
     1503         */
    12291504        PVBOXNETFLTVNIC pVNIC = list_head(&pThis->u.s.hVNICs);
    12301505        if (RT_LIKELY(pVNIC))
  • trunk/src/VBox/Main/src-server/solaris/NetIf-solaris.cpp

    r36248 r36730  
    9393        SolarisNICMap.insert(NICPair("spwr", "SMC EtherPower II 10/100 (9432) Ethernet"));
    9494        SolarisNICMap.insert(NICPair("vboxnet", "VirtualBox Host Ethernet"));
     95        SolarisNICMap.insert(NICPair("vboxvnic_template", "VirtualBox Virtual Network Interface Template"));
    9596        SolarisNICMap.insert(NICPair("vlan", "Virtual LAN Ethernet"));
    9697        SolarisNICMap.insert(NICPair("vnic", "Virtual Network Interface Ethernet"));
     
    211212     */
    212213    if (!strncmp(pszIface, "ip.tun", 6))
     214        return _B_FALSE;
     215
     216    /*
     217     * Skip our own dynamic VNICs but don't skip VNIC templates.
     218     * These names originate from VBoxNetFltBow-solaris.c, hardcoded here for now.
     219     */
     220    if (    strncmp(pszIface, "vboxvnic_template", 17)
     221        && !strncmp(pszIface, "vboxvnic", 8))
    213222        return _B_FALSE;
    214223
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