I have made a patch to allow the use of the 'old' tap mode network interface in addition to the new bridging mode. The changes are based entirely on existing VirtualBox code and a lot of existing code could simply be re-used as-is. The patch will (should) not change the behaviour of existing/other network interfaces.

The tap interface can be enabled by setting DEFS+=VBOX_WITH_TAP in the kmk makefiles (I could not find a more specific location for this define, as the networking code seems to be all over the place).

If applicable, I will hereby release the changes under the MIT license.

Ivo
Index: src/VBox/Main/include/NetworkAdapterImpl.h
===================================================================
--- src/VBox/Main/include/NetworkAdapterImpl.h  (revision 27964)
+++ src/VBox/Main/include/NetworkAdapterImpl.h  (working copy)
@@ -115,6 +115,7 @@
 
     // INetworkAdapter methods
     STDMETHOD(AttachToNAT)();
+    STDMETHOD(AttachToTapInterface)();
     STDMETHOD(AttachToBridgedInterface)();
     STDMETHOD(AttachToInternalNetwork)();
     STDMETHOD(AttachToHostOnlyInterface)();
Index: src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- src/VBox/Main/include/ConsoleImpl.h (revision 27964)
+++ src/VBox/Main/include/ConsoleImpl.h (working copy)
@@ -409,7 +409,7 @@
 
     HRESULT callTapSetupApplication(bool isStatic, RTFILE tapFD, Bstr 
&tapDevice,
                                     Bstr &tapSetupApplication);
-#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD))
+#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD) || defined(VBOX_WITH_NETTAP))
     HRESULT attachToTapInterface(INetworkAdapter *networkAdapter);
     HRESULT detachFromTapInterface(INetworkAdapter *networkAdapter);
 #endif
@@ -595,7 +595,7 @@
     PPDMLED      mapNetworkLeds[SchemaDefs::NetworkAdapterCount];
     PPDMLED      mapSharedFolderLed;
     PPDMLED      mapUSBLed[2];
-#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD))
+#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD) || defined(VBOX_WITH_NETTAP))
     Utf8Str      maTAPDeviceName[8];
     RTFILE       maTapFD[8];
 #endif
Index: src/VBox/Main/NetworkAdapterImpl.cpp
===================================================================
--- src/VBox/Main/NetworkAdapterImpl.cpp        (revision 27964)
+++ src/VBox/Main/NetworkAdapterImpl.cpp        (working copy)
@@ -897,7 +897,57 @@
 
     return S_OK;
 }
+STDMETHODIMP NetworkAdapter::AttachToTapInterface()
+{
+#ifdef VBOX_WITH_NETTAP
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(mParent);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    /* don't do anything if we're already host interface attached */
+    if (mData->mAttachmentType != NetworkAttachmentType_Tap)
+    {
+        mData.backup();
+
+        /* first detach the current attachment */
+        // Commented this for now as it reset the parameter 
mData->mHostInterface
+        // which is essential while changing the Attachment dynamically.
+        //detach();
+
+        mData->mAttachmentType = NetworkAttachmentType_Tap;
+
+        m_fModified = true;
+        // leave the lock before informing callbacks
+        alock.release();
+
+        AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);       // mParent 
is const, no need to lock
+        mParent->setModified(Machine::IsModified_NetworkAdapters);
+        mlock.release();
+
+        /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
+        HRESULT rc = mParent->onNetworkAdapterChange(this, TRUE);
+        if (FAILED(rc))
+        {
+            /* If changing the attachment failed then we can't assume that the
+             * previous attachment will attach correctly and thus return error
+             * along with dettaching all attachments.
+             */
+            Detach();
+            return rc;
+        }
+    }
+
+    return S_OK;
+#else
+    return Detach();
+#endif
+}
+
 STDMETHODIMP NetworkAdapter::AttachToInternalNetwork()
 {
     AutoCaller autoCaller(this);
@@ -1091,6 +1141,15 @@
             if (FAILED(rc)) return rc;
         break;
 
+#ifdef VBOX_WITH_NETTAP
+        case NetworkAttachmentType_Tap:
+            rc = COMSETTER(HostInterface)(Bstr(data.strName));
+            if (FAILED(rc)) return rc;
+            rc = AttachToTapInterface();
+            if (FAILED(rc)) return rc;
+        break;
+#endif
+
         case NetworkAttachmentType_Internal:
             mData->mInternalNetwork = data.strName;
             Assert(!mData->mInternalNetwork.isEmpty());
@@ -1163,6 +1222,12 @@
             data.strName = mData->mHostInterface;
         break;
 
+#ifdef VBOX_WITH_NETTAP
+        case NetworkAttachmentType_Tap:
+            data.strName = mData->mHostInterface;
+        break;
+#endif
+
         case NetworkAttachmentType_Internal:
             data.strName = mData->mInternalNetwork;
         break;
@@ -1321,6 +1386,16 @@
             mData->mHostInterface = "";
             break;
         }
+
+#ifdef VBOX_WITH_NETTAP
+        case NetworkAttachmentType_Tap:
+        {
+            /* reset handle and device name */
+            mData->mHostInterface = "";
+            break;
+        }
+#endif
+
         case NetworkAttachmentType_Internal:
         {
             mData->mInternalNetwork.setNull();
Index: src/VBox/Main/ConsoleImpl2.cpp
===================================================================
--- src/VBox/Main/ConsoleImpl2.cpp      (revision 27964)
+++ src/VBox/Main/ConsoleImpl2.cpp      (working copy)
@@ -3138,6 +3138,47 @@
             break;
         }
 
+#if defined(VBOX_WITH_NETTAP)
+        case NetworkAttachmentType_Tap:
+        {
+            hrc = pThis->attachToTapInterface(aNetworkAdapter);
+            if (FAILED(hrc))
+            {
+                switch (hrc)
+                {
+                    case VERR_ACCESS_DENIED:
+                        return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, 
RT_SRC_POS,  N_(
+                                         "Failed to open '/dev/net/tun' for 
read/write access. Please check the "
+                                         "permissions of that node. Either run 
'chmod 0666 /dev/net/tun' or "
+                                         "change the group of that node and 
make yourself a member of that group. Make "
+                                         "sure that these changes are 
permanent, especially if you are "
+                                         "using udev"));
+                    default:
+                        AssertMsgFailed(("Could not attach to host interface! 
Bad!\n"));
+                        return VMSetError(pVM, VERR_HOSTIF_INIT_FAILED, 
RT_SRC_POS, N_(
+                                         "Failed to initialize Host Interface 
Networking"));
+                }
+            }
+
+            Assert((int)pThis->maTapFD[uInstance] >= 0);
+            if ((int)pThis->maTapFD[uInstance] >= 0)
+            {
+                if (fSniffer)
+                {
+                    rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL0);  
             RC_CHECK();
+                }
+                else
+                {
+                    rc = CFGMR3InsertNode(pInst, "LUN#0", &pLunL0);            
             RC_CHECK();
+                }
+                rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface");    
             RC_CHECK();
+                rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);                
             RC_CHECK();
+                rc = CFGMR3InsertInteger(pCfg, "FileHandle", 
pThis->maTapFD[uInstance]);    RC_CHECK();
+            }
+            break;
+        }
+#endif
+
         case NetworkAttachmentType_Internal:
         {
             hrc = aNetworkAdapter->COMGETTER(InternalNetwork)(&str);    H();
@@ -3378,6 +3419,9 @@
             break;
 
         case NetworkAttachmentType_Bridged:
+#ifdef VBOX_WITH_NETTAP
+        case NetworkAttachmentType_Tap:
+#endif
         case NetworkAttachmentType_Internal:
         case NetworkAttachmentType_HostOnly:
         case NetworkAttachmentType_NAT:
Index: src/VBox/Main/ApplianceImplExport.cpp
===================================================================
--- src/VBox/Main/ApplianceImplExport.cpp       (revision 27964)
+++ src/VBox/Main/ApplianceImplExport.cpp       (working copy)
@@ -472,6 +472,12 @@
                     case NetworkAttachmentType_HostOnly:
                         strAttachmentType = "HostOnly";
                     break;
+
+#ifdef VBOX_WITH_NETTAP
+                    case NetworkAttachmentType_Tap:
+                        strAttachmentType = "Tap";
+                    break;
+#endif
                 }
 
                 pNewDesc->addEntry(VirtualSystemDescriptionType_NetworkAdapter,
Index: src/VBox/Main/xml/Settings.cpp
===================================================================
--- src/VBox/Main/xml/Settings.cpp      (revision 27964)
+++ src/VBox/Main/xml/Settings.cpp      (working copy)
@@ -1869,6 +1869,13 @@
             nic.mode = NetworkAttachmentType_Bridged;
             pelmAdapterChild->getAttributeValue("name", nic.strName);    // 
optional host interface name
         }
+#ifdef VBOX_WITH_NETTAP
+        else if ((pelmAdapterChild = pelmAdapter->findChildElement("Tap")))
+        {
+            nic.mode = NetworkAttachmentType_Tap;
+            pelmAdapterChild->getAttributeValue("name", nic.strName);    // 
optional host interface name
+        }
+#endif
         else if ((pelmAdapterChild = 
pelmAdapter->findChildElement("InternalNetwork")))
         {
             nic.mode = NetworkAttachmentType_Internal;
@@ -3367,6 +3374,11 @@
             case NetworkAttachmentType_Bridged:
                 
pelmAdapter->createChild("BridgedInterface")->setAttribute("name", nic.strName);
             break;
+#ifdef VBOX_WITH_NETTAP
+            case NetworkAttachmentType_Tap:
+                pelmAdapter->createChild("Tap")->setAttribute("name", 
nic.strName);
+            break;
+#endif
 
             case NetworkAttachmentType_Internal:
                 
pelmAdapter->createChild("InternalNetwork")->setAttribute("name", nic.strName);
Index: src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- src/VBox/Main/ConsoleImpl.cpp       (revision 27964)
+++ src/VBox/Main/ConsoleImpl.cpp       (working copy)
@@ -6344,7 +6344,7 @@
 }
 
 #endif /* VBOX_WITH_USB */
-#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD))
+#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || 
defined(RT_OS_FREEBSD) || defined(VBOX_WITH_NETTAP))
 
 /**
  * Helper function to handle host interface device creation and attachment.
Index: src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- src/VBox/Main/idl/VirtualBox.xidl   (revision 27964)
+++ src/VBox/Main/idl/VirtualBox.xidl   (working copy)
@@ -11544,6 +11544,7 @@
     <const name="Bridged"               value="2"/>
     <const name="Internal"              value="3"/>
     <const name="HostOnly"              value="4"/>
+    <const name="Tap"                   value="5"/>
   </enum>
 
   <enum
@@ -11693,6 +11694,12 @@
       </desc>
     </method>
 
+    <method name="attachToTapInterface">
+      <desc>
+        Attach the network adapter to a bridged host interface.
+      </desc>
+    </method>
+
     <method name="attachToInternalNetwork">
       <desc>
         Attach the network adapter to an internal network.
Index: src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
===================================================================
--- src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp     
(revision 27964)
+++ src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp     
(working copy)
@@ -93,6 +93,9 @@
     switch (attachmentType())
     {
         case KNetworkAttachmentType_Bridged:
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+#endif
             mBrgName = mAdapter.GetHostInterface();
             if (mBrgName.isEmpty()) mBrgName = QString::null;
             break;
@@ -136,6 +139,12 @@
             mAdapter.SetHostInterface (alternativeName());
             mAdapter.AttachToBridgedInterface();
             break;
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+#endif
+            mAdapter.SetHostInterface (alternativeName());
+            mAdapter.AttachToTapInterface();
+            break;
         case KNetworkAttachmentType_Internal:
             mAdapter.SetInternalNetwork (alternativeName());
             mAdapter.AttachToInternalNetwork();
@@ -248,6 +257,9 @@
     switch (aType)
     {
         case KNetworkAttachmentType_Bridged:
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+#endif
             result = mBrgName;
             break;
         case KNetworkAttachmentType_Internal:
@@ -323,6 +335,12 @@
             mCbAdapterName->insertItems (0, mParent->brgList());
             mCbAdapterName->setEditable (false);
             break;
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+//            mCbAdapterName->insertItems (0, mParent->brgList());
+            mCbAdapterName->setEditable (true);
+            break;
+#endif
         case KNetworkAttachmentType_Internal:
             mCbAdapterName->insertItems (0, mParent->intList());
             mCbAdapterName->setEditable (true);
@@ -343,6 +361,9 @@
         {
             case KNetworkAttachmentType_Bridged:
             case KNetworkAttachmentType_HostOnly:
+#ifdef VBOX_WITH_NETTAP
+            case KNetworkAttachmentType_Tap:
+#endif
             {
                 /* Adapters list 'empty' */
                 int pos = mCbAdapterName->findData (emptyItemCode);
@@ -367,6 +388,17 @@
     /* Select previous or default item */
     switch (attachmentType())
     {
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+        {
+            //int pos = mCbAdapterName->findText (alternativeName());
+            //if (pos == -1)
+                mCbAdapterName->insertItem (0, alternativeName(), 
alternativeName());
+            mCbAdapterName->setCurrentIndex (0);
+            //mCbAdapterName->setCurrentIndex (pos == -1 ? 0 : pos);
+            break;
+        }
+#endif
         case KNetworkAttachmentType_Bridged:
         case KNetworkAttachmentType_HostOnly:
         {
@@ -421,6 +453,18 @@
             }
             break;
         }
+#ifdef VBOX_WITH_NETTAP
+        case KNetworkAttachmentType_Tap:
+        {
+            QString newName (mCbAdapterName->itemData 
(mCbAdapterName->currentIndex()).toString() ==
+                             QString (emptyItemCode) ||
+                             mCbAdapterName->currentText().isEmpty() ?
+                             QString::null : mCbAdapterName->currentText());
+            if (mBrgName != newName)
+                mBrgName = newName;
+            break;
+        }
+#endif
         case KNetworkAttachmentType_HostOnly:
         {
             QString newName (mCbAdapterName->itemData 
(mCbAdapterName->currentIndex()).toString() ==
@@ -547,6 +591,14 @@
         KNetworkAttachmentType_HostOnly);
     mCbAttachmentType->setItemData (4,
         mCbAttachmentType->itemText (4), Qt::ToolTipRole);
+#ifdef VBOX_WITH_NETTAP
+    mCbAttachmentType->insertItem (5,
+        vboxGlobal().toString (KNetworkAttachmentType_Tap));
+    mCbAttachmentType->setItemData (5,
+        KNetworkAttachmentType_Tap);
+    mCbAttachmentType->setItemData (5,
+        mCbAttachmentType->itemText (5), Qt::ToolTipRole);
+#endif
 
     /* Set the old value */
     mCbAttachmentType->setCurrentIndex (currentAttachment);
Index: src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp    (revision 27964)
+++ src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp    (working copy)
@@ -2148,6 +2148,11 @@
                 if (type == KNetworkAttachmentType_Bridged)
                     attType = attType.arg (tr ("Bridged adapter, %1",
                         "details report (network)").arg 
(adapter.GetHostInterface()));
+#if VBOX_WITH_NETTAP
+                else if (type == KNetworkAttachmentType_Tap)
+                    attType = attType.arg (tr ("Tap adapter, %1",
+                        "details report (network)").arg 
(adapter.GetHostInterface()));
+#endif
                 else if (type == KNetworkAttachmentType_Internal)
                     attType = attType.arg (tr ("Internal network, '%1'",
                         "details report (network)").arg 
(adapter.GetInternalNetwork()));
@@ -3112,6 +3117,10 @@
         tr ("Internal Network", "NetworkAttachmentType");
     mNetworkAttachmentTypes [KNetworkAttachmentType_HostOnly] =
         tr ("Host-only Adapter", "NetworkAttachmentType");
+#ifdef VBOX_WITH_NETTAP
+    mNetworkAttachmentTypes [KNetworkAttachmentType_Tap] =
+        tr ("Tap interface", "NetworkAttachmentType");
+#endif
 
     mClipboardTypes [KClipboardMode_Disabled] =
         tr ("Disabled", "ClipboardType");
Index: src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
===================================================================
--- src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp        (revision 27964)
+++ src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp        (working copy)
@@ -215,6 +215,9 @@
     { "--nic",                      MODIFYVM_NIC,                       
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
     { "--cableconnected",           MODIFYVM_CABLECONNECTED,            
RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
     { "--bridgeadapter",            MODIFYVM_BRIDGEADAPTER,             
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
+#ifdef VBOX_WITH_NETTAP
+    { "--tapname",                  MODIFYVM_BRIDGEADAPTER,             
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX }, //We use the same properties to 
store this
+#endif
     { "--hostonlyadapter",          MODIFYVM_HOSTONLYADAPTER,           
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
     { "--intnet",                   MODIFYVM_INTNET,                    
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
     { "--natnet",                   MODIFYVM_NATNET,                    
RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
@@ -1150,6 +1153,13 @@
                     CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
                     CHECK_ERROR(nic, AttachToBridgedInterface());
                 }
+#ifdef VBOX_WITH_NETTAP
+                else if (  !strcmp(ValueUnion.psz, "tap"))
+                {
+                    CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+                    CHECK_ERROR(nic, AttachToTapInterface());
+                }
+#endif
                 else if (!strcmp(ValueUnion.psz, "intnet"))
                 {
                     CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
Index: src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp    (revision 27964)
+++ src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp    (working copy)
@@ -776,6 +776,21 @@
                             strAttachment = Utf8StrFmt("Bridged Interface 
'%lS'", strBridgeAdp.raw());
                         break;
                     }
+#ifdef VBOX_WITH_NETTAP
+                    case NetworkAttachmentType_Tap:
+                    {
+                        Bstr strBridgeAdp;
+                        
nic->COMGETTER(HostInterface)(strBridgeAdp.asOutParam());
+                        if (details == VMINFO_MACHINEREADABLE)
+                        {
+                            RTPrintf("tapadapter%d=\"%lS\"\n", currentNIC + 1, 
strBridgeAdp.raw());
+                            strAttachment = "tap";
+                        }
+                        else
+                            strAttachment = Utf8StrFmt("Tap Interface '%lS'", 
strBridgeAdp.raw());
+                        break;
+                    }
+#endif
                     case NetworkAttachmentType_Internal:
                     {
                         Bstr strNetwork;
Index: src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
===================================================================
--- src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp       (revision 27964)
+++ src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp       (working copy)
@@ -457,6 +457,20 @@
                         CHECK_ERROR_RET(adapter, 
COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
                         CHECK_ERROR_RET(adapter, AttachToBridgedInterface(), 
1);
                     }
+#ifdef VBOX_WITH_NETTAP
+                    else if (  !strcmp(a->argv[2], "tap"))
+                    {
+                        if (a->argc <= 3)
+                        {
+                            errorArgument("Missing argument to '%s'", 
a->argv[2]);
+                            rc = E_FAIL;
+                            break;
+                        }
+                        CHECK_ERROR_RET(adapter, COMSETTER(Enabled)(TRUE), 1);
+                        CHECK_ERROR_RET(adapter, 
COMSETTER(HostInterface)(Bstr(a->argv[3])), 1);
+                        CHECK_ERROR_RET(adapter, AttachToTapInterface(), 1);
+                    }
+#endif
                     else if (!strcmp(a->argv[2], "intnet"))
                     {
                         if (a->argc <= 3)
_______________________________________________
vbox-dev mailing list
[email protected]
http://vbox.innotek.de/mailman/listinfo/vbox-dev

Reply via email to