VirtualBox

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

Last change on this file since 104338 was 104338, checked in by vboxsync, 7 months ago

VBox/intnet.h: Corrected alignment padding in INTNETSG.

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