VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NetLib/VBoxNetIntIf.cpp@ 97078

Last change on this file since 97078 was 96407, checked in by vboxsync, 2 years 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: 4.4 KB
Line 
1/* $Id: VBoxNetIntIf.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * VBoxNetIntIf - IntNet Interface Client Routines.
4 */
5
6/*
7 * Copyright (C) 2009-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DEFAULT
33#include "VBoxNetLib.h"
34#include <VBox/intnet.h>
35#include <VBox/intnetinline.h>
36#include <VBox/sup.h>
37#include <VBox/vmm/vmm.h>
38#include <iprt/errcore.h>
39#include <VBox/log.h>
40
41#include <iprt/string.h>
42
43
44
45/**
46 * Flushes the send buffer.
47 *
48 * @returns VBox status code.
49 * @param pSession The support driver session.
50 * @param hIf The interface handle to flush.
51 */
52int VBoxNetIntIfFlush(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf)
53{
54 INTNETIFSENDREQ SendReq;
55 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
56 SendReq.Hdr.cbReq = sizeof(SendReq);
57 SendReq.pSession = pSession;
58 SendReq.hIf = hIf;
59 return SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
60}
61
62
63/**
64 * Copys the SG segments into the specified fram.
65 *
66 * @param pvFrame The frame buffer.
67 * @param cSegs The number of segments.
68 * @param paSegs The segments.
69 */
70static void vboxnetIntIfCopySG(void *pvFrame, size_t cSegs, PCINTNETSEG paSegs)
71{
72 uint8_t *pbDst = (uint8_t *)pvFrame;
73 for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
74 {
75 memcpy(pbDst, paSegs[iSeg].pv, paSegs[iSeg].cb);
76 pbDst += paSegs[iSeg].cb;
77 }
78}
79
80
81/**
82 * Writes a frame packet to the buffer.
83 *
84 * @returns VBox status code.
85 * @param pBuf The buffer.
86 * @param pRingBuf The ring buffer to read from.
87 * @param cSegs The number of segments.
88 * @param paSegs The segments.
89 */
90int VBoxNetIntIfRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, size_t cSegs, PCINTNETSEG paSegs)
91{
92 RT_NOREF(pBuf);
93
94 /*
95 * Validate input.
96 */
97 AssertPtr(pBuf);
98 AssertPtr(pRingBuf);
99 AssertPtr(paSegs);
100 Assert(cSegs > 0);
101
102 /*
103 * Calc frame size.
104 */
105 uint32_t cbFrame = 0;
106 for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
107 cbFrame += paSegs[iSeg].cb;
108 Assert(cbFrame >= sizeof(RTMAC) * 2);
109
110 /*
111 * Allocate a frame, copy the data and commit it.
112 */
113 PINTNETHDR pHdr = NULL;
114 void *pvFrame = NULL;
115 int rc = IntNetRingAllocateFrame(pRingBuf, cbFrame, &pHdr, &pvFrame);
116 if (RT_SUCCESS(rc))
117 {
118 vboxnetIntIfCopySG(pvFrame, cSegs, paSegs);
119 IntNetRingCommitFrame(pRingBuf, pHdr);
120 return VINF_SUCCESS;
121 }
122
123 return rc;
124}
125
126
127/**
128 * Sends a frame
129 *
130 * @returns VBox status code.
131 * @param pSession The support driver session.
132 * @param hIf The interface handle.
133 * @param pBuf The interface buffer.
134 * @param cSegs The number of segments.
135 * @param paSegs The segments.
136 * @param fFlush Whether to flush the write.
137 */
138int VBoxNetIntIfSend(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf,
139 size_t cSegs, PCINTNETSEG paSegs, bool fFlush)
140{
141 int rc = VBoxNetIntIfRingWriteFrame(pBuf, &pBuf->Send, cSegs, paSegs);
142 if (rc == VERR_BUFFER_OVERFLOW)
143 {
144 VBoxNetIntIfFlush(pSession, hIf);
145 rc = VBoxNetIntIfRingWriteFrame(pBuf, &pBuf->Send, cSegs, paSegs);
146 }
147 if (RT_SUCCESS(rc) && fFlush)
148 rc = VBoxNetIntIfFlush(pSession, hIf);
149 return rc;
150}
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