VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/DrvNetShaper.cpp@ 45761

Last change on this file since 45761 was 45061, checked in by vboxsync, 12 years ago

Review of PDM driver destructors making sure that variables they use are correctly initialized in the constructor. Found several RTFileClose(0) cases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.2 KB
Line 
1/* $Id: DrvNetShaper.cpp 45061 2013-03-18 14:09:03Z vboxsync $ */
2/** @file
3 * NetShaperFilter - Network shaper filter driver.
4 */
5
6/*
7 * Copyright (C) 2011-2013 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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_NET_SHAPER
23
24#include <VBox/vmm/pdmdrv.h>
25#include <VBox/vmm/pdmnetifs.h>
26#include <VBox/vmm/pdmnetshaper.h>
27
28#include <VBox/log.h>
29#include <iprt/assert.h>
30#include <iprt/critsect.h>
31#include <iprt/string.h>
32#include <iprt/uuid.h>
33
34#include "VBoxDD.h"
35
36/*******************************************************************************
37* Structures and Typedefs *
38*******************************************************************************/
39/**
40 * Block driver instance data.
41 *
42 * @implements PDMINETWORKUP
43 * @implements PDMINETWORKDOWN
44 * @implements PDMINETWORKCONFIG
45 */
46typedef struct DRVNETSHAPER
47{
48 /** Pointer to the driver instance. */
49 PPDMDRVINS pDrvInsR3;
50 /** The network interface. */
51 PDMINETWORKUP INetworkUpR3;
52 /** The connector that's attached to us. */
53 PPDMINETWORKUP pIBelowNetR3;
54
55 /** Pointer to the driver instance. */
56 PPDMDRVINSR0 pDrvInsR0;
57 /** The network interface. */
58 PDMINETWORKUPR0 INetworkUpR0;
59 /** The connector that's attached to us. */
60 PPDMINETWORKUPR0 pIBelowNetR0;
61
62 /** Ring-3 base interface for the ring-0 context. */
63 PDMIBASER0 IBaseR0;
64 /** Ring-3 base interface for the raw-mode context. */
65 PDMIBASERC IBaseRC;
66
67 /** For when we're the leaf driver. */
68 PDMCRITSECT XmitLock;
69
70 /** The network interface. */
71 PDMINETWORKDOWN INetworkDown;
72 /** The network config interface.
73 * @todo this is a main interface and shouldn't be here... */
74 PDMINETWORKCONFIG INetworkConfig;
75 /** The port we're attached to. */
76 PPDMINETWORKDOWN pIAboveNet;
77 /** The config port interface we're attached to. */
78 PPDMINETWORKCONFIG pIAboveConfig;
79 /** The filter that represents us at bandwidth group. */
80 PDMNSFILTER Filter;
81 /** The name of bandwidth group we are attached to. */
82 char * pszBwGroup;
83
84 /** TX: Total number of bytes to allocate. */
85 STAMCOUNTER StatXmitBytesRequested;
86 /** TX: Number of bytes delayed. */
87 STAMCOUNTER StatXmitBytesDenied;
88 /** TX: Number of bytes allowed to pass. */
89 STAMCOUNTER StatXmitBytesGranted;
90 /** TX: Total number of packets being sent. */
91 STAMCOUNTER StatXmitPktsRequested;
92 /** TX: Number of packets delayed. */
93 STAMCOUNTER StatXmitPktsDenied;
94 /** TX: Number of packets allowed to pass. */
95 STAMCOUNTER StatXmitPktsGranted;
96 /** TX: Number of calls to pfnXmitPending. */
97 STAMCOUNTER StatXmitPendingCalled;
98} DRVNETSHAPER, *PDRVNETSHAPER;
99
100
101/**
102 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
103 */
104PDMBOTHCBDECL(int) drvNetShaperUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
105{
106 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
107 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
108 {
109 int rc = PDMCritSectTryEnter(&pThis->XmitLock);
110 if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
111 rc = VERR_TRY_AGAIN;
112 return rc;
113 }
114 return pThis->CTX_SUFF(pIBelowNet)->pfnBeginXmit(pThis->CTX_SUFF(pIBelowNet), fOnWorkerThread);
115}
116
117
118/**
119 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
120 */
121PDMBOTHCBDECL(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
122 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
123{
124 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
125 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
126 return VERR_NET_DOWN;
127 //LogFlow(("drvNetShaperUp_AllocBuf: cb=%d\n", cbMin));
128 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesRequested, cbMin);
129 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsRequested);
130#if defined(IN_RING3) || defined(IN_RING0)
131 if (!PDMNsAllocateBandwidth(&pThis->Filter, cbMin))
132 {
133 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin);
134 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied);
135 return VERR_TRY_AGAIN;
136 }
137#endif
138 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin);
139 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted);
140 //LogFlow(("drvNetShaperUp_AllocBuf: got cb=%d\n", cbMin));
141 return pThis->CTX_SUFF(pIBelowNet)->pfnAllocBuf(pThis->CTX_SUFF(pIBelowNet), cbMin, pGso, ppSgBuf);
142}
143
144
145/**
146 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
147 */
148PDMBOTHCBDECL(int) drvNetShaperUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
149{
150 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
151 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
152 return VERR_NET_DOWN;
153 return pThis->CTX_SUFF(pIBelowNet)->pfnFreeBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf);
154}
155
156
157/**
158 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
159 */
160PDMBOTHCBDECL(int) drvNetShaperUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
161{
162 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
163 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
164 return VERR_NET_DOWN;
165
166 return pThis->CTX_SUFF(pIBelowNet)->pfnSendBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf, fOnWorkerThread);
167}
168
169
170/**
171 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
172 */
173PDMBOTHCBDECL(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface)
174{
175 //LogFlow(("drvNetShaperUp_EndXmit:\n"));
176 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
177 if (RT_LIKELY(pThis->CTX_SUFF(pIBelowNet)))
178 pThis->CTX_SUFF(pIBelowNet)->pfnEndXmit(pThis->CTX_SUFF(pIBelowNet));
179 else
180 PDMCritSectLeave(&pThis->XmitLock);
181}
182
183
184/**
185 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
186 */
187PDMBOTHCBDECL(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
188{
189 LogFlow(("drvNetShaperUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
190 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
191 if (pThis->CTX_SUFF(pIBelowNet))
192 pThis->CTX_SUFF(pIBelowNet)->pfnSetPromiscuousMode(pThis->CTX_SUFF(pIBelowNet), fPromiscuous);
193}
194
195
196#ifdef IN_RING3
197/**
198 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
199 */
200static DECLCALLBACK(void) drvR3NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
201{
202 LogFlow(("drvNetShaperUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
203 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
204 if (pThis->pIBelowNetR3)
205 pThis->pIBelowNetR3->pfnNotifyLinkChanged(pThis->pIBelowNetR3, enmLinkState);
206}
207
208/**
209 * @interface_method_impl{PDMINETWORKDOWN,pfnWaitReceiveAvail}
210 */
211static DECLCALLBACK(int) drvR3NetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
212{
213 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
214 return pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, cMillies);
215}
216
217
218/**
219 * @interface_method_impl{PDMINETWORKDOWN,pfnReceive}
220 */
221static DECLCALLBACK(int) drvR3NetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
222{
223 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
224 return pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, pvBuf, cb);
225}
226
227
228/**
229 * @interface_method_impl{PDMINETWORKDOWN,pfnReceiveGso}
230 */
231static DECLCALLBACK(int) drvR3NetShaperDown_ReceiveGso(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb, PCPDMNETWORKGSO pGso)
232{
233 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
234 if (pThis->pIAboveNet->pfnReceiveGso)
235 return pThis->pIAboveNet->pfnReceiveGso(pThis->pIAboveNet, pvBuf, cb, pGso);
236 return VERR_NOT_SUPPORTED;
237}
238
239
240/**
241 * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending}
242 */
243static DECLCALLBACK(void) drvR3NetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface)
244{
245 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
246 STAM_REL_COUNTER_INC(&pThis->StatXmitPendingCalled);
247 pThis->pIAboveNet->pfnXmitPending(pThis->pIAboveNet);
248}
249
250
251/**
252 * Gets the current Media Access Control (MAC) address.
253 *
254 * @returns VBox status code.
255 * @param pInterface Pointer to the interface structure containing the called function pointer.
256 * @param pMac Where to store the MAC address.
257 * @thread EMT
258 */
259static DECLCALLBACK(int) drvR3NetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
260{
261 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
262 return pThis->pIAboveConfig->pfnGetMac(pThis->pIAboveConfig, pMac);
263}
264
265/**
266 * Gets the new link state.
267 *
268 * @returns The current link state.
269 * @param pInterface Pointer to the interface structure containing the called function pointer.
270 * @thread EMT
271 */
272static DECLCALLBACK(PDMNETWORKLINKSTATE) drvR3NetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)
273{
274 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
275 return pThis->pIAboveConfig->pfnGetLinkState(pThis->pIAboveConfig);
276}
277
278/**
279 * Sets the new link state.
280 *
281 * @returns VBox status code.
282 * @param pInterface Pointer to the interface structure containing the called function pointer.
283 * @param enmState The new link state
284 * @thread EMT
285 */
286static DECLCALLBACK(int) drvR3NetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
287{
288 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
289 return pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig, enmState);
290}
291
292
293/**
294 * @interface_method_impl{PDMIBASER0,pfnQueryInterface}
295 */
296static DECLCALLBACK(RTR0PTR) drvR3NetShaperIBaseR0_QueryInterface(PPDMIBASER0 pInterface, const char *pszIID)
297{
298 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, IBaseR0);
299 PDMIBASER0_RETURN_INTERFACE(pThis->pDrvInsR3, pszIID, PDMINETWORKUP, &pThis->INetworkUpR0);
300 return NIL_RTR0PTR;
301}
302
303/**
304 * @interface_method_impl{PDMIBASERC,pfnQueryInterface}
305 */
306static DECLCALLBACK(RTRCPTR) drvR3NetShaperIBaseRC_QueryInterface(PPDMIBASERC pInterface, const char *pszIID)
307{
308 return NIL_RTRCPTR;
309}
310
311/**
312 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
313 */
314static DECLCALLBACK(void *) drvR3NetShaperIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
315{
316 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
317 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
318 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
319 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASER0, &pThis->IBaseR0);
320 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASERC, &pThis->IBaseRC);
321 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUpR3);
322 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown);
323 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
324 return NULL;
325}
326
327
328/**
329 * @interface_method_impl{PDMDRVREG,pfnDetach}
330 */
331static DECLCALLBACK(void) drvR3NetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
332{
333 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
334
335 LogFlow(("drvNetShaperDetach: pDrvIns: %p, fFlags: %u\n", pDrvIns, fFlags));
336 PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
337 pThis->pIBelowNetR3 = NULL;
338 pThis->pIBelowNetR0 = NIL_RTR0PTR;
339 PDMCritSectLeave(&pThis->XmitLock);
340}
341
342
343/**
344 * @interface_method_impl{PDMDRVREG,pfnAttach}
345 */
346static DECLCALLBACK(int) drvR3NetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
347{
348 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
349 LogFlow(("drvNetShaperAttach/#%#x: fFlags=%#x\n", pDrvIns->iInstance, fFlags));
350 PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
351
352 /*
353 * Query the network connector interface.
354 */
355 PPDMIBASE pBaseDown;
356 int rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
357 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
358 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
359 {
360 pThis->pIBelowNetR3 = NULL;
361 pThis->pIBelowNetR0 = NIL_RTR0PTR;
362 rc = VINF_SUCCESS;
363 }
364 else if (RT_SUCCESS(rc))
365 {
366 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
367 if (pThis->pIBelowNetR3)
368 {
369 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
370 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
371 rc = VINF_SUCCESS;
372 }
373 else
374 {
375 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
376 rc = VERR_PDM_MISSING_INTERFACE_BELOW;
377 }
378 }
379 else
380 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
381
382 PDMCritSectLeave(&pThis->XmitLock);
383 return VINF_SUCCESS;
384}
385
386
387/**
388 * @interface_method_impl{PDMDRVREG,pfnDestruct}
389 */
390static DECLCALLBACK(void) drvR3NetShaperDestruct(PPDMDRVINS pDrvIns)
391{
392 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
393 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
394
395 PDMDrvHlpNetShaperDetach(pDrvIns, &pThis->Filter);
396
397 if (PDMCritSectIsInitialized(&pThis->XmitLock))
398 PDMR3CritSectDelete(&pThis->XmitLock);
399}
400
401
402/**
403 * @interface_method_impl{Construct a NAT network transport driver instance,
404 * PDMDRVREG,pfnDestruct}
405 */
406static DECLCALLBACK(int) drvR3NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
407{
408 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
409 LogFlow(("drvNetShaperConstruct:\n"));
410 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
411
412 /*
413 * Init the static parts.
414 */
415 pThis->pDrvInsR3 = pDrvIns;
416 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns);
417 /* IBase */
418 pDrvIns->IBase.pfnQueryInterface = drvR3NetShaperIBase_QueryInterface;
419 pThis->IBaseR0.pfnQueryInterface = drvR3NetShaperIBaseR0_QueryInterface;
420 pThis->IBaseRC.pfnQueryInterface = drvR3NetShaperIBaseRC_QueryInterface;
421 /* INetworkUp */
422 pThis->INetworkUpR3.pfnBeginXmit = drvNetShaperUp_BeginXmit;
423 pThis->INetworkUpR3.pfnAllocBuf = drvNetShaperUp_AllocBuf;
424 pThis->INetworkUpR3.pfnFreeBuf = drvNetShaperUp_FreeBuf;
425 pThis->INetworkUpR3.pfnSendBuf = drvNetShaperUp_SendBuf;
426 pThis->INetworkUpR3.pfnEndXmit = drvNetShaperUp_EndXmit;
427 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvNetShaperUp_SetPromiscuousMode;
428 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3NetShaperUp_NotifyLinkChanged;
429 /* Resolve the ring-0 context interface addresses. */
430 int rc = pDrvIns->pHlpR3->pfnLdrGetR0InterfaceSymbols(pDrvIns, &pThis->INetworkUpR0,
431 sizeof(pThis->INetworkUpR0),
432 "drvNetShaperUp_", PDMINETWORKUP_SYM_LIST);
433 AssertLogRelRCReturn(rc, rc);
434 /* INetworkDown */
435 pThis->INetworkDown.pfnWaitReceiveAvail = drvR3NetShaperDown_WaitReceiveAvail;
436 pThis->INetworkDown.pfnReceive = drvR3NetShaperDown_Receive;
437 pThis->INetworkDown.pfnReceiveGso = drvR3NetShaperDown_ReceiveGso;
438 pThis->INetworkDown.pfnXmitPending = drvR3NetShaperDown_XmitPending;
439 /* INetworkConfig */
440 pThis->INetworkConfig.pfnGetMac = drvR3NetShaperDownCfg_GetMac;
441 pThis->INetworkConfig.pfnGetLinkState = drvR3NetShaperDownCfg_GetLinkState;
442 pThis->INetworkConfig.pfnSetLinkState = drvR3NetShaperDownCfg_SetLinkState;
443
444 /*
445 * Create the locks.
446 */
447 rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper");
448 AssertRCReturn(rc, rc);
449
450 /*
451 * Validate the config.
452 */
453 if (!CFGMR3AreValuesValid(pCfg, "BwGroup\0"))
454 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
455
456 /*
457 * Find the bandwidth group we have to attach to.
458 */
459 rc = CFGMR3QueryStringAlloc(pCfg, "BwGroup", &pThis->pszBwGroup);
460 if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
461 {
462 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
463 N_("DrvNetShaper: Configuration error: Querying \"BwGroup\" as string failed"));
464 return rc;
465 }
466 else
467 rc = VINF_SUCCESS;
468
469 pThis->Filter.pIDrvNetR3 = &pThis->INetworkDown;
470 rc = PDMDrvHlpNetShaperAttach(pDrvIns, pThis->pszBwGroup, &pThis->Filter);
471 if (RT_FAILURE(rc))
472 {
473 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
474 N_("DrvNetShaper: Configuration error: Failed to attach to bandwidth group"));
475 return rc;
476 }
477
478 /*
479 * Query the network port interface.
480 */
481 pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
482 if (!pThis->pIAboveNet)
483 {
484 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network port interface!\n"));
485 return VERR_PDM_MISSING_INTERFACE_ABOVE;
486 }
487
488 /*
489 * Query the network config interface.
490 */
491 pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG);
492 if (!pThis->pIAboveConfig)
493 {
494 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network config interface!\n"));
495 return VERR_PDM_MISSING_INTERFACE_ABOVE;
496 }
497
498 /*
499 * Query the network connector interface.
500 */
501 PPDMIBASE pBaseDown;
502 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
503 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
504 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
505 {
506 pThis->pIBelowNetR3 = NULL;
507 pThis->pIBelowNetR0 = NIL_RTR0PTR;
508 }
509 else if (RT_SUCCESS(rc))
510 {
511 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
512 if (!pThis->pIBelowNetR3)
513 {
514 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
515 return VERR_PDM_MISSING_INTERFACE_BELOW;
516 }
517 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
518 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
519 }
520 else
521 {
522 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
523 return rc;
524 }
525
526 /*
527 * Register statistics.
528 */
529 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesRequested, "Bytes/Tx/Requested", STAMUNIT_BYTES, "Number of requested TX bytes.");
530 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesDenied, "Bytes/Tx/Denied", STAMUNIT_BYTES, "Number of denied TX bytes.");
531 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesGranted, "Bytes/Tx/Granted", STAMUNIT_BYTES, "Number of granted TX bytes.");
532
533 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsRequested, "Packets/Tx/Requested", "Number of requested TX packets.");
534 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsDenied, "Packets/Tx/Denied", "Number of denied TX packets.");
535 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsGranted, "Packets/Tx/Granted", "Number of granted TX packets.");
536 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPendingCalled, "Tx/WakeUp", "Number of wakeup TX calls.");
537
538 return VINF_SUCCESS;
539}
540
541
542
543/**
544 * Network sniffer filter driver registration record.
545 */
546const PDMDRVREG g_DrvNetShaper =
547{
548 /* u32Version */
549 PDM_DRVREG_VERSION,
550 /* szName */
551 "NetShaper",
552 /* szRCMod */
553 "",
554 /* szR0Mod */
555 "VBoxDDR0.r0",
556 /* pszDescription */
557 "Network Shaper Filter Driver",
558 /* fFlags */
559 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
560 /* fClass. */
561 PDM_DRVREG_CLASS_NETWORK,
562 /* cMaxInstances */
563 UINT32_MAX,
564 /* cbInstance */
565 sizeof(DRVNETSHAPER),
566 /* pfnConstruct */
567 drvR3NetShaperConstruct,
568 /* pfnDestruct */
569 drvR3NetShaperDestruct,
570 /* pfnRelocate */
571 NULL,
572 /* pfnIOCtl */
573 NULL,
574 /* pfnPowerOn */
575 NULL,
576 /* pfnReset */
577 NULL,
578 /* pfnSuspend */
579 NULL,
580 /* pfnResume */
581 NULL,
582 /* pfnAttach */
583 drvR3NetShaperAttach,
584 /* pfnDetach */
585 drvR3NetShaperDetach,
586 /* pfnPowerOff */
587 NULL,
588 /* pfnSoftReset */
589 NULL,
590 /* u32EndVersion */
591 PDM_DRVREG_VERSION
592};
593#endif /* IN_RING3 */
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