Changeset 59990 in vbox
- Timestamp:
- Mar 11, 2016 12:39:06 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetLwf-win.cpp
r59971 r59990 16 16 #define LOG_GROUP LOG_GROUP_NET_FLT_DRV 17 17 18 //#define VBOXNETLWF_TEST_NO_FRAMES_OVER_2K19 //#define VBOXNETLWF_TEST_NO_REALLOCATE20 21 18 //#define VBOXNETLWF_SYNC_SEND 22 /* Payload + Ethernet header + VLAN tag = Max Ethernet frame size */ 23 #define VBOXNETLWF_MAX_FRAME_SIZE(mtu) (mtu + sizeof(RTNETETHERHDR) + 4) 19 20 /* 21 * Don't ask me why it is 42. Empirically this is what goes down the stack. 22 * OTOH, as we know from trustworthy sources, 42 is the answer, so be it. 23 */ 24 #define VBOXNETLWF_MAX_FRAME_SIZE(mtu) (mtu + 42) 24 25 25 26 #include <VBox/version.h> … … 198 199 /** MAC address of underlying adapter */ 199 200 RTMAC MacAddr; 200 /** Saved MTU size */201 ULONG uMtuSize;202 201 /** Saved offload configuration */ 203 202 NDIS_OFFLOAD SavedOffloadConfig; … … 912 911 #endif /* !VBOXNETLWF_SYNC_SEND */ 913 912 914 #ifdef VBOXNETLWF_TEST_NO_REALLOCATE915 913 /* Allocate buffer pools */ 916 914 NET_BUFFER_LIST_POOL_PARAMETERS PoolParams; … … 923 921 PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */ 924 922 PoolParams.PoolTag = VBOXNETLWF_MEM_TAG; 925 #ifndef VBOXNETLWF_SYNC_SEND926 PoolParams.DataSize = 9088;927 #endif /* !VBOXNETLWF_SYNC_SEND */928 923 929 924 pModuleCtx->hPool = NdisAllocateNetBufferListPool(hFilter, &PoolParams); … … 936 931 } 937 932 Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool 0x%p\n", pModuleCtx->hPool)); 938 #endif /* VBOXNETLWF_TEST_NO_REALLOCATE */939 933 940 934 NDIS_FILTER_ATTRIBUTES Attributes; … … 1050 1044 PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx; 1051 1045 vboxNetLwfWinChangeState(pModuleCtx, LwfState_Restarting, LwfState_Paused); 1052 1046 vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting); 1053 1047 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 1054 #ifndef VBOXNETLWF_TEST_NO_REALLOCATE1055 ULONG uNewMtuSize = 1500; /* If we fail to find out MTU, we can always assume 1500. */1056 PNDIS_RESTART_ATTRIBUTES pAttributes = pParameters->RestartAttributes;1057 while (pAttributes && pAttributes->Oid != OID_GEN_MINIPORT_RESTART_ATTRIBUTES)1058 pAttributes = pAttributes->Next;1059 if (pAttributes)1060 {1061 PNDIS_RESTART_GENERAL_ATTRIBUTES pGenAttrs = (PNDIS_RESTART_GENERAL_ATTRIBUTES)pAttributes->Data;1062 uNewMtuSize = pGenAttrs->MtuSize;1063 }1064 1065 /* Let's see if MTU has changed. Re-allocate the pool if it has. */1066 if (pModuleCtx->uMtuSize != uNewMtuSize)1067 {1068 pModuleCtx->uMtuSize = uNewMtuSize;1069 if (pModuleCtx->hPool)1070 {1071 /*1072 * Don't need to wait for pending sends to complete since we are already1073 * in paused state. Just free the old pool.1074 */1075 NdisFreeNetBufferListPool(pModuleCtx->hPool);1076 pModuleCtx->hPool = NULL;1077 }1078 }1079 if (!pModuleCtx->hPool)1080 {1081 /* Allocate a new pool. */1082 NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;1083 NdisZeroMemory(&PoolParams, sizeof(PoolParams));1084 PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;1085 PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;1086 PoolParams.Header.Size = sizeof(PoolParams);1087 PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;1088 PoolParams.fAllocateNetBuffer = TRUE;1089 PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */1090 PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;1091 #ifndef VBOXNETLWF_SYNC_SEND1092 PoolParams.DataSize = VBOXNETLWF_MAX_FRAME_SIZE(pModuleCtx->uMtuSize);1093 #endif /* !VBOXNETLWF_SYNC_SEND */1094 1095 pModuleCtx->hPool = NdisAllocateNetBufferListPool(pModuleCtx->hFilter, &PoolParams);1096 if (!pModuleCtx->hPool)1097 {1098 LogError(("vboxNetLwfWinRestart: NdisAllocateNetBufferListPool failed\n"));1099 Status = NDIS_STATUS_RESOURCES;1100 }1101 else1102 {1103 Log4(("vboxNetLwfWinRestart: allocated NBL+NB pool 0x%p with MTU=%u\n",1104 pModuleCtx->hPool, pModuleCtx->uMtuSize));1105 }1106 }1107 1108 vboxNetLwfWinChangeState(pModuleCtx, Status == NDIS_STATUS_SUCCESS ? LwfState_Running : LwfState_Paused, LwfState_Restarting);1109 #else /* !VBOXNETLWF_TEST_NO_REALLOCATE */1110 vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting);1111 #endif /* !VBOXNETLWF_TEST_NO_REALLOCATE */1112 1048 LogFlow(("<==vboxNetLwfWinRestart: Status = 0x%x\n", Status)); 1113 1049 return Status; … … 1121 1057 for (PNET_BUFFER pBuf = NET_BUFFER_LIST_FIRST_NB(pList); pBuf; pBuf = NET_BUFFER_NEXT_NB(pBuf)) 1122 1058 { 1123 Log(("%s packet: cb=%d\n", pszMsg, NET_BUFFER_DATA_LENGTH(pBuf))); 1059 Log6(("%s packet: cb=%d offset=%d", pszMsg, NET_BUFFER_DATA_LENGTH(pBuf), NET_BUFFER_DATA_OFFSET(pBuf))); 1060 for (PMDL pMdl = NET_BUFFER_FIRST_MDL(pBuf); 1061 pMdl != NULL; 1062 pMdl = NDIS_MDL_LINKAGE(pMdl)) 1063 { 1064 Log6((" MDL: cb=%d", MmGetMdlByteCount(pMdl))); 1065 } 1066 Log6(("\n")); 1124 1067 } 1125 1068 } … … 1287 1230 DECLINLINE(void) vboxNetLwfWinFreeMdlChain(PMDL pMdl) 1288 1231 { 1289 #ifdef VBOXNETLWF_SYNC_SEND1290 1232 PMDL pMdlNext; 1291 1233 while (pMdl) 1292 1234 { 1293 1235 pMdlNext = pMdl->Next; 1236 #ifndef VBOXNETLWF_SYNC_SEND 1237 PUCHAR pDataBuf; 1238 ULONG cb = 0; 1239 NdisQueryMdl(pMdl, &pDataBuf, &cb, NormalPagePriority); 1240 #endif /* !VBOXNETLWF_SYNC_SEND */ 1294 1241 NdisFreeMdl(pMdl); 1295 1242 Log4(("vboxNetLwfWinFreeMdlChain: freed MDL 0x%p\n", pMdl)); 1243 #ifndef VBOXNETLWF_SYNC_SEND 1244 NdisFreeMemory(pDataBuf, 0, 0); 1245 Log4(("vboxNetLwfWinFreeMdlChain: freed data buffer 0x%p\n", pDataBuf)); 1246 #endif /* !VBOXNETLWF_SYNC_SEND */ 1296 1247 pMdl = pMdlNext; 1297 1248 } 1298 #endif /* VBOXNETLWF_SYNC_SEND */1299 1249 } 1300 1250 … … 1354 1304 } 1355 1305 #else /* !VBOXNETLWF_SYNC_SEND */ 1356 #ifdef VBOXNETLWF_TEST_NO_FRAMES_OVER_2K 1357 AssertReturn(pSG->cbTotal < 2048, NULL); 1358 #else /* !VBOXNETLWF_TEST_NO_FRAMES_OVER_2K */ 1359 AssertReturn(pSG->cbTotal <= VBOXNETLWF_MAX_FRAME_SIZE(pModule->uMtuSize), NULL); 1360 #endif /* !VBOXNETLWF_TEST_NO_FRAMES_OVER_2K */ 1361 PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferList(pModule->hPool, 1362 0 /** @todo ContextSize */, 1363 0 /** @todo ContextBackFill */); 1364 NET_BUFFER_LIST_NEXT_NBL(pBufList) = NULL; /** @todo Is it even needed? */ 1365 NET_BUFFER *pBuffer = NET_BUFFER_LIST_FIRST_NB(pBufList); 1366 NDIS_STATUS Status = NdisRetreatNetBufferDataStart(pBuffer, pSG->cbTotal, 0 /** @todo DataBackfill */, NULL); 1367 if (Status == NDIS_STATUS_SUCCESS) 1368 { 1369 uint8_t *pDst = (uint8_t*)NdisGetDataBuffer(pBuffer, pSG->cbTotal, NULL, 1, 0); 1370 if (pDst) 1371 { 1372 for (int i = 0; i < pSG->cSegsUsed; i++) 1373 { 1374 NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb); 1375 pDst += pSG->aSegs[i].cb; 1376 } 1377 Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB+MDL+Data 0x%p\n", pBufList)); 1306 PNET_BUFFER_LIST pBufList = NULL; 1307 ULONG cbMdl = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal); 1308 ULONG uDataOffset = cbMdl - pSG->cbTotal; 1309 PUCHAR pDataBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pModule->hFilter, cbMdl, 1310 VBOXNETLWF_MEM_TAG, NormalPoolPriority); 1311 if (pDataBuf) 1312 { 1313 Log4(("vboxNetLwfWinSGtoNB: allocated data buffer (cb=%u) 0x%p\n", cbMdl, pDataBuf)); 1314 PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pDataBuf, cbMdl); 1315 if (!pMdl) 1316 { 1317 NdisFreeMemory(pDataBuf, 0, 0); 1318 Log4(("vboxNetLwfWinSGtoNB: freed data buffer 0x%p\n", pDataBuf)); 1319 LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL (cb=%u)\n", cbMdl)); 1320 LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n")); 1321 return NULL; 1322 } 1323 PUCHAR pDst = pDataBuf + uDataOffset; 1324 for (int i = 0; i < pSG->cSegsUsed; i++) 1325 { 1326 NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb); 1327 pDst += pSG->aSegs[i].cb; 1328 } 1329 pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool, 1330 0 /* ContextSize */, 1331 0 /* ContextBackFill */, 1332 pMdl, 1333 uDataOffset, 1334 pSG->cbTotal); 1335 if (pBufList) 1336 { 1337 Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList)); 1378 1338 pBufList->SourceHandle = pModule->hFilter; 1379 1339 /** @todo Do we need to initialize anything else? */ … … 1381 1341 else 1382 1342 { 1383 LogError(("vboxNetLwfWinSGtoNB: failed to obtain the buffer pointer (size=%u)\n", pSG->cbTotal)); 1384 NdisAdvanceNetBufferDataStart(pBuffer, pSG->cbTotal, false, NULL); /** @todo why bother? */ 1385 NdisFreeNetBufferList(pBufList); 1386 pBufList = NULL; 1343 LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n")); 1344 vboxNetLwfWinFreeMdlChain(pMdl); 1387 1345 } 1388 1346 } 1389 1347 else 1390 1348 { 1391 LogError(("vboxNetLwfWinSGtoNB: NdisRetreatNetBufferDataStart failed with 0x%x (size=%u)\n", Status, pSG->cbTotal)); 1392 NdisFreeNetBufferList(pBufList); 1393 pBufList = NULL; 1349 LogError(("vboxNetLwfWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl)); 1394 1350 } 1395 1351 #endif /* !VBOXNETLWF_SYNC_SEND */ … … 1569 1525 LogFlow(("==>vboxNetLwfWinSendNetBufferLists: module=%p\n", hModuleCtx)); 1570 1526 PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx; 1527 vboxNetLwfWinDumpPackets("vboxNetLwfWinSendNetBufferLists: got", pBufLists); 1571 1528 1572 1529 if (!ASMAtomicReadBool(&pModule->fActive)) … … 1704 1661 LogFlow(("==>vboxNetLwfWinReceiveNetBufferLists: module=%p\n", hModuleCtx)); 1705 1662 PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx; 1663 vboxNetLwfWinDumpPackets("vboxNetLwfWinReceiveNetBufferLists: got", pBufLists); 1706 1664 1707 1665 if (!ASMAtomicReadBool(&pModule->fActive)) … … 2213 2171 if (pBufList) 2214 2172 { 2173 vboxNetLwfWinDumpPackets("vboxNetFltPortOsXmit: sending down", pBufList); 2215 2174 #ifdef VBOXNETLWF_SYNC_SEND 2216 2175 aEvents[nEvents++] = &pModule->EventWire; … … 2227 2186 if (pBufList) 2228 2187 { 2188 vboxNetLwfWinDumpPackets("vboxNetFltPortOsXmit: sending up", pBufList); 2229 2189 #ifdef VBOXNETLWF_SYNC_SEND 2230 2190 aEvents[nEvents++] = &pModule->EventHost;
Note:
See TracChangeset
for help on using the changeset viewer.