VirtualBox

Ticket #11863: diff_intnet_4_1

File diff_intnet_4_1, 25.5 KB (added by Frank Mehnert, 11 years ago)

Patch for VBox 4.1.26 (included in VBox 4.1.28)

Line 
1Index: include/VBox/intnetinline.h
2===================================================================
3--- include/VBox/intnetinline.h (revision 87022)
4+++ include/VBox/intnetinline.h (revision 87027)
5@@ -43,13 +43,13 @@
6 * Valid internal networking frame type.
7 *
8 * @returns true / false.
9- * @param u16Type The frame type to check.
10+ * @param u8Type The frame type to check.
11 */
12-DECLINLINE(bool) IntNetIsValidFrameType(uint16_t u16Type)
13+DECLINLINE(bool) IntNetIsValidFrameType(uint8_t u8Type)
14 {
15- if (RT_LIKELY( u16Type == INTNETHDR_TYPE_FRAME
16- || u16Type == INTNETHDR_TYPE_GSO
17- || u16Type == INTNETHDR_TYPE_PADDING))
18+ if (RT_LIKELY( u8Type == INTNETHDR_TYPE_FRAME
19+ || u8Type == INTNETHDR_TYPE_GSO
20+ || u8Type == INTNETHDR_TYPE_PADDING))
21 return true;
22 return false;
23 }
24@@ -327,7 +327,7 @@
25 uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame;
26 #ifdef VBOX_STRICT
27 const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
28- Assert(IntNetIsValidFrameType(pHdr->u16Type));
29+ Assert(IntNetIsValidFrameType(pHdr->u8Type));
30 Assert(off < pBuf->cbBuf);
31 Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
32 #endif
33@@ -353,7 +353,7 @@
34 PPDMNETWORKGSO pGso = (PPDMNETWORKGSO)((uint8_t *)pHdr + pHdr->offFrame);
35 #ifdef VBOX_STRICT
36 const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf;
37- Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO);
38+ Assert(pHdr->u8Type == INTNETHDR_TYPE_GSO);
39 Assert(off < pBuf->cbBuf);
40 Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
41 #endif
42@@ -374,7 +374,7 @@
43 Assert(offReadOld >= pRingBuf->offStart);
44 Assert(offReadOld < pRingBuf->offEnd);
45 Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr);
46- Assert(IntNetIsValidFrameType(pHdr->u16Type));
47+ Assert(IntNetIsValidFrameType(pHdr->u8Type));
48
49 /* skip the frame */
50 uint32_t offReadNew = offReadOld + pHdr->offFrame + pHdr->cbFrame;
51@@ -401,7 +401,7 @@
52 * Don't touch this!
53 * @param ppvFrame Where to return the frame pointer.
54 */
55-DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type,
56+DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint8_t u8Type,
57 PINTNETHDR *ppHdr, void **ppvFrame)
58 {
59 /*
60@@ -425,11 +425,11 @@
61 offNew = pRingBuf->offStart;
62 if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
63 return VERR_WRONG_ORDER; /* race */
64- Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
65+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
66
67 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
68- pHdr->u16Type = u16Type;
69- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
70+ pHdr->u8Type = u8Type;
71+ pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame);
72 pHdr->offFrame = sizeof(INTNETHDR);
73
74 *ppHdr = pHdr;
75@@ -446,11 +446,11 @@
76 uint32_t offNew = pRingBuf->offStart + cb;
77 if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
78 return VERR_WRONG_ORDER; /* race */
79- Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
80+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
81
82 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
83- pHdr->u16Type = u16Type;
84- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
85+ pHdr->u8Type = u8Type;
86+ pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame);
87 pHdr->offFrame = pRingBuf->offStart - offWriteInt;
88
89 *ppHdr = pHdr;
90@@ -466,11 +466,11 @@
91 uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR);
92 if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
93 return VERR_WRONG_ORDER; /* race */
94- Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
95+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
96
97 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
98- pHdr->u16Type = u16Type;
99- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
100+ pHdr->u8Type = u8Type;
101+ pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame);
102 pHdr->offFrame = sizeof(INTNETHDR);
103
104 *ppHdr = pHdr;
105@@ -560,7 +560,7 @@
106 Assert(offWriteCom == pRingBuf->offEnd);
107 offWriteCom = pRingBuf->offStart;
108 }
109- Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, cbFrame));
110+ Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, cbFrame));
111 ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
112 STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
113 STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
114@@ -588,7 +588,7 @@
115 INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf);
116 Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf));
117
118- if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
119+ if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
120 cbUsed += sizeof(PDMNETWORKGSO);
121
122 /*
123@@ -612,13 +612,14 @@
124 {
125 /** @todo Later: Try unallocate the extra memory. */
126 PINTNETHDR pHdrPadding = (PINTNETHDR)((uint8_t *)pHdr + pHdr->offFrame + cbAlignedUsed);
127- pHdrPadding->u16Type = INTNETHDR_TYPE_PADDING;
128- pHdrPadding->cbFrame = (uint16_t)(cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR));
129+ pHdrPadding->u8Type = INTNETHDR_TYPE_PADDING;
130+ pHdrPadding->cbFrame = cbAlignedFrame - cbAlignedUsed - (uint32_t)sizeof(INTNETHDR);
131+ Assert(pHdrPadding->cbFrame == cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR));
132 pHdrPadding->offFrame = sizeof(INTNETHDR);
133- pHdr->cbFrame = (uint16_t)cbUsed;
134+ pHdr->cbFrame = (uint32_t)cbUsed; Assert(pHdr->cbFrame == cbUsed);
135 }
136
137- Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed));
138+ Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed));
139 ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
140 STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbUsed);
141 STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
142@@ -664,8 +665,8 @@
143 Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (1)\n", offWriteInt, offNew));
144
145 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
146- pHdr->u16Type = INTNETHDR_TYPE_FRAME;
147- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
148+ pHdr->u8Type = INTNETHDR_TYPE_FRAME;
149+ pHdr->cbFrame = (uint32_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
150 pHdr->offFrame = sizeof(INTNETHDR);
151
152 memcpy(pHdr + 1, pvFrame, cbFrame);
153@@ -689,8 +690,8 @@
154 Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (2)\n", offWriteInt, offNew));
155
156 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
157- pHdr->u16Type = INTNETHDR_TYPE_FRAME;
158- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
159+ pHdr->u8Type = INTNETHDR_TYPE_FRAME;
160+ pHdr->cbFrame = (uint32_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
161 pHdr->offFrame = pRingBuf->offStart - offWriteInt;
162
163 memcpy((uint8_t *)pRingBuf + pRingBuf->offStart, pvFrame, cbFrame);
164@@ -713,8 +714,8 @@
165 Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (3)\n", offWriteInt, offNew));
166
167 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
168- pHdr->u16Type = INTNETHDR_TYPE_FRAME;
169- pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
170+ pHdr->u8Type = INTNETHDR_TYPE_FRAME;
171+ pHdr->cbFrame = (uint32_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
172 pHdr->offFrame = sizeof(INTNETHDR);
173
174 memcpy(pHdr + 1, pvFrame, cbFrame);
175Index: include/VBox/intnet.h
176===================================================================
177--- include/VBox/intnet.h (revision 87022)
178+++ include/VBox/intnet.h (revision 87027)
179@@ -209,11 +209,11 @@
180 */
181 typedef struct INTNETHDR
182 {
183+ /** The size of the frame. */
184+ uint32_t cbFrame : 24;
185 /** Header type. This is currently serving as a magic, it
186 * can be extended later to encode special command frames and stuff. */
187- uint16_t u16Type;
188- /** The size of the frame. */
189- uint16_t cbFrame;
190+ uint32_t u8Type : 8;
191 /** The offset from the start of this header to where the actual frame starts.
192 * This is used to keep the frame it self contiguous in virtual memory and
193 * thereby both simplify access as well as the descriptor. */
194@@ -231,16 +231,16 @@
195 AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT);
196 AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
197
198-/** @name Frame types (INTNETHDR::u16Type).
199+/** @name Frame types (INTNETHDR::u8Type).
200 * @{ */
201 /** Normal frames. */
202-#define INTNETHDR_TYPE_FRAME 0x2442
203+#define INTNETHDR_TYPE_FRAME 0x42
204 /** Padding frames. */
205-#define INTNETHDR_TYPE_PADDING 0x3553
206+#define INTNETHDR_TYPE_PADDING 0x53
207 /** Generic segment offload frames.
208 * The frame starts with a PDMNETWORKGSO structure which is followed by the
209 * header template and data. */
210-#define INTNETHDR_TYPE_GSO 0x4664
211+#define INTNETHDR_TYPE_GSO 0x64
212 AssertCompileSize(PDMNETWORKGSO, 8);
213 /** @} */
214
215@@ -252,9 +252,9 @@
216 { \
217 AssertPtr(pHdr); \
218 Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
219- Assert( (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \
220- || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \
221- || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
222+ Assert( (pHdr)->u8Type == INTNETHDR_TYPE_FRAME \
223+ || (pHdr)->u8Type == INTNETHDR_TYPE_GSO \
224+ || (pHdr)->u8Type == INTNETHDR_TYPE_PADDING); \
225 { \
226 uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
227 uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \
228Index: src/VBox/Devices/Network/SrvIntNetR0.cpp
229===================================================================
230--- src/VBox/Devices/Network/SrvIntNetR0.cpp (revision 87022)
231+++ src/VBox/Devices/Network/SrvIntNetR0.cpp (revision 87027)
232@@ -2664,6 +2664,11 @@
233 } u;
234
235 /*
236+ * @todo: We have to adjust MSS so it does not exceed the value configured
237+ * for the host's interface.
238+ */
239+
240+ /*
241 * Carve out the frame segments with the header and frame in different
242 * scatter / gather segments.
243 */
244@@ -3507,8 +3512,8 @@
245 PINTNETHDR pHdr;
246 while ((pHdr = IntNetRingGetNextFrameToRead(&pIf->pIntBuf->Send)) != NULL)
247 {
248- uint16_t const u16Type = pHdr->u16Type;
249- if (u16Type == INTNETHDR_TYPE_FRAME)
250+ uint8_t const u8Type = pHdr->u8Type;
251+ if (u8Type == INTNETHDR_TYPE_FRAME)
252 {
253 /* Send regular frame. */
254 void *pvCurFrame = IntNetHdrGetFramePtr(pHdr, pIf->pIntBuf);
255@@ -3517,7 +3522,7 @@
256 intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame, false /*fGso*/, (uint16_t *)&Sg.fFlags);
257 enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &Sg, pDstTab);
258 }
259- else if (u16Type == INTNETHDR_TYPE_GSO)
260+ else if (u8Type == INTNETHDR_TYPE_GSO)
261 {
262 /* Send GSO frame if sane. */
263 PPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, pIf->pIntBuf);
264@@ -3539,7 +3544,7 @@
265 /* Unless it's a padding frame, we're getting babble from the producer. */
266 else
267 {
268- if (u16Type != INTNETHDR_TYPE_PADDING)
269+ if (u8Type != INTNETHDR_TYPE_PADDING)
270 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatBadFrames); /* ignore */
271 enmSwDecision = INTNETSWDECISION_DROP;
272 }
273Index: src/VBox/Devices/Network/DrvIntNet.cpp
274===================================================================
275--- src/VBox/Devices/Network/DrvIntNet.cpp (revision 87022)
276+++ src/VBox/Devices/Network/DrvIntNet.cpp (revision 87027)
277@@ -462,12 +462,12 @@
278 #endif
279 Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
280 Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
281- Assert( pHdr->u16Type == INTNETHDR_TYPE_FRAME
282- || pHdr->u16Type == INTNETHDR_TYPE_GSO);
283+ Assert( pHdr->u8Type == INTNETHDR_TYPE_FRAME
284+ || pHdr->u8Type == INTNETHDR_TYPE_GSO);
285 Assert(PDMCritSectIsOwner(&pThis->XmitLock));
286
287 /** @todo LATER: try unalloc the frame. */
288- pHdr->u16Type = INTNETHDR_TYPE_PADDING;
289+ pHdr->u8Type = INTNETHDR_TYPE_PADDING;
290 IntNetRingCommitFrame(&pThis->CTX_SUFF(pBuf)->Send, pHdr);
291
292 #ifdef IN_RING3
293@@ -702,9 +702,9 @@
294 }
295
296 Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offReadX, pHdr));
297- uint16_t u16Type = pHdr->u16Type;
298- if ( ( u16Type == INTNETHDR_TYPE_FRAME
299- || u16Type == INTNETHDR_TYPE_GSO)
300+ uint8_t u8Type = pHdr->u8Type;
301+ if ( ( u8Type == INTNETHDR_TYPE_FRAME
302+ || u8Type == INTNETHDR_TYPE_GSO)
303 && !pThis->fLinkDown)
304 {
305 /*
306@@ -714,7 +714,7 @@
307 int rc = pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, 0);
308 if (rc == VINF_SUCCESS)
309 {
310- if (u16Type == INTNETHDR_TYPE_FRAME)
311+ if (u8Type == INTNETHDR_TYPE_FRAME)
312 {
313 /*
314 * Normal frame.
315@@ -813,7 +813,7 @@
316 /*
317 * NIC is going down, likely because the VM is being reset. Skip the frame.
318 */
319- AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
320+ AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
321 IntNetRingSkipFrame(pRingBuf);
322 }
323 else
324@@ -830,7 +830,7 @@
325 /*
326 * Link down or unknown frame - skip to the next frame.
327 */
328- AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
329+ AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
330 IntNetRingSkipFrame(pRingBuf);
331 STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
332 }
333Index: src/VBox/Devices/Network/DevVirtioNet.cpp
334===================================================================
335--- src/VBox/Devices/Network/DevVirtioNet.cpp (revision 87022)
336+++ src/VBox/Devices/Network/DevVirtioNet.cpp (revision 87027)
337@@ -65,8 +65,8 @@
338 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
339
340
341-#define VNET_TX_DELAY 150 /* 150 microseconds */
342-#define VNET_MAX_FRAME_SIZE 65536 // TODO: Is it the right limit?
343+#define VNET_TX_DELAY 150 /**< 150 microseconds */
344+#define VNET_MAX_FRAME_SIZE 65535 + 18 /**< Max IP packet size + Ethernet header with VLAN tag */
345 #define VNET_MAC_FILTER_LEN 32
346 #define VNET_MAX_VID (1 << 12)
347
348@@ -1155,6 +1155,8 @@
349 /* Compute total frame size. */
350 for (unsigned int i = 1; i < elem.nOut; i++)
351 uSize += elem.aSegsOut[i].cb;
352+ Log5(("%s vnetTransmitPendingPackets: complete frame is %u bytes.\n",
353+ INSTANCE(pThis), uSize));
354 Assert(uSize <= VNET_MAX_FRAME_SIZE);
355 if (pState->pDrv)
356 {
357Index: src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
358===================================================================
359--- src/VBox/Devices/Network/testcase/tstIntNet-1.cpp (revision 87022)
360+++ src/VBox/Devices/Network/testcase/tstIntNet-1.cpp (revision 87027)
361@@ -462,7 +462,7 @@
362 PINTNETHDR pHdr;
363 while ((pHdr = IntNetRingGetNextFrameToRead(pRingBuf)))
364 {
365- if (pHdr->u16Type == INTNETHDR_TYPE_FRAME)
366+ if (pHdr->u8Type == INTNETHDR_TYPE_FRAME)
367 {
368 size_t cbFrame = pHdr->cbFrame;
369 const void *pvFrame = IntNetHdrGetFramePtr(pHdr, pBuf);
370@@ -539,7 +539,7 @@
371 }
372 }
373 }
374- else if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
375+ else if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
376 {
377 PCPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, pBuf);
378 size_t cbFrame = pHdr->cbFrame;
379@@ -567,9 +567,9 @@
380 g_cErrors++;
381 }
382 }
383- else if (pHdr->u16Type != INTNETHDR_TYPE_PADDING)
384+ else if (pHdr->u8Type != INTNETHDR_TYPE_PADDING)
385 {
386- RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u16Type);
387+ RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u8Type);
388 STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
389 g_cErrors++;
390 }
391Index: src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp
392===================================================================
393--- src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp (revision 87022)
394+++ src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp (revision 87027)
395@@ -61,14 +61,14 @@
396 */
397 PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&pBuf->Recv);
398 if ( !pHdr
399- || ( pHdr->u16Type != INTNETHDR_TYPE_FRAME
400- && pHdr->u16Type != INTNETHDR_TYPE_GSO))
401+ || ( pHdr->u8Type != INTNETHDR_TYPE_FRAME
402+ && pHdr->u8Type != INTNETHDR_TYPE_GSO))
403 return NULL;
404
405 size_t cbFrame = pHdr->cbFrame;
406 const void *pvFrame = IntNetHdrGetFramePtr(pHdr, pBuf);
407 PCPDMNETWORKGSO pGso = NULL;
408- if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
409+ if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
410 {
411 pGso = (PCPDMNETWORKGSO)pvFrame;
412 if (!PDMNetGsoIsValid(pGso, cbFrame, cbFrame - sizeof(*pGso)))
413Index: src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp
414===================================================================
415--- src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp (revision 87022)
416+++ src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp (revision 87027)
417@@ -43,7 +43,7 @@
418 */
419 PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&pBuf->Recv);
420 if ( !pHdr
421- || pHdr->u16Type != INTNETHDR_TYPE_FRAME)
422+ || pHdr->u8Type != INTNETHDR_TYPE_FRAME)
423 return false;
424
425 size_t cbFrame = pHdr->cbFrame;
426Index: src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
427===================================================================
428--- src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c (revision 87022)
429+++ src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c (revision 87027)
430@@ -1119,6 +1119,59 @@
431
432
433 /**
434+ * Checks whether this SG list contains a GSO packet.
435+ *
436+ * @returns true / false accordingly.
437+ * @param pSG The (scatter/)gather list.
438+ */
439+DECLINLINE(bool) vboxNetFltLinuxIsGso(PINTNETSG pSG)
440+{
441+#if defined(VBOXNETFLT_WITH_GSO_XMIT_WIRE) || defined(VBOXNETFLT_WITH_GSO_XMIT_HOST)
442+ return !((PDMNETWORKGSOTYPE)pSG->GsoCtx.u8Type == PDMNETWORKGSOTYPE_INVALID);
443+#else /* !VBOXNETFLT_WITH_GSO_XMIT_WIRE && !VBOXNETFLT_WITH_GSO_XMIT_HOST */
444+ return false;
445+#endif /* !VBOXNETFLT_WITH_GSO_XMIT_WIRE && !VBOXNETFLT_WITH_GSO_XMIT_HOST */
446+}
447+
448+
449+/**
450+ * Find out the frame size (of a single segment in case of GSO frames).
451+ *
452+ * @returns the frame size.
453+ * @param pSG The (scatter/)gather list.
454+ */
455+DECLINLINE(uint32_t) vboxNetFltLinuxFrameSize(PINTNETSG pSG)
456+{
457+ uint16_t u16Type = 0;
458+ uint32_t cbVlanTag = 0;
459+ if (pSG->aSegs[0].cb >= sizeof(RTNETETHERHDR))
460+ u16Type = RT_BE2H_U16(((PCRTNETETHERHDR)pSG->aSegs[0].pv)->EtherType);
461+ else if (pSG->cbTotal >= sizeof(RTNETETHERHDR))
462+ {
463+ uint32_t off = RT_OFFSETOF(RTNETETHERHDR, EtherType);
464+ uint32_t i;
465+ for (i = 0; i < pSG->cSegsUsed; ++i)
466+ {
467+ if (off <= pSG->aSegs[i].cb)
468+ {
469+ if (off + sizeof(uint16_t) <= pSG->aSegs[i].cb)
470+ u16Type = RT_BE2H_U16(*(uint16_t *)((uintptr_t)pSG->aSegs[i].pv + off));
471+ else if (i + 1 < pSG->cSegsUsed)
472+ u16Type = RT_BE2H_U16( ((uint16_t)( ((uint8_t *)pSG->aSegs[i].pv)[off] ) << 8)
473+ + *(uint8_t *)pSG->aSegs[i + 1].pv); /* ASSUMES no empty segments! */
474+ /* else: frame is too short. */
475+ break;
476+ }
477+ off -= pSG->aSegs[i].cb;
478+ }
479+ }
480+ if (u16Type == RTNET_ETHERTYPE_VLAN)
481+ cbVlanTag = 4;
482+ return (vboxNetFltLinuxIsGso(pSG) ? (uint32_t)pSG->GsoCtx.cbMaxSeg + pSG->GsoCtx.cbHdrs : pSG->cbTotal) - cbVlanTag;
483+}
484+
485+
486+/**
487 * Internal worker that create a linux sk_buff for a
488 * (scatter/)gather list.
489 *
490@@ -1138,6 +1191,17 @@
491 LogRel(("VBoxNetFlt: Dropped empty packet coming from internal network.\n"));
492 return NULL;
493 }
494+ Log5(("VBoxNetFlt: Packet to %s of %d bytes (frame=%d).\n", fDstWire?"wire":"host", pSG->cbTotal, vboxNetFltLinuxFrameSize(pSG)));
495+ if (fDstWire && (vboxNetFltLinuxFrameSize(pSG) > ASMAtomicReadU32(&pThis->u.s.cbMtu) + 14))
496+ {
497+ static bool s_fOnce = true;
498+ if (s_fOnce)
499+ {
500+ s_fOnce = false;
501+ printk("VBoxNetFlt: Dropped over-sized packet (%d bytes) coming from internal network.\n", vboxNetFltLinuxFrameSize(pSG));
502+ }
503+ return NULL;
504+ }
505
506 /** @todo We should use fragments mapping the SG buffers with large packets.
507 * 256 bytes seems to be the a threshold used a lot for this. It
508@@ -2057,6 +2121,8 @@
509
510 /* Get the mac address while we still have a valid net_device reference. */
511 memcpy(&pThis->u.s.MacAddr, pDev->dev_addr, sizeof(pThis->u.s.MacAddr));
512+ /* Initialize MTU */
513+ pThis->u.s.cbMtu = pDev->mtu;
514
515 /*
516 * Install a packet filter for this device with a protocol wildcard (ETH_P_ALL).
517@@ -2218,6 +2284,24 @@
518 return NOTIFY_OK;
519 }
520
521+/**
522+ * Callback for listening to MTU change event.
523+ *
524+ * We need to track changes of host's inteface MTU to discard over-sized frames
525+ * coming from the internal network as they may hang the TX queue of host's
526+ * adapter.
527+ *
528+ * @returns NOTIFY_OK
529+ * @param pThis The netfilter instance.
530+ * @param pDev Pointer to device structure of host's interface.
531+ */
532+static int vboxNetFltLinuxDeviceMtuChange(PVBOXNETFLTINS pThis, struct net_device *pDev)
533+{
534+ ASMAtomicWriteU32(&pThis->u.s.cbMtu, pDev->mtu);
535+ Log(("vboxNetFltLinuxDeviceMtuChange: set MTU for %s to %d\n", pThis->szName, pDev->mtu));
536+ return NOTIFY_OK;
537+}
538+
539 #ifdef LOG_ENABLED
540 /** Stringify the NETDEV_XXX constants. */
541 static const char *vboxNetFltLinuxGetNetDevEventName(unsigned long ulEventType)
542@@ -2285,6 +2369,9 @@
543 case NETDEV_GOING_DOWN:
544 rc = vboxNetFltLinuxDeviceGoingDown(pThis, pDev);
545 break;
546+ case NETDEV_CHANGEMTU:
547+ rc = vboxNetFltLinuxDeviceMtuChange(pThis, pDev);
548+ break;
549 case NETDEV_CHANGENAME:
550 break;
551 #ifdef NETDEV_FEAT_CHANGE
552Index: src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
553===================================================================
554--- src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (revision 87022)
555+++ src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (revision 87027)
556@@ -159,6 +159,8 @@
557 * @{ */
558 /** Pointer to the device. */
559 struct net_device * volatile pDev;
560+ /** MTU of host's interface. */
561+ uint32_t cbMtu;
562 /** Whether we've successfully put the interface into to promiscuous mode.
563 * This is for dealing with the ENETDOWN case. */
564 bool volatile fPromiscuousSet;

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy