Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-ports-gnome
Path: blob/main/emulators/virtualbox-ose/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c
17359 views
1
--- src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c.orig 2021-01-07 15:41:28 UTC
2
+++ src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
3
@@ -52,6 +52,7 @@
4
#include <net/if_dl.h>
5
#include <net/if_types.h>
6
#include <net/ethernet.h>
7
+#include <net/if_vlan_var.h>
8
9
#include <netgraph/ng_message.h>
10
#include <netgraph/netgraph.h>
11
@@ -73,6 +74,7 @@
12
13
#define VBOXNETFLT_OS_SPECFIC 1
14
#include "../VBoxNetFltInternal.h"
15
+#include "freebsd/the-freebsd-kernel.h"
16
17
static int vboxnetflt_modevent(struct module *, int, void *);
18
static ng_constructor_t ng_vboxnetflt_constructor;
19
@@ -361,7 +363,14 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p i
20
{
21
if (mtag != NULL || !fActive)
22
{
23
+#if __FreeBSD_version >= 1300049
24
+ struct epoch_tracker et;
25
+ NET_EPOCH_ENTER(et);
26
+#endif
27
ether_demux(ifp, m);
28
+#if __FreeBSD_version >= 1300049
29
+ NET_EPOCH_EXIT(et);
30
+#endif
31
if (fActive)
32
vboxNetFltRelease(pThis, true /*fBusy*/);
33
VBOXCURVNET_RESTORE();
34
@@ -436,6 +445,8 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend
35
struct ifnet *ifp = pThis->u.s.ifp;
36
unsigned int cSegs = 0;
37
bool fDropIt = false, fActive;
38
+ bool is_vl_tagged = false;
39
+ uint16_t vl_tag;
40
PINTNETSG pSG;
41
42
VBOXCURVNET_SET(ifp->if_vnet);
43
@@ -448,6 +459,19 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend
44
if (m == NULL)
45
break;
46
47
+ /* Prepend a VLAN header for consumption by the virtual switch */
48
+ if (m->m_flags & M_VLANTAG) {
49
+ vl_tag = m->m_pkthdr.ether_vtag;
50
+ is_vl_tagged = true;
51
+
52
+ m = ether_vlanencap(m, m->m_pkthdr.ether_vtag);
53
+ if (m == NULL) {
54
+ printf("vboxflt: unable to prepend VLAN header\n");
55
+ break;
56
+ }
57
+ m->m_flags &= ~M_VLANTAG;
58
+ }
59
+
60
for (m0 = m; m0 != NULL; m0 = m0->m_next)
61
if (m0->m_len > 0)
62
cSegs++;
63
@@ -462,10 +486,39 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend
64
vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
65
fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_WIRE);
66
RTMemTmpFree(pSG);
67
+
68
+ /* Restore the VLAN flags before re-injecting the packet */
69
+ if (is_vl_tagged && !fDropIt) {
70
+ struct ether_vlan_header *vl_hdr;
71
+
72
+ /* This shouldn't fail, as the header was just prepended */
73
+ if (m->m_len < sizeof(*vl_hdr) && (m = m_pullup(m, sizeof(*vl_hdr))) == NULL) {
74
+ printf("vboxflt: unable to pullup VLAN header\n");
75
+ m_freem(m);
76
+ break;
77
+ }
78
+
79
+ /* Copy the MAC dhost/shost over the 802.1q field */
80
+ vl_hdr = mtod(m, struct ether_vlan_header *);
81
+ bcopy((char *)vl_hdr, (char *)vl_hdr + ETHER_VLAN_ENCAP_LEN, ETHER_HDR_LEN - ETHER_TYPE_LEN);
82
+ m_adj(m, ETHER_VLAN_ENCAP_LEN);
83
+
84
+ m->m_pkthdr.ether_vtag = vl_tag;
85
+ m->m_flags |= M_VLANTAG;
86
+ }
87
+
88
if (fDropIt)
89
m_freem(m);
90
- else
91
+ else {
92
+#if __FreeBSD_version >= 1300049
93
+ struct epoch_tracker et;
94
+ NET_EPOCH_ENTER(et);
95
+#endif
96
ether_demux(ifp, m);
97
+#if __FreeBSD_version >= 1300049
98
+ NET_EPOCH_EXIT(et);
99
+#endif
100
+ }
101
}
102
vboxNetFltRelease(pThis, true /* fBusy */);
103
VBOXCURVNET_RESTORE();
104
@@ -521,6 +574,7 @@ static void vboxNetFltFreeBSDoutput(void *arg, int pen
105
*/
106
int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst)
107
{
108
+ IPRT_FREEBSD_SAVE_EFL_AC();
109
NOREF(pvIfData);
110
111
void (*input_f)(struct ifnet *, struct mbuf *);
112
@@ -537,10 +591,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p
113
{
114
m = vboxNetFltFreeBSDSGMBufFromSG(pThis, pSG);
115
if (m == NULL)
116
+ {
117
+ IPRT_FREEBSD_RESTORE_EFL_AC();
118
return VERR_NO_MEMORY;
119
+ }
120
m = m_pullup(m, ETHER_HDR_LEN);
121
if (m == NULL)
122
+ {
123
+ IPRT_FREEBSD_RESTORE_EFL_AC();
124
return VERR_NO_MEMORY;
125
+ }
126
127
m->m_flags |= M_PKTHDR;
128
ether_output_frame(ifp, m);
129
@@ -550,10 +610,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p
130
{
131
m = vboxNetFltFreeBSDSGMBufFromSG(pThis, pSG);
132
if (m == NULL)
133
+ {
134
+ IPRT_FREEBSD_RESTORE_EFL_AC();
135
return VERR_NO_MEMORY;
136
+ }
137
m = m_pullup(m, ETHER_HDR_LEN);
138
if (m == NULL)
139
+ {
140
+ IPRT_FREEBSD_RESTORE_EFL_AC();
141
return VERR_NO_MEMORY;
142
+ }
143
/*
144
* Delivering packets to the host will be captured by the
145
* input hook. Tag the packet with a mbuf tag so that we
146
@@ -564,6 +630,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p
147
if (mtag == NULL)
148
{
149
m_freem(m);
150
+ IPRT_FREEBSD_RESTORE_EFL_AC();
151
return VERR_NO_MEMORY;
152
}
153
154
@@ -574,6 +641,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p
155
ifp->if_input(ifp, m);
156
}
157
VBOXCURVNET_RESTORE();
158
+ IPRT_FREEBSD_RESTORE_EFL_AC();
159
return VINF_SUCCESS;
160
}
161
162
@@ -586,6 +654,7 @@ static bool vboxNetFltFreeBsdIsPromiscuous(PVBOXNETFLT
163
164
int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
165
{
166
+ IPRT_FREEBSD_SAVE_EFL_AC();
167
char nam[NG_NODESIZ];
168
struct ifnet *ifp;
169
node_p node;
170
@@ -594,7 +663,10 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, voi
171
NOREF(pvContext);
172
ifp = ifunit(pThis->szName);
173
if (ifp == NULL)
174
+ {
175
+ IPRT_FREEBSD_RESTORE_EFL_AC();
176
return VERR_INTNET_FLT_IF_NOT_FOUND;
177
+ }
178
179
/* Create a new netgraph node for this instance */
180
if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0)
181
@@ -638,12 +710,14 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, voi
182
vboxNetFltRelease(pThis, true /*fBusy*/);
183
}
184
VBOXCURVNET_RESTORE();
185
+ IPRT_FREEBSD_RESTORE_EFL_AC();
186
187
return VINF_SUCCESS;
188
}
189
190
bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
191
{
192
+ IPRT_FREEBSD_SAVE_EFL_AC();
193
struct ifnet *ifp, *ifp0;
194
195
ifp = ASMAtomicUoReadPtrT(&pThis->u.s.ifp, struct ifnet *);
196
@@ -660,6 +734,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThi
197
pThis->u.s.node = NULL;
198
}
199
VBOXCURVNET_RESTORE();
200
+ IPRT_FREEBSD_RESTORE_EFL_AC();
201
202
if (ifp0 != NULL)
203
{
204
@@ -672,6 +747,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThi
205
206
void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
207
{
208
+ IPRT_FREEBSD_SAVE_EFL_AC();
209
210
taskqueue_drain(taskqueue_fast, &pThis->u.s.tskin);
211
taskqueue_drain(taskqueue_fast, &pThis->u.s.tskout);
212
@@ -684,6 +760,7 @@ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
213
ng_rmnode_self(pThis->u.s.node);
214
VBOXCURVNET_RESTORE();
215
pThis->u.s.node = NULL;
216
+ IPRT_FREEBSD_RESTORE_EFL_AC();
217
}
218
219
int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
220
@@ -697,6 +774,7 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
221
222
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
223
{
224
+ IPRT_FREEBSD_SAVE_EFL_AC();
225
struct ifnet *ifp;
226
struct ifreq ifreq;
227
int error;
228
@@ -730,7 +808,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b
229
NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_CONNECT,
230
sizeof(struct ngm_connect), M_NOWAIT);
231
if (msg == NULL)
232
+ {
233
+ IPRT_FREEBSD_RESTORE_EFL_AC();
234
return;
235
+ }
236
con = (struct ngm_connect *)msg->data;
237
snprintf(con->path, NG_PATHSIZ, "vboxnetflt_%s:", ifp->if_xname);
238
strlcpy(con->ourhook, "lower", NG_HOOKSIZ);
239
@@ -744,7 +825,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b
240
NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_CONNECT,
241
sizeof(struct ngm_connect), M_NOWAIT);
242
if (msg == NULL)
243
+ {
244
+ IPRT_FREEBSD_RESTORE_EFL_AC();
245
return;
246
+ }
247
con = (struct ngm_connect *)msg->data;
248
snprintf(con->path, NG_PATHSIZ, "vboxnetflt_%s:",
249
ifp->if_xname);
250
@@ -767,7 +851,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b
251
NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_RMHOOK,
252
sizeof(struct ngm_rmhook), M_NOWAIT);
253
if (msg == NULL)
254
+ {
255
+ IPRT_FREEBSD_RESTORE_EFL_AC();
256
return;
257
+ }
258
rm = (struct ngm_rmhook *)msg->data;
259
strlcpy(rm->ourhook, "input", NG_HOOKSIZ);
260
NG_SEND_MSG_PATH(error, node, msg, path, 0);
261
@@ -778,12 +865,16 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b
262
NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_RMHOOK,
263
sizeof(struct ngm_rmhook), M_NOWAIT);
264
if (msg == NULL)
265
+ {
266
+ IPRT_FREEBSD_RESTORE_EFL_AC();
267
return;
268
+ }
269
rm = (struct ngm_rmhook *)msg->data;
270
strlcpy(rm->ourhook, "output", NG_HOOKSIZ);
271
NG_SEND_MSG_PATH(error, node, msg, path, 0);
272
}
273
VBOXCURVNET_RESTORE();
274
+ IPRT_FREEBSD_RESTORE_EFL_AC();
275
}
276
277
int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
278
279