VirtualBox

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

Last change on this file since 95433 was 93652, checked in by vboxsync, 3 years ago

VMM/PDMDriver,DrvIntNet,DrvNetShaper: Properly disable all ring-0 driver stuff. bugref:10094

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