VirtualBox

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

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

NetShaper: R0 support (#5582)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 KB
Line 
1/* $Id: DrvNetShaper.cpp 42062 2012-07-09 15:10:00Z vboxsync $ */
2/** @file
3 * NetShaperFilter - Network shaper filter driver.
4 */
5
6/*
7 * Copyright (C) 2011-2012 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#ifdef IN_RING3
131 if (!PDMR3NsAllocateBandwidth(&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#ifdef IN_RING0
139 if (!PDMR0NsAllocateBandwidth(&pThis->Filter, cbMin))
140 {
141 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin);
142 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied);
143 return VERR_TRY_AGAIN;
144 }
145#endif
146 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin);
147 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted);
148 //LogFlow(("drvNetShaperUp_AllocBuf: got cb=%d\n", cbMin));
149 return pThis->CTX_SUFF(pIBelowNet)->pfnAllocBuf(pThis->CTX_SUFF(pIBelowNet), cbMin, pGso, ppSgBuf);
150}
151
152
153/**
154 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
155 */
156PDMBOTHCBDECL(int) drvNetShaperUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
157{
158 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
159 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
160 return VERR_NET_DOWN;
161 return pThis->CTX_SUFF(pIBelowNet)->pfnFreeBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf);
162}
163
164
165/**
166 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
167 */
168PDMBOTHCBDECL(int) drvNetShaperUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
169{
170 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
171 if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
172 return VERR_NET_DOWN;
173
174 return pThis->CTX_SUFF(pIBelowNet)->pfnSendBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf, fOnWorkerThread);
175}
176
177
178/**
179 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
180 */
181PDMBOTHCBDECL(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface)
182{
183 //LogFlow(("drvNetShaperUp_EndXmit:\n"));
184 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
185 if (RT_LIKELY(pThis->CTX_SUFF(pIBelowNet)))
186 pThis->CTX_SUFF(pIBelowNet)->pfnEndXmit(pThis->CTX_SUFF(pIBelowNet));
187 else
188 PDMCritSectLeave(&pThis->XmitLock);
189}
190
191
192/**
193 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
194 */
195PDMBOTHCBDECL(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
196{
197 LogFlow(("drvNetShaperUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
198 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
199 if (pThis->CTX_SUFF(pIBelowNet))
200 pThis->CTX_SUFF(pIBelowNet)->pfnSetPromiscuousMode(pThis->CTX_SUFF(pIBelowNet), fPromiscuous);
201}
202
203
204#ifdef IN_RING3
205/**
206 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
207 */
208static DECLCALLBACK(void) drvR3NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
209{
210 LogFlow(("drvNetShaperUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
211 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
212 if (pThis->pIBelowNetR3)
213 pThis->pIBelowNetR3->pfnNotifyLinkChanged(pThis->pIBelowNetR3, enmLinkState);
214}
215
216/**
217 * @interface_method_impl{PDMINETWORKDOWN,pfnWaitReceiveAvail}
218 */
219static DECLCALLBACK(int) drvR3NetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
220{
221 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
222 return pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, cMillies);
223}
224
225
226/**
227 * @interface_method_impl{PDMINETWORKDOWN,pfnReceive}
228 */
229static DECLCALLBACK(int) drvR3NetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
230{
231 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
232 return pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, pvBuf, cb);
233}
234
235
236/**
237 * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending}
238 */
239static DECLCALLBACK(void) drvR3NetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface)
240{
241 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
242 STAM_REL_COUNTER_INC(&pThis->StatXmitPendingCalled);
243 pThis->pIAboveNet->pfnXmitPending(pThis->pIAboveNet);
244}
245
246
247/**
248 * Gets the current Media Access Control (MAC) address.
249 *
250 * @returns VBox status code.
251 * @param pInterface Pointer to the interface structure containing the called function pointer.
252 * @param pMac Where to store the MAC address.
253 * @thread EMT
254 */
255static DECLCALLBACK(int) drvR3NetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
256{
257 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
258 return pThis->pIAboveConfig->pfnGetMac(pThis->pIAboveConfig, pMac);
259}
260
261/**
262 * Gets the new link state.
263 *
264 * @returns The current link state.
265 * @param pInterface Pointer to the interface structure containing the called function pointer.
266 * @thread EMT
267 */
268static DECLCALLBACK(PDMNETWORKLINKSTATE) drvR3NetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)
269{
270 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
271 return pThis->pIAboveConfig->pfnGetLinkState(pThis->pIAboveConfig);
272}
273
274/**
275 * Sets the new link state.
276 *
277 * @returns VBox status code.
278 * @param pInterface Pointer to the interface structure containing the called function pointer.
279 * @param enmState The new link state
280 * @thread EMT
281 */
282static DECLCALLBACK(int) drvR3NetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
283{
284 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
285 return pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig, enmState);
286}
287
288
289/**
290 * @interface_method_impl{PDMIBASER0,pfnQueryInterface}
291 */
292static DECLCALLBACK(RTR0PTR) drvR3NetShaperIBaseR0_QueryInterface(PPDMIBASER0 pInterface, const char *pszIID)
293{
294 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, IBaseR0);
295 PDMIBASER0_RETURN_INTERFACE(pThis->pDrvInsR3, pszIID, PDMINETWORKUP, &pThis->INetworkUpR0);
296 return NIL_RTR0PTR;
297}
298
299/**
300 * @interface_method_impl{PDMIBASERC,pfnQueryInterface}
301 */
302static DECLCALLBACK(RTRCPTR) drvR3NetShaperIBaseRC_QueryInterface(PPDMIBASERC pInterface, const char *pszIID)
303{
304 return NIL_RTRCPTR;
305}
306
307/**
308 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
309 */
310static DECLCALLBACK(void *) drvR3NetShaperIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
311{
312 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
313 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
314 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
315 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASER0, &pThis->IBaseR0);
316 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASERC, &pThis->IBaseRC);
317 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUpR3);
318 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown);
319 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
320 return NULL;
321}
322
323
324/**
325 * @interface_method_impl{PDMDRVREG,pfnDetach}
326 */
327static DECLCALLBACK(void) drvR3NetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
328{
329 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
330
331 LogFlow(("drvNetShaperDetach: pDrvIns: %p, fFlags: %u\n", pDrvIns, fFlags));
332 PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
333 pThis->pIBelowNetR3 = NULL;
334 pThis->pIBelowNetR0 = NIL_RTR0PTR;
335 PDMCritSectLeave(&pThis->XmitLock);
336}
337
338
339/**
340 * @interface_method_impl{PDMDRVREG,pfnAttach}
341 */
342static DECLCALLBACK(int) drvR3NetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
343{
344 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
345 LogFlow(("drvNetShaperAttach/#%#x: fFlags=%#x\n", pDrvIns->iInstance, fFlags));
346 PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
347
348 /*
349 * Query the network connector interface.
350 */
351 PPDMIBASE pBaseDown;
352 int rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
353 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
354 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
355 {
356 pThis->pIBelowNetR3 = NULL;
357 pThis->pIBelowNetR0 = NIL_RTR0PTR;
358 rc = VINF_SUCCESS;
359 }
360 else if (RT_SUCCESS(rc))
361 {
362 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
363 if (pThis->pIBelowNetR3)
364 {
365 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
366 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
367 rc = VINF_SUCCESS;
368 }
369 else
370 {
371 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
372 rc = VERR_PDM_MISSING_INTERFACE_BELOW;
373 }
374 }
375 else
376 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
377
378 PDMCritSectLeave(&pThis->XmitLock);
379 return VINF_SUCCESS;
380}
381
382
383/**
384 * @interface_method_impl{PDMDRVREG,pfnDestruct}
385 */
386static DECLCALLBACK(void) drvR3NetShaperDestruct(PPDMDRVINS pDrvIns)
387{
388 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
389 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
390
391 PDMDrvHlpNetShaperDetach(pDrvIns, &pThis->Filter);
392
393 if (PDMCritSectIsInitialized(&pThis->XmitLock))
394 PDMR3CritSectDelete(&pThis->XmitLock);
395}
396
397
398/**
399 * @interface_method_impl{Construct a NAT network transport driver instance,
400 * PDMDRVREG,pfnDestruct}
401 */
402static DECLCALLBACK(int) drvR3NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
403{
404 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
405 LogFlow(("drvNetShaperConstruct:\n"));
406 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
407
408 /*
409 * Init the static parts.
410 */
411 pThis->pDrvInsR3 = pDrvIns;
412 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns);
413 /* IBase */
414 pDrvIns->IBase.pfnQueryInterface = drvR3NetShaperIBase_QueryInterface;
415 pThis->IBaseR0.pfnQueryInterface = drvR3NetShaperIBaseR0_QueryInterface;
416 pThis->IBaseRC.pfnQueryInterface = drvR3NetShaperIBaseRC_QueryInterface;
417 /* INetworkUp */
418 pThis->INetworkUpR3.pfnBeginXmit = drvNetShaperUp_BeginXmit;
419 pThis->INetworkUpR3.pfnAllocBuf = drvNetShaperUp_AllocBuf;
420 pThis->INetworkUpR3.pfnFreeBuf = drvNetShaperUp_FreeBuf;
421 pThis->INetworkUpR3.pfnSendBuf = drvNetShaperUp_SendBuf;
422 pThis->INetworkUpR3.pfnEndXmit = drvNetShaperUp_EndXmit;
423 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvNetShaperUp_SetPromiscuousMode;
424 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3NetShaperUp_NotifyLinkChanged;
425 /*
426 * Resolve the ring-0 context interface addresses.
427 */
428 int rc = pDrvIns->pHlpR3->pfnLdrGetR0InterfaceSymbols(pDrvIns, &pThis->INetworkUpR0,
429 sizeof(pThis->INetworkUpR0),
430 "drvNetShaperUp_", PDMINETWORKUP_SYM_LIST);
431 AssertLogRelRCReturn(rc, rc);
432 /* INetworkDown */
433 pThis->INetworkDown.pfnWaitReceiveAvail = drvR3NetShaperDown_WaitReceiveAvail;
434 pThis->INetworkDown.pfnReceive = drvR3NetShaperDown_Receive;
435 pThis->INetworkDown.pfnXmitPending = drvR3NetShaperDown_XmitPending;
436 /* INetworkConfig */
437 pThis->INetworkConfig.pfnGetMac = drvR3NetShaperDownCfg_GetMac;
438 pThis->INetworkConfig.pfnGetLinkState = drvR3NetShaperDownCfg_GetLinkState;
439 pThis->INetworkConfig.pfnSetLinkState = drvR3NetShaperDownCfg_SetLinkState;
440
441 /*
442 * Create the locks.
443 */
444 rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper");
445 AssertRCReturn(rc, rc);
446
447 /*
448 * Validate the config.
449 */
450 if (!CFGMR3AreValuesValid(pCfg, "BwGroup\0"))
451 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
452
453 /*
454 * Find the bandwidth group we have to attach to.
455 */
456 rc = CFGMR3QueryStringAlloc(pCfg, "BwGroup", &pThis->pszBwGroup);
457 if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
458 {
459 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
460 N_("DrvNetShaper: Configuration error: Querying \"BwGroup\" as string failed"));
461 return rc;
462 }
463 else
464 rc = VINF_SUCCESS;
465
466 pThis->Filter.pIDrvNet = &pThis->INetworkDown;
467 rc = PDMDrvHlpNetShaperAttach(pDrvIns, pThis->pszBwGroup, &pThis->Filter);
468 if (RT_FAILURE(rc))
469 {
470 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
471 N_("DrvNetShaper: Configuration error: Failed to attach to bandwidth group"));
472 return rc;
473 }
474
475 /*
476 * Query the network port interface.
477 */
478 pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
479 if (!pThis->pIAboveNet)
480 {
481 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network port interface!\n"));
482 return VERR_PDM_MISSING_INTERFACE_ABOVE;
483 }
484
485 /*
486 * Query the network config interface.
487 */
488 pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG);
489 if (!pThis->pIAboveConfig)
490 {
491 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network config interface!\n"));
492 return VERR_PDM_MISSING_INTERFACE_ABOVE;
493 }
494
495 /*
496 * Query the network connector interface.
497 */
498 PPDMIBASE pBaseDown;
499 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
500 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
501 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
502 {
503 pThis->pIBelowNetR3 = NULL;
504 pThis->pIBelowNetR0 = NIL_RTR0PTR;
505 }
506 else if (RT_SUCCESS(rc))
507 {
508 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
509 if (!pThis->pIBelowNetR3)
510 {
511 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
512 return VERR_PDM_MISSING_INTERFACE_BELOW;
513 }
514 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
515 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
516 }
517 else
518 {
519 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
520 return rc;
521 }
522
523 /*
524 * Register statistics.
525 */
526 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesRequested, "Bytes/Tx/Requested", STAMUNIT_BYTES, "Number of requested TX bytes.");
527 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesDenied, "Bytes/Tx/Denied", STAMUNIT_BYTES, "Number of denied TX bytes.");
528 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesGranted, "Bytes/Tx/Granted", STAMUNIT_BYTES, "Number of granted TX bytes.");
529
530 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsRequested, "Packets/Tx/Requested", "Number of requested TX packets.");
531 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsDenied, "Packets/Tx/Denied", "Number of denied TX packets.");
532 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsGranted, "Packets/Tx/Granted", "Number of granted TX packets.");
533 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPendingCalled, "Tx/WakeUp", "Number of wakeup TX calls.");
534
535 return VINF_SUCCESS;
536}
537
538
539
540/**
541 * Network sniffer filter driver registration record.
542 */
543const PDMDRVREG g_DrvNetShaper =
544{
545 /* u32Version */
546 PDM_DRVREG_VERSION,
547 /* szName */
548 "NetShaper",
549 /* szRCMod */
550 "",
551 /* szR0Mod */
552 "VBoxDDR0.r0",
553 /* pszDescription */
554 "Network Shaper Filter Driver",
555 /* fFlags */
556 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
557 /* fClass. */
558 PDM_DRVREG_CLASS_NETWORK,
559 /* cMaxInstances */
560 UINT32_MAX,
561 /* cbInstance */
562 sizeof(DRVNETSHAPER),
563 /* pfnConstruct */
564 drvR3NetShaperConstruct,
565 /* pfnDestruct */
566 drvR3NetShaperDestruct,
567 /* pfnRelocate */
568 NULL,
569 /* pfnIOCtl */
570 NULL,
571 /* pfnPowerOn */
572 NULL,
573 /* pfnReset */
574 NULL,
575 /* pfnSuspend */
576 NULL,
577 /* pfnResume */
578 NULL,
579 /* pfnAttach */
580 drvR3NetShaperAttach,
581 /* pfnDetach */
582 drvR3NetShaperDetach,
583 /* pfnPowerOff */
584 NULL,
585 /* pfnSoftReset */
586 NULL,
587 /* u32EndVersion */
588 PDM_DRVREG_VERSION
589};
590#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