summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/NetworkAdapterImpl.cpp')
-rw-r--r--src/VBox/Main/src-server/NetworkAdapterImpl.cpp111
1 files changed, 103 insertions, 8 deletions
diff --git a/src/VBox/Main/src-server/NetworkAdapterImpl.cpp b/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
index c7e1fa17..e3908bb3 100644
--- a/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
+++ b/src/VBox/Main/src-server/NetworkAdapterImpl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -23,6 +23,7 @@
#include "GuestOSTypeImpl.h"
#include "HostImpl.h"
#include "SystemPropertiesImpl.h"
+#include "VirtualBoxImpl.h"
#include <iprt/string.h>
#include <iprt/cpp/utils.h>
@@ -439,8 +440,7 @@ STDMETHODIMP NetworkAdapter::COMSETTER(MACAddress)(IN_BSTR aMACAddress)
return rc;
}
-STDMETHODIMP NetworkAdapter::COMGETTER(AttachmentType)(
- NetworkAttachmentType_T *aAttachmentType)
+STDMETHODIMP NetworkAdapter::COMGETTER(AttachmentType)(NetworkAttachmentType_T *aAttachmentType)
{
CheckComArgOutPointerValid(aAttachmentType);
@@ -454,8 +454,7 @@ STDMETHODIMP NetworkAdapter::COMGETTER(AttachmentType)(
return S_OK;
}
-STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(
- NetworkAttachmentType_T aAttachmentType)
+STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(NetworkAttachmentType_T aAttachmentType)
{
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -477,6 +476,14 @@ STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(
mData->mInternalNetwork = "intnet";
}
+ /* there must a NAT network name */
+ if (mData->mNATNetwork.isEmpty())
+ {
+ Log(("NAT network name not defined, setting to default \"NatNetwork\"\n"));
+ mData->mNATNetwork = "NatNetwork";
+ }
+
+ NetworkAttachmentType_T oldAttachmentType = mData->mAttachmentType;
mData->mAttachmentType = aAttachmentType;
m_fModified = true;
@@ -487,6 +494,12 @@ STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(
mParent->setModified(Machine::IsModified_NetworkAdapters);
mlock.release();
+ if (oldAttachmentType == NetworkAttachmentType_NATNetwork)
+ checkAndSwitchFromNatNetworking(mData->mNATNetwork.raw());
+
+ if (aAttachmentType == NetworkAttachmentType_NATNetwork)
+ switchToNatNetworking(mData->mNATNetwork.raw());
+
/* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
mParent->onNetworkAdapterChange(this, TRUE);
}
@@ -525,6 +538,15 @@ STDMETHODIMP NetworkAdapter::COMSETTER(BridgedInterface)(IN_BSTR aBridgedInterfa
if (mData->mBridgedInterface != aBridgedInterface)
{
+ /* if an empty/null string is to be set, bridged interface must be
+ * turned off */
+ if ( (aBridgedInterface == NULL || *aBridgedInterface == '\0')
+ && mData->mAttachmentType == NetworkAttachmentType_Bridged)
+ {
+ return setError(E_FAIL,
+ tr("Empty or null bridged interface name is not valid"));
+ }
+
mData.backup();
mData->mBridgedInterface = aBridgedInterface;
@@ -576,6 +598,15 @@ STDMETHODIMP NetworkAdapter::COMSETTER(HostOnlyInterface)(IN_BSTR aHostOnlyInter
if (mData->mHostOnlyInterface != aHostOnlyInterface)
{
+ /* if an empty/null string is to be set, host only interface must be
+ * turned off */
+ if ( (aHostOnlyInterface == NULL || *aHostOnlyInterface == '\0')
+ && mData->mAttachmentType == NetworkAttachmentType_HostOnly)
+ {
+ return setError(E_FAIL,
+ tr("Empty or null host only interface name is not valid"));
+ }
+
mData.backup();
mData->mHostOnlyInterface = aHostOnlyInterface;
@@ -683,7 +714,19 @@ STDMETHODIMP NetworkAdapter::COMSETTER(NATNetwork)(IN_BSTR aNATNetwork)
if (mData->mNATNetwork != aNATNetwork)
{
+
+ /* if an empty/null string is to be set, host only interface must be
+ * turned off */
+ if ( (aNATNetwork == NULL || *aNATNetwork == '\0')
+ && mData->mAttachmentType == NetworkAttachmentType_NATNetwork)
+ {
+ return setError(E_FAIL,
+ tr("Empty or null NAT network name is not valid"));
+ }
+
mData.backup();
+
+ Bstr oldNatNetworkName = mData->mNATNetwork;
mData->mNATNetwork = aNATNetwork;
m_fModified = true;
@@ -694,9 +737,14 @@ STDMETHODIMP NetworkAdapter::COMSETTER(NATNetwork)(IN_BSTR aNATNetwork)
mParent->setModified(Machine::IsModified_NetworkAdapters);
mlock.release();
- /* Changing the NAT network isn't allowed during runtime, therefore
- * no immediate replug in CFGM logic => changeAdapter=FALSE */
- mParent->onNetworkAdapterChange(this, FALSE);
+ checkAndSwitchFromNatNetworking(oldNatNetworkName.raw());
+
+ switchToNatNetworking(aNATNetwork);
+
+ /* When changing the host adapter, adapt the CFGM logic to make this
+ * change immediately effect and to notify the guest that the network
+ * might have changed, therefore changeAdapter=TRUE. */
+ mParent->onNetworkAdapterChange(this, TRUE);
}
return S_OK;
@@ -1208,6 +1256,7 @@ HRESULT NetworkAdapter::loadSettings(BandwidthControl *bwctl,
mData->mHostOnlyInterface = data.strHostOnlyName;
mData->mGenericDriver = data.strGenericDriver;
mData->mGenericProperties = data.genericProperties;
+ mData->mNATNetwork = data.strNATNetworkName;
// leave the lock before setting attachment type
alock.release();
@@ -1268,6 +1317,8 @@ HRESULT NetworkAdapter::saveSettings(settings::NetworkAdapter &data)
data.strGenericDriver = mData->mGenericDriver;
data.genericProperties = mData->mGenericProperties;
+ data.strNATNetworkName = mData->mNATNetwork;
+
// after saving settings, we are no longer different from the XML on disk
m_fModified = false;
@@ -1511,4 +1562,48 @@ void NetworkAdapter::updateBandwidthGroup(BandwidthGroup *aBwGroup)
LogFlowThisFuncLeave();
}
+
+
+HRESULT NetworkAdapter::checkAndSwitchFromNatNetworking(IN_BSTR networkName)
+{
+ MachineState_T state;
+
+ HRESULT hrc = mParent->COMGETTER(State)(&state);
+ if (FAILED(hrc))
+ return hrc;
+
+ if (state == MachineState_Running)
+ {
+ Bstr bstrName;
+ hrc = mParent->COMGETTER(Name)(bstrName.asOutParam());
+ LogRel(("VM '%ls' stops using NAT network '%ls'\n", bstrName.raw(), networkName));
+ int natCount = mParent->getVirtualBox()->natNetworkRefDec(networkName);
+ if (natCount == -1)
+ return E_INVALIDARG; /* no such network */
+ }
+
+ return S_OK;
+}
+
+
+HRESULT NetworkAdapter::switchToNatNetworking(IN_BSTR aNatNetworkName)
+{
+ MachineState_T state;
+
+ HRESULT hrc = mParent->COMGETTER(State)(&state);
+ if (FAILED(hrc))
+ return hrc;
+
+ if (state == MachineState_Running)
+ {
+ Bstr bstrName;
+ hrc = mParent->COMGETTER(Name)(bstrName.asOutParam());
+ LogRel(("VM '%ls' starts using NAT network '%ls'\n", bstrName.raw(), aNatNetworkName));
+ int natCount = mParent->getVirtualBox()->natNetworkRefInc(aNatNetworkName);
+ if (natCount == -1)
+ return E_INVALIDARG; /* not found */
+ }
+
+ return S_OK;
+}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */