VirtualBox

source: vbox/trunk/include/VBox/intnet.h@ 76507

Last change on this file since 76507 was 76507, checked in by vboxsync, 5 years ago

/include: scm --fix-header-guards. bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 51.9 KB
Line 
1/** @file
2 * INTNET - Internal Networking. (DEV,++)
3 */
4
5/*
6 * Copyright (C) 2006-2017 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_intnet_h
27#define ___VBox_intnet_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <VBox/types.h>
33#include <VBox/vmm/stam.h>
34#include <VBox/sup.h>
35#include <iprt/assert.h>
36#include <iprt/asm.h>
37
38RT_C_DECLS_BEGIN
39
40
41/**
42 * Generic two-sided ring buffer.
43 *
44 * The deal is that there is exactly one writer and one reader.
45 * When offRead equals offWrite the buffer is empty. In the other
46 * extreme the writer will not use the last free byte in the buffer.
47 */
48typedef struct INTNETRINGBUF
49{
50 /** The offset from this structure to the start of the buffer. */
51 uint32_t offStart;
52 /** The offset from this structure to the end of the buffer. (exclusive). */
53 uint32_t offEnd;
54 /** The current read offset. */
55 uint32_t volatile offReadX;
56 /** Alignment. */
57 uint32_t u32Align0;
58
59 /** The committed write offset. */
60 uint32_t volatile offWriteCom;
61 /** Writer internal current write offset.
62 * This is ahead of offWriteCom when buffer space is handed to a third party for
63 * data gathering. offWriteCom will be assigned this value by the writer then
64 * the frame is ready. */
65 uint32_t volatile offWriteInt;
66 /** The number of bytes written (not counting overflows). */
67 STAMCOUNTER cbStatWritten;
68 /** The number of frames written (not counting overflows). */
69 STAMCOUNTER cStatFrames;
70 /** The number of overflows. */
71 STAMCOUNTER cOverflows;
72} INTNETRINGBUF;
73AssertCompileSize(INTNETRINGBUF, 48);
74/** Pointer to a ring buffer. */
75typedef INTNETRINGBUF *PINTNETRINGBUF;
76
77/** The alignment of a ring buffer. */
78#define INTNETRINGBUF_ALIGNMENT sizeof(INTNETHDR)
79
80/**
81 * Asserts the sanity of the specified INTNETRINGBUF structure.
82 */
83#ifdef VBOX_STRICT
84# define INTNETRINGBUF_ASSERT_SANITY(pRingBuf) \
85 do \
86 { \
87 AssertPtr(pRingBuf); \
88 { \
89 uint32_t const offWriteCom = (pRingBuf)->offWriteCom; \
90 uint32_t const offRead = (pRingBuf)->offReadX; \
91 uint32_t const offWriteInt = (pRingBuf)->offWriteInt; \
92 \
93 AssertMsg(offWriteCom == RT_ALIGN_32(offWriteCom, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteCom)); \
94 AssertMsg(offWriteCom >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteCom, (pRingBuf)->offStart)); \
95 AssertMsg(offWriteCom < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteCom, (pRingBuf)->offEnd)); \
96 \
97 AssertMsg(offRead == RT_ALIGN_32(offRead, INTNETHDR_ALIGNMENT), ("%#x\n", offRead)); \
98 AssertMsg(offRead >= (pRingBuf)->offStart, ("%#x %#x\n", offRead, (pRingBuf)->offStart)); \
99 AssertMsg(offRead < (pRingBuf)->offEnd, ("%#x %#x\n", offRead, (pRingBuf)->offEnd)); \
100 \
101 AssertMsg(offWriteInt == RT_ALIGN_32(offWriteInt, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteInt)); \
102 AssertMsg(offWriteInt >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteInt, (pRingBuf)->offStart)); \
103 AssertMsg(offWriteInt < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteInt, (pRingBuf)->offEnd)); \
104 AssertMsg( offRead <= offWriteCom \
105 ? offWriteCom <= offWriteInt || offWriteInt < offRead \
106 : offWriteCom <= offWriteInt, \
107 ("W=%#x W'=%#x R=%#x\n", offWriteCom, offWriteInt, offRead)); \
108 } \
109 } while (0)
110#else
111# define INTNETRINGBUF_ASSERT_SANITY(pRingBuf) do { } while (0)
112#endif
113
114
115
116/**
117 * A interface buffer.
118 */
119typedef struct INTNETBUF
120{
121 /** Magic number (INTNETBUF_MAGIC). */
122 uint32_t u32Magic;
123 /** The size of the entire buffer. */
124 uint32_t cbBuf;
125 /** The size of the send area. */
126 uint32_t cbSend;
127 /** The size of the receive area. */
128 uint32_t cbRecv;
129 /** The receive buffer. */
130 INTNETRINGBUF Recv;
131 /** The send buffer. */
132 INTNETRINGBUF Send;
133 /** Number of times yields help solve an overflow. */
134 STAMCOUNTER cStatYieldsOk;
135 /** Number of times yields didn't help solve an overflow. */
136 STAMCOUNTER cStatYieldsNok;
137 /** Number of lost packets due to overflows. */
138 STAMCOUNTER cStatLost;
139 /** Number of bad frames (both rings). */
140 STAMCOUNTER cStatBadFrames;
141 /** Reserved for future use. */
142 STAMCOUNTER aStatReserved[2];
143 /** Reserved for future send profiling. */
144 STAMPROFILE StatSend1;
145 /** Reserved for future send profiling. */
146 STAMPROFILE StatSend2;
147 /** Reserved for future receive profiling. */
148 STAMPROFILE StatRecv1;
149 /** Reserved for future receive profiling. */
150 STAMPROFILE StatRecv2;
151 /** Reserved for future profiling. */
152 STAMPROFILE StatReserved;
153} INTNETBUF;
154AssertCompileSize(INTNETBUF, 320);
155AssertCompileMemberOffset(INTNETBUF, Recv, 16);
156AssertCompileMemberOffset(INTNETBUF, Send, 64);
157
158/** Pointer to an interface buffer. */
159typedef INTNETBUF *PINTNETBUF;
160/** Pointer to a const interface buffer. */
161typedef INTNETBUF const *PCINTNETBUF;
162
163/** Magic number for INTNETBUF::u32Magic (Sir William Gerald Golding). */
164#define INTNETBUF_MAGIC UINT32_C(0x19110919)
165
166/**
167 * Asserts the sanity of the specified INTNETBUF structure.
168 */
169#define INTNETBUF_ASSERT_SANITY(pBuf) \
170 do \
171 { \
172 AssertPtr(pBuf); \
173 Assert((pBuf)->u32Magic == INTNETBUF_MAGIC); \
174 { \
175 uint32_t const offRecvStart = (pBuf)->Recv.offStart + RT_UOFFSETOF(INTNETBUF, Recv); \
176 uint32_t const offRecvEnd = (pBuf)->Recv.offStart + RT_UOFFSETOF(INTNETBUF, Recv); \
177 uint32_t const offSendStart = (pBuf)->Send.offStart + RT_UOFFSETOF(INTNETBUF, Send); \
178 uint32_t const offSendEnd = (pBuf)->Send.offStart + RT_UOFFSETOF(INTNETBUF, Send); \
179 \
180 Assert(offRecvEnd > offRecvStart); \
181 Assert(offRecvEnd - offRecvStart == (pBuf)->cbRecv); \
182 Assert(offRecvStart == sizeof(INTNETBUF)); \
183 \
184 Assert(offSendEnd > offSendStart); \
185 Assert(offSendEnd - offSendStart == (pBuf)->cbSend); \
186 Assert(pffSendEnd <= (pBuf)->cbBuf); \
187 \
188 Assert(offSendStart == offRecvEnd); \
189 } \
190 } while (0)
191
192
193/** Internal networking interface handle. */
194typedef uint32_t INTNETIFHANDLE;
195/** Pointer to an internal networking interface handle. */
196typedef INTNETIFHANDLE *PINTNETIFHANDLE;
197
198/** Or mask to obscure the handle index. */
199#define INTNET_HANDLE_MAGIC 0x88880000
200/** Mask to extract the handle index. */
201#define INTNET_HANDLE_INDEX_MASK 0xffff
202/** The maximum number of handles (exclusive) */
203#define INTNET_HANDLE_MAX 0xffff
204/** Invalid handle. */
205#define INTNET_HANDLE_INVALID (0)
206
207
208/**
209 * The frame header.
210 *
211 * The header is intentionally 8 bytes long. It will always
212 * start at an 8 byte aligned address. Assuming that the buffer
213 * size is a multiple of 8 bytes, that means that we can guarantee
214 * that the entire header is contiguous in both virtual and physical
215 * memory.
216 */
217typedef struct INTNETHDR
218{
219 /** The size of the frame. */
220 uint32_t cbFrame : 24;
221 /** Header type. This is currently serving as a magic, it
222 * can be extended later to encode special command frames and stuff. */
223 uint32_t u8Type : 8;
224 /** The offset from the start of this header to where the actual frame starts.
225 * This is used to keep the frame it self contiguous in virtual memory and
226 * thereby both simplify access as well as the descriptor. */
227 int32_t offFrame;
228} INTNETHDR;
229AssertCompileSize(INTNETHDR, 8);
230AssertCompileSizeAlignment(INTNETBUF, sizeof(INTNETHDR));
231/** Pointer to a frame header.*/
232typedef INTNETHDR *PINTNETHDR;
233/** Pointer to a const frame header.*/
234typedef INTNETHDR const *PCINTNETHDR;
235
236/** The alignment of a frame header. */
237#define INTNETHDR_ALIGNMENT sizeof(INTNETHDR)
238AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT);
239AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
240
241/** @name Frame types (INTNETHDR::u8Type).
242 * @{ */
243/** Normal frames. */
244#define INTNETHDR_TYPE_FRAME 0x42
245/** Padding frames. */
246#define INTNETHDR_TYPE_PADDING 0x53
247/** Generic segment offload frames.
248 * The frame starts with a PDMNETWORKGSO structure which is followed by the
249 * header template and data. */
250#define INTNETHDR_TYPE_GSO 0x64
251AssertCompileSize(PDMNETWORKGSO, 8);
252/** @} */
253
254/**
255 * Asserts the sanity of the specified INTNETHDR.
256 */
257#ifdef VBOX_STRICT
258#define INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf) \
259 do \
260 { \
261 AssertPtr(pHdr); \
262 Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
263 Assert( (pHdr)->u8Type == INTNETHDR_TYPE_FRAME \
264 || (pHdr)->u8Type == INTNETHDR_TYPE_GSO \
265 || (pHdr)->u8Type == INTNETHDR_TYPE_PADDING); \
266 { \
267 uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
268 uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \
269 \
270 Assert(offHdr >= (pRingBuf)->offStart); \
271 Assert(offHdr < (pRingBuf)->offEnd); \
272 \
273 /* could do more thorough work here... later, perhaps. */ \
274 Assert(offFrame >= (pRingBuf)->offStart); \
275 Assert(offFrame < (pRingBuf)->offEnd); \
276 } \
277 } while (0)
278#else
279# define INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf) do { } while (0)
280#endif
281
282
283/**
284 * Scatter / Gather segment (internal networking).
285 */
286typedef struct INTNETSEG
287{
288 /** The physical address. NIL_RTHCPHYS is not set. */
289 RTHCPHYS Phys;
290 /** Pointer to the segment data. */
291 void *pv;
292 /** The segment size. */
293 uint32_t cb;
294} INTNETSEG;
295/** Pointer to a internal networking frame segment. */
296typedef INTNETSEG *PINTNETSEG;
297/** Pointer to a internal networking frame segment. */
298typedef INTNETSEG const *PCINTNETSEG;
299
300
301/**
302 * Scatter / Gather list (internal networking).
303 *
304 * This is used when communicating with the trunk port.
305 */
306typedef struct INTNETSG
307{
308 /** Owner data, don't touch! */
309 void *pvOwnerData;
310 /** User data. */
311 void *pvUserData;
312 /** User data 2 in case anyone needs it. */
313 void *pvUserData2;
314 /** GSO context information, set the type to invalid if not relevant. */
315 PDMNETWORKGSO GsoCtx;
316 /** The total length of the scatter gather list. */
317 uint32_t cbTotal;
318 /** The number of users (references).
319 * This is used by the SGRelease code to decide when it can be freed. */
320 uint16_t volatile cUsers;
321 /** Flags, see INTNETSG_FLAGS_* */
322 uint16_t volatile fFlags;
323#if ARCH_BITS == 64
324 /** Alignment padding. */
325 uint16_t uPadding;
326#endif
327 /** The number of segments allocated. */
328 uint16_t cSegsAlloc;
329 /** The number of segments actually used. */
330 uint16_t cSegsUsed;
331 /** Variable sized list of segments. */
332 INTNETSEG aSegs[1];
333} INTNETSG;
334AssertCompileSizeAlignment(INTNETSG, 8);
335/** Pointer to a scatter / gather list. */
336typedef INTNETSG *PINTNETSG;
337/** Pointer to a const scatter / gather list. */
338typedef INTNETSG const *PCINTNETSG;
339
340/** @name INTNETSG::fFlags definitions.
341 * @{ */
342/** Set if the SG is free. */
343#define INTNETSG_FLAGS_FREE RT_BIT_32(1)
344/** Set if the SG is a temporary one that will become invalid upon return.
345 * Try to finish using it before returning, and if that's not possible copy
346 * to other buffers.
347 * When not set, the callee should always free the SG.
348 * Attempts to free it made by the callee will be quietly ignored. */
349#define INTNETSG_FLAGS_TEMP RT_BIT_32(2)
350/** ARP packet, IPv4 + MAC.
351 * @internal */
352#define INTNETSG_FLAGS_ARP_IPV4 RT_BIT_32(3)
353/** Copied to the temporary buffer.
354 * @internal */
355#define INTNETSG_FLAGS_PKT_CP_IN_TMP RT_BIT_32(4)
356/** @} */
357
358
359/** @name Direction (frame source or destination)
360 * @{ */
361/** To/From the wire. */
362#define INTNETTRUNKDIR_WIRE RT_BIT_32(0)
363/** To/From the host. */
364#define INTNETTRUNKDIR_HOST RT_BIT_32(1)
365/** Mask of valid bits. */
366#define INTNETTRUNKDIR_VALID_MASK UINT32_C(3)
367/** @} */
368
369/**
370 * Switch decisions returned by INTNETTRUNKSWPORT::pfnPreRecv.
371 */
372typedef enum INTNETSWDECISION
373{
374 /** The usual invalid zero value. */
375 INTNETSWDECISION_INVALID = 0,
376 /** Everywhere. */
377 INTNETSWDECISION_BROADCAST,
378 /** Only to the internal network. */
379 INTNETSWDECISION_INTNET,
380 /** Only for the trunk (host/wire). */
381 INTNETSWDECISION_TRUNK,
382 /** Used internally to indicate that the packet cannot be handled in the
383 * current context. */
384 INTNETSWDECISION_BAD_CONTEXT,
385 /** Used internally to indicate that the packet should be dropped. */
386 INTNETSWDECISION_DROP,
387 /** The usual 32-bit type expansion. */
388 INTNETSWDECISION_32BIT_HACK = 0x7fffffff
389} INTNETSWDECISION;
390
391
392/**
393 * Network layer address type.
394 */
395typedef enum INTNETADDRTYPE
396{
397 /** The invalid 0 entry. */
398 kIntNetAddrType_Invalid = 0,
399 /** IP version 4. */
400 kIntNetAddrType_IPv4,
401 /** IP version 6. */
402 kIntNetAddrType_IPv6,
403 /** IPX. */
404 kIntNetAddrType_IPX,
405 /** The end of the valid values. */
406 kIntNetAddrType_End,
407 /** The usual 32-bit hack. */
408 kIntNetAddrType_32BitHack = 0x7fffffff
409} INTNETADDRTYPE;
410
411
412/** Pointer to the interface side of a trunk port. */
413typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
414
415
416/**
417 * Special variation of INTNETTRUNKIFPORT::pfnRelease for use with
418 * INTNETTRUNKSWPORT::pfnDisconnect.
419 *
420 * @param pIfPort Pointer to the INTNETTRUNKIFPORT instance.
421 */
422typedef DECLCALLBACK(void) FNINTNETTRUNKIFPORTRELEASEBUSY(PINTNETTRUNKIFPORT pIfPort);
423/** Pointer to a FNINTNETTRUNKIFPORTRELEASEBUSY function. */
424typedef FNINTNETTRUNKIFPORTRELEASEBUSY *PFNINTNETTRUNKIFPORTRELEASEBUSY;
425
426
427/** Pointer to the switch side of a trunk port. */
428typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
429/**
430 * This is the port on the internal network 'switch', i.e.
431 * what the driver is connected to.
432 *
433 * This is only used for the in-kernel trunk connections.
434 */
435typedef struct INTNETTRUNKSWPORT
436{
437 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
438 uint32_t u32Version;
439
440 /**
441 * Examine the packet and figure out where it is going.
442 *
443 * This method is for making packet switching decisions in contexts where
444 * pfnRecv cannot be called or is no longer applicable. This method can be
445 * called from any context.
446 *
447 * @returns INTNETSWDECISION_BROADCAST, INTNETSWDECISION_INTNET or
448 * INTNETSWDECISION_TRUNK. The source is excluded from broadcast &
449 * trunk, of course.
450 *
451 * @param pSwitchPort Pointer to this structure.
452 * @param pvHdrs Pointer to the packet headers.
453 * @param cbHdrs Size of the packet headers. This must be at least 6
454 * bytes (the destination MAC address), but should if
455 * possible also include any VLAN tag and network
456 * layer header (wireless mac address sharing).
457 * @param fSrc Where this frame comes from. Only one bit should be
458 * set!
459 *
460 * @remarks Will only grab the switch table spinlock (interrupt safe). May
461 * signal an event semaphore iff we're racing network cleanup. The
462 * caller must be busy when calling.
463 */
464 DECLR0CALLBACKMEMBER(INTNETSWDECISION, pfnPreRecv,(PINTNETTRUNKSWPORT pSwitchPort,
465 void const *pvHdrs, size_t cbHdrs, uint32_t fSrc));
466
467 /**
468 * Incoming frame.
469 *
470 * The frame may be modified when the trunk port on the switch is set to share
471 * the mac address of the host when hitting the wire. Currently frames
472 * containing ARP packets are subject to this, later other protocols like
473 * NDP/ICMPv6 may need editing as well when operating in this mode. The edited
474 * packet should be forwarded to the host/wire when @c false is returned.
475 *
476 * @returns true if we've handled it and it should be dropped.
477 * false if it should hit the wire/host.
478 *
479 * @param pSwitchPort Pointer to this structure.
480 * @param pvIf Pointer to the interface which received this frame
481 * if available. Can be NULL.
482 * @param pSG The (scatter /) gather structure for the frame. This
483 * will only be use during the call, so a temporary one can
484 * be used. The Phys member will not be used.
485 * @param fSrc Where this frame comes from. Exactly one bit shall be
486 * set!
487 *
488 * @remarks Will only grab the switch table spinlock (interrupt safe). Will
489 * signal event semaphores. The caller must be busy when calling.
490 *
491 * @remarks NAT and TAP will use this interface.
492 *
493 * @todo Do any of the host require notification before frame modifications?
494 * If so, we'll add a callback to INTNETTRUNKIFPORT for this
495 * (pfnSGModifying) and a SG flag.
496 */
497 DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pSwitchPort, void *pvIf, PINTNETSG pSG, uint32_t fSrc));
498
499 /**
500 * Retain a SG.
501 *
502 * @param pSwitchPort Pointer to this structure.
503 * @param pSG Pointer to the (scatter /) gather structure.
504 *
505 * @remarks Will not grab any locks. The caller must be busy when calling.
506 */
507 DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
508
509 /**
510 * Release a SG.
511 *
512 * This is called by the pfnXmit code when done with a SG. This may safe
513 * be done in an asynchronous manner.
514 *
515 * @param pSwitchPort Pointer to this structure.
516 * @param pSG Pointer to the (scatter /) gather structure.
517 *
518 * @remarks May signal an event semaphore later on, currently code won't though.
519 * The caller is busy when making this call.
520 */
521 DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
522
523 /**
524 * Selects whether outgoing SGs should have their physical address set.
525 *
526 * By enabling physical addresses in the scatter / gather segments it should
527 * be possible to save some unnecessary address translation and memory locking
528 * in the network stack. (Internal networking knows the physical address for
529 * all the INTNETBUF data and that it's locked memory.) There is a negative
530 * side effects though, frames that crosses page boundaries will require
531 * multiple scather / gather segments.
532 *
533 * @returns The old setting.
534 *
535 * @param pSwitchPort Pointer to this structure.
536 * @param fEnable Whether to enable or disable it.
537 *
538 * @remarks Will not grab any locks. The caller must be busy when calling.
539 */
540 DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable));
541
542 /**
543 * Reports the MAC address of the trunk.
544 *
545 * This is supposed to be called when creating, connection or reconnecting the
546 * trunk and when the MAC address is changed by the system admin.
547 *
548 * @param pSwitchPort Pointer to this structure.
549 * @param pMacAddr The MAC address.
550 *
551 * @remarks May take a spinlock or two. The caller must be busy when calling.
552 */
553 DECLR0CALLBACKMEMBER(void, pfnReportMacAddress,(PINTNETTRUNKSWPORT pSwitchPort, PCRTMAC pMacAddr));
554
555 /**
556 * Reports the promicuousness of the interface.
557 *
558 * This is supposed to be called when creating, connection or reconnecting the
559 * trunk and when the mode is changed by the system admin.
560 *
561 * @param pSwitchPort Pointer to this structure.
562 * @param fPromiscuous True if the host operates the interface in
563 * promiscuous mode, false if not.
564 *
565 * @remarks May take a spinlock or two. The caller must be busy when calling.
566 */
567 DECLR0CALLBACKMEMBER(void, pfnReportPromiscuousMode,(PINTNETTRUNKSWPORT pSwitchPort, bool fPromiscuous));
568
569 /**
570 * Reports the GSO capabilities of the host, wire or both.
571 *
572 * This is supposed to be used only when creating, connecting or reconnecting
573 * the trunk. It is assumed that the GSO capabilities are kind of static the
574 * rest of the time.
575 *
576 * @param pSwitchPort Pointer to this structure.
577 * @param fGsoCapabilities The GSO capability bit mask. The bits
578 * corresponds to the GSO type with the same value.
579 * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
580 *
581 * @remarks Does not take any locks. The caller must be busy when calling.
582 */
583 DECLR0CALLBACKMEMBER(void, pfnReportGsoCapabilities,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fGsoCapabilities, uint32_t fDst));
584
585 /**
586 * Reports the no-preemption-xmit capabilities of the host and wire.
587 *
588 * This is supposed to be used only when creating, connecting or reconnecting
589 * the trunk. It is assumed that the GSO capabilities are kind of static the
590 * rest of the time.
591 *
592 * @param pSwitchPort Pointer to this structure.
593 * @param fNoPreemptDsts The destinations (INTNETTRUNKDIR_XXX) which it
594 * is safe to transmit to with preemption disabled.
595 * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
596 *
597 * @remarks Does not take any locks. The caller must be busy when calling.
598 */
599 DECLR0CALLBACKMEMBER(void, pfnReportNoPreemptDsts,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fNoPreemptDsts));
600
601 /**
602 * Notifications about changes to host IP addresses.
603 *
604 * This is used by networks bridged to wifi that share mac with
605 * the host. Host reports changes to its IP addresses so that L3
606 * switching can ingore guests spoofing host's own IP addresses
607 *
608 * This callback may be null to indicate we are not interested.
609 *
610 * @param pSwitchPort Pointer to this structure.
611 * @param fAdded Whether address is added of removed.
612 * @param enmType Address type.
613 * @param pvAddr Pointer to the address.
614 */
615 DECLR0CALLBACKMEMBER(void, pfnNotifyHostAddress,(PINTNETTRUNKSWPORT pSwitchPort, bool fAdded,
616 INTNETADDRTYPE enmType, const void *pvAddr));
617
618 /**
619 * OS triggered trunk disconnect.
620 *
621 * The caller shall must be busy when calling this method to prevent racing the
622 * network destruction code. This method will always consume this busy reference
623 * (released via @a pfnReleaseBusy using @a pIfPort).
624 *
625 * The caller shall guarantee that there are absolutely no chance of concurrent
626 * calls to this method on the same instance.
627 *
628 * @param pSwitchPort Pointer to this structure.
629 * @param pIfPort The interface port structure corresponding to @a
630 * pSwitchPort and which should be used when
631 * calling @a pfnReleaseBusy. This is required as
632 * the method may no longer have access to a valid
633 * @a pIfPort pointer.
634 * @param pfnReleaseBusy Callback for releasing the callers busy
635 * reference to it's side of things.
636 */
637 DECLR0CALLBACKMEMBER(void, pfnDisconnect,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT pIfPort,
638 PFNINTNETTRUNKIFPORTRELEASEBUSY pfnReleaseBusy));
639
640 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
641 uint32_t u32VersionEnd;
642} INTNETTRUNKSWPORT;
643
644/**
645 * Version number for the INTNETTRUNKIFPORT::u32Version and
646 * INTNETTRUNKIFPORT::u32VersionEnd fields.
647 *
648 * NB: Version @c 0xA2CDf005 is consumed by 4.x branches for the
649 * backport of pfnNotifyHostAddress. On the next version bump use
650 * @c 0xA2CDf006 and remove this reminder.
651 */
652# define INTNETTRUNKSWPORT_VERSION UINT32_C(0xA2CDf004)
653
654
655/**
656 * The trunk interface state used set by INTNETTRUNKIFPORT::pfnSetState.
657 */
658typedef enum INTNETTRUNKIFSTATE
659{
660 /** The invalid zero entry. */
661 INTNETTRUNKIFSTATE_INVALID = 0,
662 /** The trunk is inactive. No calls to INTNETTRUNKSWPORT::pfnRecv or
663 * INTNETTRUNKSWPORT::pfnPreRecv. Calling other methods is OK. */
664 INTNETTRUNKIFSTATE_INACTIVE,
665 /** The trunk is active, no restrictions on methods or anything. */
666 INTNETTRUNKIFSTATE_ACTIVE,
667 /** The trunk is about to be disconnected from the internal network. No
668 * calls to any INTNETRUNKSWPORT methods. */
669 INTNETTRUNKIFSTATE_DISCONNECTING,
670 /** The end of the valid states. */
671 INTNETTRUNKIFSTATE_END,
672 /** The usual 32-bit type blow up hack. */
673 INTNETTRUNKIFSTATE_32BIT_HACK = 0x7fffffff
674} INTNETTRUNKIFSTATE;
675
676
677/**
678 * This is the port on the trunk interface, i.e. the driver side which the
679 * internal network is connected to.
680 *
681 * This is only used for the in-kernel trunk connections.
682 */
683typedef struct INTNETTRUNKIFPORT
684{
685 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
686 uint32_t u32Version;
687
688 /**
689 * Retain the object.
690 *
691 * It will normally be called while owning the internal network semaphore.
692 *
693 * @param pIfPort Pointer to this structure.
694 *
695 * @remarks May own the big mutex, no spinlocks.
696 */
697 DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
698
699 /**
700 * Releases the object.
701 *
702 * This must be called for every pfnRetain call.
703 *
704 * @param pIfPort Pointer to this structure.
705 *
706 * @remarks May own the big mutex, no spinlocks.
707 */
708 DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
709
710 /**
711 * Disconnect from the switch and release the object.
712 *
713 * The is the counter action of the
714 * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
715 *
716 * @param pIfPort Pointer to this structure.
717 *
718 * @remarks Owns the big mutex.
719 */
720 DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
721
722 /**
723 * Changes the state of the trunk interface.
724 *
725 * The interface is created in the inactive state (INTNETTRUNKIFSTATE_INACTIVE).
726 * When the first connect VM or service is activated, the internal network
727 * activates the trunk (INTNETTRUNKIFSTATE_ACTIVE). The state may then be set
728 * back and forth between INACTIVE and ACTIVE as VMs are paused, added and
729 * removed.
730 *
731 * Eventually though, the network is destroyed as a result of there being no
732 * more VMs left in it and the state is changed to disconnecting
733 * (INTNETTRUNKIFSTATE_DISCONNECTING) and pfnWaitForIdle is called to make sure
734 * there are no active calls in either direction when pfnDisconnectAndRelease is
735 * called.
736 *
737 * A typical operation to performed by this method is to enable/disable promiscuous
738 * mode on the host network interface when entering/leaving the active state.
739 *
740 * @returns The previous state.
741 *
742 * @param pIfPort Pointer to this structure.
743 * @param enmState The new state.
744 *
745 * @remarks Owns the big mutex. No racing pfnSetState, pfnWaitForIdle,
746 * pfnDisconnectAndRelease or INTNETTRUNKFACTORY::pfnCreateAndConnect
747 * calls.
748 */
749 DECLR0CALLBACKMEMBER(INTNETTRUNKIFSTATE, pfnSetState,(PINTNETTRUNKIFPORT pIfPort, INTNETTRUNKIFSTATE enmState));
750
751 /**
752 * Notifies when the MAC address of an interface is set or changes.
753 *
754 * @param pIfPort Pointer to this structure.
755 * @param pvIfData Pointer to the trunk's interface data (see
756 * pfnConnectInterface).
757 * @param pMac Pointer to the MAC address of the connecting VM NIC.
758 *
759 * @remarks Only busy references to the trunk and the interface.
760 */
761 DECLR0CALLBACKMEMBER(void, pfnNotifyMacAddress,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PCRTMAC pMac));
762
763 /**
764 * Called when an interface is connected to the network.
765 *
766 * @returns IPRT status code.
767 * @param pIfPort Pointer to this structure.
768 * @param pvIf Opaque pointer to the interface being connected.
769 * For use INTNETTRUNKSWPORT::pfnRecv.
770 * @param ppvIfData Pointer to a pointer variable that the trunk
771 * implementation can use to associate data with the
772 * interface. This pointer will be passed to the
773 * pfnXmit, pfnNotifyMacAddress and
774 * pfnDisconnectInterface methods.
775 *
776 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
777 */
778 DECLR0CALLBACKMEMBER(int, pfnConnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIf, void **ppvIfData));
779
780 /**
781 * Called when an interface is disconnected from the network.
782 *
783 * @param pIfPort Pointer to this structure.
784 * @param pvIfData Pointer to the trunk's interface data (see
785 * pfnConnectInterface).
786 *
787 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
788 */
789 DECLR0CALLBACKMEMBER(void, pfnDisconnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData));
790
791 /**
792 * Waits for the interface to become idle.
793 *
794 * This method must be called before disconnecting and releasing the object in
795 * order to prevent racing incoming/outgoing frames and device
796 * enabling/disabling.
797 *
798 * @returns IPRT status code (see RTSemEventWait).
799 * @param pIfPort Pointer to this structure.
800 * @param cMillies The number of milliseconds to wait. 0 means
801 * no waiting at all. Use RT_INDEFINITE_WAIT for
802 * an indefinite wait.
803 *
804 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
805 */
806 DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
807
808 /**
809 * Transmit a frame.
810 *
811 * @return VBox status code. Error generally means we'll drop the frame.
812 * @param pIfPort Pointer to this structure.
813 * @param pvIfData Pointer to the trunk's interface data (see
814 * pfnConnectInterface).
815 * @param pSG Pointer to the (scatter /) gather structure for the frame.
816 * This may or may not be a temporary buffer. If it's temporary
817 * the transmit operation(s) then it's required to make a copy
818 * of the frame unless it can be transmitted synchronously.
819 * @param fDst The destination mask. At least one bit will be set.
820 *
821 * @remarks No locks. May be called concurrently on several threads.
822 */
823 DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PINTNETSG pSG, uint32_t fDst));
824
825 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
826 uint32_t u32VersionEnd;
827} INTNETTRUNKIFPORT;
828
829/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
830#define INTNETTRUNKIFPORT_VERSION UINT32_C(0xA2CDe001)
831
832
833/**
834 * The component factory interface for create a network
835 * interface filter (like VBoxNetFlt).
836 */
837typedef struct INTNETTRUNKFACTORY
838{
839 /**
840 * Release this factory.
841 *
842 * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
843 * will retain a reference to the factory and the caller has to call this method to
844 * release it once the pfnCreateAndConnect call(s) has been done.
845 *
846 * @param pIfFactory Pointer to this structure.
847 */
848 DECLR0CALLBACKMEMBER(void, pfnRelease,(struct INTNETTRUNKFACTORY *pIfFactory));
849
850 /**
851 * Create an instance for the specfied host interface and connects it
852 * to the internal network trunk port.
853 *
854 * The initial interface active state is false (suspended).
855 *
856 *
857 * @returns VBox status code.
858 * @retval VINF_SUCCESS and *ppIfPort set on success.
859 * @retval VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
860 * @retval VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
861 * @retval VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
862 *
863 * @param pIfFactory Pointer to this structure.
864 * @param pszName The interface name (OS specific).
865 * @param pSwitchPort Pointer to the port interface on the switch that
866 * this interface is being connected to.
867 * @param fFlags Creation flags, see below.
868 * @param ppIfPort Where to store the pointer to the interface port
869 * on success.
870 *
871 * @remarks Called while owning the network and the out-bound trunk semaphores.
872 */
873 DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
874 PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags,
875 PINTNETTRUNKIFPORT *ppIfPort));
876} INTNETTRUNKFACTORY;
877/** Pointer to the trunk factory. */
878typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
879
880/** The UUID for the (current) trunk factory. (case sensitive) */
881#define INTNETTRUNKFACTORY_UUID_STR "de504d93-1d1e-4781-8b73-6ea39a0e36a2"
882
883/** @name INTNETTRUNKFACTORY::pfnCreateAndConnect flags.
884 * @{ */
885/** Don't put the filtered interface in promiscuous mode.
886 * This is used for wireless interface since these can misbehave if
887 * we try to put them in promiscuous mode. (Wireless interfaces are
888 * normally bridged on level 3 instead of level 2.) */
889#define INTNETTRUNKFACTORY_FLAG_NO_PROMISC RT_BIT_32(0)
890/** @} */
891
892
893/**
894 * The trunk connection type.
895 *
896 * Used by IntNetR0Open and associated interfaces.
897 */
898typedef enum INTNETTRUNKTYPE
899{
900 /** Invalid trunk type. */
901 kIntNetTrunkType_Invalid = 0,
902 /** No trunk connection. */
903 kIntNetTrunkType_None,
904 /** We don't care which kind of trunk connection if the network exists,
905 * if it doesn't exist create it without a connection. */
906 kIntNetTrunkType_WhateverNone,
907 /** VirtualBox host network interface filter driver.
908 * The trunk name is the name of the host network interface. */
909 kIntNetTrunkType_NetFlt,
910 /** VirtualBox adapter host driver. */
911 kIntNetTrunkType_NetAdp,
912 /** Nat service (ring-0). */
913 kIntNetTrunkType_SrvNat,
914 /** The end of valid types. */
915 kIntNetTrunkType_End,
916 /** The usual 32-bit hack. */
917 kIntNetTrunkType_32bitHack = 0x7fffffff
918} INTNETTRUNKTYPE;
919
920/** @name IntNetR0Open flags.
921 *
922 * The desired policy options must be specified explicitly, if omitted it is
923 * understood that whatever is current or default is fine with the caller.
924 *
925 * @todo Move the policies out of the flags, use three new parameters.
926 *
927 * @{ */
928/** Share the MAC address with the host when sending something to the wire via the trunk.
929 * This is typically used when the trunk is a NetFlt for a wireless interface. */
930#define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE RT_BIT_32(0)
931/** Require that the current security and promiscuous policies of the network
932 * is exactly as the ones specified in this open network request.
933 *
934 * Use this with INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES to prevent
935 * restrictions from being lifted. If no further policy changes are desired,
936 * apply the relevant _FIXED flags. */
937#define INTNET_OPEN_FLAGS_REQUIRE_EXACT RT_BIT_32(1)
938/** Require that the security and promiscuous policies of the network is at
939 * least as restrictive as specified this request specifies and prevent them
940 * being lifted later on. */
941#define INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES RT_BIT_32(2)
942
943/** Network access policy: Fixed if set, changable if clear. */
944#define INTNET_OPEN_FLAGS_ACCESS_FIXED RT_BIT_32(3)
945/** Network access policy: Public network. */
946#define INTNET_OPEN_FLAGS_ACCESS_PUBLIC RT_BIT_32(4)
947/** Network access policy: Restricted network. */
948#define INTNET_OPEN_FLAGS_ACCESS_RESTRICTED RT_BIT_32(5)
949
950/** Promiscuous mode policy: Is it fixed or changable by new participants? */
951#define INTNET_OPEN_FLAGS_PROMISC_FIXED RT_BIT_32(6)
952/** Promiscuous mode policy: Allow the clients to request it. */
953#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS RT_BIT_32(7)
954/** Promiscuous mode policy: Deny the clients from requesting it. */
955#define INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS RT_BIT_32(8)
956/** Promiscuous mode policy: Allow the trunk-host to request it. */
957#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST RT_BIT_32(9)
958/** Promiscuous mode policy: Deny the trunk-host from requesting it. */
959#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST RT_BIT_32(10)
960/** Promiscuous mode policy: Allow the trunk-wire to request it. */
961#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE RT_BIT_32(11)
962/** Promiscuous mode policy: Deny the trunk-wire from requesting it. */
963#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE RT_BIT_32(12)
964
965/** Interface policies: Is it fixed or changable (by admin).
966 * @note Per interface, not network wide. */
967#define INTNET_OPEN_FLAGS_IF_FIXED RT_BIT_32(13)
968/** Interface promiscuous mode policy: Allow the interface to request it. */
969#define INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW RT_BIT_32(14)
970/** Interface promiscuous mode policy: Deny the interface from requesting it. */
971#define INTNET_OPEN_FLAGS_IF_PROMISC_DENY RT_BIT_32(15)
972/** Interface promiscuous mode policy: See unrelated trunk traffic. */
973#define INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK RT_BIT_32(16)
974/** Interface promiscuous mode policy: No unrelated trunk traffic visible. */
975#define INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK RT_BIT_32(17)
976
977/** Trunk policy: Fixed if set, changable if clear.
978 * @remarks The DISABLED options are considered more restrictive by
979 * INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES. */
980#define INTNET_OPEN_FLAGS_TRUNK_FIXED RT_BIT_32(18)
981/** Trunk policy: The host end should be enabled. */
982#define INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED RT_BIT_32(19)
983/** Trunk policy: The host end should be disabled. */
984#define INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED RT_BIT_32(20)
985/** Trunk policy: The host should only see packets destined for it. */
986#define INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE RT_BIT_32(21)
987/** Trunk policy: The host should see all packets. */
988#define INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE RT_BIT_32(22)
989/** Trunk policy: The wire end should be enabled. */
990#define INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED RT_BIT_32(23)
991/** Trunk policy: The wire end should be disabled. */
992#define INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED RT_BIT_32(24)
993/** Trunk policy: The wire should only see packets destined for it. */
994#define INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE RT_BIT_32(25)
995/** Trunk policy: The wire should see all packets. */
996#define INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE RT_BIT_32(26)
997
998/** Used to enable host specific workarounds.
999 *
1000 * On darwin this will clear ip_tos in DHCP packets when
1001 * INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE is also set. */
1002#define INTNET_OPEN_FLAGS_WORKAROUND_1 RT_BIT_32(31)
1003
1004
1005/** The mask of valid flags. */
1006#define INTNET_OPEN_FLAGS_MASK UINT32_C(0x83ffffff)
1007/** The mask of all flags use to fix (lock) settings. */
1008#define INTNET_OPEN_FLAGS_FIXED_MASK \
1009 ( INTNET_OPEN_FLAGS_ACCESS_FIXED \
1010 | INTNET_OPEN_FLAGS_PROMISC_FIXED \
1011 | INTNET_OPEN_FLAGS_IF_FIXED \
1012 | INTNET_OPEN_FLAGS_TRUNK_FIXED )
1013
1014/** The mask of all policy pairs. */
1015#define INTNET_OPEN_FLAGS_PAIR_MASK \
1016 ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC | INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
1017 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
1018 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
1019 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
1020 | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
1021 | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
1022 | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
1023 | INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
1024 | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
1025 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
1026 )
1027/** The mask of all relaxed policy bits. */
1028#define INTNET_OPEN_FLAGS_RELAXED_MASK \
1029 ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC \
1030 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS \
1031 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST \
1032 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE \
1033 | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW \
1034 | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK \
1035 | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED \
1036 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
1037 | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED \
1038 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
1039 )
1040/** The mask of all strict policy bits. */
1041#define INTNET_OPEN_FLAGS_STRICT_MASK \
1042 ( INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
1043 | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
1044 | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
1045 | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
1046 | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
1047 | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
1048 | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
1049 | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
1050 | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
1051 | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
1052 )
1053/** @} */
1054
1055/** The maximum length of a network name. */
1056#define INTNET_MAX_NETWORK_NAME 128
1057
1058/** The maximum length of a trunk name. */
1059#define INTNET_MAX_TRUNK_NAME 64
1060
1061
1062/**
1063 * Request buffer for IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN.
1064 * @see IntNetR0Open.
1065 */
1066typedef struct INTNETOPENREQ
1067{
1068 /** The request header. */
1069 SUPVMMR0REQHDR Hdr;
1070 /** Alternative to passing the taking the session from the VM handle.
1071 * Either use this member or use the VM handle, don't do both. */
1072 PSUPDRVSESSION pSession;
1073 /** The network name. (input) */
1074 char szNetwork[INTNET_MAX_NETWORK_NAME];
1075 /** What to connect to the trunk port. (input)
1076 * This is specific to the trunk type below. */
1077 char szTrunk[INTNET_MAX_TRUNK_NAME];
1078 /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
1079 INTNETTRUNKTYPE enmTrunkType;
1080 /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
1081 uint32_t fFlags;
1082 /** The size of the send buffer. (input) */
1083 uint32_t cbSend;
1084 /** The size of the receive buffer. (input) */
1085 uint32_t cbRecv;
1086 /** The handle to the network interface. (output) */
1087 INTNETIFHANDLE hIf;
1088} INTNETOPENREQ;
1089/** Pointer to an IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
1090typedef INTNETOPENREQ *PINTNETOPENREQ;
1091
1092INTNETR0DECL(int) IntNetR0OpenReq(PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
1093
1094
1095/**
1096 * Request buffer for IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
1097 * @see IntNetR0IfClose.
1098 */
1099typedef struct INTNETIFCLOSEREQ
1100{
1101 /** The request header. */
1102 SUPVMMR0REQHDR Hdr;
1103 /** Alternative to passing the taking the session from the VM handle.
1104 * Either use this member or use the VM handle, don't do both. */
1105 PSUPDRVSESSION pSession;
1106 /** The handle to the network interface. */
1107 INTNETIFHANDLE hIf;
1108} INTNETIFCLOSEREQ;
1109/** Pointer to an IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request
1110 * buffer. */
1111typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
1112
1113INTNETR0DECL(int) IntNetR0IfCloseReq(PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
1114
1115
1116/**
1117 * Request buffer for IntNetR0IfGetRing3BufferReq /
1118 * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS.
1119 * @see IntNetR0IfGetRing3Buffer.
1120 */
1121typedef struct INTNETIFGETBUFFERPTRSREQ
1122{
1123 /** The request header. */
1124 SUPVMMR0REQHDR Hdr;
1125 /** Alternative to passing the taking the session from the VM handle.
1126 * Either use this member or use the VM handle, don't do both. */
1127 PSUPDRVSESSION pSession;
1128 /** Handle to the interface. */
1129 INTNETIFHANDLE hIf;
1130 /** The pointer to the ring-3 buffer. (output) */
1131 R3PTRTYPE(PINTNETBUF) pRing3Buf;
1132 /** The pointer to the ring-0 buffer. (output) */
1133 R0PTRTYPE(PINTNETBUF) pRing0Buf;
1134} INTNETIFGETBUFFERPTRSREQ;
1135/** Pointer to an IntNetR0IfGetRing3BufferReq /
1136 * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS request buffer. */
1137typedef INTNETIFGETBUFFERPTRSREQ *PINTNETIFGETBUFFERPTRSREQ;
1138
1139INTNETR0DECL(int) IntNetR0IfGetBufferPtrsReq(PSUPDRVSESSION pSession, PINTNETIFGETBUFFERPTRSREQ pReq);
1140
1141
1142/**
1143 * Request buffer for IntNetR0IfSetPromiscuousModeReq /
1144 * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
1145 * @see IntNetR0IfSetPromiscuousMode.
1146 */
1147typedef struct INTNETIFSETPROMISCUOUSMODEREQ
1148{
1149 /** The request header. */
1150 SUPVMMR0REQHDR Hdr;
1151 /** Alternative to passing the taking the session from the VM handle.
1152 * Either use this member or use the VM handle, don't do both. */
1153 PSUPDRVSESSION pSession;
1154 /** Handle to the interface. */
1155 INTNETIFHANDLE hIf;
1156 /** The new promiscuous mode. */
1157 bool fPromiscuous;
1158} INTNETIFSETPROMISCUOUSMODEREQ;
1159/** Pointer to an IntNetR0IfSetPromiscuousModeReq /
1160 * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
1161typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
1162
1163INTNETR0DECL(int) IntNetR0IfSetPromiscuousModeReq(PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
1164
1165
1166/**
1167 * Request buffer for IntNetR0IfSetMacAddressReq /
1168 * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
1169 * @see IntNetR0IfSetMacAddress.
1170 */
1171typedef struct INTNETIFSETMACADDRESSREQ
1172{
1173 /** The request header. */
1174 SUPVMMR0REQHDR Hdr;
1175 /** Alternative to passing the taking the session from the VM handle.
1176 * Either use this member or use the VM handle, don't do both. */
1177 PSUPDRVSESSION pSession;
1178 /** Handle to the interface. */
1179 INTNETIFHANDLE hIf;
1180 /** The new MAC address. */
1181 RTMAC Mac;
1182} INTNETIFSETMACADDRESSREQ;
1183/** Pointer to an IntNetR0IfSetMacAddressReq /
1184 * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
1185typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
1186
1187INTNETR0DECL(int) IntNetR0IfSetMacAddressReq(PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
1188
1189
1190/**
1191 * Request buffer for IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
1192 * @see IntNetR0IfSetActive.
1193 */
1194typedef struct INTNETIFSETACTIVEREQ
1195{
1196 /** The request header. */
1197 SUPVMMR0REQHDR Hdr;
1198 /** Alternative to passing the taking the session from the VM handle.
1199 * Either use this member or use the VM handle, don't do both. */
1200 PSUPDRVSESSION pSession;
1201 /** Handle to the interface. */
1202 INTNETIFHANDLE hIf;
1203 /** The new state. */
1204 bool fActive;
1205} INTNETIFSETACTIVEREQ;
1206/** Pointer to an IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE
1207 * request buffer. */
1208typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
1209
1210INTNETR0DECL(int) IntNetR0IfSetActiveReq(PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
1211
1212
1213/**
1214 * Request buffer for IntNetR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
1215 * @see IntNetR0IfSend.
1216 */
1217typedef struct INTNETIFSENDREQ
1218{
1219 /** The request header. */
1220 SUPVMMR0REQHDR Hdr;
1221 /** Alternative to passing the taking the session from the VM handle.
1222 * Either use this member or use the VM handle, don't do both. */
1223 PSUPDRVSESSION pSession;
1224 /** Handle to the interface. */
1225 INTNETIFHANDLE hIf;
1226} INTNETIFSENDREQ;
1227/** Pointer to an IntNetR0IfSend() argument package. */
1228typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
1229
1230INTNETR0DECL(int) IntNetR0IfSendReq(PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
1231
1232
1233/**
1234 * Request buffer for IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
1235 * @see IntNetR0IfWait.
1236 */
1237typedef struct INTNETIFWAITREQ
1238{
1239 /** The request header. */
1240 SUPVMMR0REQHDR Hdr;
1241 /** Alternative to passing the taking the session from the VM handle.
1242 * Either use this member or use the VM handle, don't do both. */
1243 PSUPDRVSESSION pSession;
1244 /** Handle to the interface. */
1245 INTNETIFHANDLE hIf;
1246 /** The number of milliseconds to wait. */
1247 uint32_t cMillies;
1248} INTNETIFWAITREQ;
1249/** Pointer to an IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
1250typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
1251
1252INTNETR0DECL(int) IntNetR0IfWaitReq(PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
1253
1254
1255/**
1256 * Request buffer for IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT.
1257 * @see IntNetR0IfAbortWait.
1258 */
1259typedef struct INTNETIFABORTWAITREQ
1260{
1261 /** The request header. */
1262 SUPVMMR0REQHDR Hdr;
1263 /** Alternative to passing the taking the session from the VM handle.
1264 * Either use this member or use the VM handle, don't do both. */
1265 PSUPDRVSESSION pSession;
1266 /** Handle to the interface. */
1267 INTNETIFHANDLE hIf;
1268 /** Set this to fend off all future IntNetR0Wait calls. */
1269 bool fNoMoreWaits;
1270} INTNETIFABORTWAITREQ;
1271/** Pointer to an IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT
1272 * request buffer. */
1273typedef INTNETIFABORTWAITREQ *PINTNETIFABORTWAITREQ;
1274
1275INTNETR0DECL(int) IntNetR0IfAbortWaitReq(PSUPDRVSESSION pSession, PINTNETIFABORTWAITREQ pReq);
1276
1277
1278#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
1279/** @name
1280 * @{
1281 */
1282
1283INTNETR0DECL(int) IntNetR0Init(void);
1284INTNETR0DECL(void) IntNetR0Term(void);
1285INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork,
1286 INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
1287 uint32_t cbSend, uint32_t cbRecv, PINTNETIFHANDLE phIf);
1288INTNETR0DECL(uint32_t) IntNetR0GetNetworkCount(void);
1289
1290INTNETR0DECL(int) IntNetR0IfClose(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1291INTNETR0DECL(int) IntNetR0IfGetBufferPtrs(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession,
1292 R3PTRTYPE(PINTNETBUF) *ppRing3Buf, R0PTRTYPE(PINTNETBUF) *ppRing0Buf);
1293INTNETR0DECL(int) IntNetR0IfSetPromiscuousMode(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous);
1294INTNETR0DECL(int) IntNetR0IfSetMacAddress(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCRTMAC pMac);
1295INTNETR0DECL(int) IntNetR0IfSetActive(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive);
1296INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1297INTNETR0DECL(int) IntNetR0IfWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies);
1298INTNETR0DECL(int) IntNetR0IfAbortWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1299
1300/** @} */
1301#endif /* IN_RING0 */
1302
1303RT_C_DECLS_END
1304
1305#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use