VirtualBox

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

Last change on this file since 57753 was 56839, checked in by vboxsync, 9 years ago

IntNet: Note that INTNETTRUNKSWPORT_VERSION 0xA2CDf005 will be
consumed on 4.x branches and should not be used on the trunk.

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