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