VirtualBox

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

Last change on this file since 44536 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

  • 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 44528 2013-02-04 14:27:54Z 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 /*
430 * Resolve the ring-0 context interface addresses.
431 */
432 int rc = pDrvIns->pHlpR3->pfnLdrGetR0InterfaceSymbols(pDrvIns, &pThis->INetworkUpR0,
433 sizeof(pThis->INetworkUpR0),
434 "drvNetShaperUp_", PDMINETWORKUP_SYM_LIST);
435 AssertLogRelRCReturn(rc, rc);
436 /* INetworkDown */
437 pThis->INetworkDown.pfnWaitReceiveAvail = drvR3NetShaperDown_WaitReceiveAvail;
438 pThis->INetworkDown.pfnReceive = drvR3NetShaperDown_Receive;
439 pThis->INetworkDown.pfnReceiveGso = drvR3NetShaperDown_ReceiveGso;
440 pThis->INetworkDown.pfnXmitPending = drvR3NetShaperDown_XmitPending;
441 /* INetworkConfig */
442 pThis->INetworkConfig.pfnGetMac = drvR3NetShaperDownCfg_GetMac;
443 pThis->INetworkConfig.pfnGetLinkState = drvR3NetShaperDownCfg_GetLinkState;
444 pThis->INetworkConfig.pfnSetLinkState = drvR3NetShaperDownCfg_SetLinkState;
445
446 /*
447 * Create the locks.
448 */
449 rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper");
450 AssertRCReturn(rc, rc);
451
452 /*
453 * Validate the config.
454 */
455 if (!CFGMR3AreValuesValid(pCfg, "BwGroup\0"))
456 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
457
458 /*
459 * Find the bandwidth group we have to attach to.
460 */
461 rc = CFGMR3QueryStringAlloc(pCfg, "BwGroup", &pThis->pszBwGroup);
462 if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
463 {
464 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
465 N_("DrvNetShaper: Configuration error: Querying \"BwGroup\" as string failed"));
466 return rc;
467 }
468 else
469 rc = VINF_SUCCESS;
470
471 pThis->Filter.pIDrvNetR3 = &pThis->INetworkDown;
472 rc = PDMDrvHlpNetShaperAttach(pDrvIns, pThis->pszBwGroup, &pThis->Filter);
473 if (RT_FAILURE(rc))
474 {
475 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
476 N_("DrvNetShaper: Configuration error: Failed to attach to bandwidth group"));
477 return rc;
478 }
479
480 /*
481 * Query the network port interface.
482 */
483 pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
484 if (!pThis->pIAboveNet)
485 {
486 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network port interface!\n"));
487 return VERR_PDM_MISSING_INTERFACE_ABOVE;
488 }
489
490 /*
491 * Query the network config interface.
492 */
493 pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG);
494 if (!pThis->pIAboveConfig)
495 {
496 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network config interface!\n"));
497 return VERR_PDM_MISSING_INTERFACE_ABOVE;
498 }
499
500 /*
501 * Query the network connector interface.
502 */
503 PPDMIBASE pBaseDown;
504 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
505 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
506 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
507 {
508 pThis->pIBelowNetR3 = NULL;
509 pThis->pIBelowNetR0 = NIL_RTR0PTR;
510 }
511 else if (RT_SUCCESS(rc))
512 {
513 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
514 if (!pThis->pIBelowNetR3)
515 {
516 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
517 return VERR_PDM_MISSING_INTERFACE_BELOW;
518 }
519 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
520 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
521 }
522 else
523 {
524 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
525 return rc;
526 }
527
528 /*
529 * Register statistics.
530 */
531 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesRequested, "Bytes/Tx/Requested", STAMUNIT_BYTES, "Number of requested TX bytes.");
532 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesDenied, "Bytes/Tx/Denied", STAMUNIT_BYTES, "Number of denied TX bytes.");
533 PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesGranted, "Bytes/Tx/Granted", STAMUNIT_BYTES, "Number of granted TX bytes.");
534
535 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsRequested, "Packets/Tx/Requested", "Number of requested TX packets.");
536 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsDenied, "Packets/Tx/Denied", "Number of denied TX packets.");
537 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsGranted, "Packets/Tx/Granted", "Number of granted TX packets.");
538 PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPendingCalled, "Tx/WakeUp", "Number of wakeup TX calls.");
539
540 return VINF_SUCCESS;
541}
542
543
544
545/**
546 * Network sniffer filter driver registration record.
547 */
548const PDMDRVREG g_DrvNetShaper =
549{
550 /* u32Version */
551 PDM_DRVREG_VERSION,
552 /* szName */
553 "NetShaper",
554 /* szRCMod */
555 "",
556 /* szR0Mod */
557 "VBoxDDR0.r0",
558 /* pszDescription */
559 "Network Shaper Filter Driver",
560 /* fFlags */
561 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
562 /* fClass. */
563 PDM_DRVREG_CLASS_NETWORK,
564 /* cMaxInstances */
565 UINT32_MAX,
566 /* cbInstance */
567 sizeof(DRVNETSHAPER),
568 /* pfnConstruct */
569 drvR3NetShaperConstruct,
570 /* pfnDestruct */
571 drvR3NetShaperDestruct,
572 /* pfnRelocate */
573 NULL,
574 /* pfnIOCtl */
575 NULL,
576 /* pfnPowerOn */
577 NULL,
578 /* pfnReset */
579 NULL,
580 /* pfnSuspend */
581 NULL,
582 /* pfnResume */
583 NULL,
584 /* pfnAttach */
585 drvR3NetShaperAttach,
586 /* pfnDetach */
587 drvR3NetShaperDetach,
588 /* pfnPowerOff */
589 NULL,
590 /* pfnSoftReset */
591 NULL,
592 /* u32EndVersion */
593 PDM_DRVREG_VERSION
594};
595#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