VirtualBox

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

Last change on this file since 97964 was 97342, checked in by vboxsync, 2 years ago

NetworkServices/IntNetSwitch,Devices/Network/DrvIntNet,Devices/Network/SrvIntNetR0: Don't require a dedicated waiting thread to get notified when there is something to receive but make it possible to register a callback which is called and sends an IPC message instead, bugref:10297 [build and scm fixes]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.1 KB
Line 
1/** @file
2 * INTNET - Internal Networking. (DEV,++)
3 */
4
5/*
6 * Copyright (C) 2006-2022 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 uint16_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 INTNETSEG aSegs[1];
359} INTNETSG;
360AssertCompileSizeAlignment(INTNETSG, 8);
361/** Pointer to a scatter / gather list. */
362typedef INTNETSG *PINTNETSG;
363/** Pointer to a const scatter / gather list. */
364typedef INTNETSG const *PCINTNETSG;
365
366/** @name INTNETSG::fFlags definitions.
367 * @{ */
368/** Set if the SG is free. */
369#define INTNETSG_FLAGS_FREE RT_BIT_32(1)
370/** Set if the SG is a temporary one that will become invalid upon return.
371 * Try to finish using it before returning, and if that's not possible copy
372 * to other buffers.
373 * When not set, the callee should always free the SG.
374 * Attempts to free it made by the callee will be quietly ignored. */
375#define INTNETSG_FLAGS_TEMP RT_BIT_32(2)
376/** ARP packet, IPv4 + MAC.
377 * @internal */
378#define INTNETSG_FLAGS_ARP_IPV4 RT_BIT_32(3)
379/** Copied to the temporary buffer.
380 * @internal */
381#define INTNETSG_FLAGS_PKT_CP_IN_TMP RT_BIT_32(4)
382/** @} */
383
384
385/** @name Direction (frame source or destination)
386 * @{ */
387/** To/From the wire. */
388#define INTNETTRUNKDIR_WIRE RT_BIT_32(0)
389/** To/From the host. */
390#define INTNETTRUNKDIR_HOST RT_BIT_32(1)
391/** Mask of valid bits. */
392#define INTNETTRUNKDIR_VALID_MASK UINT32_C(3)
393/** @} */
394
395/**
396 * Switch decisions returned by INTNETTRUNKSWPORT::pfnPreRecv.
397 */
398typedef enum INTNETSWDECISION
399{
400 /** The usual invalid zero value. */
401 INTNETSWDECISION_INVALID = 0,
402 /** Everywhere. */
403 INTNETSWDECISION_BROADCAST,
404 /** Only to the internal network. */
405 INTNETSWDECISION_INTNET,
406 /** Only for the trunk (host/wire). */
407 INTNETSWDECISION_TRUNK,
408 /** Used internally to indicate that the packet cannot be handled in the
409 * current context. */
410 INTNETSWDECISION_BAD_CONTEXT,
411 /** Used internally to indicate that the packet should be dropped. */
412 INTNETSWDECISION_DROP,
413 /** The usual 32-bit type expansion. */
414 INTNETSWDECISION_32BIT_HACK = 0x7fffffff
415} INTNETSWDECISION;
416
417
418/**
419 * Network layer address type.
420 */
421typedef enum INTNETADDRTYPE
422{
423 /** The invalid 0 entry. */
424 kIntNetAddrType_Invalid = 0,
425 /** IP version 4. */
426 kIntNetAddrType_IPv4,
427 /** IP version 6. */
428 kIntNetAddrType_IPv6,
429 /** IPX. */
430 kIntNetAddrType_IPX,
431 /** The end of the valid values. */
432 kIntNetAddrType_End,
433 /** The usual 32-bit hack. */
434 kIntNetAddrType_32BitHack = 0x7fffffff
435} INTNETADDRTYPE;
436
437
438/** Pointer to the interface side of a trunk port. */
439typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
440
441
442/**
443 * Special variation of INTNETTRUNKIFPORT::pfnRelease for use with
444 * INTNETTRUNKSWPORT::pfnDisconnect.
445 *
446 * @param pIfPort Pointer to the INTNETTRUNKIFPORT instance.
447 */
448typedef DECLCALLBACKTYPE(void, FNINTNETTRUNKIFPORTRELEASEBUSY,(PINTNETTRUNKIFPORT pIfPort));
449/** Pointer to a FNINTNETTRUNKIFPORTRELEASEBUSY function. */
450typedef FNINTNETTRUNKIFPORTRELEASEBUSY *PFNINTNETTRUNKIFPORTRELEASEBUSY;
451
452
453/** Pointer to the switch side of a trunk port. */
454typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
455/**
456 * This is the port on the internal network 'switch', i.e.
457 * what the driver is connected to.
458 *
459 * This is only used for the in-kernel trunk connections.
460 */
461typedef struct INTNETTRUNKSWPORT
462{
463 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
464 uint32_t u32Version;
465
466 /**
467 * Examine the packet and figure out where it is going.
468 *
469 * This method is for making packet switching decisions in contexts where
470 * pfnRecv cannot be called or is no longer applicable. This method can be
471 * called from any context.
472 *
473 * @returns INTNETSWDECISION_BROADCAST, INTNETSWDECISION_INTNET or
474 * INTNETSWDECISION_TRUNK. The source is excluded from broadcast &
475 * trunk, of course.
476 *
477 * @param pSwitchPort Pointer to this structure.
478 * @param pvHdrs Pointer to the packet headers.
479 * @param cbHdrs Size of the packet headers. This must be at least 6
480 * bytes (the destination MAC address), but should if
481 * possible also include any VLAN tag and network
482 * layer header (wireless mac address sharing).
483 * @param fSrc Where this frame comes from. Only one bit should be
484 * set!
485 *
486 * @remarks Will only grab the switch table spinlock (interrupt safe). May
487 * signal an event semaphore iff we're racing network cleanup. The
488 * caller must be busy when calling.
489 */
490 DECLR0CALLBACKMEMBER(INTNETSWDECISION, pfnPreRecv,(PINTNETTRUNKSWPORT pSwitchPort,
491 void const *pvHdrs, size_t cbHdrs, uint32_t fSrc));
492
493 /**
494 * Incoming frame.
495 *
496 * The frame may be modified when the trunk port on the switch is set to share
497 * the mac address of the host when hitting the wire. Currently frames
498 * containing ARP packets are subject to this, later other protocols like
499 * NDP/ICMPv6 may need editing as well when operating in this mode. The edited
500 * packet should be forwarded to the host/wire when @c false is returned.
501 *
502 * @returns true if we've handled it and it should be dropped.
503 * false if it should hit the wire/host.
504 *
505 * @param pSwitchPort Pointer to this structure.
506 * @param pvIf Pointer to the interface which received this frame
507 * if available. Can be NULL.
508 * @param pSG The (scatter /) gather structure for the frame. This
509 * will only be use during the call, so a temporary one can
510 * be used. The Phys member will not be used.
511 * @param fSrc Where this frame comes from. Exactly one bit shall be
512 * set!
513 *
514 * @remarks Will only grab the switch table spinlock (interrupt safe). Will
515 * signal event semaphores. The caller must be busy when calling.
516 *
517 * @remarks NAT and TAP will use this interface.
518 *
519 * @todo Do any of the host require notification before frame modifications?
520 * If so, we'll add a callback to INTNETTRUNKIFPORT for this
521 * (pfnSGModifying) and a SG flag.
522 */
523 DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pSwitchPort, void *pvIf, PINTNETSG pSG, uint32_t fSrc));
524
525 /**
526 * Retain a SG.
527 *
528 * @param pSwitchPort Pointer to this structure.
529 * @param pSG Pointer to the (scatter /) gather structure.
530 *
531 * @remarks Will not grab any locks. The caller must be busy when calling.
532 */
533 DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
534
535 /**
536 * Release a SG.
537 *
538 * This is called by the pfnXmit code when done with a SG. This may safe
539 * be done in an asynchronous manner.
540 *
541 * @param pSwitchPort Pointer to this structure.
542 * @param pSG Pointer to the (scatter /) gather structure.
543 *
544 * @remarks May signal an event semaphore later on, currently code won't though.
545 * The caller is busy when making this call.
546 */
547 DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
548
549 /**
550 * Selects whether outgoing SGs should have their physical address set.
551 *
552 * By enabling physical addresses in the scatter / gather segments it should
553 * be possible to save some unnecessary address translation and memory locking
554 * in the network stack. (Internal networking knows the physical address for
555 * all the INTNETBUF data and that it's locked memory.) There is a negative
556 * side effects though, frames that crosses page boundaries will require
557 * multiple scather / gather segments.
558 *
559 * @returns The old setting.
560 *
561 * @param pSwitchPort Pointer to this structure.
562 * @param fEnable Whether to enable or disable it.
563 *
564 * @remarks Will not grab any locks. The caller must be busy when calling.
565 */
566 DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable));
567
568 /**
569 * Reports the MAC address of the trunk.
570 *
571 * This is supposed to be called when creating, connection or reconnecting the
572 * trunk and when the MAC address is changed by the system admin.
573 *
574 * @param pSwitchPort Pointer to this structure.
575 * @param pMacAddr The MAC address.
576 *
577 * @remarks May take a spinlock or two. The caller must be busy when calling.
578 */
579 DECLR0CALLBACKMEMBER(void, pfnReportMacAddress,(PINTNETTRUNKSWPORT pSwitchPort, PCRTMAC pMacAddr));
580
581 /**
582 * Reports the promicuousness of the interface.
583 *
584 * This is supposed to be called when creating, connection or reconnecting the
585 * trunk and when the mode is changed by the system admin.
586 *
587 * @param pSwitchPort Pointer to this structure.
588 * @param fPromiscuous True if the host operates the interface in
589 * promiscuous mode, false if not.
590 *
591 * @remarks May take a spinlock or two. The caller must be busy when calling.
592 */
593 DECLR0CALLBACKMEMBER(void, pfnReportPromiscuousMode,(PINTNETTRUNKSWPORT pSwitchPort, bool fPromiscuous));
594
595 /**
596 * Reports the GSO capabilities of the host, wire or both.
597 *
598 * This is supposed to be used only when creating, connecting or reconnecting
599 * the trunk. It is assumed that the GSO capabilities are kind of static the
600 * rest of the time.
601 *
602 * @param pSwitchPort Pointer to this structure.
603 * @param fGsoCapabilities The GSO capability bit mask. The bits
604 * corresponds to the GSO type with the same value.
605 * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
606 *
607 * @remarks Does not take any locks. The caller must be busy when calling.
608 */
609 DECLR0CALLBACKMEMBER(void, pfnReportGsoCapabilities,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fGsoCapabilities, uint32_t fDst));
610
611 /**
612 * Reports the no-preemption-xmit capabilities of the host and wire.
613 *
614 * This is supposed to be used only when creating, connecting or reconnecting
615 * the trunk. It is assumed that the GSO capabilities are kind of static the
616 * rest of the time.
617 *
618 * @param pSwitchPort Pointer to this structure.
619 * @param fNoPreemptDsts The destinations (INTNETTRUNKDIR_XXX) which it
620 * is safe to transmit to with preemption disabled.
621 * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
622 *
623 * @remarks Does not take any locks. The caller must be busy when calling.
624 */
625 DECLR0CALLBACKMEMBER(void, pfnReportNoPreemptDsts,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fNoPreemptDsts));
626
627 /**
628 * Notifications about changes to host IP addresses.
629 *
630 * This is used by networks bridged to wifi that share mac with
631 * the host. Host reports changes to its IP addresses so that L3
632 * switching can ingore guests spoofing host's own IP addresses
633 *
634 * This callback may be null to indicate we are not interested.
635 *
636 * @param pSwitchPort Pointer to this structure.
637 * @param fAdded Whether address is added of removed.
638 * @param enmType Address type.
639 * @param pvAddr Pointer to the address.
640 */
641 DECLR0CALLBACKMEMBER(void, pfnNotifyHostAddress,(PINTNETTRUNKSWPORT pSwitchPort, bool fAdded,
642 INTNETADDRTYPE enmType, const void *pvAddr));
643
644 /**
645 * OS triggered trunk disconnect.
646 *
647 * The caller shall must be busy when calling this method to prevent racing the
648 * network destruction code. This method will always consume this busy reference
649 * (released via @a pfnReleaseBusy using @a pIfPort).
650 *
651 * The caller shall guarantee that there are absolutely no chance of concurrent
652 * calls to this method on the same instance.
653 *
654 * @param pSwitchPort Pointer to this structure.
655 * @param pIfPort The interface port structure corresponding to @a
656 * pSwitchPort and which should be used when
657 * calling @a pfnReleaseBusy. This is required as
658 * the method may no longer have access to a valid
659 * @a pIfPort pointer.
660 * @param pfnReleaseBusy Callback for releasing the callers busy
661 * reference to it's side of things.
662 */
663 DECLR0CALLBACKMEMBER(void, pfnDisconnect,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETTRUNKIFPORT pIfPort,
664 PFNINTNETTRUNKIFPORTRELEASEBUSY pfnReleaseBusy));
665
666 /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
667 uint32_t u32VersionEnd;
668} INTNETTRUNKSWPORT;
669
670/**
671 * Version number for the INTNETTRUNKIFPORT::u32Version and
672 * INTNETTRUNKIFPORT::u32VersionEnd fields.
673 *
674 * NB: Version @c 0xA2CDf005 is consumed by 4.x branches for the
675 * backport of pfnNotifyHostAddress. On the next version bump use
676 * @c 0xA2CDf006 and remove this reminder.
677 */
678# define INTNETTRUNKSWPORT_VERSION UINT32_C(0xA2CDf004)
679
680
681/**
682 * The trunk interface state used set by INTNETTRUNKIFPORT::pfnSetState.
683 */
684typedef enum INTNETTRUNKIFSTATE
685{
686 /** The invalid zero entry. */
687 INTNETTRUNKIFSTATE_INVALID = 0,
688 /** The trunk is inactive. No calls to INTNETTRUNKSWPORT::pfnRecv or
689 * INTNETTRUNKSWPORT::pfnPreRecv. Calling other methods is OK. */
690 INTNETTRUNKIFSTATE_INACTIVE,
691 /** The trunk is active, no restrictions on methods or anything. */
692 INTNETTRUNKIFSTATE_ACTIVE,
693 /** The trunk is about to be disconnected from the internal network. No
694 * calls to any INTNETRUNKSWPORT methods. */
695 INTNETTRUNKIFSTATE_DISCONNECTING,
696 /** The end of the valid states. */
697 INTNETTRUNKIFSTATE_END,
698 /** The usual 32-bit type blow up hack. */
699 INTNETTRUNKIFSTATE_32BIT_HACK = 0x7fffffff
700} INTNETTRUNKIFSTATE;
701
702
703/**
704 * This is the port on the trunk interface, i.e. the driver side which the
705 * internal network is connected to.
706 *
707 * This is only used for the in-kernel trunk connections.
708 */
709typedef struct INTNETTRUNKIFPORT
710{
711 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
712 uint32_t u32Version;
713
714 /**
715 * Retain the object.
716 *
717 * It will normally be called while owning the internal network semaphore.
718 *
719 * @param pIfPort Pointer to this structure.
720 *
721 * @remarks May own the big mutex, no spinlocks.
722 */
723 DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
724
725 /**
726 * Releases the object.
727 *
728 * This must be called for every pfnRetain call.
729 *
730 * @param pIfPort Pointer to this structure.
731 *
732 * @remarks May own the big mutex, no spinlocks.
733 */
734 DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
735
736 /**
737 * Disconnect from the switch and release the object.
738 *
739 * The is the counter action of the
740 * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
741 *
742 * @param pIfPort Pointer to this structure.
743 *
744 * @remarks Owns the big mutex.
745 */
746 DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
747
748 /**
749 * Changes the state of the trunk interface.
750 *
751 * The interface is created in the inactive state (INTNETTRUNKIFSTATE_INACTIVE).
752 * When the first connect VM or service is activated, the internal network
753 * activates the trunk (INTNETTRUNKIFSTATE_ACTIVE). The state may then be set
754 * back and forth between INACTIVE and ACTIVE as VMs are paused, added and
755 * removed.
756 *
757 * Eventually though, the network is destroyed as a result of there being no
758 * more VMs left in it and the state is changed to disconnecting
759 * (INTNETTRUNKIFSTATE_DISCONNECTING) and pfnWaitForIdle is called to make sure
760 * there are no active calls in either direction when pfnDisconnectAndRelease is
761 * called.
762 *
763 * A typical operation to performed by this method is to enable/disable promiscuous
764 * mode on the host network interface when entering/leaving the active state.
765 *
766 * @returns The previous state.
767 *
768 * @param pIfPort Pointer to this structure.
769 * @param enmState The new state.
770 *
771 * @remarks Owns the big mutex. No racing pfnSetState, pfnWaitForIdle,
772 * pfnDisconnectAndRelease or INTNETTRUNKFACTORY::pfnCreateAndConnect
773 * calls.
774 */
775 DECLR0CALLBACKMEMBER(INTNETTRUNKIFSTATE, pfnSetState,(PINTNETTRUNKIFPORT pIfPort, INTNETTRUNKIFSTATE enmState));
776
777 /**
778 * Notifies when the MAC address of an interface is set or changes.
779 *
780 * @param pIfPort Pointer to this structure.
781 * @param pvIfData Pointer to the trunk's interface data (see
782 * pfnConnectInterface).
783 * @param pMac Pointer to the MAC address of the connecting VM NIC.
784 *
785 * @remarks Only busy references to the trunk and the interface.
786 */
787 DECLR0CALLBACKMEMBER(void, pfnNotifyMacAddress,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PCRTMAC pMac));
788
789 /**
790 * Called when an interface is connected to the network.
791 *
792 * @returns IPRT status code.
793 * @param pIfPort Pointer to this structure.
794 * @param pvIf Opaque pointer to the interface being connected.
795 * For use INTNETTRUNKSWPORT::pfnRecv.
796 * @param ppvIfData Pointer to a pointer variable that the trunk
797 * implementation can use to associate data with the
798 * interface. This pointer will be passed to the
799 * pfnXmit, pfnNotifyMacAddress and
800 * pfnDisconnectInterface methods.
801 *
802 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
803 */
804 DECLR0CALLBACKMEMBER(int, pfnConnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIf, void **ppvIfData));
805
806 /**
807 * Called when an interface is disconnected from the network.
808 *
809 * @param pIfPort Pointer to this structure.
810 * @param pvIfData Pointer to the trunk's interface data (see
811 * pfnConnectInterface).
812 *
813 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
814 */
815 DECLR0CALLBACKMEMBER(void, pfnDisconnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData));
816
817 /**
818 * Waits for the interface to become idle.
819 *
820 * This method must be called before disconnecting and releasing the object in
821 * order to prevent racing incoming/outgoing frames and device
822 * enabling/disabling.
823 *
824 * @returns IPRT status code (see RTSemEventWait).
825 * @param pIfPort Pointer to this structure.
826 * @param cMillies The number of milliseconds to wait. 0 means
827 * no waiting at all. Use RT_INDEFINITE_WAIT for
828 * an indefinite wait.
829 *
830 * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
831 */
832 DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
833
834 /**
835 * Transmit a frame.
836 *
837 * @return VBox status code. Error generally means we'll drop the frame.
838 * @param pIfPort Pointer to this structure.
839 * @param pvIfData Pointer to the trunk's interface data (see
840 * pfnConnectInterface).
841 * @param pSG Pointer to the (scatter /) gather structure for the frame.
842 * This may or may not be a temporary buffer. If it's temporary
843 * the transmit operation(s) then it's required to make a copy
844 * of the frame unless it can be transmitted synchronously.
845 * @param fDst The destination mask. At least one bit will be set.
846 *
847 * @remarks No locks. May be called concurrently on several threads.
848 */
849 DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PINTNETSG pSG, uint32_t fDst));
850
851 /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
852 uint32_t u32VersionEnd;
853} INTNETTRUNKIFPORT;
854
855/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
856#define INTNETTRUNKIFPORT_VERSION UINT32_C(0xA2CDe001)
857
858
859/**
860 * The component factory interface for create a network
861 * interface filter (like VBoxNetFlt).
862 */
863typedef struct INTNETTRUNKFACTORY
864{
865 /**
866 * Release this factory.
867 *
868 * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
869 * will retain a reference to the factory and the caller has to call this method to
870 * release it once the pfnCreateAndConnect call(s) has been done.
871 *
872 * @param pIfFactory Pointer to this structure.
873 */
874 DECLR0CALLBACKMEMBER(void, pfnRelease,(struct INTNETTRUNKFACTORY *pIfFactory));
875
876 /**
877 * Create an instance for the specfied host interface and connects it
878 * to the internal network trunk port.
879 *
880 * The initial interface active state is false (suspended).
881 *
882 *
883 * @returns VBox status code.
884 * @retval VINF_SUCCESS and *ppIfPort set on success.
885 * @retval VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
886 * @retval VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
887 * @retval VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
888 *
889 * @param pIfFactory Pointer to this structure.
890 * @param pszName The interface name (OS specific).
891 * @param pSwitchPort Pointer to the port interface on the switch that
892 * this interface is being connected to.
893 * @param fFlags Creation flags, see below.
894 * @param ppIfPort Where to store the pointer to the interface port
895 * on success.
896 *
897 * @remarks Called while owning the network and the out-bound trunk semaphores.
898 */
899 DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
900 PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags,
901 PINTNETTRUNKIFPORT *ppIfPort));
902} INTNETTRUNKFACTORY;
903/** Pointer to the trunk factory. */
904typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
905
906/** The UUID for the (current) trunk factory. (case sensitive) */
907#define INTNETTRUNKFACTORY_UUID_STR "de504d93-1d1e-4781-8b73-6ea39a0e36a2"
908
909/** @name INTNETTRUNKFACTORY::pfnCreateAndConnect flags.
910 * @{ */
911/** Don't put the filtered interface in promiscuous mode.
912 * This is used for wireless interface since these can misbehave if
913 * we try to put them in promiscuous mode. (Wireless interfaces are
914 * normally bridged on level 3 instead of level 2.) */
915#define INTNETTRUNKFACTORY_FLAG_NO_PROMISC RT_BIT_32(0)
916/** @} */
917
918
919/**
920 * The trunk connection type.
921 *
922 * Used by IntNetR0Open and associated interfaces.
923 */
924typedef enum INTNETTRUNKTYPE
925{
926 /** Invalid trunk type. */
927 kIntNetTrunkType_Invalid = 0,
928 /** No trunk connection. */
929 kIntNetTrunkType_None,
930 /** We don't care which kind of trunk connection if the network exists,
931 * if it doesn't exist create it without a connection. */
932 kIntNetTrunkType_WhateverNone,
933 /** VirtualBox host network interface filter driver.
934 * The trunk name is the name of the host network interface. */
935 kIntNetTrunkType_NetFlt,
936 /** VirtualBox adapter host driver. */
937 kIntNetTrunkType_NetAdp,
938 /** Nat service (ring-0). */
939 kIntNetTrunkType_SrvNat,
940 /** The end of valid types. */
941 kIntNetTrunkType_End,
942 /** The usual 32-bit hack. */
943 kIntNetTrunkType_32bitHack = 0x7fffffff
944} INTNETTRUNKTYPE;
945
946/** @name IntNetR0Open flags.
947 *
948 * The desired policy options must be specified explicitly, if omitted it is
949 * understood that whatever is current or default is fine with the caller.
950 *
951 * @todo Move the policies out of the flags, use three new parameters.
952 *
953 * @{ */
954/** Share the MAC address with the host when sending something to the wire via the trunk.
955 * This is typically used when the trunk is a NetFlt for a wireless interface. */
956#define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE RT_BIT_32(0)
957/** Require that the current security and promiscuous policies of the network
958 * is exactly as the ones specified in this open network request.
959 *
960 * Use this with INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES to prevent
961 * restrictions from being lifted. If no further policy changes are desired,
962 * apply the relevant _FIXED flags. */
963#define INTNET_OPEN_FLAGS_REQUIRE_EXACT RT_BIT_32(1)
964/** Require that the security and promiscuous policies of the network is at
965 * least as restrictive as specified this request specifies and prevent them
966 * being lifted later on. */
967#define INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES RT_BIT_32(2)
968
969/** Network access policy: Fixed if set, changable if clear. */
970#define INTNET_OPEN_FLAGS_ACCESS_FIXED RT_BIT_32(3)
971/** Network access policy: Public network. */
972#define INTNET_OPEN_FLAGS_ACCESS_PUBLIC RT_BIT_32(4)
973/** Network access policy: Restricted network. */
974#define INTNET_OPEN_FLAGS_ACCESS_RESTRICTED RT_BIT_32(5)
975
976/** Promiscuous mode policy: Is it fixed or changable by new participants? */
977#define INTNET_OPEN_FLAGS_PROMISC_FIXED RT_BIT_32(6)
978/** Promiscuous mode policy: Allow the clients to request it. */
979#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS RT_BIT_32(7)
980/** Promiscuous mode policy: Deny the clients from requesting it. */
981#define INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS RT_BIT_32(8)
982/** Promiscuous mode policy: Allow the trunk-host to request it. */
983#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST RT_BIT_32(9)
984/** Promiscuous mode policy: Deny the trunk-host from requesting it. */
985#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST RT_BIT_32(10)
986/** Promiscuous mode policy: Allow the trunk-wire to request it. */
987#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE RT_BIT_32(11)
988/** Promiscuous mode policy: Deny the trunk-wire from requesting it. */
989#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE RT_BIT_32(12)
990
991/** Interface policies: Is it fixed or changable (by admin).
992 * @note Per interface, not network wide. */
993#define INTNET_OPEN_FLAGS_IF_FIXED RT_BIT_32(13)
994/** Interface promiscuous mode policy: Allow the interface to request it. */
995#define INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW RT_BIT_32(14)
996/** Interface promiscuous mode policy: Deny the interface from requesting it. */
997#define INTNET_OPEN_FLAGS_IF_PROMISC_DENY RT_BIT_32(15)
998/** Interface promiscuous mode policy: See unrelated trunk traffic. */
999#define INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK RT_BIT_32(16)
1000/** Interface promiscuous mode policy: No unrelated trunk traffic visible. */
1001#define INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK RT_BIT_32(17)
1002
1003/** Trunk policy: Fixed if set, changable if clear.
1004 * @remarks The DISABLED options are considered more restrictive by
1005 * INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES. */
1006#define INTNET_OPEN_FLAGS_TRUNK_FIXED RT_BIT_32(18)
1007/** Trunk policy: The host end should be enabled. */
1008#define INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED RT_BIT_32(19)
1009/** Trunk policy: The host end should be disabled. */
1010#define INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED RT_BIT_32(20)
1011/** Trunk policy: The host should only see packets destined for it. */
1012#define INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE RT_BIT_32(21)
1013/** Trunk policy: The host should see all packets. */
1014#define INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE RT_BIT_32(22)
1015/** Trunk policy: The wire end should be enabled. */
1016#define INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED RT_BIT_32(23)
1017/** Trunk policy: The wire end should be disabled. */
1018#define INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED RT_BIT_32(24)
1019/** Trunk policy: The wire should only see packets destined for it. */
1020#define INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE RT_BIT_32(25)
1021/** Trunk policy: The wire should see all packets. */
1022#define INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE RT_BIT_32(26)
1023
1024/** Used to enable host specific workarounds.
1025 *
1026 * On darwin this will clear ip_tos in DHCP packets when
1027 * INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE is also set. */
1028#define INTNET_OPEN_FLAGS_WORKAROUND_1 RT_BIT_32(31)
1029
1030
1031/** The mask of valid flags. */
1032#define INTNET_OPEN_FLAGS_MASK UINT32_C(0x83ffffff)
1033/** The mask of all flags use to fix (lock) settings. */
1034#define INTNET_OPEN_FLAGS_FIXED_MASK \
1035 ( INTNET_OPEN_FLAGS_ACCESS_FIXED \
1036 | INTNET_OPEN_FLAGS_PROMISC_FIXED \
1037 | INTNET_OPEN_FLAGS_IF_FIXED \
1038 | INTNET_OPEN_FLAGS_TRUNK_FIXED )
1039
1040/** The mask of all policy pairs. */
1041#define INTNET_OPEN_FLAGS_PAIR_MASK \
1042 ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC | INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
1043 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
1044 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
1045 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
1046 | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
1047 | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
1048 | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
1049 | INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
1050 | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
1051 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
1052 )
1053/** The mask of all relaxed policy bits. */
1054#define INTNET_OPEN_FLAGS_RELAXED_MASK \
1055 ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC \
1056 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS \
1057 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST \
1058 | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE \
1059 | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW \
1060 | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK \
1061 | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED \
1062 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
1063 | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED \
1064 | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
1065 )
1066/** The mask of all strict policy bits. */
1067#define INTNET_OPEN_FLAGS_STRICT_MASK \
1068 ( INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
1069 | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
1070 | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
1071 | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
1072 | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
1073 | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
1074 | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
1075 | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
1076 | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
1077 | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
1078 )
1079/** @} */
1080
1081/** The maximum length of a network name. */
1082#define INTNET_MAX_NETWORK_NAME 128
1083
1084/** The maximum length of a trunk name. */
1085#define INTNET_MAX_TRUNK_NAME 64
1086
1087
1088/**
1089 * Request buffer for IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN.
1090 * @see IntNetR0Open.
1091 */
1092typedef struct INTNETOPENREQ
1093{
1094 /** The request header. */
1095 SUPVMMR0REQHDR Hdr;
1096 /** Alternative to passing the taking the session from the VM handle.
1097 * Either use this member or use the VM handle, don't do both. */
1098 PSUPDRVSESSION pSession;
1099 /** The network name. (input) */
1100 char szNetwork[INTNET_MAX_NETWORK_NAME];
1101 /** What to connect to the trunk port. (input)
1102 * This is specific to the trunk type below. */
1103 char szTrunk[INTNET_MAX_TRUNK_NAME];
1104 /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
1105 INTNETTRUNKTYPE enmTrunkType;
1106 /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
1107 uint32_t fFlags;
1108 /** The size of the send buffer. (input) */
1109 uint32_t cbSend;
1110 /** The size of the receive buffer. (input) */
1111 uint32_t cbRecv;
1112 /** The handle to the network interface. (output) */
1113 INTNETIFHANDLE hIf;
1114} INTNETOPENREQ;
1115/** Pointer to an IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
1116typedef INTNETOPENREQ *PINTNETOPENREQ;
1117
1118INTNETR0DECL(int) IntNetR0OpenReq(PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
1119
1120
1121/**
1122 * Request buffer for IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
1123 * @see IntNetR0IfClose.
1124 */
1125typedef struct INTNETIFCLOSEREQ
1126{
1127 /** The request header. */
1128 SUPVMMR0REQHDR Hdr;
1129 /** Alternative to passing the taking the session from the VM handle.
1130 * Either use this member or use the VM handle, don't do both. */
1131 PSUPDRVSESSION pSession;
1132 /** The handle to the network interface. */
1133 INTNETIFHANDLE hIf;
1134} INTNETIFCLOSEREQ;
1135/** Pointer to an IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request
1136 * buffer. */
1137typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
1138
1139INTNETR0DECL(int) IntNetR0IfCloseReq(PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
1140
1141
1142/**
1143 * Request buffer for IntNetR0IfGetRing3BufferReq /
1144 * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS.
1145 * @see IntNetR0IfGetRing3Buffer.
1146 */
1147typedef struct INTNETIFGETBUFFERPTRSREQ
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 pointer to the ring-3 buffer. (output) */
1157 R3PTRTYPE(PINTNETBUF) pRing3Buf;
1158 /** The pointer to the ring-0 buffer. (output) */
1159 R0PTRTYPE(PINTNETBUF) pRing0Buf;
1160} INTNETIFGETBUFFERPTRSREQ;
1161/** Pointer to an IntNetR0IfGetRing3BufferReq /
1162 * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS request buffer. */
1163typedef INTNETIFGETBUFFERPTRSREQ *PINTNETIFGETBUFFERPTRSREQ;
1164
1165INTNETR0DECL(int) IntNetR0IfGetBufferPtrsReq(PSUPDRVSESSION pSession, PINTNETIFGETBUFFERPTRSREQ pReq);
1166
1167
1168/**
1169 * Request buffer for IntNetR0IfSetPromiscuousModeReq /
1170 * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
1171 * @see IntNetR0IfSetPromiscuousMode.
1172 */
1173typedef struct INTNETIFSETPROMISCUOUSMODEREQ
1174{
1175 /** The request header. */
1176 SUPVMMR0REQHDR Hdr;
1177 /** Alternative to passing the taking the session from the VM handle.
1178 * Either use this member or use the VM handle, don't do both. */
1179 PSUPDRVSESSION pSession;
1180 /** Handle to the interface. */
1181 INTNETIFHANDLE hIf;
1182 /** The new promiscuous mode. */
1183 bool fPromiscuous;
1184} INTNETIFSETPROMISCUOUSMODEREQ;
1185/** Pointer to an IntNetR0IfSetPromiscuousModeReq /
1186 * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
1187typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
1188
1189INTNETR0DECL(int) IntNetR0IfSetPromiscuousModeReq(PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
1190
1191
1192/**
1193 * Request buffer for IntNetR0IfSetMacAddressReq /
1194 * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
1195 * @see IntNetR0IfSetMacAddress.
1196 */
1197typedef struct INTNETIFSETMACADDRESSREQ
1198{
1199 /** The request header. */
1200 SUPVMMR0REQHDR Hdr;
1201 /** Alternative to passing the taking the session from the VM handle.
1202 * Either use this member or use the VM handle, don't do both. */
1203 PSUPDRVSESSION pSession;
1204 /** Handle to the interface. */
1205 INTNETIFHANDLE hIf;
1206 /** The new MAC address. */
1207 RTMAC Mac;
1208} INTNETIFSETMACADDRESSREQ;
1209/** Pointer to an IntNetR0IfSetMacAddressReq /
1210 * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
1211typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
1212
1213INTNETR0DECL(int) IntNetR0IfSetMacAddressReq(PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
1214
1215
1216/**
1217 * Request buffer for IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
1218 * @see IntNetR0IfSetActive.
1219 */
1220typedef struct INTNETIFSETACTIVEREQ
1221{
1222 /** The request header. */
1223 SUPVMMR0REQHDR Hdr;
1224 /** Alternative to passing the taking the session from the VM handle.
1225 * Either use this member or use the VM handle, don't do both. */
1226 PSUPDRVSESSION pSession;
1227 /** Handle to the interface. */
1228 INTNETIFHANDLE hIf;
1229 /** The new state. */
1230 bool fActive;
1231} INTNETIFSETACTIVEREQ;
1232/** Pointer to an IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE
1233 * request buffer. */
1234typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
1235
1236INTNETR0DECL(int) IntNetR0IfSetActiveReq(PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
1237
1238
1239/**
1240 * Request buffer for IntNetR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
1241 * @see IntNetR0IfSend.
1242 */
1243typedef struct INTNETIFSENDREQ
1244{
1245 /** The request header. */
1246 SUPVMMR0REQHDR Hdr;
1247 /** Alternative to passing the taking the session from the VM handle.
1248 * Either use this member or use the VM handle, don't do both. */
1249 PSUPDRVSESSION pSession;
1250 /** Handle to the interface. */
1251 INTNETIFHANDLE hIf;
1252} INTNETIFSENDREQ;
1253/** Pointer to an IntNetR0IfSend() argument package. */
1254typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
1255
1256INTNETR0DECL(int) IntNetR0IfSendReq(PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
1257
1258
1259/**
1260 * Request buffer for IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
1261 * @see IntNetR0IfWait.
1262 */
1263typedef struct INTNETIFWAITREQ
1264{
1265 /** The request header. */
1266 SUPVMMR0REQHDR Hdr;
1267 /** Alternative to passing the taking the session from the VM handle.
1268 * Either use this member or use the VM handle, don't do both. */
1269 PSUPDRVSESSION pSession;
1270 /** Handle to the interface. */
1271 INTNETIFHANDLE hIf;
1272 /** The number of milliseconds to wait. */
1273 uint32_t cMillies;
1274} INTNETIFWAITREQ;
1275/** Pointer to an IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
1276typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
1277
1278INTNETR0DECL(int) IntNetR0IfWaitReq(PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
1279
1280
1281/**
1282 * Request buffer for IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT.
1283 * @see IntNetR0IfAbortWait.
1284 */
1285typedef struct INTNETIFABORTWAITREQ
1286{
1287 /** The request header. */
1288 SUPVMMR0REQHDR Hdr;
1289 /** Alternative to passing the taking the session from the VM handle.
1290 * Either use this member or use the VM handle, don't do both. */
1291 PSUPDRVSESSION pSession;
1292 /** Handle to the interface. */
1293 INTNETIFHANDLE hIf;
1294 /** Set this to fend off all future IntNetR0Wait calls. */
1295 bool fNoMoreWaits;
1296} INTNETIFABORTWAITREQ;
1297/** Pointer to an IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT
1298 * request buffer. */
1299typedef INTNETIFABORTWAITREQ *PINTNETIFABORTWAITREQ;
1300
1301INTNETR0DECL(int) IntNetR0IfAbortWaitReq(PSUPDRVSESSION pSession, PINTNETIFABORTWAITREQ pReq);
1302
1303
1304#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
1305/** @name
1306 * @{
1307 */
1308
1309INTNETR0DECL(int) IntNetR0Init(void);
1310INTNETR0DECL(void) IntNetR0Term(void);
1311INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork,
1312 INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
1313 uint32_t cbSend, uint32_t cbRecv, PINTNETIFHANDLE phIf);
1314INTNETR0DECL(uint32_t) IntNetR0GetNetworkCount(void);
1315
1316INTNETR0DECL(int) IntNetR0IfClose(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1317INTNETR0DECL(int) IntNetR0IfGetBufferPtrs(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession,
1318 R3PTRTYPE(PINTNETBUF) *ppRing3Buf, R0PTRTYPE(PINTNETBUF) *ppRing0Buf);
1319INTNETR0DECL(int) IntNetR0IfSetPromiscuousMode(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous);
1320INTNETR0DECL(int) IntNetR0IfSetMacAddress(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCRTMAC pMac);
1321INTNETR0DECL(int) IntNetR0IfSetActive(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive);
1322INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1323INTNETR0DECL(int) IntNetR0IfWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies);
1324INTNETR0DECL(int) IntNetR0IfAbortWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
1325
1326/** @} */
1327#endif /* IN_RING0 */
1328
1329/**
1330 * Callback function for use with IntNetR3Open to signalling incoming data.
1331 *
1332 * @param hIf Interface handle.
1333 * @param pvUser User parameter.
1334 */
1335typedef DECLCALLBACKTYPE(void, FNINTNETIFRECVAVAIL,(INTNETIFHANDLE hIf, void *pvUser));
1336/** Pointer to a FNINTNETIFRECVAVAIL callback. */
1337typedef FNINTNETIFRECVAVAIL *PFNINTNETIFRECVAVAIL;
1338
1339#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
1340INTNETR3DECL(int) IntNetR3Open(PSUPDRVSESSION pSession, const char *pszNetwork,
1341 INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
1342 uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail,
1343 void *pvUserRecvAvail, PINTNETIFHANDLE phIf);
1344#endif
1345
1346RT_C_DECLS_END
1347
1348#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