| 1 | Index: 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);
|
|---|
| 175 | Index: 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; \
|
|---|
| 228 | Index: 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 | }
|
|---|
| 273 | Index: 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 | }
|
|---|
| 333 | Index: 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 | {
|
|---|
| 357 | Index: 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 | }
|
|---|
| 391 | Index: 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)))
|
|---|
| 413 | Index: 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;
|
|---|
| 426 | Index: 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
|
|---|
| 552 | Index: 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;
|
|---|