VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/NetworkAdapterImpl.cpp@ 39882

Last change on this file since 39882 was 39248, checked in by vboxsync, 13 years ago

Runtime: new guest OS type for Solaris 11
Frontends/VirtualBox: add new patterns for Solaris 11 guest OS type, reuse the icon
Frontends/VBoxManage: more details for "list ostypes"
Main/xml: make guest OS type in config file an arbitrary string (still validated/mapped in the old way in the settings code), remove hardcoded limit of 8 network adapters
Main/Global: move list of valid guest OS types into a single place, add function to get the network adapter limit for each chipset type
Main/Console+Machine+Snapshot+NetworkAdapter+Appliance+VirtualBox+Guest+SystemProperties: consistently use the appropriate network adapter limit so that ICH9 chipset can use 36 network adapters, adapt to cleaned up guest OS type handling, remove leftover rendundant guest OS mapping, whitespace
Network/NAT: release log message cosmetics, allow unlimited number of instances, fix maxconn clamping
Network/PCNet+VirtioNet+E1000: allow unlimited number of instances

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.0 KB
Line 
1/* $Id: NetworkAdapterImpl.cpp 39248 2011-11-09 12:29:53Z vboxsync $ */
2/** @file
3 * Implementation of INetworkAdaptor in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2006-2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "NetworkAdapterImpl.h"
19#include "NATEngineImpl.h"
20#include "AutoCaller.h"
21#include "Logging.h"
22#include "MachineImpl.h"
23#include "GuestOSTypeImpl.h"
24#include "HostImpl.h"
25#include "SystemPropertiesImpl.h"
26
27#include <iprt/string.h>
28#include <iprt/cpp/utils.h>
29
30#include <VBox/err.h>
31#include <VBox/settings.h>
32
33#include "AutoStateDep.h"
34
35// constructor / destructor
36////////////////////////////////////////////////////////////////////////////////
37
38NetworkAdapter::NetworkAdapter()
39 : mParent(NULL)
40{
41}
42
43NetworkAdapter::~NetworkAdapter()
44{
45}
46
47HRESULT NetworkAdapter::FinalConstruct()
48{
49
50 return BaseFinalConstruct();
51}
52
53void NetworkAdapter::FinalRelease()
54{
55 uninit();
56 BaseFinalRelease();
57}
58
59// public initializer/uninitializer for internal purposes only
60////////////////////////////////////////////////////////////////////////////////
61
62/**
63 * Initializes the network adapter object.
64 *
65 * @param aParent Handle of the parent object.
66 */
67HRESULT NetworkAdapter::init(Machine *aParent, ULONG aSlot)
68{
69 LogFlowThisFunc(("aParent=%p, aSlot=%d\n", aParent, aSlot));
70
71 ComAssertRet(aParent, E_INVALIDARG);
72 uint32_t maxNetworkAdapters = Global::getMaxNetworkAdapters(aParent->getChipsetType());
73 ComAssertRet(aSlot < maxNetworkAdapters, E_INVALIDARG);
74
75 /* Enclose the state transition NotReady->InInit->Ready */
76 AutoInitSpan autoInitSpan(this);
77 AssertReturn(autoInitSpan.isOk(), E_FAIL);
78
79 unconst(mParent) = aParent;
80 unconst(mNATEngine).createObject();
81 mNATEngine->init(aParent, this);
82 /* mPeer is left null */
83
84 m_fModified = false;
85
86 mData.allocate();
87
88 /* initialize data */
89 mData->mSlot = aSlot;
90
91 /* default to Am79C973 */
92 mData->mAdapterType = NetworkAdapterType_Am79C973;
93
94 /* generate the MAC address early to guarantee it is the same both after
95 * changing some other property (i.e. after mData.backup()) and after the
96 * subsequent mData.rollback(). */
97 generateMACAddress();
98
99 /* Confirm a successful initialization */
100 autoInitSpan.setSucceeded();
101
102 return S_OK;
103}
104
105/**
106 * Initializes the network adapter object given another network adapter object
107 * (a kind of copy constructor). This object shares data with
108 * the object passed as an argument.
109 *
110 * @note This object must be destroyed before the original object
111 * it shares data with is destroyed.
112 *
113 * @note Locks @a aThat object for reading.
114 */
115HRESULT NetworkAdapter::init(Machine *aParent, NetworkAdapter *aThat)
116{
117 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
118
119 ComAssertRet(aParent && aThat, E_INVALIDARG);
120
121 /* Enclose the state transition NotReady->InInit->Ready */
122 AutoInitSpan autoInitSpan(this);
123 AssertReturn(autoInitSpan.isOk(), E_FAIL);
124
125 unconst(mParent) = aParent;
126 unconst(mPeer) = aThat;
127 unconst(mNATEngine).createObject();
128 mNATEngine->init(aParent, this, aThat->mNATEngine);
129
130 AutoCaller thatCaller(aThat);
131 AssertComRCReturnRC(thatCaller.rc());
132
133 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
134 mData.share(aThat->mData);
135
136 /* Confirm a successful initialization */
137 autoInitSpan.setSucceeded();
138
139 return S_OK;
140}
141
142/**
143 * Initializes the guest object given another guest object
144 * (a kind of copy constructor). This object makes a private copy of data
145 * of the original object passed as an argument.
146 *
147 * @note Locks @a aThat object for reading.
148 */
149HRESULT NetworkAdapter::initCopy(Machine *aParent, NetworkAdapter *aThat)
150{
151 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
152
153 ComAssertRet(aParent && aThat, E_INVALIDARG);
154
155 /* Enclose the state transition NotReady->InInit->Ready */
156 AutoInitSpan autoInitSpan(this);
157 AssertReturn(autoInitSpan.isOk(), E_FAIL);
158
159 unconst(mParent) = aParent;
160 /* mPeer is left null */
161
162 unconst(mNATEngine).createObject();
163 mNATEngine->initCopy(aParent, this, aThat->mNATEngine);
164
165 AutoCaller thatCaller(aThat);
166 AssertComRCReturnRC(thatCaller.rc());
167
168 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
169 mData.attachCopy(aThat->mData);
170
171 /* Confirm a successful initialization */
172 autoInitSpan.setSucceeded();
173
174 return S_OK;
175}
176
177/**
178 * Uninitializes the instance and sets the ready flag to FALSE.
179 * Called either from FinalRelease() or by the parent when it gets destroyed.
180 */
181void NetworkAdapter::uninit()
182{
183 LogFlowThisFunc(("\n"));
184
185 /* Enclose the state transition Ready->InUninit->NotReady */
186 AutoUninitSpan autoUninitSpan(this);
187 if (autoUninitSpan.uninitDone())
188 return;
189
190 mData.free();
191
192 unconst(mNATEngine).setNull();
193 unconst(mPeer) = NULL;
194 unconst(mParent) = NULL;
195}
196
197// INetworkAdapter properties
198////////////////////////////////////////////////////////////////////////////////
199
200STDMETHODIMP NetworkAdapter::COMGETTER(AdapterType)(NetworkAdapterType_T *aAdapterType)
201{
202 CheckComArgOutPointerValid(aAdapterType);
203
204 AutoCaller autoCaller(this);
205 if (FAILED(autoCaller.rc())) return autoCaller.rc();
206
207 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
208
209 *aAdapterType = mData->mAdapterType;
210
211 return S_OK;
212}
213
214STDMETHODIMP NetworkAdapter::COMSETTER(AdapterType)(NetworkAdapterType_T aAdapterType)
215{
216 AutoCaller autoCaller(this);
217 if (FAILED(autoCaller.rc())) return autoCaller.rc();
218
219 /* the machine needs to be mutable */
220 AutoMutableStateDependency adep(mParent);
221 if (FAILED(adep.rc())) return adep.rc();
222
223 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
224
225 /* make sure the value is allowed */
226 switch (aAdapterType)
227 {
228 case NetworkAdapterType_Am79C970A:
229 case NetworkAdapterType_Am79C973:
230#ifdef VBOX_WITH_E1000
231 case NetworkAdapterType_I82540EM:
232 case NetworkAdapterType_I82543GC:
233 case NetworkAdapterType_I82545EM:
234#endif
235#ifdef VBOX_WITH_VIRTIO
236 case NetworkAdapterType_Virtio:
237#endif /* VBOX_WITH_VIRTIO */
238 break;
239 default:
240 return setError(E_FAIL,
241 tr("Invalid network adapter type '%d'"),
242 aAdapterType);
243 }
244
245 if (mData->mAdapterType != aAdapterType)
246 {
247 mData.backup();
248 mData->mAdapterType = aAdapterType;
249
250 m_fModified = true;
251 // leave the lock before informing callbacks
252 alock.release();
253
254 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
255 mParent->setModified(Machine::IsModified_NetworkAdapters);
256 mlock.release();
257
258 /* Changing the network adapter type during runtime is not allowed,
259 * therefore no immediate change in CFGM logic => changeAdapter=FALSE. */
260 mParent->onNetworkAdapterChange(this, FALSE);
261 }
262
263 return S_OK;
264}
265
266STDMETHODIMP NetworkAdapter::COMGETTER(Slot)(ULONG *aSlot)
267{
268 CheckComArgOutPointerValid(aSlot);
269
270 AutoCaller autoCaller(this);
271 if (FAILED(autoCaller.rc())) return autoCaller.rc();
272
273 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
274
275 *aSlot = mData->mSlot;
276
277 return S_OK;
278}
279
280STDMETHODIMP NetworkAdapter::COMGETTER(Enabled)(BOOL *aEnabled)
281{
282 CheckComArgOutPointerValid(aEnabled);
283
284 AutoCaller autoCaller(this);
285 if (FAILED(autoCaller.rc())) return autoCaller.rc();
286
287 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
288
289 *aEnabled = mData->mEnabled;
290
291 return S_OK;
292}
293
294STDMETHODIMP NetworkAdapter::COMSETTER(Enabled)(BOOL aEnabled)
295{
296 AutoCaller autoCaller(this);
297 if (FAILED(autoCaller.rc())) return autoCaller.rc();
298
299 /* the machine needs to be mutable */
300 AutoMutableStateDependency adep(mParent);
301 if (FAILED(adep.rc())) return adep.rc();
302
303 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
304
305 if (mData->mEnabled != aEnabled)
306 {
307 mData.backup();
308 mData->mEnabled = aEnabled;
309
310 m_fModified = true;
311 // leave the lock before informing callbacks
312 alock.release();
313
314 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
315 mParent->setModified(Machine::IsModified_NetworkAdapters);
316 mlock.release();
317
318 /* Disabling the network adapter during runtime is not allowed
319 * therefore no immediate change in CFGM logic => changeAdapter=FALSE. */
320 mParent->onNetworkAdapterChange(this, FALSE);
321 }
322
323 return S_OK;
324}
325
326STDMETHODIMP NetworkAdapter::COMGETTER(MACAddress)(BSTR *aMACAddress)
327{
328 CheckComArgOutPointerValid(aMACAddress);
329
330 AutoCaller autoCaller(this);
331 if (FAILED(autoCaller.rc())) return autoCaller.rc();
332
333 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
334
335 ComAssertRet(!mData->mMACAddress.isEmpty(), E_FAIL);
336
337 mData->mMACAddress.cloneTo(aMACAddress);
338
339 return S_OK;
340}
341
342HRESULT NetworkAdapter::updateMacAddress(Utf8Str aMACAddress)
343{
344 HRESULT rc = S_OK;
345
346 /*
347 * Are we supposed to generate a MAC?
348 */
349 if (aMACAddress.isEmpty())
350 generateMACAddress();
351 else
352 {
353 if (mData->mMACAddress != aMACAddress)
354 {
355 /*
356 * Verify given MAC address
357 */
358 char *macAddressStr = aMACAddress.mutableRaw();
359 int i = 0;
360 while ((i < 13) && macAddressStr && *macAddressStr && (rc == S_OK))
361 {
362 char c = *macAddressStr;
363 /* canonicalize hex digits to capital letters */
364 if (c >= 'a' && c <= 'f')
365 {
366 /** @todo the runtime lacks an ascii lower/upper conv */
367 c &= 0xdf;
368 *macAddressStr = c;
369 }
370 /* we only accept capital letters */
371 if (((c < '0') || (c > '9')) &&
372 ((c < 'A') || (c > 'F')))
373 rc = setError(E_INVALIDARG, tr("Invalid MAC address format"));
374 /* the second digit must have even value for unicast addresses */
375 if ((i == 1) && (!!(c & 1) == (c >= '0' && c <= '9')))
376 rc = setError(E_INVALIDARG, tr("Invalid MAC address format"));
377
378 macAddressStr++;
379 i++;
380 }
381 /* we must have parsed exactly 12 characters */
382 if (i != 12)
383 rc = setError(E_INVALIDARG, tr("Invalid MAC address format"));
384
385 if (SUCCEEDED(rc))
386 mData->mMACAddress = aMACAddress;
387 }
388 }
389
390 return rc;
391}
392
393STDMETHODIMP NetworkAdapter::COMSETTER(MACAddress)(IN_BSTR aMACAddress)
394{
395 AutoCaller autoCaller(this);
396 if (FAILED(autoCaller.rc())) return autoCaller.rc();
397
398 /* the machine needs to be mutable */
399 AutoMutableStateDependency adep(mParent);
400 if (FAILED(adep.rc())) return adep.rc();
401
402
403 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
404 mData.backup();
405
406 HRESULT rc = updateMacAddress(aMACAddress);
407 if (SUCCEEDED(rc))
408 {
409 m_fModified = true;
410 // leave the lock before informing callbacks
411 alock.release();
412
413 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
414 mParent->setModified(Machine::IsModified_NetworkAdapters);
415 mlock.release();
416
417 /* Changing the MAC via the Main API during runtime is not allowed,
418 * therefore no immediate change in CFGM logic => changeAdapter=FALSE. */
419 mParent->onNetworkAdapterChange(this, FALSE);
420 }
421
422 return rc;
423}
424
425STDMETHODIMP NetworkAdapter::COMGETTER(AttachmentType)(
426 NetworkAttachmentType_T *aAttachmentType)
427{
428 CheckComArgOutPointerValid(aAttachmentType);
429
430 AutoCaller autoCaller(this);
431 if (FAILED(autoCaller.rc())) return autoCaller.rc();
432
433 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
434
435 *aAttachmentType = mData->mAttachmentType;
436
437 return S_OK;
438}
439
440STDMETHODIMP NetworkAdapter::COMSETTER(AttachmentType)(
441 NetworkAttachmentType_T aAttachmentType)
442{
443 AutoCaller autoCaller(this);
444 if (FAILED(autoCaller.rc())) return autoCaller.rc();
445
446 /* the machine needs to be mutable */
447 AutoMutableStateDependency adep(mParent);
448 if (FAILED(adep.rc())) return adep.rc();
449
450 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
451
452 if (mData->mAttachmentType != aAttachmentType)
453 {
454 mData.backup();
455
456 /* there must an internal network name */
457 if (mData->mInternalNetwork.isEmpty())
458 {
459 Log(("Internal network name not defined, setting to default \"intnet\"\n"));
460 mData->mInternalNetwork = "intnet";
461 }
462
463 mData->mAttachmentType = aAttachmentType;
464
465 m_fModified = true;
466 // leave the lock before informing callbacks
467 alock.release();
468
469 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
470 mParent->setModified(Machine::IsModified_NetworkAdapters);
471 mlock.release();
472
473 /* Adapt the CFGM logic and notify the guest => changeAdapter=TRUE. */
474 mParent->onNetworkAdapterChange(this, TRUE);
475 }
476
477 return S_OK;
478}
479
480STDMETHODIMP NetworkAdapter::COMGETTER(BridgedInterface)(BSTR *aBridgedInterface)
481{
482 CheckComArgOutPointerValid(aBridgedInterface);
483
484 AutoCaller autoCaller(this);
485 if (FAILED(autoCaller.rc())) return autoCaller.rc();
486
487 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
488
489 mData->mBridgedInterface.cloneTo(aBridgedInterface);
490
491 return S_OK;
492}
493
494STDMETHODIMP NetworkAdapter::COMSETTER(BridgedInterface)(IN_BSTR aBridgedInterface)
495{
496 Bstr bstrEmpty("");
497 if (!aBridgedInterface)
498 aBridgedInterface = bstrEmpty.raw();
499
500 AutoCaller autoCaller(this);
501 if (FAILED(autoCaller.rc())) return autoCaller.rc();
502
503 /* the machine needs to be mutable */
504 AutoMutableStateDependency adep(mParent);
505 if (FAILED(adep.rc())) return adep.rc();
506
507 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
508
509 if (mData->mBridgedInterface != aBridgedInterface)
510 {
511 mData.backup();
512 mData->mBridgedInterface = aBridgedInterface;
513
514 m_fModified = true;
515 // leave the lock before informing callbacks
516 alock.release();
517
518 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
519 mParent->setModified(Machine::IsModified_NetworkAdapters);
520 mlock.release();
521
522 /* When changing the host adapter, adapt the CFGM logic to make this
523 * change immediately effect and to notify the guest that the network
524 * might have changed, therefore changeAdapter=TRUE. */
525 mParent->onNetworkAdapterChange(this, TRUE);
526 }
527
528 return S_OK;
529}
530
531STDMETHODIMP NetworkAdapter::COMGETTER(HostOnlyInterface)(BSTR *aHostOnlyInterface)
532{
533 CheckComArgOutPointerValid(aHostOnlyInterface);
534
535 AutoCaller autoCaller(this);
536 if (FAILED(autoCaller.rc())) return autoCaller.rc();
537
538 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
539
540 mData->mHostOnlyInterface.cloneTo(aHostOnlyInterface);
541
542 return S_OK;
543}
544
545STDMETHODIMP NetworkAdapter::COMSETTER(HostOnlyInterface)(IN_BSTR aHostOnlyInterface)
546{
547 Bstr bstrEmpty("");
548 if (!aHostOnlyInterface)
549 aHostOnlyInterface = bstrEmpty.raw();
550
551 AutoCaller autoCaller(this);
552 if (FAILED(autoCaller.rc())) return autoCaller.rc();
553
554 /* the machine needs to be mutable */
555 AutoMutableStateDependency adep(mParent);
556 if (FAILED(adep.rc())) return adep.rc();
557
558 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
559
560 if (mData->mHostOnlyInterface != aHostOnlyInterface)
561 {
562 mData.backup();
563 mData->mHostOnlyInterface = aHostOnlyInterface;
564
565 m_fModified = true;
566 // leave the lock before informing callbacks
567 alock.release();
568
569 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
570 mParent->setModified(Machine::IsModified_NetworkAdapters);
571 mlock.release();
572
573 /* When changing the host adapter, adapt the CFGM logic to make this
574 * change immediately effect and to notify the guest that the network
575 * might have changed, therefore changeAdapter=TRUE. */
576 mParent->onNetworkAdapterChange(this, TRUE);
577 }
578
579 return S_OK;
580}
581
582STDMETHODIMP NetworkAdapter::COMGETTER(InternalNetwork)(BSTR *aInternalNetwork)
583{
584 CheckComArgOutPointerValid(aInternalNetwork);
585
586 AutoCaller autoCaller(this);
587 if (FAILED(autoCaller.rc())) return autoCaller.rc();
588
589 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
590
591 mData->mInternalNetwork.cloneTo(aInternalNetwork);
592
593 return S_OK;
594}
595
596STDMETHODIMP NetworkAdapter::COMSETTER(InternalNetwork)(IN_BSTR aInternalNetwork)
597{
598 AutoCaller autoCaller(this);
599 if (FAILED(autoCaller.rc())) return autoCaller.rc();
600
601 /* the machine needs to be mutable */
602 AutoMutableStateDependency adep(mParent);
603 if (FAILED(adep.rc())) return adep.rc();
604
605 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
606
607 if (mData->mInternalNetwork != aInternalNetwork)
608 {
609 /* if an empty/null string is to be set, internal networking must be
610 * turned off */
611 if ( (aInternalNetwork == NULL || *aInternalNetwork == '\0')
612 && mData->mAttachmentType == NetworkAttachmentType_Internal)
613 {
614 return setError(E_FAIL,
615 tr("Empty or null internal network name is not valid"));
616 }
617
618 mData.backup();
619 mData->mInternalNetwork = aInternalNetwork;
620
621 m_fModified = true;
622 // leave the lock before informing callbacks
623 alock.release();
624
625 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
626 mParent->setModified(Machine::IsModified_NetworkAdapters);
627 mlock.release();
628
629 /* When changing the internal network, adapt the CFGM logic to make this
630 * change immediately effect and to notify the guest that the network
631 * might have changed, therefore changeAdapter=TRUE. */
632 mParent->onNetworkAdapterChange(this, TRUE);
633 }
634
635 return S_OK;
636}
637
638STDMETHODIMP NetworkAdapter::COMGETTER(NATNetwork)(BSTR *aNATNetwork)
639{
640 CheckComArgOutPointerValid(aNATNetwork);
641
642 AutoCaller autoCaller(this);
643 if (FAILED(autoCaller.rc())) return autoCaller.rc();
644
645 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
646
647 mData->mNATNetwork.cloneTo(aNATNetwork);
648
649 return S_OK;
650}
651
652STDMETHODIMP NetworkAdapter::COMSETTER(NATNetwork)(IN_BSTR aNATNetwork)
653{
654 Bstr bstrEmpty("");
655 if (!aNATNetwork)
656 aNATNetwork = bstrEmpty.raw();
657
658 AutoCaller autoCaller(this);
659 if (FAILED(autoCaller.rc())) return autoCaller.rc();
660
661 /* the machine needs to be mutable */
662 AutoMutableStateDependency adep(mParent);
663 if (FAILED(adep.rc())) return adep.rc();
664
665 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
666
667 if (mData->mNATNetwork != aNATNetwork)
668 {
669 mData.backup();
670 mData->mNATNetwork = aNATNetwork;
671
672 m_fModified = true;
673 // leave the lock before informing callbacks
674 alock.release();
675
676 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
677 mParent->setModified(Machine::IsModified_NetworkAdapters);
678 mlock.release();
679
680 /* Changing the NAT network isn't allowed during runtime, therefore
681 * no immediate replug in CFGM logic => changeAdapter=FALSE */
682 mParent->onNetworkAdapterChange(this, FALSE);
683 }
684
685 return S_OK;
686}
687
688STDMETHODIMP NetworkAdapter::COMGETTER(GenericDriver)(BSTR *aGenericDriver)
689{
690 CheckComArgOutPointerValid(aGenericDriver);
691
692 AutoCaller autoCaller(this);
693 if (FAILED(autoCaller.rc())) return autoCaller.rc();
694
695 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
696
697 mData->mGenericDriver.cloneTo(aGenericDriver);
698
699 return S_OK;
700}
701
702STDMETHODIMP NetworkAdapter::COMSETTER(GenericDriver)(IN_BSTR aGenericDriver)
703{
704 Bstr bstrEmpty("");
705 if (!aGenericDriver)
706 aGenericDriver = bstrEmpty.raw();
707
708 AutoCaller autoCaller(this);
709 if (FAILED(autoCaller.rc())) return autoCaller.rc();
710
711 /* the machine needs to be mutable */
712 AutoMutableStateDependency adep(mParent);
713 if (FAILED(adep.rc())) return adep.rc();
714
715 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
716
717 if (mData->mGenericDriver != aGenericDriver)
718 {
719 mData.backup();
720 mData->mGenericDriver = aGenericDriver;
721
722 /* leave the lock before informing callbacks */
723 alock.release();
724
725 mParent->onNetworkAdapterChange(this, FALSE);
726 }
727
728 return S_OK;
729}
730
731STDMETHODIMP NetworkAdapter::COMGETTER(CableConnected)(BOOL *aConnected)
732{
733 CheckComArgOutPointerValid(aConnected);
734
735 AutoCaller autoCaller(this);
736 if (FAILED(autoCaller.rc())) return autoCaller.rc();
737
738 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
739
740 *aConnected = mData->mCableConnected;
741
742 return S_OK;
743}
744
745STDMETHODIMP NetworkAdapter::COMSETTER(CableConnected)(BOOL aConnected)
746{
747 AutoCaller autoCaller(this);
748 if (FAILED(autoCaller.rc())) return autoCaller.rc();
749
750 /* the machine needs to be mutable */
751 AutoMutableStateDependency adep(mParent);
752 if (FAILED(adep.rc())) return adep.rc();
753
754 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
755
756 if (aConnected != mData->mCableConnected)
757 {
758 mData.backup();
759 mData->mCableConnected = aConnected;
760
761 m_fModified = true;
762 // leave the lock before informing callbacks
763 alock.release();
764
765 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
766 mParent->setModified(Machine::IsModified_NetworkAdapters);
767 mlock.release();
768
769 /* No change in CFGM logic => changeAdapter=FALSE. */
770 mParent->onNetworkAdapterChange(this, FALSE);
771 }
772
773 return S_OK;
774}
775
776STDMETHODIMP NetworkAdapter::COMGETTER(LineSpeed)(ULONG *aSpeed)
777{
778 CheckComArgOutPointerValid(aSpeed);
779
780 AutoCaller autoCaller(this);
781 if (FAILED(autoCaller.rc())) return autoCaller.rc();
782
783 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
784
785 *aSpeed = mData->mLineSpeed;
786
787 return S_OK;
788}
789
790STDMETHODIMP NetworkAdapter::COMSETTER(LineSpeed)(ULONG aSpeed)
791{
792 AutoCaller autoCaller(this);
793 if (FAILED(autoCaller.rc())) return autoCaller.rc();
794
795 /* the machine needs to be mutable */
796 AutoMutableStateDependency adep(mParent);
797 if (FAILED(adep.rc())) return adep.rc();
798
799 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
800
801 if (aSpeed != mData->mLineSpeed)
802 {
803 mData.backup();
804 mData->mLineSpeed = aSpeed;
805
806 m_fModified = true;
807 // leave the lock before informing callbacks
808 alock.release();
809
810 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
811 mParent->setModified(Machine::IsModified_NetworkAdapters);
812 mlock.release();
813
814 /* No change in CFGM logic => changeAdapter=FALSE. */
815 mParent->onNetworkAdapterChange(this, FALSE);
816 }
817
818 return S_OK;
819}
820
821
822STDMETHODIMP NetworkAdapter::COMGETTER(PromiscModePolicy)(NetworkAdapterPromiscModePolicy_T *aPromiscModePolicy)
823{
824 CheckComArgOutPointerValid(aPromiscModePolicy);
825
826 AutoCaller autoCaller(this);
827 HRESULT hrc = autoCaller.rc();
828 if (SUCCEEDED(hrc))
829 {
830 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
831 *aPromiscModePolicy = mData->mPromiscModePolicy;
832 }
833 return hrc;
834}
835
836STDMETHODIMP NetworkAdapter::COMSETTER(PromiscModePolicy)(NetworkAdapterPromiscModePolicy_T aPromiscModePolicy)
837{
838 switch (aPromiscModePolicy)
839 {
840 case NetworkAdapterPromiscModePolicy_Deny:
841 case NetworkAdapterPromiscModePolicy_AllowNetwork:
842 case NetworkAdapterPromiscModePolicy_AllowAll:
843 break;
844 default:
845 return setError(E_INVALIDARG, tr("Invalid promiscuous mode policy (%d)"), aPromiscModePolicy);
846 }
847
848 AutoCaller autoCaller(this);
849 HRESULT hrc = autoCaller.rc();
850
851 if (SUCCEEDED(hrc))
852 {
853 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
854 if (aPromiscModePolicy != mData->mPromiscModePolicy)
855 {
856 mData.backup();
857 mData->mPromiscModePolicy = aPromiscModePolicy;
858 m_fModified = true;
859
860 alock.release();
861 mParent->setModifiedLock(Machine::IsModified_NetworkAdapters);
862 mParent->onNetworkAdapterChange(this, TRUE);
863 }
864 }
865
866 return hrc;
867}
868
869STDMETHODIMP NetworkAdapter::COMGETTER(TraceEnabled)(BOOL *aEnabled)
870{
871 CheckComArgOutPointerValid(aEnabled);
872
873 AutoCaller autoCaller(this);
874 if (FAILED(autoCaller.rc())) return autoCaller.rc();
875
876 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
877
878 *aEnabled = mData->mTraceEnabled;
879 return S_OK;
880}
881
882STDMETHODIMP NetworkAdapter::COMSETTER(TraceEnabled)(BOOL aEnabled)
883{
884 AutoCaller autoCaller(this);
885 if (FAILED(autoCaller.rc())) return autoCaller.rc();
886
887 /* the machine needs to be mutable */
888 AutoMutableStateDependency adep(mParent);
889 if (FAILED(adep.rc())) return adep.rc();
890
891 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
892
893 if (aEnabled != mData->mTraceEnabled)
894 {
895 mData.backup();
896 mData->mTraceEnabled = aEnabled;
897
898 m_fModified = true;
899 // leave the lock before informing callbacks
900 alock.release();
901
902 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
903 mParent->setModified(Machine::IsModified_NetworkAdapters);
904 mlock.release();
905
906 /* Adapt the CFGM logic changeAdapter=TRUE */
907 mParent->onNetworkAdapterChange(this, TRUE);
908 }
909
910 return S_OK;
911}
912
913STDMETHODIMP NetworkAdapter::COMGETTER(TraceFile)(BSTR *aTraceFile)
914{
915 CheckComArgOutPointerValid(aTraceFile);
916
917 AutoCaller autoCaller(this);
918 if (FAILED(autoCaller.rc())) return autoCaller.rc();
919
920 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
921
922 mData->mTraceFile.cloneTo(aTraceFile);
923
924 return S_OK;
925}
926
927STDMETHODIMP NetworkAdapter::COMSETTER(TraceFile)(IN_BSTR aTraceFile)
928{
929 AutoCaller autoCaller(this);
930 if (FAILED(autoCaller.rc())) return autoCaller.rc();
931
932 /* the machine needs to be mutable */
933 AutoMutableStateDependency adep(mParent);
934 if (FAILED(adep.rc())) return adep.rc();
935
936 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
937
938 if (mData->mTraceFile != aTraceFile)
939 {
940 mData.backup();
941 mData->mTraceFile = aTraceFile;
942
943 m_fModified = true;
944 // leave the lock before informing callbacks
945 alock.release();
946
947 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
948 mParent->setModified(Machine::IsModified_NetworkAdapters);
949 mlock.release();
950
951 /* No change in CFGM logic => changeAdapter=FALSE. */
952 mParent->onNetworkAdapterChange(this, FALSE);
953 }
954
955 return S_OK;
956}
957
958STDMETHODIMP NetworkAdapter::COMGETTER(NatDriver)(INATEngine **aNatDriver)
959{
960 CheckComArgOutPointerValid(aNatDriver);
961
962 AutoCaller autoCaller(this);
963 if (FAILED(autoCaller.rc())) return autoCaller.rc();
964
965 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
966
967 mNATEngine.queryInterfaceTo(aNatDriver);
968
969 return S_OK;
970}
971
972STDMETHODIMP NetworkAdapter::COMGETTER(BootPriority)(ULONG *aBootPriority)
973{
974 CheckComArgOutPointerValid(aBootPriority);
975
976 AutoCaller autoCaller(this);
977 if (FAILED(autoCaller.rc())) return autoCaller.rc();
978
979 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
980
981 *aBootPriority = mData->mBootPriority;
982
983 return S_OK;
984}
985
986STDMETHODIMP NetworkAdapter::COMSETTER(BootPriority)(ULONG aBootPriority)
987{
988 AutoCaller autoCaller(this);
989 if (FAILED(autoCaller.rc())) return autoCaller.rc();
990
991 /* the machine needs to be mutable */
992 AutoMutableStateDependency adep(mParent);
993 if (FAILED(adep.rc())) return adep.rc();
994
995 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
996
997 if (aBootPriority != mData->mBootPriority)
998 {
999 mData.backup();
1000 mData->mBootPriority = aBootPriority;
1001
1002 m_fModified = true;
1003 // leave the lock before informing callbacks
1004 alock.release();
1005
1006 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, no need to lock
1007 mParent->setModified(Machine::IsModified_NetworkAdapters);
1008 mlock.release();
1009
1010 /* No change in CFGM logic => changeAdapter=FALSE. */
1011 mParent->onNetworkAdapterChange(this, FALSE);
1012 }
1013
1014 return S_OK;
1015}
1016
1017// INetworkAdapter methods
1018////////////////////////////////////////////////////////////////////////////////
1019
1020STDMETHODIMP NetworkAdapter::GetProperty(IN_BSTR aKey, BSTR *aValue)
1021{
1022 CheckComArgOutPointerValid(aValue);
1023
1024 AutoCaller autoCaller(this);
1025 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1026
1027 Bstr key = aKey;
1028 Bstr value;
1029
1030 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1031
1032 Utf8Str strKey(key);
1033 settings::StringsMap::const_iterator it = mData->mGenericProperties.find(strKey);
1034 if (it != mData->mGenericProperties.end())
1035 {
1036 value = it->second; // source is a Utf8Str
1037 value.cloneTo(aValue);
1038 }
1039
1040 return S_OK;
1041}
1042
1043STDMETHODIMP NetworkAdapter::SetProperty(IN_BSTR aKey, IN_BSTR aValue)
1044{
1045 LogFlowThisFunc(("\n"));
1046
1047 AutoCaller autoCaller(this);
1048 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1049
1050 /* The machine needs to be mutable. */
1051 AutoMutableStateDependency adep(mParent);
1052 if (FAILED(adep.rc())) return adep.rc();
1053
1054 Bstr key = aKey;
1055
1056 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1057
1058 bool fGenericChange = (mData->mAttachmentType == NetworkAttachmentType_Generic);
1059
1060 /* Generic properties processing.
1061 * Look up the old value first; if nothing's changed then do nothing.
1062 */
1063 Utf8Str strValue(aValue);
1064 Utf8Str strKey(aKey);
1065 Utf8Str strOldValue;
1066
1067 settings::StringsMap::const_iterator it = mData->mGenericProperties.find(strKey);
1068 if (it != mData->mGenericProperties.end())
1069 strOldValue = it->second;
1070
1071 if (strOldValue != strValue)
1072 {
1073 if (strValue.isEmpty())
1074 mData->mGenericProperties.erase(strKey);
1075 else
1076 mData->mGenericProperties[strKey] = strValue;
1077
1078 /* leave the lock before informing callbacks */
1079 alock.release();
1080
1081 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
1082 mParent->setModified(Machine::IsModified_NetworkAdapters);
1083 mlock.release();
1084
1085 /* Avoid deadlock when the event triggers a call to a method of this
1086 * interface. */
1087 adep.release();
1088
1089 mParent->onNetworkAdapterChange(this, fGenericChange);
1090 }
1091
1092 return S_OK;
1093}
1094
1095STDMETHODIMP NetworkAdapter::GetProperties(IN_BSTR aNames,
1096 ComSafeArrayOut(BSTR, aReturnNames),
1097 ComSafeArrayOut(BSTR, aReturnValues))
1098{
1099 CheckComArgOutSafeArrayPointerValid(aReturnNames);
1100 CheckComArgOutSafeArrayPointerValid(aReturnValues);
1101
1102 AutoCaller autoCaller(this);
1103 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1104
1105 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1106
1107 /// @todo make use of aNames according to the documentation
1108 NOREF(aNames);
1109
1110 com::SafeArray<BSTR> names(mData->mGenericProperties.size());
1111 com::SafeArray<BSTR> values(mData->mGenericProperties.size());
1112 size_t i = 0;
1113
1114 for (settings::StringsMap::const_iterator it = mData->mGenericProperties.begin();
1115 it != mData->mGenericProperties.end();
1116 ++it)
1117 {
1118 it->first.cloneTo(&names[i]);
1119 it->second.cloneTo(&values[i]);
1120 ++i;
1121 }
1122
1123 names.detachTo(ComSafeArrayOutArg(aReturnNames));
1124 values.detachTo(ComSafeArrayOutArg(aReturnValues));
1125
1126 return S_OK;
1127}
1128
1129
1130
1131// public methods only for internal purposes
1132////////////////////////////////////////////////////////////////////////////////
1133
1134/**
1135 * Loads settings from the given adapter node.
1136 * May be called once right after this object creation.
1137 *
1138 * @param aAdapterNode <Adapter> node.
1139 *
1140 * @note Locks this object for writing.
1141 */
1142HRESULT NetworkAdapter::loadSettings(BandwidthControl *bwctl,
1143 const settings::NetworkAdapter &data)
1144{
1145 AutoCaller autoCaller(this);
1146 AssertComRCReturnRC(autoCaller.rc());
1147
1148 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1149
1150 /* Note: we assume that the default values for attributes of optional
1151 * nodes are assigned in the Data::Data() constructor and don't do it
1152 * here. It implies that this method may only be called after constructing
1153 * a new BIOSSettings object while all its data fields are in the default
1154 * values. Exceptions are fields whose creation time defaults don't match
1155 * values that should be applied when these fields are not explicitly set
1156 * in the settings file (for backwards compatibility reasons). This takes
1157 * place when a setting of a newly created object must default to A while
1158 * the same setting of an object loaded from the old settings file must
1159 * default to B. */
1160
1161 HRESULT rc = S_OK;
1162
1163 mData->mAdapterType = data.type;
1164 mData->mEnabled = data.fEnabled;
1165 /* MAC address (can be null) */
1166 rc = updateMacAddress(data.strMACAddress);
1167 if (FAILED(rc)) return rc;
1168 /* cable (required) */
1169 mData->mCableConnected = data.fCableConnected;
1170 /* line speed (defaults to 100 Mbps) */
1171 mData->mLineSpeed = data.ulLineSpeed;
1172 mData->mPromiscModePolicy = data.enmPromiscModePolicy;
1173 /* tracing (defaults to false) */
1174 mData->mTraceEnabled = data.fTraceEnabled;
1175 mData->mTraceFile = data.strTraceFile;
1176 /* boot priority (defaults to 0, i.e. lowest) */
1177 mData->mBootPriority = data.ulBootPriority;
1178 /* bandwidth group */
1179 if (data.strBandwidthGroup.isEmpty())
1180 updateBandwidthGroup(NULL);
1181 else
1182 {
1183 ComObjPtr<BandwidthGroup> group;
1184 rc = bwctl->getBandwidthGroupByName(data.strBandwidthGroup, group, true);
1185 if (FAILED(rc)) return rc;
1186 }
1187
1188 mNATEngine->loadSettings(data.nat);
1189 mData->mBridgedInterface = data.strBridgedName;
1190 mData->mInternalNetwork = data.strInternalNetworkName;
1191 mData->mHostOnlyInterface = data.strHostOnlyName;
1192 mData->mGenericDriver = data.strGenericDriver;
1193 mData->mGenericProperties = data.genericProperties;
1194
1195 // leave the lock before setting attachment type
1196 alock.release();
1197
1198 rc = COMSETTER(AttachmentType)(data.mode);
1199 if (FAILED(rc)) return rc;
1200
1201 // after loading settings, we are no longer different from the XML on disk
1202 m_fModified = false;
1203
1204 return S_OK;
1205}
1206
1207/**
1208 * Saves settings to the given adapter node.
1209 *
1210 * Note that the given Adapter node is completely empty on input.
1211 *
1212 * @param aAdapterNode <Adapter> node.
1213 *
1214 * @note Locks this object for reading.
1215 */
1216HRESULT NetworkAdapter::saveSettings(settings::NetworkAdapter &data)
1217{
1218 AutoCaller autoCaller(this);
1219 AssertComRCReturnRC(autoCaller.rc());
1220
1221 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1222
1223 data.fEnabled = !!mData->mEnabled;
1224 data.strMACAddress = mData->mMACAddress;
1225 data.fCableConnected = !!mData->mCableConnected;
1226
1227 data.enmPromiscModePolicy = mData->mPromiscModePolicy;
1228 data.ulLineSpeed = mData->mLineSpeed;
1229
1230 data.fTraceEnabled = !!mData->mTraceEnabled;
1231
1232 data.strTraceFile = mData->mTraceFile;
1233
1234 data.ulBootPriority = mData->mBootPriority;
1235
1236 if (mData->mBandwidthGroup.isNull())
1237 data.strBandwidthGroup = "";
1238 else
1239 data.strBandwidthGroup = mData->mBandwidthGroup->getName();
1240
1241 data.type = mData->mAdapterType;
1242
1243 data.mode = mData->mAttachmentType;
1244
1245 mNATEngine->commit();
1246 mNATEngine->saveSettings(data.nat);
1247
1248 data.strBridgedName = mData->mBridgedInterface;
1249
1250 data.strHostOnlyName = mData->mHostOnlyInterface;
1251
1252 data.strInternalNetworkName = mData->mInternalNetwork;
1253
1254 data.strGenericDriver = mData->mGenericDriver;
1255 data.genericProperties = mData->mGenericProperties;
1256
1257 // after saving settings, we are no longer different from the XML on disk
1258 m_fModified = false;
1259
1260 return S_OK;
1261}
1262
1263/**
1264 * Returns true if any setter method has modified settings of this instance.
1265 * @return
1266 */
1267bool NetworkAdapter::isModified() {
1268 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1269 bool fChanged = m_fModified;
1270 fChanged |= (mData->mAdapterType == NetworkAttachmentType_NAT? mNATEngine->isModified() : false);
1271 return fChanged;
1272}
1273
1274/**
1275 * @note Locks this object for writing.
1276 */
1277void NetworkAdapter::rollback()
1278{
1279 /* sanity */
1280 AutoCaller autoCaller(this);
1281 AssertComRCReturnVoid(autoCaller.rc());
1282
1283 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1284
1285 mData.rollback();
1286}
1287
1288/**
1289 * @note Locks this object for writing, together with the peer object (also
1290 * for writing) if there is one.
1291 */
1292void NetworkAdapter::commit()
1293{
1294 /* sanity */
1295 AutoCaller autoCaller(this);
1296 AssertComRCReturnVoid(autoCaller.rc());
1297
1298 /* sanity too */
1299 AutoCaller peerCaller(mPeer);
1300 AssertComRCReturnVoid(peerCaller.rc());
1301
1302 /* lock both for writing since we modify both (mPeer is "master" so locked
1303 * first) */
1304 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
1305
1306 if (mData.isBackedUp())
1307 {
1308 mData.commit();
1309 if (mPeer)
1310 {
1311 /* attach new data to the peer and reshare it */
1312 mPeer->mData.attach(mData);
1313 }
1314 }
1315}
1316
1317/**
1318 * @note Locks this object for writing, together with the peer object
1319 * represented by @a aThat (locked for reading).
1320 */
1321void NetworkAdapter::copyFrom(NetworkAdapter *aThat)
1322{
1323 AssertReturnVoid(aThat != NULL);
1324
1325 /* sanity */
1326 AutoCaller autoCaller(this);
1327 AssertComRCReturnVoid(autoCaller.rc());
1328
1329 /* sanity too */
1330 AutoCaller thatCaller(aThat);
1331 AssertComRCReturnVoid(thatCaller.rc());
1332
1333 /* peer is not modified, lock it for reading (aThat is "master" so locked
1334 * first) */
1335 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
1336 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
1337
1338 /* this will back up current data */
1339 mData.assignCopy(aThat->mData);
1340}
1341
1342void NetworkAdapter::applyDefaults(GuestOSType *aOsType)
1343{
1344 AssertReturnVoid(aOsType != NULL);
1345
1346 /* sanity */
1347 AutoCaller autoCaller(this);
1348 AssertComRCReturnVoid(autoCaller.rc());
1349
1350 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1351
1352 bool e1000enabled = false;
1353#ifdef VBOX_WITH_E1000
1354 e1000enabled = true;
1355#endif // VBOX_WITH_E1000
1356
1357 NetworkAdapterType_T defaultType = aOsType->networkAdapterType();
1358
1359 /* Set default network adapter for this OS type */
1360 if (defaultType == NetworkAdapterType_I82540EM ||
1361 defaultType == NetworkAdapterType_I82543GC ||
1362 defaultType == NetworkAdapterType_I82545EM)
1363 {
1364 if (e1000enabled) mData->mAdapterType = defaultType;
1365 }
1366 else mData->mAdapterType = defaultType;
1367
1368 /* Enable and connect the first one adapter to the NAT */
1369 if (mData->mSlot == 0)
1370 {
1371 mData->mEnabled = true;
1372 mData->mAttachmentType = NetworkAttachmentType_NAT;
1373 mData->mCableConnected = true;
1374 }
1375}
1376
1377// private methods
1378////////////////////////////////////////////////////////////////////////////////
1379
1380/**
1381 * Generates a new unique MAC address based on our vendor ID and
1382 * parts of a GUID.
1383 *
1384 * @note Must be called from under the object's write lock or within the init
1385 * span.
1386 */
1387void NetworkAdapter::generateMACAddress()
1388{
1389 Utf8Str mac;
1390 Host::generateMACAddress(mac);
1391 LogFlowThisFunc(("generated MAC: '%s'\n", mac.c_str()));
1392 mData->mMACAddress = mac;
1393}
1394
1395STDMETHODIMP NetworkAdapter::COMGETTER(BandwidthGroup)(IBandwidthGroup **aBwGroup)
1396{
1397 LogFlowThisFuncEnter();
1398 CheckComArgOutPointerValid(aBwGroup);
1399
1400 AutoCaller autoCaller(this);
1401 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1402
1403 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1404
1405 mData->mBandwidthGroup.queryInterfaceTo(aBwGroup);
1406
1407 LogFlowThisFuncLeave();
1408 return S_OK;
1409}
1410
1411STDMETHODIMP NetworkAdapter::COMSETTER(BandwidthGroup)(IBandwidthGroup *aBwGroup)
1412{
1413 LogFlowThisFuncEnter();
1414
1415 AutoCaller autoCaller(this);
1416 if (FAILED(autoCaller.rc())) return autoCaller.rc();
1417
1418 /* the machine needs to be mutable */
1419 AutoMutableStateDependency adep(mParent);
1420 if (FAILED(adep.rc())) return adep.rc();
1421
1422 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1423
1424 if (mData->mBandwidthGroup != aBwGroup)
1425 {
1426 mData.backup();
1427
1428 updateBandwidthGroup(static_cast<BandwidthGroup*>(aBwGroup));
1429
1430 m_fModified = true;
1431 // leave the lock before informing callbacks
1432 alock.release();
1433
1434 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
1435 mParent->setModified(Machine::IsModified_NetworkAdapters);
1436 mlock.release();
1437
1438 /* TODO: changeAdapter=???. */
1439 mParent->onNetworkAdapterChange(this, FALSE);
1440 }
1441
1442 LogFlowThisFuncLeave();
1443 return S_OK;
1444}
1445
1446void NetworkAdapter::updateBandwidthGroup(BandwidthGroup *aBwGroup)
1447{
1448 LogFlowThisFuncEnter();
1449 Assert(isWriteLockOnCurrentThread());
1450
1451 mData.backup();
1452 if (!mData->mBandwidthGroup.isNull())
1453 {
1454 mData->mBandwidthGroup->release();
1455 mData->mBandwidthGroup.setNull();
1456 }
1457
1458 if (aBwGroup)
1459 {
1460 mData->mBandwidthGroup = aBwGroup;
1461 mData->mBandwidthGroup->reference();
1462 }
1463
1464 LogFlowThisFuncLeave();
1465}
1466/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

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