VirtualBox

Changeset 13654 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Oct 29, 2008 3:01:22 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
38596
Message:

Solaris/VBoxNetFlt: Added IPv6 support (untested).

Location:
trunk/src/VBox/HostDrivers/VBoxNetFlt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h

    r13538 r13654  
    153153            /** @name Solaris instance data.
    154154             * @{ */
    155             /** Pointer to the bound IP stream. */
    156             void volatile *pvIpStream;
     155            /** Pointer to the bound IPv4 stream. */
     156            void volatile *pvIp4Stream;
     157            /** Pointer to the bound IPv6 stream. */
     158            void volatile *pvIp6Stream;
    157159            /** Pointer to the bound ARP stream. */
    158160            void volatile *pvArpStream;
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c

    r13630 r13654  
    276276{
    277277    kUndefined = 0,
    278     kIpStream = 0x1b,
     278    kIp4Stream = 0x1b,
     279    kIp6Stream = 0xcc,
    279280    kArpStream = 0xab,
    280281    kPromiscStream = 0xdf
     
    690691    switch (pStream->Type)
    691692    {
    692         case kIpStream:         ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pvIpStream, pStream);         break;
     693        case kIp4Stream:        ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pvIp4Stream, pStream);        break;
     694        case kIp6Stream:        ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pvIp6Stream, pStream);        break;
    693695        case kArpStream:        ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pvArpStream, pStream);        break;
    694696        case kPromiscStream:    ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.pvPromiscStream, pStream);    break;
     
    836838    switch (pStream->Type)
    837839    {
    838         case kIpStream:         ASMAtomicUoWritePtr(pStream->pThis->u.s.pvIpStream, NULL);      break;
     840        case kIp4Stream:        ASMAtomicUoWritePtr(pStream->pThis->u.s.pvIp4Stream, NULL);     break;
     841        case kIp6Stream:        ASMAtomicUoWritePtr(pStream->pThis->u.s.pvIp6Stream, NULL);     break;
    839842        case kArpStream:        ASMAtomicUoWritePtr(pStream->pThis->u.s.pvArpStream, NULL);     break;
    840843        case kPromiscStream:    ASMAtomicUoWritePtr(pStream->pThis->u.s.pvPromiscStream, NULL); break;
     
    940943                                    if (pNotifyInd->dl_data != DL_CURR_PHYS_ADDR)
    941944                                        break;
    942                                    
     945
    943946                                    size_t cOffset = pNotifyInd->dl_addr_offset;
    944947                                    size_t cbAddr = pNotifyInd->dl_addr_length;
    945                                    
     948
    946949                                    if (!cOffset || !cbAddr)
    947950                                    {
     
    957960                                    break;
    958961                                }
    959                                
     962
    960963                                case DL_NOTE_LINK_UP:
    961964                                {
     
    984987                            break;
    985988                        }
    986                        
     989
    987990                        case DL_BIND_ACK:
    988991                        {
     
    14891492
    14901493/**
    1491  * Relinks the lower and the upper stream.
     1494 * Relinks the lower and the upper IPv4 stream.
    14921495 *
    14931496 * @returns VBox status code.
     
    14971500 * @param   ArpMuxFd    The ARP multiplexor ID.
    14981501 */
    1499 static int vboxNetFltSolarisRelink(vnode_t *pVNode, struct lifreq *pInterface, int IpMuxFd, int ArpMuxFd)
    1500 {
    1501     LogFlow((DEVICE_NAME ":vboxNetFltSolarisRelink: pVNode=%p pInterface=%p IpMuxFd=%d ArpMuxFd=%d\n", pVNode,
     1502static int vboxNetFltSolarisRelinkIp4(vnode_t *pVNode, struct lifreq *pInterface, int IpMuxFd, int ArpMuxFd)
     1503{
     1504    LogFlow((DEVICE_NAME ":vboxNetFltSolarisRelinkIp4: pVNode=%p pInterface=%p IpMuxFd=%d ArpMuxFd=%d\n", pVNode,
    15021505            pInterface, IpMuxFd, ArpMuxFd));
    15031506
     
    15151518            return VINF_SUCCESS;
    15161519
    1517         LogRel((DEVICE_NAME ":vboxNetFltSolarisRelink: failed to set new Mux Id.\n"));
     1520        LogRel((DEVICE_NAME ":vboxNetFltSolarisRelinkIp4: failed to set new Mux Id.\n"));
    15181521    }
    15191522    else
    1520         LogRel((DEVICE_NAME ":vboxNetFltSolarisRelink: failed to link.\n"));
     1523        LogRel((DEVICE_NAME ":vboxNetFltSolarisRelinkIp4: failed to link.\n"));
     1524
     1525    return VERR_GENERAL_FAILURE;
     1526}
     1527
     1528
     1529/**
     1530 * Relinks the lower and the upper IPv6 stream.
     1531 *
     1532 * @returns VBox status code.
     1533 * @param   pVNode      Pointer to the device vnode.
     1534 * @param   pInterface  Pointer to the interface.
     1535 * @param   Ip6MuxFd    The IPv6 multiplexor ID.
     1536 */
     1537static int vboxNetFltSolarisRelinkIp6(vnode_t *pVNode, struct lifreq *pInterface, int Ip6MuxFd)
     1538{
     1539    LogFlow((DEVICE_NAME ":vboxNetFltSolarisRelinkIp6: pVNode=%p pInterface=%p Ip6MuxFd=%d\n", pVNode, pInterface, Ip6MuxFd));
     1540
     1541    int NewIp6MuxId;
     1542    int rc = strioctl(pVNode, I_PLINK, (intptr_t)Ip6MuxFd, 0, K_TO_K, kcred, &NewIp6MuxId);
     1543    if (!rc)
     1544    {
     1545        pInterface->lifr_ip_muxid = NewIp6MuxId;
     1546        rc = vboxNetFltSolarisSetMuxId(pVNode, pInterface);
     1547        if (RT_SUCCESS(rc))
     1548            return VINF_SUCCESS;
     1549
     1550        LogRel((DEVICE_NAME ":vboxNetFltSolarisRelinkIp6: failed to set new Mux Id.\n"));
     1551    }
     1552    else
     1553        LogRel((DEVICE_NAME ":vboxNetFltSolarisRelinkIp6: failed to link.\n"));
    15211554
    15221555    return VERR_GENERAL_FAILURE;
     
    16801713
    16811714/**
    1682  * Dynamically attaches this streams module on to the host stack.
    1683  * As a side-effect, the streams also gets opened/closed during
    1684  * the actual injection/ejection phase.
     1715 * Dynamically attach under IPv4 and ARP streams on the host stack.
    16851716 *
    16861717 * @returns VBox status code.
     
    16881719 * @param   fAttach     Is this an attach or detach.
    16891720 */
    1690 static int vboxNetFltSolarisModSetup(PVBOXNETFLTINS pThis, bool fAttach)
    1691 {
    1692     LogFlow(("vboxNetFltSolarisModSetup: pThis=%p (%s) fAttach=%s\n", pThis, pThis->szName, fAttach ? "true" : "false"));
    1693 
     1721static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach)
     1722{
    16941723    /*
    16951724     * Statuatory Warning: Hackish code ahead.
     
    16971726    char *pszModName = DEVICE_NAME;
    16981727
    1699     struct lifreq Interface;
    1700     bzero(&Interface, sizeof(Interface));
    1701     Interface.lifr_addr.ss_family = AF_INET;
    1702     strncpy(Interface.lifr_name, pThis->szName, sizeof(Interface.lifr_name));
     1728    struct lifreq Ip4Interface;
     1729    bzero(&Ip4Interface, sizeof(Ip4Interface));
     1730    Ip4Interface.lifr_addr.ss_family = AF_INET;
     1731    strncpy(Ip4Interface.lifr_name, pThis->szName, sizeof(Ip4Interface.lifr_name));
    17031732
    17041733    struct strmodconf StrMod;
     
    17121741    int rc2;
    17131742    int ret;
    1714     ldi_ident_t IPDevId = ldi_ident_from_anon();
    1715     ldi_ident_t ARPDevId = ldi_ident_from_anon();
    1716     ldi_handle_t IPDevHandle;
    1717     ldi_handle_t UDPDevHandle;
    1718     ldi_handle_t ARPDevHandle;
     1743    ldi_ident_t DeviceIdent = ldi_ident_from_anon();
     1744    ldi_handle_t Ip4DevHandle;
     1745    ldi_handle_t ArpDevHandle;
    17191746
    17201747    /*
    17211748     * Open the IP and ARP streams as layered devices.
    17221749     */
    1723     rc = ldi_open_by_name(IP_DEV_NAME, FREAD | FWRITE, kcred, &IPDevHandle, IPDevId);
    1724     ldi_ident_release(IPDevId);
     1750    rc = ldi_open_by_name(IP_DEV_NAME, FREAD | FWRITE, kcred, &Ip4DevHandle, DeviceIdent);
    17251751    if (rc)
    17261752    {
    1727         LogRel((DEVICE_NAME ":failed to open the IP stream on '%s'.\n", pThis->szName));
     1753        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to open the IP stream on '%s'.\n", pThis->szName));
     1754        ldi_ident_release(DeviceIdent);
    17281755        return VERR_INTNET_FLT_IF_FAILED;
    17291756    }
    17301757
    1731     rc = ldi_open_by_name("/dev/arp", FREAD | FWRITE, kcred, &ARPDevHandle, ARPDevId);
    1732     ldi_ident_release(ARPDevId);
     1758    rc = ldi_open_by_name("/dev/arp", FREAD | FWRITE, kcred, &ArpDevHandle, DeviceIdent);
    17331759    if (rc)
    17341760    {
    1735         LogRel((DEVICE_NAME ":failed to open the ARP stream on '%s'.\n", pThis->szName));
    1736         ldi_close(IPDevHandle, FREAD | FWRITE, kcred);
     1761        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to open the ARP stream on '%s'.\n", pThis->szName));
     1762        ldi_ident_release(DeviceIdent);
     1763        ldi_close(Ip4DevHandle, FREAD | FWRITE, kcred);
    17371764        return VERR_INTNET_FLT_IF_FAILED;
    17381765    }
    17391766
     1767    ldi_ident_release(DeviceIdent);
     1768
    17401769    /*
    17411770     * Obtain the interface flags from IP.
    17421771     */
    1743     rc = vboxNetFltSolarisGetIfFlags(IPDevHandle, &Interface);
     1772    rc = vboxNetFltSolarisGetIfFlags(Ip4DevHandle, &Ip4Interface);
    17441773    if (RT_SUCCESS(rc))
    17451774    {
     
    17481777         * things that are not possible from the layered interface.
    17491778         */
    1750         vnode_t *pVNodeUDP = NULL;
    1751         vnode_t *pVNodeUDPHeld = NULL;
    1752         TIUSER *pUserUDP = NULL;
    1753         rc = vboxNetFltSolarisOpenDev(UDP_DEV_NAME, &pVNodeUDP, &pVNodeUDPHeld, &pUserUDP);
     1779        vnode_t *pUdp4VNode = NULL;
     1780        vnode_t *pUdp4VNodeHeld = NULL;
     1781        TIUSER *pUdp4User = NULL;
     1782        rc = vboxNetFltSolarisOpenDev(UDP_DEV_NAME, &pUdp4VNode, &pUdp4VNodeHeld, &pUdp4User);
    17541783        if (RT_SUCCESS(rc))
    17551784        {
     
    17571786             * Get the multiplexor IDs.
    17581787             */
    1759             rc = ldi_ioctl(IPDevHandle, SIOCGLIFMUXID, (intptr_t)&Interface, FKIOCTL, kcred, &ret);
     1788            rc = ldi_ioctl(Ip4DevHandle, SIOCGLIFMUXID, (intptr_t)&Ip4Interface, FKIOCTL, kcred, &ret);
    17601789            if (!rc)
    17611790            {
     
    17641793                 * once a module is I_PLINK, we need to reobtain it for inserting/removing ourselves from the stack.
    17651794                 */
    1766                 int IpMuxFd;
     1795                int Ip4MuxFd;
    17671796                int ArpMuxFd;
    1768                 rc = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_ip_muxid, &IpMuxFd);
    1769                 rc2 = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_arp_muxid, &ArpMuxFd);
     1797                rc = vboxNetFltSolarisMuxIdToFd(pUdp4VNode, Ip4Interface.lifr_ip_muxid, &Ip4MuxFd);
     1798                rc2 = vboxNetFltSolarisMuxIdToFd(pUdp4VNode, Ip4Interface.lifr_arp_muxid, &ArpMuxFd);
    17701799                if (   RT_SUCCESS(rc)
    17711800                    && RT_SUCCESS(rc2))
     
    17761805                     */
    17771806                    int ret;
    1778                     rc = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret);
    1779                     rc2 = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_arp_muxid, 0, K_TO_K, kcred, &ret);
     1807                    rc = strioctl(pUdp4VNode, I_PUNLINK, (intptr_t)Ip4Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret);
     1808                    rc2 = strioctl(pUdp4VNode, I_PUNLINK, (intptr_t)Ip4Interface.lifr_arp_muxid, 0, K_TO_K, kcred, &ret);
    17801809                    if (   !rc
    17811810                        && !rc2)
     
    17841813                         * Obtain the vnode from the useless userland file descriptor.
    17851814                         */
    1786                         file_t *pIpFile = getf(IpMuxFd);
     1815                        file_t *pIpFile = getf(Ip4MuxFd);
    17871816                        file_t *pArpFile = getf(ArpMuxFd);
    17881817                        if (   pIpFile
     
    17911820                            && pIpFile->f_vnode)
    17921821                        {
    1793                             vnode_t *pVNodeIp = pIpFile->f_vnode;
    1794                             vnode_t *pVNodeArp = pArpFile->f_vnode;
     1822                            vnode_t *pIp4VNode = pIpFile->f_vnode;
     1823                            vnode_t *pArpVNode = pArpFile->f_vnode;
    17951824
    17961825                            /*
    17971826                             * Find the position on the host stack for attaching/detaching ourselves.
    17981827                             */
    1799                             rc = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeIp, &StrMod.pos);
    1800                             rc2 = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeArp, &ArpStrMod.pos);
     1828                            rc = vboxNetFltSolarisDetermineModPos(fAttach, pIp4VNode, &StrMod.pos);
     1829                            rc2 = vboxNetFltSolarisDetermineModPos(fAttach, pArpVNode, &ArpStrMod.pos);
    18011830                            if (   RT_SUCCESS(rc)
    18021831                                && RT_SUCCESS(rc2))
     
    18081837                                 */
    18091838                                g_VBoxNetFltSolarisInstance = pThis;
    1810                                 g_VBoxNetFltSolarisStreamType = kIpStream;
     1839                                g_VBoxNetFltSolarisStreamType = kIp4Stream;
    18111840
    18121841                                /*
    18131842                                 * Inject/Eject from the host IP stack.
    18141843                                 */
    1815                                 rc = strioctl(pVNodeIp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K,
     1844                                rc = strioctl(pIp4VNode, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K,
    18161845                                            kcred, &ret);
    18171846                                if (!rc)
     
    18211850                                     */
    18221851                                    g_VBoxNetFltSolarisStreamType = kArpStream;
    1823                                     rc = strioctl(pVNodeArp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&ArpStrMod, 0, K_TO_K,
     1852                                    rc = strioctl(pArpVNode, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&ArpStrMod, 0, K_TO_K,
    18241853                                                kcred, &ret);
    18251854                                    if (!rc)
     
    18321861                                         * otherwise we've pretty much screwed up the host interface.
    18331862                                         */
    1834                                         rc = vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd);
     1863                                        rc = vboxNetFltSolarisRelinkIp4(pUdp4VNode, &Ip4Interface, Ip4MuxFd, ArpMuxFd);
    18351864                                        if (RT_SUCCESS(rc))
    18361865                                        {
     
    18391868                                             * we end up close twice which is an instant kernel panic.
    18401869                                             */
    1841                                             vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP);
    1842                                             ldi_close(ARPDevHandle, FREAD | FWRITE, kcred);
    1843                                             ldi_close(IPDevHandle, FREAD | FWRITE, kcred);
    1844 
    1845                                             LogFlow((DEVICE_NAME ":vboxNetFltSolarisModSetup: Success! %s %s@(Ip:%d Arp:%d) "
     1870                                            vboxNetFltSolarisCloseDev(pUdp4VNodeHeld, pUdp4User);
     1871                                            ldi_close(ArpDevHandle, FREAD | FWRITE, kcred);
     1872                                            ldi_close(Ip4DevHandle, FREAD | FWRITE, kcred);
     1873
     1874                                            LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: Success! %s %s@(IPv4:%d Arp:%d) "
    18461875                                                    "%s interface %s\n", fAttach ? "Injected" : "Ejected", StrMod.mod_name,
    18471876                                                    StrMod.pos, ArpStrMod.pos, fAttach ? "to" : "from", pThis->szName));
     
    18501879                                        else
    18511880                                        {
    1852                                             LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: Relinking failed. Mode=%s rc=%d.\n",
     1881                                            LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: Relinking failed. Mode=%s rc=%d.\n",
    18531882                                                    fAttach ? "inject" : "eject", rc));
    18541883                                        }
     
    18581887                                         */
    18591888                                        if (fAttach)
    1860                                             strioctl(pVNodeIp, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);
     1889                                            strioctl(pIp4VNode, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);
    18611890                                    }
    18621891                                    else
    18631892                                    {
    1864                                         LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to %s the ARP stack. rc=%d\n",
     1893                                        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to %s the ARP stack. rc=%d\n",
    18651894                                                fAttach ? "inject into" : "eject from", rc));
    18661895                                    }
    18671896
    18681897                                    if (fAttach)
    1869                                         strioctl(pVNodeIp, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);
    1870 
    1871                                     vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd);
     1898                                        strioctl(pIp4VNode, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);
     1899
     1900                                    vboxNetFltSolarisRelinkIp4(pUdp4VNode, &Ip4Interface, Ip4MuxFd, ArpMuxFd);
    18721901                                }
    18731902                                else
    18741903                                {
    1875                                     LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to %s the IP stack. rc=%d\n",
     1904                                    LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to %s the IP stack. rc=%d\n",
    18761905                                            fAttach ? "inject into" : "eject from", rc));
    18771906                                }
    18781907                            }
    18791908                            else
    1880                                 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to find position. rc=%d rc2=%d\n", rc, rc2));
     1909                                LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to find position. rc=%d rc2=%d\n", rc, rc2));
    18811910                        }
    18821911                        else
    1883                             LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get vnode from MuxFd.\n"));
     1912                            LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to get vnode from MuxFd.\n"));
    18841913                    }
    18851914                    else
    1886                         LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2));
     1915                        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2));
    18871916                }
    18881917                else
    1889                     LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get MuxFd from MuxId. rc=%d rc2=%d\n"));
     1918                    LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to get MuxFd from MuxId. rc=%d rc2=%d\n"));
    18901919            }
    18911920            else
    1892                 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get Mux Ids. rc=%d\n", rc));
    1893             vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP);
     1921                LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to get Mux Ids. rc=%d\n", rc));
     1922            vboxNetFltSolarisCloseDev(pUdp4VNodeHeld, pUdp4User);
    18941923        }
    18951924        else
    1896             LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to open UDP. rc=%d\n", rc));
     1925            LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: failed to open UDP. rc=%d\n", rc));
    18971926    }
    18981927    else
     
    19011930         * This would happen for interfaces that are not plumbed.
    19021931         */
    1903         LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: Warning: seems '%s' is unplumbed.\n", pThis->szName));
     1932        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp4: Warning: seems '%s' is unplumbed.\n", pThis->szName));
    19041933        rc = VINF_SUCCESS;
    19051934    }
    19061935
    1907     ldi_close(ARPDevHandle, FREAD | FWRITE, kcred);
    1908     ldi_close(IPDevHandle, FREAD | FWRITE, kcred);
     1936    ldi_close(ArpDevHandle, FREAD | FWRITE, kcred);
     1937    ldi_close(Ip4DevHandle, FREAD | FWRITE, kcred);
    19091938
    19101939    if (RT_SUCCESS(rc))
     
    19131942    return VERR_INTNET_FLT_IF_FAILED;
    19141943}
     1944
     1945
     1946/**
     1947 * Dynamically attach under IPv6 on the host stack.
     1948 *
     1949 * @returns VBox status code.
     1950 * @param   pThis       The instance.
     1951 * @param   fAttach     Is this an attach or detach.
     1952 */
     1953static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach)
     1954{
     1955    /*
     1956     * Statuatory Warning: Hackish code ahead.
     1957     */
     1958    char *pszModName = DEVICE_NAME;
     1959
     1960    struct lifreq Ip6Interface;
     1961    bzero(&Ip6Interface, sizeof(Ip6Interface));
     1962    Ip6Interface.lifr_addr.ss_family = AF_INET6;
     1963    strncpy(Ip6Interface.lifr_name, pThis->szName, sizeof(Ip6Interface.lifr_name));
     1964
     1965    struct strmodconf StrMod;
     1966    StrMod.mod_name = pszModName;
     1967    StrMod.pos = -1;        /* this is filled in later. */
     1968
     1969    int rc;
     1970    int rc2;
     1971    int ret;
     1972    ldi_ident_t DeviceIdent = ldi_ident_from_anon();
     1973    ldi_handle_t Ip6DevHandle;
     1974    ldi_handle_t Udp6DevHandle;
     1975
     1976    /*
     1977     * Open the IPv6 stream as a layered devices.
     1978     */
     1979    rc = ldi_open_by_name(IP6_DEV_NAME, FREAD | FWRITE, kcred, &Ip6DevHandle, DeviceIdent);
     1980    ldi_ident_release(DeviceIdent);
     1981    if (rc)
     1982    {
     1983        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to open the IPv6 stream on '%s'.\n", pThis->szName));
     1984        return VERR_INTNET_FLT_IF_FAILED;
     1985    }
     1986
     1987    /*
     1988     * Obtain the interface flags from IPv6.
     1989     */
     1990    rc = vboxNetFltSolarisGetIfFlags(Ip6DevHandle, &Ip6Interface);
     1991    if (RT_SUCCESS(rc))
     1992    {
     1993        /*
     1994         * Open the UDP stream. We sort of cheat here and obtain the vnode so that we can perform
     1995         * things that are not possible from the layered interface.
     1996         */
     1997        vnode_t *pUdp6VNode = NULL;
     1998        vnode_t *pUdp6VNodeHeld = NULL;
     1999        TIUSER *pUdp6User = NULL;
     2000        rc = vboxNetFltSolarisOpenDev(UDP6_DEV_NAME, &pUdp6VNode, &pUdp6VNodeHeld, &pUdp6User);
     2001        if (RT_SUCCESS(rc))
     2002        {
     2003            /*
     2004             * Get the multiplexor IDs.
     2005             */
     2006            rc = ldi_ioctl(Ip6DevHandle, SIOCGLIFMUXID, (intptr_t)&Ip6Interface, FKIOCTL, kcred, &ret);
     2007            if (!rc)
     2008            {
     2009                /*
     2010                 * Get the multiplex file descriptor to the lower streams. Generally this is lost
     2011                 * once a module is I_PLINK, we need to reobtain it for inserting/removing ourselves from the stack.
     2012                 */
     2013                int Ip6MuxFd;
     2014                rc = vboxNetFltSolarisMuxIdToFd(pUdp6VNode, Ip6Interface.lifr_ip_muxid, &Ip6MuxFd);
     2015                if (RT_SUCCESS(rc))
     2016                {
     2017                    /*
     2018                     * We need to I_PUNLINK on these multiplexor IDs before we can start
     2019                     * operating on the lower stream as insertions are direct operations on the lower stream.
     2020                     */
     2021                    int ret;
     2022                    rc = strioctl(pUdp6VNode, I_PUNLINK, (intptr_t)Ip6Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret);
     2023                    if (!rc)
     2024                    {
     2025                        /*
     2026                         * Obtain the vnode from the useless userland file descriptor.
     2027                         */
     2028                        file_t *pIpFile = getf(Ip6MuxFd);
     2029                        if (   pIpFile
     2030                            && pIpFile->f_vnode)
     2031                        {
     2032                            vnode_t *pIp6VNode = pIpFile->f_vnode;
     2033
     2034                            /*
     2035                             * Find the position on the host stack for attaching/detaching ourselves.
     2036                             */
     2037                            rc = vboxNetFltSolarisDetermineModPos(fAttach, pIp6VNode, &StrMod.pos);
     2038                            if (RT_SUCCESS(rc))
     2039                            {
     2040                                /*
     2041                                 * Set global data which will be grabbed by ModOpen.
     2042                                 * There is a known (though very unlikely) race here because
     2043                                 * of the inability to pass user data while inserting.
     2044                                 */
     2045                                g_VBoxNetFltSolarisInstance = pThis;
     2046                                g_VBoxNetFltSolarisStreamType = kIp6Stream;
     2047
     2048                                /*
     2049                                 * Inject/Eject from the host IP stack.
     2050                                 */
     2051                                rc = strioctl(pIp6VNode, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K,
     2052                                            kcred, &ret);
     2053                                if (!rc)
     2054                                {
     2055                                    g_VBoxNetFltSolarisInstance = NULL;
     2056                                    g_VBoxNetFltSolarisStreamType = kUndefined;
     2057
     2058                                    /*
     2059                                     * Our job's not yet over; we need to relink the upper and lower streams
     2060                                     * otherwise we've pretty much screwed up the host interface.
     2061                                     */
     2062                                    rc = vboxNetFltSolarisRelinkIp6(pUdp6VNode, &Ip6Interface, Ip6MuxFd);
     2063                                    if (RT_SUCCESS(rc))
     2064                                    {
     2065                                        /*
     2066                                         * Close the devices ONLY during the return from function case; otherwise
     2067                                         * we end up close twice which is an instant kernel panic.
     2068                                         */
     2069                                        vboxNetFltSolarisCloseDev(pUdp6VNodeHeld, pUdp6User);
     2070                                        ldi_close(Ip6DevHandle, FREAD | FWRITE, kcred);
     2071
     2072                                        LogFlow((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: Success! %s %s@(IPv6:%d) "
     2073                                                "%s interface %s\n", fAttach ? "Injected" : "Ejected", StrMod.mod_name,
     2074                                                StrMod.pos, fAttach ? "to" : "from", pThis->szName));
     2075                                        return VINF_SUCCESS;
     2076                                    }
     2077                                    else
     2078                                    {
     2079                                        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: Relinking failed. Mode=%s rc=%d.\n",
     2080                                                fAttach ? "inject" : "eject", rc));
     2081                                    }
     2082
     2083                                    if (fAttach)
     2084                                        strioctl(pIp6VNode, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);
     2085
     2086                                    vboxNetFltSolarisRelinkIp6(pUdp6VNode, &Ip6Interface, Ip6MuxFd);
     2087                                }
     2088                                else
     2089                                {
     2090                                    LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to %s the IP stack. rc=%d\n",
     2091                                            fAttach ? "inject into" : "eject from", rc));
     2092                                }
     2093                            }
     2094                            else
     2095                                LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to find position. rc=%d rc2=%d\n", rc, rc2));
     2096                        }
     2097                        else
     2098                             LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get vnode from MuxFd.\n"));
     2099                    }
     2100                    else
     2101                        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2));
     2102                }
     2103                else
     2104                    LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get MuxFd from MuxId. rc=%d rc2=%d\n"));
     2105            }
     2106            else
     2107                LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get Mux Ids. rc=%d\n", rc));
     2108            vboxNetFltSolarisCloseDev(pUdp6VNodeHeld, pUdp6User);
     2109        }
     2110        else
     2111            LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to open UDP. rc=%d\n", rc));
     2112    }
     2113    else
     2114        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachIp6: failed to get IPv6 flags.\n", pThis->szName));
     2115
     2116    ldi_close(Ip6DevHandle, FREAD | FWRITE, kcred);
     2117
     2118    if (RT_SUCCESS(rc))
     2119        return rc;
     2120
     2121    return VERR_INTNET_FLT_IF_FAILED;
     2122}
     2123
     2124
     2125/**
     2126 * Wrapper for attaching our module to the specificed stream on the host stack.
     2127 * As a side-effect, the streams also gets opened/closed during the actual injection/ejection phase.
     2128 *
     2129 * @returns VBox status code.
     2130 * @param   pThis       The instance.
     2131 * @param   fAttach     Is this an attach or detach.
     2132 * @param   StreamType  Identifies the host stream the module be inject/ejected.
     2133 */
     2134static int vboxNetFltSolarisModSetup(PVBOXNETFLTINS pThis, bool fAttach, VBOXNETFLTSTREAMTYPE StreamType)
     2135{
     2136    LogFlow(("vboxNetFltSolarisModSetup: pThis=%p (%s) fAttach=%s StreamType=%d\n", pThis, pThis->szName,
     2137            fAttach ? "true" : "false", StreamType));
     2138
     2139    switch (StreamType)
     2140    {
     2141        case kIp4Stream:
     2142        case kArpStream:
     2143            return vboxNetFltSolarisAttachIp4(pThis, fAttach);
     2144
     2145        case kIp6Stream:
     2146            return vboxNetFltSolarisAttachIp6(pThis, fAttach);
     2147
     2148        default:
     2149            LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: Invalid stream type %d\n", StreamType));
     2150            return VERR_INTNET_FLT_IF_FAILED;
     2151    }
     2152}
     2153
    19152154
    19162155
     
    19312170    if (RT_SUCCESS(rc))
    19322171    {
    1933         rc = vboxNetFltSolarisModSetup(pThis, true);
     2172        rc = vboxNetFltSolarisModSetup(pThis, true, kIp4Stream);
    19342173        if (RT_SUCCESS(rc))
     2174        {
     2175            vboxNetFltSolarisModSetup(pThis, true, kIp6Stream);
     2176            /* Ignore Ipv6 binding errors as it's optional. */
     2177
    19352178            ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, false);
     2179        }
    19362180        else
    19372181            vboxNetFltSolarisCloseStream(pThis);
     
    19602204    ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
    19612205    vboxNetFltSolarisCloseStream(pThis);
    1962     rc = vboxNetFltSolarisModSetup(pThis, false);
     2206    rc = vboxNetFltSolarisModSetup(pThis, false, kIp4Stream);
     2207    if (pThis->u.s.pvIp6Stream)
     2208        vboxNetFltSolarisModSetup(pThis, false, kIp6Stream);
    19632209
    19642210    RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
     
    28753121     * Init. the solaris specific data.
    28763122     */
    2877     pThis->u.s.pvIpStream = NULL;
     3123    pThis->u.s.pvIp4Stream = NULL;
     3124    pThis->u.s.pvIp6Stream = NULL;
    28783125    pThis->u.s.pvArpStream = NULL;
    28793126    pThis->u.s.pvPromiscStream = NULL;
     
    29263173         * We either bind to both or neither; so atomic reading one should be sufficient.
    29273174         */
    2928         vboxnetflt_stream_t *pIpStream  = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvIpStream);
    2929         if (!pIpStream)
     3175        vboxnetflt_stream_t *pIp4Stream  = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvIp4Stream);
     3176        if (!pIp4Stream)
    29303177            return rc;
    29313178
     
    29373184        {
    29383185            PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pMsg->b_rptr;
    2939             bool fArp = (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP));
    29403186
    29413187            /*
    29423188             * Send message up ARP stream.
    29433189             */
    2944             if (fArp)
     3190            if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP))
    29453191            {
    29463192                LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_HOST ARP\n"));
     
    29713217                    freemsg(pMsg);  /* Should really never happen... */
    29723218            }
     3219            else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
     3220            {
     3221                /*
     3222                 * Send messages up IPv6 stream.
     3223                 */
     3224                LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_HOST IPv6\n"));
     3225
     3226                vboxnetflt_stream_t *pIp6Stream  = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvIp6Stream);
     3227                if (pIp6Stream)
     3228                {
     3229                    pMsg->b_rptr += sizeof(RTNETETHERHDR);
     3230                    queue_t *pIp6ReadQueue = pIp6Stream->pReadQueue;
     3231                    putnext(pIp6ReadQueue, pMsg);
     3232                }
     3233                else
     3234                    freemsg(pMsg);
     3235            }
    29733236            else
    29743237            {
    29753238                /*
    2976                  * Send messages up IP stream.
     3239                 * Send messages up IPv4 stream.
    29773240                 */
    2978                 LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_HOST\n"));
     3241                LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_HOST IPv4\n"));
    29793242
    29803243                pMsg->b_rptr += sizeof(RTNETETHERHDR);
    2981                 queue_t *pIpReadQueue = pIpStream->pReadQueue;
    2982                 putnext(pIpReadQueue, pMsg);
     3244                queue_t *pIp4ReadQueue = pIp4Stream->pReadQueue;
     3245                putnext(pIp4ReadQueue, pMsg);
    29833246            }
    29843247        }
     
    29863249        {
    29873250            LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkFromSG failed.\n"));
    2988             rc = VERR_NO_MEMORY;               
     3251            rc = VERR_NO_MEMORY;
    29893252        }
    29903253    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette