diff options
Diffstat (limited to 'src/VBox/Main/src-server/NetworkAdapterImpl.cpp')
-rw-r--r-- | src/VBox/Main/src-server/NetworkAdapterImpl.cpp | 111 |
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: */ |