Changeset 10557 in vbox for trunk/src/VBox
- Timestamp:
- Jul 12, 2008 12:19:35 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10551 r10557 43 43 /** 44 44 * A network interface. 45 * 46 * Unless explicitly stated, all members are protect by the network semaphore. 45 47 */ 46 48 typedef struct INTNETIF 47 49 { 48 /** Pointer to the next interface. */ 50 /** Pointer to the next interface. 51 * This is protected by the INTNET::FastMutex. */ 49 52 struct INTNETIF *pNext; 50 53 /** The current MAC address for the interface. */ … … 76 79 * should return with the appropriate error condition. */ 77 80 INTNETIFHANDLE hIf; 78 /** Pointer to the network this interface is connected to. */ 81 /** Pointer to the network this interface is connected to. 82 * This is protected by the INTNET::FastMutex. */ 79 83 struct INTNETNETWORK *pNetwork; 80 84 /** The session this interface is associated with. */ … … 93 97 { 94 98 /** The Next network in the chain. 95 * This is protected by the INTNET:: Spinlock. */99 * This is protected by the INTNET::FastMutex. */ 96 100 struct INTNETNETWORK *pNext; 101 /** List of interfaces connected to the network. 102 * This is protected by the INTNET::FastMutex. */ 103 PINTNETIF pIFs; 97 104 /** The network mutex. 98 105 * It protects everything dealing with this network. */ 99 106 RTSEMFASTMUTEX FastMutex; 100 /** List of interfaces connected to the network. */101 PINTNETIF pIFs;102 107 /** Pointer to the instance data. */ 103 108 struct INTNET *pIntNet; … … 140 145 typedef struct INTNETHT 141 146 { 147 /** Spinlock protecting all access. */ 148 RTSPINLOCK Spinlock; 142 149 /** Pointer to the handle table. */ 143 150 PINTNETHTE paEntries; … … 160 167 typedef struct INTNET 161 168 { 162 /** Mutex protecting the network creation. */ 169 /** Mutex protecting the network creation, opening and destruction. 170 * (This means all operations affecting the pNetworks list.) */ 163 171 RTSEMFASTMUTEX FastMutex; 164 /** Spinlock protecting the linked list of networks and the interface handle translation table. */165 RTSPINLOCK Spinlock;166 172 /** List of networks. Protected by INTNET::Spinlock. */ 167 173 PINTNETNETWORK volatile pNetworks; … … 172 178 173 179 174 175 180 /** 176 181 * Validates and translates an interface handle to a interface pointer. 182 * 183 * The caller already owns the spinlock, which means this is 184 * for internal use only. 177 185 * 178 186 * @returns Pointer to interface. 179 187 * @returns NULL if the handle is invalid. 180 * @param p IntNet Pointer to the instance data.188 * @param pHT Pointer to the handle table. 181 189 * @param hIF The interface handle to validate and translate. 182 */ 183 DECLINLINE(PINTNETIF) intnetHandle2IFPtr(PINTNET pIntNet, INTNETIFHANDLE hIF) 184 { 185 Assert(pIntNet); 186 if ((hIF & INTNET_HANDLE_MAGIC) != INTNET_HANDLE_MAGIC) 187 return NULL; 188 189 PINTNETHT pHT = &pIntNet->IfHandles; 190 const uint32_t i = hIF & INTNET_HANDLE_INDEX_MASK; 191 PINTNETIF pIF = NULL; 190 * 191 * @internal 192 */ 193 DECLINLINE(PINTNETIF) intnetHandle2IFPtrLocked(PINTNETHT pHT, INTNETIFHANDLE hIF) 194 { 195 if (RT_LIKELY((hIF & INTNET_HANDLE_MAGIC) == INTNET_HANDLE_MAGIC)) 196 { 197 const uint32_t i = hIF & INTNET_HANDLE_INDEX_MASK; 198 if (RT_LIKELY( i < pHT->cAllocated 199 && pHT->paEntries[i].iNext >= INTNET_HANDLE_MAX 200 && pHT->paEntries[i].iNext != UINT32_MAX)) 201 return pHT->paEntries[i].pIF; 202 } 203 return NULL; 204 } 205 206 207 /** 208 * Validates and translates an interface handle to a interface pointer. 209 * 210 * @returns Pointer to interface. 211 * @returns NULL if the handle is invalid. 212 * @param pHT Pointer to the handle table. 213 * @param hIF The interface handle to validate and translate. 214 */ 215 DECLINLINE(PINTNETIF) intnetHandle2IFPtr(PINTNETHT pHT, INTNETIFHANDLE hIF) 216 { 217 AssertPtr(pHT); 192 218 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 193 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp); 194 195 if ( i < pHT->cAllocated 196 && pHT->paEntries[i].iNext >= INTNET_HANDLE_MAX 197 && pHT->paEntries[i].iNext != UINT32_MAX) 198 pIF = pHT->paEntries[i].pIF; 199 200 RTSpinlockRelease(pIntNet->Spinlock, &Tmp); 219 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 220 PINTNETIF pIF = intnetHandle2IFPtrLocked(pHT, hIF); 221 RTSpinlockRelease(pHT->Spinlock, &Tmp); 201 222 202 223 return pIF; … … 221 242 222 243 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 223 RTSpinlockAcquire(p IntNet->Spinlock, &Tmp);244 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 224 245 for (;;) 225 246 { … … 235 256 236 257 pHT->paEntries[i].pIF = pIF; 237 RTSpinlockRelease(p IntNet->Spinlock, &Tmp);258 RTSpinlockRelease(pHT->Spinlock, &Tmp); 238 259 if (paNew) 239 260 RTMemFree(paNew); … … 245 266 */ 246 267 const unsigned cNew = pHT->cAllocated + 128; 247 RTSpinlockRelease(p IntNet->Spinlock, &Tmp);268 RTSpinlockRelease(pHT->Spinlock, &Tmp); 248 269 if (--cTries <= 0) 249 270 { … … 258 279 * Acquire the spinlock and check if someone raced us. 259 280 */ 260 RTSpinlockAcquire(p IntNet->Spinlock, &Tmp);281 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 261 282 if (pHT->cAllocated < cNew) 262 283 { … … 290 311 291 312 /** 292 * Frees a handle.293 * 294 * @returns Handle on success.295 * @returns Invalid handle on failure.296 * @param p IntNet Pointer to the instance data.313 * Validates and frees a handle. 314 * 315 * @returns Pointer to interface. 316 * @returns NULL if the handle is invalid. 317 * @param pHT Pointer to the handle table. 297 318 * @param h The handle we're freeing. 298 319 */ 299 static void intnetHandleFree(PINTNET pIntNet, INTNETIFHANDLE h) 300 { 301 Assert(intnetHandle2IFPtr(pIntNet, h)); 302 PINTNETHT pHT = &pIntNet->IfHandles; 303 const uint32_t i = h & INTNET_HANDLE_INDEX_MASK; 304 320 static PINTNETIF intnetHandleFree(PINTNETHT pHT, INTNETIFHANDLE h) 321 { 305 322 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 306 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp); 307 308 if (i < pHT->cAllocated) 309 { 310 /* 311 * Insert at the end of the free list. 312 */ 323 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 324 325 /* 326 * Validate and get it, then insert the handle table entry 327 * at the end of the free list. 328 */ 329 PINTNETIF pIF = intnetHandle2IFPtrLocked(pHT, h); 330 if (pIF) 331 { 332 const uint32_t i = h & INTNET_HANDLE_INDEX_MASK; 313 333 pHT->paEntries[i].iNext = UINT32_MAX; 314 334 const uint32_t iTail = pHT->iTail; … … 319 339 pHT->iTail = i; 320 340 } 321 else 322 AssertMsgFailed(("%d >= %d\n", i, pHT->cAllocated)); 323 324 RTSpinlockRelease(pIntNet->Spinlock, &Tmp); 341 342 RTSpinlockRelease(pHT->Spinlock, &Tmp); 343 344 AssertMsg(pIF, ("%d >= %d\n", h & INTNET_HANDLE_INDEX_MASK, pHT->cAllocated)); 345 return pIF; 325 346 } 326 347 … … 617 638 */ 618 639 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 619 PINTNETIF pIf = intnetHandle2IFPtr( pIntNet, hIf);640 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 620 641 if (!pIf) 621 642 return VERR_INVALID_HANDLE; … … 694 715 */ 695 716 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 696 PINTNETIF pIf = intnetHandle2IFPtr( pIntNet, hIf);717 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 697 718 if (!pIf) 698 719 return VERR_INVALID_HANDLE; … … 746 767 * Validate input. 747 768 */ 748 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 749 PINTNETIF pIf = intnetHandle2IFPtr(pIntNet, hIf); 769 AssertPtrReturn(ppRing0Buf, VERR_INVALID_PARAMETER); 770 *ppRing0Buf = NULL; 771 AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 772 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 750 773 if (!pIf) 751 774 return VERR_INVALID_HANDLE; 752 AssertPtrReturn(ppRing0Buf, VERR_INVALID_PARAMETER); 753 754 /*755 * A ssuming that we're in Ring-0, this should be rather simple :-)775 776 /* 777 * Grab the lock and get the data. 778 * ASSUMES that the handle isn't closed while we're here. 756 779 */ 757 780 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); … … 783 806 */ 784 807 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 785 PINTNETIF pIf = intnetHandle2IFPtr( pIntNet, hIf);808 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 786 809 if (!pIf) 787 810 return VERR_INVALID_HANDLE; … … 790 813 791 814 /* 792 * Assuming that we're in Ring-0, this should be rather simple :-) 815 * Grab the lock and get the data. 816 * ASSUMES that the handle isn't closed while we're here. 793 817 */ 794 818 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); … … 796 820 return rc; 797 821 798 /** @todo make a SUPR0 api for obtaining the array. SUPR0 is keeping track of everything, there822 /** @todo make a SUPR0 api for obtaining the array. SUPR0/IPRT is keeping track of everything, there 799 823 * is no need for any extra bookkeeping here.. */ 800 824 //*ppRing0Buf = pIf->pIntBuf; … … 820 844 821 845 /* 822 * Get and validate essential handles.846 * Validate & translate input. 823 847 */ 824 848 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 825 PINTNETIF pIf = intnetHandle2IFPtr( pIntNet, hIf);849 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 826 850 if (!pIf) 827 851 { … … 829 853 return VERR_INVALID_HANDLE; 830 854 } 855 856 /* 857 * Grab the network semaphore and make the change. 858 */ 859 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 860 if (RT_FAILURE(rc)) 861 return rc; 862 831 863 if (pIf->fPromiscuous != fPromiscuous) 832 864 { 833 865 Log(("INTNETR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n", 834 866 hIf, !fPromiscuous, !!fPromiscuous)); 835 ASMAtomicXchgSize(&pIf->fPromiscuous, !!fPromiscuous); 836 } 867 ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous); 868 } 869 870 RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 837 871 return VINF_SUCCESS; 838 872 } … … 872 906 */ 873 907 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 874 PINTNETIF pIf = intnetHandle2IFPtr( pIntNet, hIf);908 PINTNETIF pIf = intnetHandle2IFPtr(&pIntNet->IfHandles, hIf); 875 909 if (!pIf) 876 910 { … … 891 925 * but the problem with such an approach is that it will cause 892 926 * one unnecessary supervisor->user->supervisor trip. There is 893 * already a risk for such, so we don't need to increase this.927 * already a slight risk for such, so no need to increase it. 894 928 */ 895 929 … … 941 975 942 976 /* 943 * Get and validate essential handles.977 * Validate, get and free the handle. 944 978 */ 945 979 AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 946 PINTNETIF pIf = intnetHandle 2IFPtr(pIntNet, hIf);980 PINTNETIF pIf = intnetHandleFree(&pIntNet->IfHandles, hIf); 947 981 if (!pIf) 948 982 return VERR_INVALID_HANDLE; 949 983 ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID); 984 985 /* 986 * Release our reference to the interface object. 987 */ 950 988 int rc = SUPR0ObjRelease(pIf->pvObj, pIf->pSession); 951 989 LogFlow(("INTNETR0IfClose: returns %Rrc\n", rc)); … … 983 1021 PINTNET pIntNet = (PINTNET)pvUser2; 984 1022 1023 RTSemFastMutexRequest(pIntNet->FastMutex); 1024 985 1025 /* 986 1026 * Delete the interface handle so the object no longer can be opened. 987 1027 */ 988 if (pIf->hIf != INTNET_HANDLE_INVALID) 989 { 990 intnetHandleFree(pIntNet, pIf->hIf); 991 ASMAtomicXchgSize(&pIf->hIf, INTNET_HANDLE_INVALID); 992 } 1028 INTNETIFHANDLE hIf = ASMAtomicXchgU32(&pIf->hIf, INTNET_HANDLE_INVALID); 1029 if (hIf != INTNET_HANDLE_INVALID) 1030 intnetHandleFree(&pIntNet->IfHandles, hIf); 993 1031 994 1032 /* … … 999 1037 if (pNetwork) 1000 1038 { 1001 RTSemFastMutexRequest(pNetwork->FastMutex);1002 1039 if (pNetwork->pIFs == pIf) 1003 1040 pNetwork->pIFs = pIf->pNext; … … 1016 1053 Assert(pPrev); 1017 1054 } 1018 RTSemFastMutexRelease(pNetwork->FastMutex);1019 1055 pIf->pNext = NULL; 1020 1056 1021 1057 /* 1022 * Release o r reference to the network.1058 * Release our reference to the network. 1023 1059 */ 1060 RTSemFastMutexRelease(pIntNet->FastMutex); 1061 1024 1062 SUPR0ObjRelease(pNetwork->pvObj, pIf->pSession); 1025 1063 pIf->pNetwork = NULL; 1026 1064 } 1065 else 1066 RTSemFastMutexRelease(pIntNet->FastMutex); 1027 1067 1028 1068 /* … … 1082 1122 RTMemFree(pIf); 1083 1123 } 1084 1085 1124 1086 1125 … … 1199 1238 1200 1239 /** 1240 * Creates the trunk connection (if any). 1241 * 1242 * @returns VBox status code. 1243 * 1244 * @param pNetwork The newly created network. 1245 * @param pSession The session handle. 1246 */ 1247 static int intnetNetworkCreateTrunkConnection(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession) 1248 { 1249 const char *pszFactoryUUID; 1250 switch (pNetwork->enmTrunkType) 1251 { 1252 /* 1253 * The 'None' case, simple. 1254 */ 1255 case kIntNetTrunkType_None: 1256 case kIntNetTrunkType_WhateverNone: 1257 return VINF_SUCCESS; 1258 default: 1259 return VERR_NOT_IMPLEMENTED; 1260 1261 case kIntNetTrunkType_NetFlt: 1262 pszFactoryUUID = INTNETTRUNKFACTORY_NETFLT_UUID_STR; 1263 break; 1264 case kIntNetTrunkType_NetTap: 1265 pszFactoryUUID = INTNETTRUNKFACTORY_NETTAP_UUID_STR; 1266 break; 1267 case kIntNetTrunkType_SrvNat: 1268 pszFactoryUUID = INTNETTRUNKFACTORY_SRVNAT_UUID_STR; 1269 break; 1270 } 1271 1272 /* 1273 * Query the factory. 1274 */ 1275 1276 return VERR_NOT_IMPLEMENTED; 1277 } 1278 1279 1280 /** 1201 1281 * Close a network which was opened/created using intnetOpenNetwork()/intnetCreateNetwork(). 1202 1282 * … … 1227 1307 { 1228 1308 LogFlow(("intnetNetworkDestruct: pvObj=%p pvUser1=%p pvUser2=%p\n", pvObj, pvUser1, pvUser2)); 1229 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;1230 1309 PINTNETNETWORK pNetwork = (PINTNETNETWORK)pvUser1; 1231 1310 PINTNET pIntNet = (PINTNET)pvUser2; 1232 1311 Assert(pNetwork->pIntNet == pIntNet); 1233 1312 1234 /* 1235 * Unlink the network.s 1236 */ 1237 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp); 1313 RTSemFastMutexRequest(pIntNet->FastMutex); 1314 1315 1316 /* 1317 * Unlink the network. 1318 * Note that it needn't be in the list if we failed during creation. 1319 */ 1238 1320 PINTNETNETWORK pPrev = pIntNet->pNetworks; 1239 1321 if (pPrev == pNetwork) … … 1247 1329 break; 1248 1330 } 1249 Assert(pPrev);1250 1331 } 1251 1332 pNetwork->pNext = NULL; 1252 1333 pNetwork->pvObj = NULL; 1253 RTSpinlockRelease(pIntNet->Spinlock, &Tmp); 1334 1335 RTSemFastMutexRequest(pNetwork->FastMutex); 1254 1336 1255 1337 /* … … 1258 1340 * deal with this by simply orphaning the interfaces. 1259 1341 */ 1260 RTSemFastMutexRequest(pNetwork->FastMutex);1261 1342 PINTNETIF pCur = pNetwork->pIFs; 1262 1343 while (pCur) … … 1267 1348 pCur = pNext; 1268 1349 } 1350 1269 1351 RTSemFastMutexRelease(pNetwork->FastMutex); 1270 1352 … … 1275 1357 pNetwork->FastMutex = NIL_RTSEMFASTMUTEX; 1276 1358 RTMemFree(pNetwork); 1359 1360 RTSemFastMutexRelease(pIntNet->FastMutex); 1277 1361 } 1278 1362 … … 1313 1397 Assert(cchName && cchName < sizeof(pCur->szName)); /* caller ensures this */ 1314 1398 1315 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;1316 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp);1317 1399 pCur = pIntNet->pNetworks; 1318 1400 while (pCur) … … 1332 1414 if (!((pCur->fFlags ^ fFlags) & (INTNET_OPEN_FLAGS_PUBLIC))) 1333 1415 { 1416 1334 1417 /* 1335 * Increment the reference and check that the 1336 * sessioncan access this network.1418 * Increment the reference and check that the session 1419 * can access this network. 1337 1420 */ 1338 1421 rc = SUPR0ObjAddRef(pCur->pvObj, pSession); 1339 RTSpinlockRelease(pIntNet->Spinlock, &Tmp);1340 1341 1422 if (RT_SUCCESS(rc)) 1342 1423 { … … 1348 1429 SUPR0ObjRelease(pCur->pvObj, pSession); 1349 1430 } 1431 else if (rc == VERR_WRONG_ORDER) 1432 rc = VERR_NOT_FOUND; /* destruction race, pretend the other isn't there. */ 1350 1433 } 1351 1434 else … … 1360 1443 pCur = pCur->pNext; 1361 1444 } 1362 RTSpinlockRelease(pIntNet->Spinlock, &Tmp);1363 1445 1364 1446 LogFlow(("intnetOpenNetwork: returns VERR_NOT_FOUND\n")); … … 1370 1452 * Creates a new network. 1371 1453 * 1372 * The call must own the INTNET::FastMutex and has already 1373 * attempted opening the network.1454 * The call must own the INTNET::FastMutex and has already attempted 1455 * opening the network and found it to be non-existing. 1374 1456 * 1375 1457 * @returns VBox status code. … … 1381 1463 * @param pszTrunk The trunk name. Its meaning is specfic to the type. 1382 1464 * @param fFlags Flags, see INTNET_OPEN_FLAGS_*. 1383 * @param ppNetwork Where to store the network. 1465 * @param ppNetwork Where to store the network. In the case of failure whatever is returned 1466 * here should be dereferenced outside the INTNET::FastMutex. 1384 1467 */ 1385 1468 static int intnetCreateNetwork(PINTNET pIntNet, PSUPDRVSESSION pSession, const char *pszNetwork, INTNETTRUNKTYPE enmTrunkType, … … 1400 1483 1401 1484 /* 1402 * Verify that the network doesn't exist.1403 */1404 const uint8_t cchName = strlen(pszNetwork);1405 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;1406 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp);1407 for (PINTNETNETWORK pCur = pIntNet->pNetworks; pCur; pCur = pCur->pNext)1408 if ( pCur->cchName == cchName1409 && !memcmp(pCur->szName, pszNetwork, cchName))1410 {1411 RTSpinlockRelease(pIntNet->Spinlock, &Tmp);1412 LogFlow(("intnetCreateNetwork: returns VERR_ALREADY_EXISTS\n"));1413 return VERR_ALREADY_EXISTS;1414 }1415 RTSpinlockRelease(pIntNet->Spinlock, &Tmp);1416 1417 /*1418 1485 * Allocate and initialize. 1419 1486 */ … … 1427 1494 pNew->pIntNet = pIntNet; 1428 1495 pNew->fFlags = fFlags; 1496 size_t cchName = strlen(pszNetwork); 1429 1497 pNew->cchName = cchName; 1430 1498 Assert(cchName && cchName < sizeof(pNew->szName)); /* caller's responsibility. */ … … 1435 1503 1436 1504 /* 1437 * Register the object in the current session .1505 * Register the object in the current session and link it into the network list. 1438 1506 */ 1439 1507 pNew->pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_INTERNAL_NETWORK, intnetNetworkDestruct, pNew, pIntNet); 1440 1508 if (pNew->pvObj) 1441 1509 { 1442 /*1443 * Check again that the network doesn't exist and then link in the new one.1444 * This must be done before we attempt any SUPR0ObjRelease call.1445 */1446 RTSpinlockAcquire(pIntNet->Spinlock, &Tmp);1447 for (PINTNETNETWORK pCur = pIntNet->pNetworks; pCur; pCur = pCur->pNext)1448 if ( pCur->cchName == cchName1449 && !memcmp(pCur->szName, pszNetwork, cchName))1450 rc = VERR_ALREADY_EXISTS;1451 1510 pNew->pNext = pIntNet->pNetworks; 1452 1511 pIntNet->pNetworks = pNew; 1453 RTSpinlockRelease(pIntNet->Spinlock, &Tmp); 1454 1512 1513 /* 1514 * Check if the current session is actually allowed to create and open 1515 * the network. It is possible to implement network name based policies 1516 * and these must be checked now. SUPR0ObjRegister does no such checks. 1517 */ 1518 rc = SUPR0ObjVerifyAccess(pNew->pvObj, pSession, pNew->szName); 1455 1519 if (RT_SUCCESS(rc)) 1456 1520 { 1457 1521 /* 1458 * Check if the current session is actually allowed to create and open 1459 * the network. It is possible to implement network name based policies 1460 * and these must be checked now. SUPR0ObjRegister does no such checks. 1522 * Connect the trunk. 1461 1523 */ 1462 rc = SUPR0ObjVerifyAccess(pNew->pvObj, pSession, pNew->szName);1524 rc = intnetNetworkCreateTrunkConnection(pNew, pSession); 1463 1525 if (RT_SUCCESS(rc)) 1464 1526 { … … 1469 1531 } 1470 1532 1471 /* The release will destroy the object. */ 1472 SUPR0ObjRelease(pNew->pvObj, pSession); 1533 /* 1534 * We unlink it here so it cannot be opened when the caller leaves 1535 * INTNET::FastMutex before dereferencing it. 1536 */ 1537 Assert(pIntNet->pNetworks == pNew); 1538 pIntNet->pNetworks = pNew->pNext; 1539 pNew->pNext = NULL; 1540 1541 *ppNetwork = pNew; 1473 1542 LogFlow(("intnetCreateNetwork: returns %Rrc\n", rc)); 1474 1543 return rc; … … 1533 1602 case kIntNetTrunkType_None: 1534 1603 case kIntNetTrunkType_WhateverNone: 1535 AssertReturn(! pszTrunk, VERR_INVALID_PARAMETER);1604 AssertReturn(!*pszTrunk, VERR_INVALID_PARAMETER); 1536 1605 break; 1537 1606 … … 1555 1624 1556 1625 /* 1557 * Try open/create the network. 1558 */ 1559 PINTNETNETWORK pNetwork; 1626 * Try open / create the network and create an interface on it for the caller to use. 1627 * 1628 * Note that because of the destructors grabbing INTNET::FastMutex and us being required 1629 * to own this semaphore for the entire network opening / creation and interface creation 1630 * sequence, intnetCreateNetwork will have to defer the network cleanup to us on failure. 1631 */ 1632 PINTNETNETWORK pNetwork = NULL; 1560 1633 rc = intnetOpenNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork); 1561 if (rc == VERR_NOT_FOUND) 1562 rc = intnetCreateNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork); 1563 if (RT_SUCCESS(rc)) 1564 { 1565 /* 1566 * Create a new interface to this network. 1567 * On failure we close the network. On success it remains open until the 1568 * interface is destroyed or the last session is doing cleanup (order problems). 1569 */ 1570 rc = intnetNetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, phIf); 1571 if (RT_FAILURE(rc)) 1634 if (RT_SUCCESS(rc) || rc == VERR_NOT_FOUND) 1635 { 1636 if (rc == VERR_NOT_FOUND) 1637 rc = intnetCreateNetwork(pIntNet, pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, &pNetwork); 1638 if (RT_SUCCESS(rc)) 1639 rc = intnetNetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, phIf); 1640 1641 RTSemFastMutexRelease(pIntNet->FastMutex); 1642 1643 if (RT_FAILURE(rc) && pNetwork) 1572 1644 intnetNetworkClose(pNetwork, pSession); 1573 1645 } 1574 1575 RTSemFastMutexRelease(pIntNet->FastMutex);1646 else 1647 RTSemFastMutexRelease(pIntNet->FastMutex); 1576 1648 1577 1649 LogFlow(("INTNETR0Open: return %Rrc *phIf=%RX32\n", rc, *phIf)); … … 1611 1683 if (!pIntNet) 1612 1684 return; 1685 AssertPtrReturnVoid(pIntNet); 1613 1686 1614 1687 /* … … 1621 1694 pIntNet->FastMutex = NIL_RTSEMFASTMUTEX; 1622 1695 } 1623 if (pIntNet-> Spinlock != NIL_RTSPINLOCK)1624 { 1625 RTSpinlockDestroy(pIntNet-> Spinlock);1626 pIntNet-> Spinlock = NIL_RTSPINLOCK;1696 if (pIntNet->IfHandles.Spinlock != NIL_RTSPINLOCK) 1697 { 1698 RTSpinlockDestroy(pIntNet->IfHandles.Spinlock); 1699 pIntNet->IfHandles.Spinlock = NIL_RTSPINLOCK; 1627 1700 } 1628 1701 … … 1653 1726 if (RT_SUCCESS(rc)) 1654 1727 { 1655 rc = RTSpinlockCreate(&pIntNet-> Spinlock);1728 rc = RTSpinlockCreate(&pIntNet->IfHandles.Spinlock); 1656 1729 if (RT_SUCCESS(rc)) 1657 1730 { -
trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
r10524 r10557 487 487 /* 488 488 * Start threaded testcase. 489 * Give it 5 mins to finish. 489 490 */ 490 491 if (!g_cErrors) … … 520 521 { 521 522 int rc2 = VINF_SUCCESS; 522 rc = RTThreadWait(ThreadSend0, 30000, &rc2); 523 if ( VBOX_SUCCESS(rc) 524 && VBOX_SUCCESS(rc2)) 525 rc = RTThreadWait(ThreadSend1, 30000, &rc2); 523 rc = RTThreadWait(ThreadSend0, 5*60*1000, &rc2); 524 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here. (2.6.23-gentoo-r3 amd64) */ 525 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--) 526 { 527 RTThreadSleep(1); 528 rc = RTThreadWait(ThreadSend0, 1, &rc2); 529 } 530 #endif 531 AssertRC(rc); 532 if (VBOX_SUCCESS(rc)) 533 { 534 ThreadSend0 = NIL_RTTHREAD; 535 rc = RTThreadWait(ThreadSend1, 5*60*1000, RT_SUCCESS(rc2) ? &rc2 : NULL); 536 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here. (2.6.23-gentoo-r3 amd64) */ 537 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--) 538 { 539 RTThreadSleep(1); 540 rc = RTThreadWait(ThreadSend1, 1, &rc2); 541 } 542 #endif 543 AssertRC(rc); 544 if (RT_SUCCESS(rc)) 545 ThreadSend1 = NIL_RTTHREAD; 546 } 526 547 if ( VBOX_SUCCESS(rc) 527 548 && VBOX_SUCCESS(rc2)) … … 544 565 * Closing time... 545 566 */ 567 rc = RTThreadWait(ThreadRecv0, 5000, &rc2); 568 if (RT_SUCCESS(rc)) 569 ThreadRecv0 = NIL_RTTHREAD; 570 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2)) 571 { 572 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 0, rc=%Vrc, rc2=%Vrc\n", rc, rc2); 573 g_cErrors++; 574 } 575 576 rc = RTThreadWait(ThreadRecv1, 5000, &rc2); 577 if (RT_SUCCESS(rc)) 578 ThreadRecv1 = NIL_RTTHREAD; 579 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2)) 580 { 581 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 1, rc=%Vrc, rc2=%Vrc\n", rc, rc2); 582 g_cErrors++; 583 } 584 546 585 rc = INTNETR0IfClose(pIntNet, hIf0); 547 586 if (VBOX_SUCCESS(rc)) … … 555 594 g_cErrors++; 556 595 } 596 557 597 rc = INTNETR0IfClose(pIntNet, hIf1); 558 598 if (VBOX_SUCCESS(rc)) … … 567 607 } 568 608 569 rc = RTThreadWait(ThreadRecv0, 5000, &rc2);570 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2))571 {572 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 0, rc=%Vrc, rc2=%Vrc\n", rc, rc2);573 g_cErrors++;574 }575 576 rc = RTThreadWait(ThreadRecv1, 5000, &rc2);577 if (VBOX_FAILURE(rc) || VBOX_FAILURE(rc2))578 {579 RTPrintf("tstIntNetR0: Failed waiting on receiver thread 1, rc=%Vrc, rc2=%Vrc\n", rc, rc2);580 g_cErrors++;581 }582 609 583 610 /* check if the network still exist... */ … … 593 620 g_cErrors++; 594 621 } 622 623 /* 624 * Give them a chance to complete... 625 */ 626 RTThreadWait(ThreadRecv0, 5000, NULL); 627 RTThreadWait(ThreadRecv1, 5000, NULL); 628 RTThreadWait(ThreadSend0, 5000, NULL); 629 RTThreadWait(ThreadSend1, 5000, NULL); 630 595 631 } 596 632 else … … 618 654 g_cErrors++; 619 655 } 656 657 if (hIf1 != INTNET_HANDLE_INVALID) 658 rc = INTNETR0IfClose(pIntNet, hIf1); 620 659 } 621 660 else … … 624 663 g_cErrors++; 625 664 } 665 666 if (hIf0 != INTNET_HANDLE_INVALID) 667 rc = INTNETR0IfClose(pIntNet, hIf0); 626 668 } 627 669 else
Note:
See TracChangeset
for help on using the changeset viewer.