VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 22 months ago

scm copyright and license note update

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

© 2023 Oracle
ContactPrivacy policyTerms of Use