VirtualBox

Ignore:
Timestamp:
May 20, 2010 5:00:05 PM (15 years ago)
Author:
vboxsync
Message:

Solaris/VBoxNetFltBow: dynamic VNIC creation and management.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c

    r29691 r29708  
    2929#include <iprt/err.h>
    3030#include <iprt/string.h>
     31#include <iprt/rand.h>
    3132#include <iprt/net.h>
    3233#include <iprt/spinlock.h>
     34#include <iprt/mem.h>
    3335
    3436#include <sys/types.h>
     
    7779/** Debugging switch for using symbols in kmdb */
    7880# define LOCAL                          static
     81/** VBOXNETFLTVNIC::u32Magic */
     82# define VBOXNETFLTVNIC_MAGIC           0x0ddfaced
    7983
    8084#if defined(DEBUG_ramshankar)
     
    183187typedef struct VBOXNETFLTVNIC
    184188{
    185     void                       *pvIf;           /* The VirtualBox interface */
    186     mac_handle_t                hInterface;     /* The lower MAC handle */
    187     datalink_id_t               hLinkId;        /* The link ID */
    188     mac_client_handle_t         hClient;        /* Client handle */
    189     mac_unicast_handle_t        hUnicast;       /* Unicast address handle  */
    190     mac_promisc_handle_t        hPromiscuous;   /* Promiscuous handle */
    191     list_node_t                 hNode;          /* Handle to the next VNIC in the list */
     189    uint32_t             u32Magic;        /* Magic number (VBOXNETFLTVNIC_MAGIC) */
     190    bool                 fCreated;        /* Whether we created the VNIC or not */
     191    void                *pvIf;            /* The VirtualBox interface */
     192    mac_handle_t         hInterface;      /* The lower MAC handle */
     193    datalink_id_t        hLinkId;         /* The link ID */
     194    mac_client_handle_t  hClient;         /* Client handle */
     195    mac_unicast_handle_t hUnicast;        /* Unicast address handle  */
     196    mac_promisc_handle_t hPromiscuous;    /* Promiscuous handle */
     197    char                 szName[128];     /* The VNIC name */
     198    list_node_t          hNode;           /* Handle to the next VNIC in the list */
    192199} VBOXNETFLTVNIC;
    193200typedef struct VBOXNETFLTVNIC *PVBOXNETFLTVNIC;
     
    206213
    207214/*******************************************************************************
    208 *   Internal Function                                                          *
     215*   Internal Functions                                                         *
    209216*******************************************************************************/
    210217LOCAL mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst);
    211218LOCAL unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg);
    212219LOCAL int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc);
    213 
    214 LOCAL int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis, bool fRediscovery);
    215 LOCAL int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis);
    216220LOCAL void vboxNetFltSolarisRecv(void *pvData, mac_resource_handle_t hResource, mblk_t *pMsg, boolean_t fLoopback);
     221LOCAL void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg);
     222LOCAL void vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis);
     223LOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC);
     224LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void);
     225LOCAL void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC);
     226LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC);
     227LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC);
    217228
    218229
     
    681692
    682693
     694LOCAL void vboxNetFltSolarisReportInfo(PVBOXNETFLTINS pThis)
     695{
     696    if (!pThis->u.s.fReportedInfo)
     697    {
     698        if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
     699        {
     700            Assert(pThis->pSwitchPort);
     701            pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
     702            pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
     703            pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
     704            pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
     705            vboxNetFltRelease(pThis, true /*fBusy*/);
     706            pThis->u.s.fReportedInfo = true;
     707        }
     708    }
     709}
     710
     711
     712LOCAL int vboxNetFltSolarisInitVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC pVNIC)
     713{
     714    /*
     715     * Some paranoia.
     716     */
     717    AssertReturn(pThis, VERR_INVALID_PARAMETER);
     718    AssertReturn(pVNIC, VERR_INVALID_PARAMETER);
     719    AssertReturn(pVNIC->hInterface, VERR_INVALID_POINTER);
     720    AssertReturn(pVNIC->hLinkId, VERR_INVALID_POINTER);
     721    AssertReturn(!pVNIC->hClient, VERR_INVALID_HANDLE);
     722
     723    int rc = mac_client_open(pVNIC->hInterface, &pVNIC->hClient,
     724                         NULL,                                   /* name of this client */
     725                         MAC_OPEN_FLAGS_USE_DATALINK_NAME |      /* client name same as underlying NIC */
     726                         MAC_OPEN_FLAGS_MULTI_PRIMARY            /* allow multiple primary unicasts */
     727                         );
     728    if (RT_LIKELY(!rc))
     729    {
     730        /*
     731         * Set the RX callback.
     732         */
     733        mac_diag_t Diag = MAC_DIAG_NONE;
     734        rc = mac_unicast_add_set_rx(pVNIC->hClient,
     735                                        NULL                        /* MAC address, use existing VNIC address */,
     736                                        MAC_UNICAST_PRIMARY |       /* Use Primary address of the VNIC */
     737                                            MAC_UNICAST_NODUPCHECK, /* Don't fail for conflicting MAC/VLAN-id combinations */
     738                                        &pVNIC->hUnicast,
     739                                        0                           /* VLAN-id */,
     740                                        &Diag,
     741                                        vboxNetFltSolarisRecv,      /* RX callback */
     742                                        pThis                       /* callback private data */
     743                                        );
     744        if (RT_LIKELY(!rc))
     745        {
     746            if (!pThis->u.s.fReportedInfo)
     747            {
     748                /*
     749                 * Obtain the MAC address of the underlying physical interface.
     750                 */
     751                mac_handle_t hLowerMac = mac_get_lower_mac_handle(pVNIC->hInterface);
     752                if (RT_LIKELY(hLowerMac))
     753                {
     754                    mac_unicast_primary_get(hLowerMac, (uint8_t *)pThis->u.s.MacAddr.au8);
     755                    vboxNetFltSolarisReportInfo(pThis);
     756                }
     757                else
     758                {
     759                    LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to get lower MAC handle for '%s'\n", pThis->szName));
     760                    rc = ENODEV;
     761                }
     762            }
     763
     764            if (!rc)
     765            {
     766                Assert(pVNIC->hClient);
     767                Assert(pVNIC->hInterface);
     768                Assert(pVNIC->hLinkId);
     769                LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance successfully initialized VNIC '%s'\n", pVNIC->szName));
     770                return 0;
     771            }
     772
     773            mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
     774            mac_rx_clear(pVNIC->hClient);
     775            pVNIC->hUnicast = NULL;
     776        }
     777        else
     778            LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to set RX callback. rc=%d Diag=%d\n", rc, Diag));
     779
     780        mac_client_close(pVNIC->hClient, 0 /* flags */);
     781        pVNIC->hClient = NULL;
     782    }
     783    else
     784        LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
     785
     786    return RTErrConvertFromErrno(rc);
     787}
     788
     789
     790LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void)
     791{
     792    PVBOXNETFLTVNIC pVNIC = RTMemAlloc(sizeof(VBOXNETFLTVNIC));
     793    if (RT_UNLIKELY(!pVNIC))
     794        return NULL;
     795
     796    pVNIC->u32Magic = VBOXNETFLTVNIC_MAGIC;
     797    pVNIC->fCreated = false;
     798    pVNIC->pvIf = NULL;
     799    pVNIC->hInterface = NULL;
     800    pVNIC->hLinkId = DATALINK_INVALID_LINKID;
     801    pVNIC->hClient = NULL;
     802    pVNIC->hUnicast = NULL;
     803    pVNIC->hPromiscuous = NULL;
     804    RT_ZERO(pVNIC->szName);
     805    list_link_init(&pVNIC->hNode);
     806    return pVNIC;
     807}
     808
     809
     810LOCAL void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC)
     811{
     812    if (pVNIC)
     813        RTMemFree(pVNIC);
     814}
     815
     816
    683817/**
    684818 * Destroy a created VNIC.
     
    686820 * @param   pThis           The VM connection instance.
    687821 */
    688 LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTINS pThis)
    689 {
    690 #if 0
    691     if (pThis->u.s.fCreatedVNIC)
    692     {
    693         vnic_delete(pThis->u.s.VNICLinkId, 0 /* Flags */);
    694         pThis->u.s.VNICLinkId = DATALINK_INVALID_LINKID;
    695         pThis->u.s.fCreatedVNIC = false;
    696     }
    697 #endif
     822LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC)
     823{
     824    if (pVNIC)
     825    {
     826        if (pVNIC->hPromiscuous)
     827        {
     828            mac_promisc_remove(pVNIC->hPromiscuous);
     829            pVNIC->hPromiscuous = NULL;
     830        }
     831
     832        if (pVNIC->hClient)
     833        {
     834            if (pVNIC->hUnicast)
     835            {
     836                mac_unicast_remove(pVNIC->hClient, pVNIC->hUnicast);
     837                pVNIC->hUnicast = NULL;
     838            }
     839
     840            mac_rx_clear(pVNIC->hClient);
     841
     842            mac_client_close(pVNIC->hClient, 0 /* fFlags */);
     843            pVNIC->hClient = NULL;
     844        }
     845
     846        if (pVNIC->hInterface)
     847        {
     848            mac_close(pVNIC->hInterface);
     849            pVNIC->hInterface = NULL;
     850        }
     851
     852        if (pVNIC->fCreated)
     853        {
     854            vnic_delete(pVNIC->hLinkId, 0 /* Flags */);
     855            pVNIC->hLinkId = DATALINK_INVALID_LINKID;
     856            pVNIC->fCreated = false;
     857        }
     858    }
    698859}
    699860
     
    703864 *
    704865 * @param   pThis           The VM connection instance.
     866 * @param   ppVNIC          Where to store the created VNIC.
    705867 *
    706868 * @returns corresponding VBox error code.
    707869 */
    708 LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis)
    709 {
    710 #if 0
     870LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppVNIC)
     871{
    711872    LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC pThis=%p\n", pThis));
    712873
    713     char szVNICName[sizeof(VBOXFLT_VNIC_NAME) + 32];
    714     RTStrPrintf(szVNICName, sizeof(szVNICName), "%s%d", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance);
    715 
    716     /* -XXX- @todo remove hardcoded Guest MAC address, should be sent from guest later. */
     874    AssertReturn(pThis, VERR_INVALID_POINTER);
     875    AssertReturn(ppVNIC, VERR_INVALID_POINTER);
     876
     877    PVBOXNETFLTVNIC pVNIC = vboxNetFltSolarisAllocVNIC();
     878    if (RT_UNLIKELY(!pVNIC))
     879        return VERR_NO_MEMORY;
     880
     881    AssertCompile(sizeof(pVNIC->szName) > sizeof(VBOXFLT_VNIC_NAME) + 64);
     882    RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance);
     883
     884    /*
     885     * Set a random MAC address.
     886     */
    717887    RTMAC GuestMac;
    718888    GuestMac.au8[0] = 0x08;
    719889    GuestMac.au8[1] = 0x00;
    720890    GuestMac.au8[2] = 0x27;
    721     GuestMac.au8[3] = 0xFE;
    722     GuestMac.au8[4] = 0x21;
    723     GuestMac.au8[5] = 0x03;
     891    RTRandBytes(&GuestMac.au8[3], 3);
    724892
    725893    AssertCompile(sizeof(RTMAC) <= MAXMACADDRLEN);
    726     uchar_t MacAddr[MAXMACADDRLEN];
    727     bzero(MacAddr, sizeof(MacAddr));
    728     bcopy(GuestMac.au8, MacAddr, RT_MIN(sizeof(GuestMac), sizeof(MacAddr)));
    729894
    730895    vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
    731     vnic_ioc_diag_t Diag = VNIC_IOC_DIAG_NONE;
    732     int MacSlot = 0;
    733     int MacLen = sizeof(GuestMac);
    734     uint32_t fFlags = 0; /* no VNIC_IOC_CREATE_NODUPCHECK */
    735     int rc = vnic_create(szVNICName, pThis->szName, &AddrType, &MacLen, MacAddr, &MacSlot, 0 /* Mac-Prefix Length */, 0 /* VLAN-ID */,
    736                         fFlags, &pThis->u.s.VNICLinkId, &Diag, NULL /* Reserved */);
     896    vnic_ioc_diag_t Diag          = VNIC_IOC_DIAG_NONE;
     897    int MacSlot                   = 0;
     898    int MacLen                    = sizeof(GuestMac);
     899    uint32_t fFlags               = 0; /* @todo it should be VNIC_IOC_CREATE_NODUPCHECK */
     900
     901    int rc = vnic_create(pVNIC->szName, pThis->szName, &AddrType, &MacLen, GuestMac.au8, &MacSlot, 0 /* Mac-Prefix Length */, 0 /* VLAN-ID */,
     902                        fFlags, &pVNIC->hLinkId, &Diag, NULL /* Reserved */);
    737903    if (!rc)
    738904    {
    739         pThis->u.s.fCreatedVNIC = true;
    740         pThis->u.s.uInstance++;
     905        pVNIC->fCreated = true;
    741906
    742907        /*
    743908         * Now try opening the created VNIC.
    744909         */
    745         rc = mac_open_by_linkid(pThis->u.s.VNICLinkId, &pThis->u.s.hInterface);
     910        rc = mac_open_by_linkid(pVNIC->hLinkId, &pVNIC->hInterface);
    746911        if (!rc)
    747912        {
    748             Assert(pThis->u.s.hInterface);
    749             LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s'\n", szVNICName, pThis->szName));
    750             return VINF_SUCCESS;
    751         }
    752         else
    753         {
    754             LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to open VNIC '%s' over '%s'. rc=%d\n", szVNICName,
    755                         pThis->szName, rc));
    756         }
    757 
    758         vboxNetFltSolarisDestroyVNIC(pThis);
    759         rc = VERR_INTNET_FLT_IF_FAILED;
    760     }
    761     else
    762     {
    763         LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed! rc=%d Diag=%d\n", rc, (int)Diag));
    764         rc = VERR_INTNET_FLT_IF_FAILED;
    765     }
    766 
    767     return rc;
    768 #endif
    769 }
    770 
    771 
    772 /**
    773  * Attach to the network interface.
    774  *
    775  * @param   pThis           The VM connection instance.
    776  * @param   fRediscovery    Whether this is a rediscovery attempt after disconnect.
    777  *
    778  * @returns corresponding VBox error code.
    779  */
    780 LOCAL int vboxNetFltSolarisAttachToInterface(PVBOXNETFLTINS pThis, bool fRediscovery)
    781 {
    782 #if 0
    783     LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface pThis=%p fRediscovery=%d\n", pThis, fRediscovery));
    784 
    785     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    786 
    787     /*
    788      * Open the underlying interface (lower MAC) and get it's handle.
    789      */
    790     int rc = mac_open_by_linkname(pThis->szName, &pThis->u.s.hInterface);
    791     if (RT_LIKELY(!rc))
    792     {
    793         /*
    794          * If this is not a VNIC, create a VNIC and open it instead.
    795          */
    796         rc = mac_is_vnic(pThis->u.s.hInterface);
    797         if (!rc)
    798         {
    799             LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface '%s' is not a VNIC. Creating one.\n", pThis->szName));
    800 
    801             mac_close(pThis->u.s.hInterface);
    802             pThis->u.s.hInterface = NULL;
    803             rc = vboxNetFltSolarisCreateVNIC(pThis);
    804         }
    805         else
    806             rc = VINF_SUCCESS;
    807 
    808         /*
    809          * At this point "hInterface" should be a handle to a VNIC, we no longer would deal with physical interface
    810          * if it has been passed by the user.
    811          */
    812         if (RT_SUCCESS(rc))
    813         {
    814             /*
    815              * Obtain the MAC address of the interface.
    816              */
    817             Assert(pThis->u.s.hInterface);
    818             AssertCompile(sizeof(RTMAC) == ETHERADDRL);
    819             mac_unicast_primary_get(pThis->u.s.hInterface, (uint8_t *)&pThis->u.s.MacAddr.au8);
    820 
    821             LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface MAC address of %s is %.*Rhxs\n", pThis->szName,
    822                      sizeof(pThis->u.s.MacAddr), &pThis->u.s.MacAddr));
    823 
    824             /** @todo Obtain the MTU size using mac_sdu_get() */
    825             /** @todo Obtain capabilities (hardware checksum etc.) using mac_capab_get() */
    826 
    827             /*
    828              * Open a client connection to the lower MAC interface.
    829              */
    830             rc = mac_client_open(pThis->u.s.hInterface, &pThis->u.s.hClient,
    831                                  NULL,                                   /* name of this client */
    832                                  MAC_OPEN_FLAGS_USE_DATALINK_NAME |     /* client name same as underlying NIC */
    833                                  MAC_OPEN_FLAGS_MULTI_PRIMARY           /* allow multiple primary unicasts */
    834                                  );
     913            rc = vboxNetFltSolarisInitVNIC(pThis, pVNIC);
    835914            if (RT_LIKELY(!rc))
    836915            {
    837                 /** @todo -XXX- if possible we must move unicast_add and rx_set to when the Guest advertises it's MAC to us.  */
    838 
    839                 /*
    840                  * Set a unicast address for this client and the packet receive callback.
    841                  * We want to use the primary unicast address of the underlying interface (VNIC) hence we pass NULL.
    842                  * Also we don't really set the RX function here, this is done when we activate promiscuous mode.
    843                  */
    844                 mac_diag_t MacDiag;
    845                 rc = mac_unicast_add(pThis->u.s.hClient, NULL /* MAC Address */,
    846                                     MAC_UNICAST_PRIMARY | MAC_UNICAST_STRIP_DISABLE |
    847                                     MAC_UNICAST_DISABLE_TX_VID_CHECK | MAC_UNICAST_NODUPCHECK | MAC_UNICAST_HW,
    848                                     &pThis->u.s.hUnicast, 0 /* VLAN id */, &MacDiag);
    849                 if (!rc)
    850                 {
    851                     if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
    852                     {
    853                         Assert(pThis->pSwitchPort);
    854                         pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
    855                         pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
    856                         pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
    857                         pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
    858                         vboxNetFltRelease(pThis, true /*fBusy*/);
    859                     }
    860 
    861                     /*
    862                      * If the user passed in the VNIC, we need to obtain the datalink ID now.
    863                      */
    864                     if (pThis->u.s.fCreatedVNIC == false)
    865                         rc = dls_mgmt_get_linkid(pThis->szName, &pThis->u.s.VNICLinkId);
    866 
    867                     if (!rc)
    868                     {
    869                         /*
    870                          * Modify the MAC address of the VNIC to match the guest's MAC address
    871                          */
    872                         LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface success!\n"));
    873 
    874                         RTMAC GuestMac;
    875                         GuestMac.au8[0] = 0x08;
    876                         GuestMac.au8[1] = 0x00;
    877                         GuestMac.au8[2] = 0x27;
    878                         GuestMac.au8[3] = 0xFE;
    879                         GuestMac.au8[4] = 0x21;
    880                         GuestMac.au8[5] = 0x03;
    881 
    882                         uchar_t MacAddr[MAXMACADDRLEN];
    883                         bcopy(GuestMac.au8, MacAddr, sizeof(GuestMac));
    884 
    885                         vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
    886                         vnic_ioc_diag_t Result = VNIC_IOC_DIAG_NONE;
    887                         int MacSlot = 0;
    888                         int MacLen = sizeof(GuestMac);
    889                         rc = vnic_modify_addr(pThis->u.s.VNICLinkId, &AddrType, &MacLen, MacAddr, &MacSlot, 0 /* Mac-Prefix Length */, &Result);
    890                         if (!rc)
    891                         {
    892                             LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface vnic_modify successful %s mac %.*Rhxs\n", pThis->szName,
    893                                             sizeof(GuestMac), &GuestMac));
    894 
    895                             mac_unicast_remove(pThis->u.s.hClient, pThis->u.s.hUnicast);
    896                             pThis->u.s.hUnicast = NULL;
    897                             rc = mac_unicast_add(pThis->u.s.hClient, NULL /* MAC Address */,
    898                                                 MAC_UNICAST_PRIMARY | MAC_UNICAST_STRIP_DISABLE |
    899                                                 MAC_UNICAST_DISABLE_TX_VID_CHECK | MAC_UNICAST_NODUPCHECK | MAC_UNICAST_HW,
    900                                                 &pThis->u.s.hUnicast, 0 /* VLAN id */, &MacDiag);
    901 
    902                             if (!rc)
    903                                 return VINF_SUCCESS;
    904 
    905                             LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to set client MAC address (2) '%s' rc=%d\n",
    906                                     pThis->szName, rc));
    907                         }
    908                         else
    909                         {
    910                             LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to modify MAC address for VNIC over '%s' rc=%d\n",
    911                                     pThis->szName, rc));
    912                         }
    913                     }
    914                     else
    915                     {
    916                         LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to obtain VNIC link id for '%s' rc=%d\n",
    917                                     pThis->szName, rc));
    918                     }
    919                 }
    920                 else
    921                     LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to set client MAC address over link '%s' rc=%d\n",
    922                             pThis->szName, rc));
    923 
    924                 mac_client_close(pThis->u.s.hClient, 0 /* fFlags */);
    925                 pThis->u.s.hClient = NULL;
     916                pThis->u.s.uInstance++;
     917                LogFlow((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC successfully created VNIC '%s' over '%s'\n", pVNIC->szName, pThis->szName));
     918                *ppVNIC = pVNIC;
     919                return VINF_SUCCESS;
    926920            }
    927921            else
    928             {
    929                 LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to create client over link '%s' rc=%d\n",
     922                LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC vboxNetFltSolarisInitVNIC failed. rc=%d\n", rc));
     923
     924            mac_close(pVNIC->hInterface);
     925            pVNIC->hInterface = NULL;
     926        }
     927        else
     928        {
     929            LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to open VNIC '%s' over '%s'. rc=%d\n", pVNIC->szName,
    930930                        pThis->szName, rc));
    931             }
    932         }
    933         else
    934         {
    935             LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface VNIC creation failed over '%s'\n", pThis->szName));
    936             rc = ENXIO;
    937         }
    938 
    939         if (pThis->u.s.hInterface)
    940         {
    941             mac_close(pThis->u.s.hInterface);
    942             pThis->u.s.hInterface = NULL;
    943         }
    944 
    945         vboxNetFltSolarisDestroyVNIC(pThis);
     931        }
     932
     933        vboxNetFltSolarisDestroyVNIC(pVNIC);
     934        rc = VERR_INTNET_FLT_IF_FAILED;
    946935    }
    947936    else
    948         LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface failed to open link '%s' rc=%d\n", pThis->szName, rc));
     937    {
     938        LogRel((DEVICE_NAME ":vboxNetFltSolarisCreateVNIC failed to create VNIC '%s' over '%s' rc=%d Diag=%d\n", pVNIC->szName,
     939                    pThis->szName, rc, Diag));
     940    }
     941
     942    vboxNetFltSolarisFreeVNIC(pVNIC);
    949943
    950944    return RTErrConvertFromErrno(rc);
    951 #endif
    952 }
    953 
    954 
    955 
    956 /**
    957  * Detach from the network interface.
    958  *
    959  * @param   pThis           The VM connection instance.
    960  * @returns corresponding VBox error code.
    961  */
    962 LOCAL int vboxNetFltSolarisDetachFromInterface(PVBOXNETFLTINS pThis)
    963 {
    964 #if 0
    965     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    966 
    967     if (pThis->u.s.hPromiscuous)
    968     {
    969         mac_promisc_remove(pThis->u.s.hPromiscuous);
    970         pThis->u.s.hPromiscuous = NULL;
    971     }
    972 
    973     if (pThis->u.s.hClient)
    974     {
    975         if (pThis->u.s.hUnicast)
    976         {
    977             mac_unicast_remove(pThis->u.s.hClient, pThis->u.s.hUnicast);
    978             pThis->u.s.hUnicast = NULL;
    979         }
    980 
    981         mac_rx_clear(pThis->u.s.hClient);
    982 
    983         mac_client_close(pThis->u.s.hClient, 0 /* fFlags */);
    984         pThis->u.s.hClient = NULL;
    985     }
    986 
    987     if (pThis->u.s.hInterface)
    988     {
    989         mac_close(pThis->u.s.hInterface);
    990         pThis->u.s.hInterface = NULL;
    991     }
    992 
    993     vboxNetFltSolarisDestroyVNIC(pThis);
    994 #endif
    995945}
    996946
     
    1034984{
    1035985    LogFlow((DEVICE_NAME ":vboxNetFltOsDisconnectIt pThis=%p\n", pThis));
    1036 //    return vboxNetFltSolarisDetachFromInterface(pThis);
    1037986    return VINF_SUCCESS;
    1038987}
     
    1042991{
    1043992    LogFlow((DEVICE_NAME ":vboxNetFltOsConnectIt pThis=%p\n", pThis));
    1044 //    return vboxNetFltSolarisAttachToInterface(pThis, false /* fRediscovery */);
    1045993    return VINF_SUCCESS;
    1046994}
     
    10521000
    10531001    /*
    1054      * If this is a VNIC remove the callbacks and close it.
    1055      */
    1056     if (pThis->u.s.fIsVNIC)
    1057     {
    1058         if (pThis->u.s.hPromiscuous)
    1059         {
    1060             mac_promisc_remove(pThis->u.s.hPromiscuous);
    1061             pThis->u.s.hPromiscuous = NULL;
    1062         }
    1063 
    1064         if (pThis->u.s.hClient)
    1065         {
    1066             if (pThis->u.s.hUnicast)
    1067             {
    1068                 mac_unicast_remove(pThis->u.s.hClient, pThis->u.s.hUnicast);
    1069                 pThis->u.s.hUnicast = NULL;
    1070             }
    1071 
    1072             mac_rx_clear(pThis->u.s.hClient);
    1073 
    1074             mac_client_close(pThis->u.s.hClient, 0 /* fFlags */);
    1075             pThis->u.s.hClient = NULL;
    1076         }
    1077 
    1078         if (pThis->u.s.hInterface)
    1079         {
    1080             mac_close(pThis->u.s.hInterface);
    1081             pThis->u.s.hInterface = NULL;
    1082         }
    1083     }
    1084 
    1085     /** @todo clean-up for physical interfaces */
     1002     * Destroy all managed VNICs. If a VNIC was passed to us, there
     1003     * will be only 1 item in the list, otherwise as many interfaces
     1004     * that were somehow not destroyed using DisconnectInterface() will be
     1005     * present.
     1006     */
     1007    PVBOXNETFLTVNIC pVNIC = NULL;
     1008    while ((pVNIC = list_remove_head(&pThis->u.s.hVNICs)) != NULL)
     1009    {
     1010        vboxNetFltSolarisDestroyVNIC(pVNIC);
     1011        vboxNetFltSolarisFreeVNIC(pVNIC);
     1012    }
     1013
     1014    list_destroy(&pThis->u.s.hVNICs);
    10861015}
    10871016
     
    10941023     * Figure out if the interface is a VNIC or a physical/etherstub/whatever NIC.
    10951024     */
    1096     int rc = mac_open_by_linkname(pThis->szName, &pThis->u.s.hInterface);
     1025    mac_handle_t hInterface;
     1026    int rc = mac_open_by_linkname(pThis->szName, &hInterface);
    10971027    if (RT_LIKELY(!rc))
    10981028    {
    1099         /*
    1100          * Check if this is a VNIC. If it's not we will create a VNIC per guest interface
    1101          * later (see vboxNetFltPortOsConnectInterface).
    1102          */
    1103         rc = mac_is_vnic(pThis->u.s.hInterface);
     1029        rc = mac_is_vnic(hInterface);
    11041030        if (!rc)
    11051031        {
    1106             mac_close(pThis->u.s.hInterface);
    1107             pThis->u.s.hInterface = NULL;
     1032            /*
     1033             * This is NOT a VNIC. Just pretend success for now.
     1034             * We will create a VNIC per guest interface later (see vboxNetFltPortOsConnectInterface).
     1035             */
    11081036            pThis->u.s.fIsVNIC = false;
     1037            mac_unicast_primary_get(hInterface, pThis->u.s.MacAddr.au8);
     1038            vboxNetFltSolarisReportInfo(pThis);
     1039            mac_close(hInterface);
    11091040            return VINF_SUCCESS;
    11101041        }
    11111042
    1112         /*
    1113          * User has passed in a VNIC, we can proceed to open it.
    1114          * Open a client connection to the lower MAC interface.
    1115          */
    11161043        pThis->u.s.fIsVNIC = true;
    1117         rc = mac_client_open(pThis->u.s.hInterface, &pThis->u.s.hClient,
    1118                              NULL,                                   /* name of this client */
    1119                              MAC_OPEN_FLAGS_USE_DATALINK_NAME |      /* client name same as underlying NIC */
    1120                              MAC_OPEN_FLAGS_MULTI_PRIMARY            /* allow multiple primary unicasts */
    1121                              );
    1122         if (RT_LIKELY(!rc))
    1123         {
     1044
     1045        PVBOXNETFLTVNIC pVNIC = vboxNetFltSolarisAllocVNIC();
     1046        if (RT_LIKELY(pVNIC))
     1047        {
     1048            pVNIC->fCreated = false;
     1049            pVNIC->hInterface = hInterface;
     1050
    11241051            /*
    11251052             * Obtain the data link ID for this VNIC, it's needed for modifying the MAC address among other things.
    11261053             */
    1127             rc = dls_mgmt_get_linkid(pThis->szName, &pThis->u.s.hLinkId);
     1054            rc = dls_mgmt_get_linkid(pThis->szName, &pVNIC->hLinkId);
    11281055            if (RT_LIKELY(!rc))
    11291056            {
    11301057                /*
    1131                  * Set the RX callback.
     1058                 * Initialize the VNIC and add it to the list of managed VNICs.
    11321059                 */
    1133                 mac_diag_t Diag = MAC_DIAG_NONE;
    1134                 rc = mac_unicast_add_set_rx(pThis->u.s.hClient,
    1135                                             NULL                        /* MAC address, use existing VNIC address */,
    1136                                             MAC_UNICAST_PRIMARY |       /* Use Primary address of the VNIC */
    1137                                                 MAC_UNICAST_NODUPCHECK, /* Don't fail for conflicting MAC/VLAN-id combinations */
    1138                                             &pThis->u.s.hUnicast,
    1139                                             0                           /* VLAN-id */,
    1140                                             &Diag,
    1141                                             vboxNetFltSolarisRecv,      /* RX callback */
    1142                                             pThis                       /* callback private data */
    1143                                             );
    1144                 if (RT_LIKELY(!rc))
     1060                RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s", pThis->szName);
     1061                rc = vboxNetFltSolarisInitVNIC(pThis, pVNIC);
     1062                if (!rc)
    11451063                {
    1146                     /*
    1147                      * Get the MAC handle of the underlying physical interface (or etherstub whatever).
    1148                      */
    1149                     mac_handle_t hLowerMac = mac_get_lower_mac_handle(pThis->u.s.hInterface);
    1150                     if (RT_LIKELY(hLowerMac))
    1151                     {
    1152                         /*
    1153                          * Obtain the MAC address & report.
    1154                          */
    1155                         mac_unicast_primary_get(hLowerMac, (uint8_t *)&pThis->u.s.MacAddr.au8);
    1156                         if (vboxNetFltTryRetainBusyNotDisconnected(pThis))
    1157                         {
    1158                             Assert(pThis->pSwitchPort);
    1159                             pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
    1160                             pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, false); /** @todo Promisc */
    1161                             pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
    1162                             pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
    1163                             vboxNetFltRelease(pThis, true /*fBusy*/);
    1164                         }
    1165 
    1166                         LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance successfully opened VNIC '%s'\n", pThis->szName));
    1167                         return VINF_SUCCESS;
    1168                     }
    1169                     else
    1170                     {
    1171                         LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to get lower MAC handle for '%s'\n", pThis->szName));
    1172                         rc = ENODEV;
    1173                     }
    1174 
    1175                     mac_unicast_remove(pThis->u.s.hClient, pThis->u.s.hUnicast);
    1176                     mac_rx_clear(pThis->u.s.hClient);
    1177                     pThis->u.s.hUnicast = NULL;
     1064                    list_insert_head(&pThis->u.s.hVNICs, pVNIC);
     1065                    return VINF_SUCCESS;
    11781066                }
    11791067                else
    1180                     LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to set RX callback. rc=%d Diag=%d\n", rc, Diag));
     1068                    LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance vboxNetFltSolarisInitVNIC failed. rc=%d\n", rc));
    11811069            }
    11821070            else
    1183                 LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to open link id for '%s' rc=%d\n", pThis->szName, rc));
    1184 
    1185             mac_client_close(pThis->u.s.hClient, 0 /* flags */);
    1186             pThis->u.s.hClient = NULL;
     1071                LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to get link id for '%s'. rc=%d\n", pThis->szName, rc));
     1072
     1073            vboxNetFltSolarisFreeVNIC(pVNIC);
    11871074        }
    11881075        else
    1189             LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to open mac client for '%s' rc=%d\n", pThis->szName, rc));
     1076            LogRel((DEVICE_NAME ":vboxNetFltOsInitInstance failed to allocate VNIC private data.\n"));
     1077
     1078        mac_close(hInterface);
    11901079    }
    11911080    else
     
    12021091     */
    12031092    pThis->u.s.fIsVNIC = false;
     1093    list_create(&pThis->u.s.hVNICs, sizeof(VBOXNETFLTVNIC), offsetof(VBOXNETFLTVNIC, hNode));
    12041094    pThis->u.s.uInstance = 0;
    1205     pThis->u.s.hInterface = NULL;
    1206     pThis->u.s.hLinkId = DATALINK_INVALID_LINKID;
    1207     pThis->u.s.hClient = NULL;
    1208     pThis->u.s.hUnicast = NULL;
    1209     pThis->u.s.hPromiscuous = NULL;
     1095    pThis->u.s.pvVNIC = NULL;
    12101096    bzero(&pThis->u.s.MacAddr, sizeof(pThis->u.s.MacAddr));
     1097    pThis->u.s.fReportedInfo = false;
    12111098    return VINF_SUCCESS;
    12121099}
     
    12251112{
    12261113    /*
    1227      * Xmit the packet down the interface (tx)
    1228      */
    1229     int rc = VERR_INVALID_HANDLE;
    1230     if (RT_LIKELY(pThis->u.s.hClient))
    1231     {
    1232         mblk_t *pMsg = vboxNetFltSolarisMBlkFromSG(pThis, pSG, fDst);
    1233         if (RT_LIKELY(pMsg))
    1234         {
    1235             LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p cbData=%d\n", pThis, MBLKL(pMsg)));
    1236 
    1237             mac_tx_cookie_t pXmitCookie = mac_tx(pThis->u.s.hClient, pMsg, 0 /* Hint */, MAC_DROP_ON_NO_DESC, NULL /* return message */);
    1238             if (RT_LIKELY(!pXmitCookie))
    1239                 return VINF_SUCCESS;
    1240 
    1241             pMsg = NULL;
    1242             rc = VERR_NET_IO_ERROR;
    1243             LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit Xmit failed.\n"));
    1244         }
    1245         else
    1246         {
    1247             LogRel((DEVICE_NAME ":vboxNetFltPortOsXmit no memory for allocating Xmit packet.\n"));
    1248             rc = VERR_NO_MEMORY;
    1249         }
     1114     * Validate parameters.
     1115     */
     1116    PVBOXNETFLTVNIC pVNIC = pvIfData;
     1117    AssertMsgReturn(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
     1118                    ("Invalid pvIfData=%p magic=%#x (expected %#x)\n", pvIfData, pVNIC ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC),
     1119                    VERR_INVALID_PARAMETER);
     1120
     1121    /*
     1122     * Xmit the packet down the appropriate VNIC interface.
     1123     */
     1124    int rc = VINF_SUCCESS;
     1125    mblk_t *pMsg = vboxNetFltSolarisMBlkFromSG(pThis, pSG, fDst);
     1126    if (RT_LIKELY(pMsg))
     1127    {
     1128        LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p cbData=%d\n", pThis, MBLKL(pMsg)));
     1129
     1130        mac_tx_cookie_t pXmitCookie = mac_tx(pVNIC->hClient, pMsg, 0 /* Hint */, MAC_DROP_ON_NO_DESC, NULL /* return message */);
     1131        if (RT_LIKELY(!pXmitCookie))
     1132            return VINF_SUCCESS;
     1133
     1134        pMsg = NULL;
     1135        rc = VERR_NET_IO_ERROR;
     1136        LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit Xmit failed pVNIC=%p.\n", pVNIC));
    12501137    }
    12511138    else
    1252         LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit missing client.\n"));
     1139    {
     1140        LogRel((DEVICE_NAME ":vboxNetFltPortOsXmit no memory for allocating Xmit packet.\n"));
     1141        rc = VERR_NO_MEMORY;
     1142    }
    12531143
    12541144    return rc;
     
    12581148void vboxNetFltPortOsNotifyMacAddress(PVBOXNETFLTINS pThis, void *pvIfData, PCRTMAC pMac)
    12591149{
    1260     LogRel((DEVICE_NAME ":vboxNetFltPortOSNotifyMacAddress %s %.6Rhxs\n", pThis->szName, pMac));
    1261 
     1150    LogFlow((DEVICE_NAME ":vboxNetFltPortOSNotifyMacAddress %s %.6Rhxs\n", pThis->szName, pMac));
     1151
     1152    /*
     1153     * Validate parameters.
     1154     */
     1155    PVBOXNETFLTVNIC pVNIC = pvIfData;
     1156    AssertMsgReturnVoid(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
     1157                    ("Invalid pvIfData=%p magic=%#x (expected %#x)\n", pvIfData, pVNIC ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC));
     1158    AssertMsgReturnVoid(pVNIC->hLinkId != DATALINK_INVALID_LINKID,
     1159                    ("Invalid hLinkId pVNIC=%p magic=%#x\n", pVNIC, pVNIC->u32Magic));
     1160
     1161    /*
     1162     * Set the MAC address of the VNIC to the one used by the VM interface.
     1163     */
    12621164    uchar_t au8GuestMac[MAXMACADDRLEN];
    12631165    bcopy(pMac->au8, au8GuestMac, sizeof(RTMAC));
    12641166
    1265     if (pThis->u.s.fIsVNIC)
    1266     {
    1267         vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
    1268         vnic_ioc_diag_t      Diag     = VNIC_IOC_DIAG_NONE;
    1269         int                  MacSlot  = 0;
    1270         int                  MacLen   = sizeof(RTMAC);
    1271 
    1272         int rc = vnic_modify_addr(pThis->u.s.hLinkId, &AddrType, &MacLen, au8GuestMac, &MacSlot, 0 /* Mac-Prefix Length */, &Diag);
    1273         if (!rc)
    1274             LogFlow((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress set '%s' MAC address to %.6Rhxs\n", pThis->szName, pMac));
     1167    vnic_mac_addr_type_t AddrType = VNIC_MAC_ADDR_TYPE_FIXED;
     1168    vnic_ioc_diag_t      Diag     = VNIC_IOC_DIAG_NONE;
     1169    int                  MacSlot  = 0;
     1170    int                  MacLen   = sizeof(RTMAC);
     1171
     1172    int rc = vnic_modify_addr(pVNIC->hLinkId, &AddrType, &MacLen, au8GuestMac, &MacSlot, 0 /* Mac-Prefix Length */, &Diag);
     1173    if (RT_UNLIKELY(rc))
     1174        LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed! rc=%d Diag=%d\n", rc, Diag));
     1175}
     1176
     1177
     1178int vboxNetFltPortOsConnectInterface(PVBOXNETFLTINS pThis, void *pvIf, void **ppvIfData)
     1179{
     1180    LogFlow((DEVICE_NAME ":vboxNetFltPortOsConnectInterface pThis=%p pvIf=%p\n", pThis, pvIf));
     1181
     1182    int rc = VINF_SUCCESS;
     1183
     1184    /*
     1185     * If the underlying interface is not a VNIC, we need to create
     1186     * a VNIC per guest NIC.
     1187     */
     1188    if (!pThis->u.s.fIsVNIC)
     1189    {
     1190        PVBOXNETFLTVNIC pVNIC = NULL;
     1191        rc = vboxNetFltSolarisCreateVNIC(pThis, &pVNIC);
     1192        if (RT_SUCCESS(rc))
     1193        {
     1194            /*
     1195             * VM Interface<->VNIC association so that we can Xmit/Recv on the right ones.
     1196             */
     1197            pVNIC->pvIf = pvIf;
     1198            *ppvIfData = pVNIC;
     1199
     1200            /*
     1201             * Add the created VNIC to the list of VNICs we manage.
     1202             */
     1203            list_insert_tail(&pThis->u.s.hVNICs, pVNIC);
     1204            LogFlow((DEVICE_NAME ":vboxNetFltPortOsConnectInterface successfully created VNIC '%s'.\n", pVNIC->szName));
     1205            return VINF_SUCCESS;
     1206        }
    12751207        else
    1276             LogRel((DEVICE_NAME ":vboxNetFltPortOsNotifyMacAddress failed! rc=%d Diag=%d\n", rc, Diag));
    1277     }
    1278 
    1279     /** @todo set MAC address for created VNICs  */
    1280 }
    1281 
    1282 
    1283 int vboxNetFltPortOsConnectInterface(PVBOXNETFLTINS pThis, void *pvIf, void **pvIfData)
    1284 {
    1285     LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface\n"));
     1208            LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface failed to create VNIC\n"));
     1209    }
     1210    else
     1211    {
     1212        PVBOXNETFLTVNIC pVNIC = list_head(&pThis->u.s.hVNICs);
     1213        if (RT_LIKELY(pVNIC))
     1214        {
     1215            *ppvIfData = pVNIC;
     1216            LogFlow((DEVICE_NAME ":vboxNetFltPortOsConnectInterface set VNIC '%s' private data\n", pVNIC->szName));
     1217        }
     1218        else
     1219        {
     1220            LogRel((DEVICE_NAME ":vboxNetFltPortOsConnectInterface huh!? Missing VNIC!\n"));
     1221            return VERR_GENERAL_FAILURE;
     1222        }
     1223    }
     1224
     1225    return rc;
     1226}
     1227
     1228
     1229int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
     1230{
     1231    LogFlow((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface pThis=%p\n", pThis));
     1232
     1233    PVBOXNETFLTVNIC pVNIC = pvIfData;
     1234    AssertMsgReturn(VALID_PTR(pVNIC) && pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC,
     1235                    ("Invalid pvIfData=%p magic=%#x (expected %#x)\n", pvIfData, pVNIC ? pVNIC->u32Magic : 0, VBOXNETFLTVNIC_MAGIC),
     1236                    VERR_INVALID_POINTER);
     1237
     1238    /*
     1239     * If the underlying interface is not a VNIC, we need to delete the created VNIC.
     1240     */
     1241    if (!pThis->u.s.fIsVNIC)
     1242    {
     1243        /*
     1244         * Remove the VNIC from the list, destroy and free it.
     1245         */
     1246        list_remove(&pThis->u.s.hVNICs, pVNIC);
     1247        LogRel((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC));
     1248        vboxNetFltSolarisDestroyVNIC(pVNIC);
     1249        vboxNetFltSolarisFreeVNIC(pVNIC);
     1250    }
     1251
    12861252    return VINF_SUCCESS;
    12871253}
    12881254
    1289 
    1290 int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
    1291 {
    1292     LogRel((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface\n"));
    1293     return VINF_SUCCESS;
    1294 }
    1295 
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