- Timestamp:
- May 5, 2015 3:28:45 AM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 100033
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r54868 r55652 162 162 /** Pointer to a const destination table. */ 163 163 typedef INTNETDSTTAB const *PCINTNETDSTTAB; 164 165 166 /** Network layer address type. */167 typedef enum INTNETADDRTYPE168 {169 /** The invalid 0 entry. */170 kIntNetAddrType_Invalid = 0,171 /** IP version 4. */172 kIntNetAddrType_IPv4,173 /** IP version 6. */174 kIntNetAddrType_IPv6,175 /** IPX. */176 kIntNetAddrType_IPX,177 /** The end of the valid values. */178 kIntNetAddrType_End,179 /** The usual 32-bit hack. */180 kIntNetAddrType_32BitHack = 0x7fffffff181 } INTNETADDRTYPE;182 /** Pointer to a network layer address type. */183 typedef INTNETADDRTYPE *PINTNETADDRTYPE;184 185 164 186 165 /** … … 356 335 struct INTNETNETWORK *pNext; 357 336 358 /** The spinlock protecting MacTab and INTNETTRUNKIF::aAddrCache.337 /** The spinlock protecting MacTab, aAddrBlacklist and INTNETIF::aAddrCache. 359 338 * Interrupt safe. */ 360 339 RTSPINLOCK hAddrSpinlock; … … 362 341 * This doubles as interface collection. */ 363 342 INTNETMACTAB MacTab; 343 344 /** The network layer address cache. (Indexed by type, 0 entry isn't used. 345 * Contains host addresses. We don't let guests spoof them. */ 346 INTNETADDRCACHE aAddrBlacklist[kIntNetAddrType_End]; 364 347 365 348 /** Wait for an interface to stop being busy so it can be removed or have its … … 1168 1151 * @param pszMsg Log message. 1169 1152 */ 1170 DECLINLINE(void) intnetR0NetworkAddrCacheDelete (PINTNETNETWORK pNetwork, PCRTNETADDRU pAddr, INTNETADDRTYPE const enmType,1171 uint8_t const cbAddr, const char *pszMsg)1172 { 1173 RTSpinlockAcquire(pNetwork->hAddrSpinlock);1174 1153 DECLINLINE(void) intnetR0NetworkAddrCacheDeleteUnlocked(PINTNETNETWORK pNetwork, 1154 PCRTNETADDRU pAddr, INTNETADDRTYPE enmType, 1155 uint8_t const cbAddr, 1156 const char *pszMsg) 1157 { 1175 1158 uint32_t iIf = pNetwork->MacTab.cEntries; 1176 1159 while (iIf--) 1177 1160 { 1178 1161 PINTNETIF pIf = pNetwork->MacTab.paEntries[iIf].pIf; 1162 1179 1163 int i = intnetR0IfAddrCacheLookup(&pIf->aAddrCache[enmType], pAddr, cbAddr); 1180 1164 if (RT_UNLIKELY(i >= 0)) 1181 1165 intnetR0IfAddrCacheDeleteIt(pIf, &pIf->aAddrCache[enmType], i, pszMsg); 1182 1166 } 1167 } 1168 1169 1170 /** 1171 * Deletes the address from all the interface caches. 1172 * 1173 * This is used to remove stale entries that has been reassigned to 1174 * other machines on the network. 1175 * 1176 * @param pNetwork The network. 1177 * @param pAddr The address. 1178 * @param enmType The address type. 1179 * @param cbAddr The address size (optimization). 1180 * @param pszMsg Log message. 1181 */ 1182 DECLINLINE(void) intnetR0NetworkAddrCacheDelete(PINTNETNETWORK pNetwork, PCRTNETADDRU pAddr, INTNETADDRTYPE const enmType, 1183 uint8_t const cbAddr, const char *pszMsg) 1184 { 1185 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 1186 1187 intnetR0NetworkAddrCacheDeleteUnlocked(pNetwork, pAddr, enmType, cbAddr, pszMsg); 1183 1188 1184 1189 RTSpinlockRelease(pNetwork->hAddrSpinlock); … … 1253 1258 1254 1259 /** 1260 * Look up specified address in the network's blacklist. 1261 * 1262 * @param pNetwork The network. 1263 * @param enmType The address type. 1264 * @param pAddr The address. 1265 */ 1266 static bool intnetR0NetworkBlacklistLookup(PINTNETNETWORK pNetwork, 1267 PCRTNETADDRU pAddr, INTNETADDRTYPE enmType) 1268 { 1269 PINTNETADDRCACHE pCache = &pNetwork->aAddrBlacklist[enmType]; 1270 1271 if (RT_UNLIKELY(pCache->cEntriesAlloc == 0)) 1272 return false; 1273 1274 const uint8_t cbAddr = pCache->cbAddress; 1275 Assert(cbAddr == intnetR0AddrSize(enmType)); 1276 1277 for (unsigned i = 0; i < pCache->cEntries; ++i) 1278 { 1279 uint8_t *pbEntry = pCache->pbEntries + pCache->cbEntry * i; 1280 if (intnetR0AddrUIsEqualEx((PCRTNETADDRU)pbEntry, pAddr, cbAddr)) 1281 return true; 1282 } 1283 1284 return false; 1285 } 1286 1287 1288 /** 1289 * Deletes specified address from network's blacklist. 1290 * 1291 * @param pNetwork The network. 1292 * @param enmType The address type. 1293 * @param pAddr The address. 1294 */ 1295 static void intnetR0NetworkBlacklistDelete(PINTNETNETWORK pNetwork, 1296 PCRTNETADDRU pAddr, INTNETADDRTYPE enmType) 1297 { 1298 PINTNETADDRCACHE pCache = &pNetwork->aAddrBlacklist[enmType]; 1299 1300 if (RT_UNLIKELY(pCache->cEntriesAlloc == 0)) 1301 return; 1302 1303 const uint8_t cbAddr = pCache->cbAddress; 1304 Assert(cbAddr == intnetR0AddrSize(enmType)); 1305 1306 for (unsigned i = 0; i < pCache->cEntries; ++i) 1307 { 1308 uint8_t *pbEntry = pCache->pbEntries + pCache->cbEntry * i; 1309 if (!intnetR0AddrUIsEqualEx((PCRTNETADDRU)pbEntry, pAddr, cbAddr)) 1310 continue; 1311 1312 --pCache->cEntries; 1313 memmove(pCache->pbEntries + i * pCache->cbEntry, 1314 pCache->pbEntries + (i + 1) * pCache->cbEntry, 1315 (pCache->cEntries - i) * pCache->cbEntry); 1316 return; 1317 } 1318 } 1319 1320 1321 /** 1322 * Adds specified address from network's blacklist. 1323 * 1324 * @param pNetwork The network. 1325 * @param enmType The address type. 1326 * @param pAddr The address. 1327 */ 1328 static void intnetR0NetworkBlacklistAdd(PINTNETNETWORK pNetwork, 1329 PCRTNETADDRU pAddr, INTNETADDRTYPE enmType) 1330 { 1331 PINTNETADDRCACHE pCache = &pNetwork->aAddrBlacklist[enmType]; 1332 1333 if (RT_UNLIKELY(pCache->cEntriesAlloc == 0)) 1334 return; 1335 1336 const uint8_t cbAddr = pCache->cbAddress; 1337 Assert(cbAddr == intnetR0AddrSize(enmType)); 1338 1339 /* lookup */ 1340 for (unsigned i = 0; i < pCache->cEntries; ++i) 1341 { 1342 uint8_t *pbEntry = pCache->pbEntries + pCache->cbEntry * i; 1343 if (RT_UNLIKELY(intnetR0AddrUIsEqualEx((PCRTNETADDRU)pbEntry, pAddr, cbAddr))) 1344 return; /* already exists */ 1345 } 1346 1347 if (pCache->cEntries >= pCache->cEntriesAlloc) 1348 { 1349 /* shift */ 1350 memmove(pCache->pbEntries, pCache->pbEntries + pCache->cbEntry, 1351 pCache->cbEntry * (pCache->cEntries - 1)); 1352 --pCache->cEntries; 1353 } 1354 1355 Assert(pCache->cEntries < pCache->cEntriesAlloc); 1356 1357 /* push */ 1358 uint8_t *pbEntry = pCache->pbEntries + pCache->cEntries * pCache->cbEntry; 1359 memcpy(pbEntry, pAddr, cbAddr); 1360 memset(pbEntry + pCache->cbAddress, '\0', pCache->cbEntry - cbAddr); 1361 ++pCache->cEntries; 1362 1363 Assert(pCache->cEntries <= pCache->cEntriesAlloc); 1364 } 1365 1366 1367 /** 1255 1368 * Adds an address to the cache, the caller is responsible for making sure it's 1256 1369 * not already in the cache. … … 1263 1376 * @param pszMsg log message. 1264 1377 */ 1265 static void intnetR0IfAddrCacheAddIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCRTNETADDRU pAddr, const char *pszMsg) 1378 static void intnetR0IfAddrCacheAddIt(PINTNETIF pIf, INTNETADDRTYPE enmAddrType, PCRTNETADDRU pAddr, 1379 const char *pszMsg) 1266 1380 { 1267 1381 PINTNETNETWORK pNetwork = pIf->pNetwork; 1268 1382 AssertReturnVoid(pNetwork); 1383 1384 PINTNETADDRCACHE pCache = &pIf->aAddrCache[enmAddrType]; 1385 1386 const uint8_t cbAddr = pCache->cbAddress; 1387 Assert(cbAddr == intnetR0AddrSize(enmAddrType)); 1388 1269 1389 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 1390 1391 bool fBlacklisted = intnetR0NetworkBlacklistLookup(pNetwork, pAddr, enmAddrType); 1392 if (fBlacklisted) 1393 { 1394 RTSpinlockRelease(pNetwork->hAddrSpinlock); 1395 1396 #ifdef LOG_ENABLED 1397 switch (enmAddrType) 1398 { 1399 case kIntNetAddrType_IPv4: 1400 Log(("%s: spoofing attempt for %RTnaipv4\n", 1401 __FUNCTION__, pAddr->IPv4)); 1402 break; 1403 case kIntNetAddrType_IPv6: 1404 Log(("%s: spoofing attempt for %RTnaipv6\n", 1405 __FUNCTION__, &pAddr->IPv6)); 1406 break; 1407 default: 1408 Log(("%s: spoofing attempt for %.*Rhxs (type %d)\n", 1409 __FUNCTION__, cbAddr, pAddr, enmAddrType)); 1410 break; 1411 } 1412 #endif 1413 return; 1414 } 1270 1415 1271 1416 if (RT_UNLIKELY(!pCache->cEntriesAlloc)) … … 1292 1437 memcpy(pbEntry, pAddr, pCache->cbAddress); 1293 1438 memset(pbEntry + pCache->cbAddress, '\0', pCache->cbEntry - pCache->cbAddress); 1439 1294 1440 #ifdef LOG_ENABLED 1295 INTNETADDRTYPE enmAddrType = (INTNETADDRTYPE)(uintptr_t)(pCache - &pIf->aAddrCache[0]);1296 1441 switch (enmAddrType) 1297 1442 { … … 1326 1471 * @param pszMsg Log message. 1327 1472 */ 1328 static void intnetR0IfAddrCacheAddSlow(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCRTNETADDRU pAddr, uint8_t const cbAddr, const char *pszMsg) 1329 { 1473 static void intnetR0IfAddrCacheAddSlow(PINTNETIF pIf, INTNETADDRTYPE enmAddrType, PCRTNETADDRU pAddr, 1474 const char *pszMsg) 1475 { 1476 PINTNETADDRCACHE pCache = &pIf->aAddrCache[enmAddrType]; 1477 1478 const uint8_t cbAddr = pCache->cbAddress; 1479 Assert(cbAddr == intnetR0AddrSize(enmAddrType)); 1480 1330 1481 /* 1331 1482 * Check all but the first and last entries, the caller … … 1345 1496 * Not found, add it. 1346 1497 */ 1347 intnetR0IfAddrCacheAddIt(pIf, pCache, pAddr, pszMsg);1498 intnetR0IfAddrCacheAddIt(pIf, enmAddrType, pAddr, pszMsg); 1348 1499 } 1349 1500 … … 1360 1511 * @param pszMsg Log message. 1361 1512 */ 1362 DECLINLINE(void) intnetR0IfAddrCacheAdd(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCRTNETADDRU pAddr, 1363 uint8_t const cbAddr, const char *pszMsg) 1364 { 1365 Assert(pCache->cbAddress == cbAddr); 1513 DECLINLINE(void) intnetR0IfAddrCacheAdd(PINTNETIF pIf, INTNETADDRTYPE enmAddrType, PCRTNETADDRU pAddr, 1514 const char *pszMsg) 1515 { 1516 PINTNETADDRCACHE pCache = &pIf->aAddrCache[enmAddrType]; 1517 1518 const uint8_t cbAddr = pCache->cbAddress; 1519 Assert(cbAddr == intnetR0AddrSize(enmAddrType)); 1366 1520 1367 1521 /* … … 1374 1528 && intnetR0AddrUIsEqualEx((PCRTNETADDRU)(pCache->pbEntries + pCache->cbEntry * i), pAddr, cbAddr))) )) 1375 1529 return; 1376 intnetR0IfAddrCacheAddSlow(pIf, pCache, pAddr, cbAddr, pszMsg); 1530 1531 intnetR0IfAddrCacheAddSlow(pIf, enmAddrType, pAddr, pszMsg); 1377 1532 } 1378 1533 … … 2150 2305 if (pMatchingIf) 2151 2306 { 2152 intnetR0IfAddrCacheAdd(pMatchingIf, &pMatchingIf->aAddrCache[kIntNetAddrType_IPv4],2153 (PCRTNETADDRU)&pDhcp->bp_yiaddr, sizeof(RTNETADDRIPV4),"DHCP_MT_ACK");2307 intnetR0IfAddrCacheAdd(pMatchingIf, kIntNetAddrType_IPv4, 2308 (PCRTNETADDRU)&pDhcp->bp_yiaddr, "DHCP_MT_ACK"); 2154 2309 intnetR0BusyDecIf(pMatchingIf); 2155 2310 } … … 2423 2578 && intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(Addr.IPv6)) < 0) 2424 2579 { 2425 intnetR0IfAddrCacheAdd It(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, "if/ipv6");2580 intnetR0IfAddrCacheAdd(pIf, kIntNetAddrType_IPv6, &Addr, "if/ipv6"); 2426 2581 } 2427 2582 } … … 2469 2624 return; 2470 2625 } 2471 intnetR0IfAddrCacheAddIt(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, "if/ipv4"); 2626 2627 intnetR0IfAddrCacheAddIt(pIf, kIntNetAddrType_IPv4, &Addr, "if/ipv4"); 2472 2628 fValidatedIpHdr = true; 2473 2629 } … … 2545 2701 if ( !memcmp(&pArpIPv4->ar_sha, &pIf->MacAddr, sizeof(RTMAC)) 2546 2702 && intnetR0IPv4AddrIsGood(pArpIPv4->ar_spa)) 2547 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], 2548 (PCRTNETADDRU)&pArpIPv4->ar_spa, sizeof(RTNETADDRIPV4), "if/arp"); 2703 { 2704 intnetR0IfAddrCacheAdd(pIf, kIntNetAddrType_IPv4, (PCRTNETADDRU)&pArpIPv4->ar_spa, "if/arp"); 2705 } 2549 2706 } 2550 2707 … … 5357 5514 5358 5515 5516 /** @copydoc INTNETTRUNKSWPORT::pfnNotifyHostAddress */ 5517 static DECLCALLBACK(void) intnetR0NetworkNotifyHostAddress(PINTNETTRUNKSWPORT pSwitchPort, 5518 bool fAdded, 5519 INTNETADDRTYPE enmType, const void *pvAddr) 5520 { 5521 PINTNETTRUNKIF pTrunkIf = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 5522 PINTNETNETWORK pNetwork = pTrunkIf->pNetwork; 5523 PCRTNETADDRU pAddr = (PCRTNETADDRU)pvAddr; 5524 uint8_t cbAddr; 5525 5526 if (enmType == kIntNetAddrType_IPv4) 5527 { 5528 Log(("%s: %s %RTnaipv4\n", 5529 __FUNCTION__, (fAdded ? "add" : "del"), 5530 pAddr->IPv4)); 5531 cbAddr = 4; 5532 } 5533 else if (enmType == kIntNetAddrType_IPv6) 5534 { 5535 Log(("%s: %s %RTnaipv6\n", 5536 __FUNCTION__, (fAdded ? "add" : "del"), 5537 pAddr)); 5538 cbAddr = 16; 5539 } 5540 else 5541 { 5542 Log(("%s: unexpected address type %d\n", __FUNCTION__, enmType)); 5543 return; 5544 } 5545 5546 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 5547 if (fAdded) /* one of host interfaces got a new address */ 5548 { 5549 /* blacklist it to prevent spoofing by guests */ 5550 intnetR0NetworkBlacklistAdd(pNetwork, pAddr, enmType); 5551 5552 /* kick out any guest that uses it */ 5553 intnetR0NetworkAddrCacheDeleteUnlocked(pNetwork, pAddr, enmType, cbAddr, "tif/host"); 5554 } 5555 else /* address deleted from one of host interfaces */ 5556 { 5557 /* stop blacklisting it, guests may use it now */ 5558 intnetR0NetworkBlacklistDelete(pNetwork, pAddr, enmType); 5559 } 5560 RTSpinlockRelease(pNetwork->hAddrSpinlock); 5561 } 5562 5563 5359 5564 /** 5360 5565 * Shutdown the trunk interface. … … 5520 5725 pTrunk->SwitchPort.pfnReportGsoCapabilities = intnetR0TrunkIfPortReportGsoCapabilities; 5521 5726 pTrunk->SwitchPort.pfnReportNoPreemptDsts = intnetR0TrunkIfPortReportNoPreemptDsts; 5727 if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 5728 pTrunk->SwitchPort.pfnNotifyHostAddress = intnetR0NetworkNotifyHostAddress; 5522 5729 pTrunk->SwitchPort.pfnDisconnect = intnetR0TrunkIfPortDisconnect; 5523 5730 pTrunk->SwitchPort.u32VersionEnd = INTNETTRUNKSWPORT_VERSION; … … 5650 5857 */ 5651 5858 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 5859 5860 for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++) 5861 intnetR0IfAddrCacheDestroy(&pNetwork->aAddrBlacklist[i]); 5652 5862 5653 5863 uint32_t iIf = pNetwork->MacTab.cEntries; … … 6112 6322 if (RT_SUCCESS(rc)) 6113 6323 { 6324 for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End && RT_SUCCESS(rc); i++) 6325 rc = intnetR0IfAddrCacheInit(&pNetwork->aAddrBlacklist[i], (INTNETADDRTYPE)i, 6326 !!(pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)); 6327 } 6328 if (RT_SUCCESS(rc)) 6329 { 6114 6330 /* 6115 6331 * Register the object in the current session and link it into the network list. -
trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
r52394 r55652 154 154 /** The MAC address of the interface. */ 155 155 RTMAC MacAddr; 156 /** PF_SYSTEM socket to listen for events (XXX: globals?) */ 157 socket_t pSysSock; 156 158 /** @} */ 157 159 # elif defined(RT_OS_LINUX) … … 171 173 /** The MAC address of the interface. */ 172 174 RTMAC MacAddr; 173 struct notifier_block Notifier; 175 struct notifier_block Notifier; /* netdevice */ 176 struct notifier_block NotifierIPv4; 177 struct notifier_block NotifierIPv6; 174 178 struct packet_type PacketType; 175 179 # ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE -
trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
r52618 r55652 52 52 #include <sys/errno.h> 53 53 #include <sys/ioccom.h> 54 #include <sys/filio.h> 54 55 #include <sys/malloc.h> 55 56 #include <sys/proc.h> … … 62 63 #include <net/kpi_interfacefilter.h> 63 64 RT_C_DECLS_END 65 66 #include <sys/kpi_socket.h> 64 67 #include <net/if.h> 68 #include <net/if_var.h> 69 #include <netinet/in.h> 70 #include <netinet/in_var.h> 71 #include <netinet6/in6_var.h> 65 72 66 73 #define VBOXNETFLT_OS_SPECFIC 1 … … 87 94 static kern_return_t VBoxNetFltDarwinStart(struct kmod_info *pKModInfo, void *pvData); 88 95 static kern_return_t VBoxNetFltDarwinStop(struct kmod_info *pKModInfo, void *pvData); 96 97 static void vboxNetFltDarwinSysSockUpcall(socket_t pSysSock, void *pvData, int fWait); 89 98 RT_C_DECLS_END 90 99 … … 1294 1303 if (pIfFilter) 1295 1304 iflt_detach(pIfFilter); 1305 1306 if (pThis->u.s.pSysSock != NULL) 1307 { 1308 sock_close(pThis->u.s.pSysSock); 1309 pThis->u.s.pSysSock = NULL; 1310 } 1296 1311 } 1297 1312 … … 1300 1315 { 1301 1316 NOREF(pvContext); 1302 return vboxNetFltDarwinAttachToInterface(pThis, false /* fRediscovery */); 1317 1318 int rc = vboxNetFltDarwinAttachToInterface(pThis, false /* fRediscovery */); 1319 if (RT_FAILURE(rc)) 1320 return rc; 1321 1322 if (pThis->pSwitchPort->pfnNotifyHostAddress == NULL) 1323 return rc; 1324 1325 /* 1326 * XXX: uwe 1327 * 1328 * Learn host's IP addresses and set up notifications for changes. 1329 * To avoid racing, set up notifications first. 1330 * 1331 * XXX: This should probably be global, since the only thing 1332 * specific to ifnet here is its IPv6 link-local address. 1333 */ 1334 errno_t error; 1335 1336 error = sock_socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT, 1337 vboxNetFltDarwinSysSockUpcall, pThis, 1338 &pThis->u.s.pSysSock); 1339 if (error != 0) 1340 { 1341 LogRel(("sock_socket(SYSPROTO_EVENT): error %d\n", error)); 1342 return rc; 1343 } 1344 1345 int nbio = 1; 1346 error = sock_ioctl(pThis->u.s.pSysSock, FIONBIO, &nbio); 1347 if (error != 0) 1348 { 1349 LogRel(("FIONBIO: error %d\n", error)); 1350 sock_close(pThis->u.s.pSysSock); 1351 return rc; 1352 } 1353 1354 if (!sock_isnonblocking(pThis->u.s.pSysSock)) 1355 { 1356 LogRel(("FIONBIO ok, but socket is blocking?!\n")); 1357 sock_close(pThis->u.s.pSysSock); 1358 return rc; 1359 } 1360 1361 struct kev_request req; 1362 req.vendor_code = KEV_VENDOR_APPLE; 1363 req.kev_class = KEV_NETWORK_CLASS; 1364 req.kev_subclass = KEV_ANY_SUBCLASS; /* need both INET and INET6, so have to request all */ 1365 1366 error = sock_ioctl(pThis->u.s.pSysSock, SIOCSKEVFILT, &req); 1367 if (error != 0) 1368 { 1369 LogRel(("SIOCSKEVFILT: error %d\n", error)); 1370 sock_close(pThis->u.s.pSysSock); 1371 return rc; 1372 } 1373 1374 ifnet_t pIfNet = pThis->u.s.pIfNet; /* already retained */ 1375 1376 ifaddr_t *pIfAddrList; 1377 error = ifnet_get_address_list(/* all interfaces*/ NULL, &pIfAddrList); 1378 if (error != 0) 1379 { 1380 LogRel(("ifnet_get_address_list: error %d\n", error)); 1381 return rc; 1382 } 1383 1384 for (ifaddr_t *pIfAddr = pIfAddrList; *pIfAddr != NULL; ++pIfAddr) 1385 { 1386 ifaddr_t ifa = *pIfAddr; 1387 sa_family_t family = ifaddr_address_family(ifa); 1388 struct sockaddr_storage ss; 1389 1390 error = ifaddr_address(ifa, (struct sockaddr *)&ss, sizeof(ss)); 1391 if (error != 0) 1392 { 1393 LogRel(("getting address family %d: error %d\n", family, error)); 1394 continue; 1395 } 1396 1397 if (family == AF_INET) 1398 { 1399 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 1400 u_int32_t u32Addr = ntohl(sin->sin_addr.s_addr); 1401 1402 if ((u32Addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 1403 continue; 1404 1405 Log(("> inet %RTnaipv4\n", sin->sin_addr.s_addr)); 1406 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1407 /* :fAdded */ true, kIntNetAddrType_IPv4, &sin->sin_addr); 1408 } 1409 else if (family == AF_INET6) 1410 { 1411 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 1412 1413 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) 1414 continue; 1415 1416 /* link-local from other interfaces are out of scope */ 1417 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && ifaddr_ifnet(ifa) != pIfNet) 1418 continue; 1419 1420 Log(("> inet6 %RTnaipv6\n", &sin6->sin6_addr)); 1421 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1422 /* :fAdded */ true, kIntNetAddrType_IPv6, &sin6->sin6_addr); 1423 } 1424 } 1425 1426 ifnet_free_address_list(pIfAddrList); 1427 1428 /* 1429 * Now that we've got current addresses, check for events that 1430 * might have happened while we were working. 1431 */ 1432 vboxNetFltDarwinSysSockUpcall(pThis->u.s.pSysSock, pThis, MBUF_DONTWAIT); 1433 1434 return rc; 1435 } 1436 1437 1438 static void vboxNetFltDarwinSysSockUpcall(socket_t pSysSock, void *pvData, int fWait) 1439 { 1440 PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvData; 1441 errno_t error; 1442 1443 NOREF(fWait); 1444 1445 if (RT_UNLIKELY(pSysSock != pThis->u.s.pSysSock)) 1446 { 1447 Log(("vboxNetFltDarwinSysSockUpcall: %p != %p?\n", 1448 pSysSock, pThis->u.s.pSysSock)); 1449 return; 1450 } 1451 1452 for (;;) { 1453 mbuf_t m; 1454 size_t len = sizeof(struct kern_event_msg) - sizeof(u_int32_t) 1455 + sizeof(struct kev_in6_data); 1456 1457 error = sock_receivembuf(pSysSock, NULL, &m, 0, &len); 1458 if (error == EWOULDBLOCK) 1459 { 1460 Log(("vboxNetFltDarwinSysSockUpcall: EWOULDBLOCK - we are done\n")); 1461 error = 0; 1462 break; 1463 } 1464 else if (error != 0) 1465 { 1466 Log(("sock_receivembuf: error %d\n", error)); 1467 break; 1468 } 1469 1470 if (len < sizeof(struct kern_event_msg) - sizeof(u_int32_t)) 1471 { 1472 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short\n", 1473 (unsigned int)len)); 1474 mbuf_freem(m); 1475 return; 1476 } 1477 1478 struct kern_event_msg *msg = (struct kern_event_msg *)mbuf_data(m); 1479 if (msg->kev_subclass == KEV_INET_SUBCLASS) 1480 { 1481 if (len - (sizeof(struct kern_event_msg) - sizeof(u_int32_t)) < sizeof(struct kev_in_data)) 1482 { 1483 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short for KEV_INET_SUBCLASS\n", 1484 (unsigned int)len)); 1485 mbuf_freem(m); 1486 return; 1487 } 1488 1489 struct kev_in_data *iev = (struct kev_in_data *)msg->event_data; 1490 PCRTNETADDRU pAddr = (PCRTNETADDRU)&iev->ia_addr; 1491 switch (msg->event_code) 1492 { 1493 case KEV_INET_NEW_ADDR: 1494 Log(("KEV_INET_NEW_ADDR %RTnaipv4\n", pAddr->IPv4)); 1495 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1496 /* :fAdded */ true, kIntNetAddrType_IPv4, pAddr); 1497 break; 1498 1499 case KEV_INET_ADDR_DELETED: 1500 Log(("KEV_INET_ADDR_DELETED %RTnaipv4\n", pAddr->IPv4)); 1501 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1502 /* :fAdded */ false, kIntNetAddrType_IPv4, &iev->ia_addr); 1503 break; 1504 1505 default: 1506 Log(("KEV INET event %u addr %RTnaipv4\n", msg->event_code, pAddr->IPv4)); 1507 break; 1508 } 1509 } 1510 else if (msg->kev_subclass == KEV_INET6_SUBCLASS) 1511 { 1512 if (len - (sizeof(struct kern_event_msg) - sizeof(u_int32_t)) < sizeof(struct kev_in6_data)) 1513 { 1514 Log(("vboxNetFltDarwinSysSockUpcall: %u bytes is too short for KEV_INET6_SUBCLASS\n", 1515 (unsigned int)len)); 1516 mbuf_freem(m); 1517 return; 1518 } 1519 1520 struct kev_in6_data *iev6 = (struct kev_in6_data *)msg->event_data; 1521 PCRTNETADDRU pAddr = (PCRTNETADDRU)&iev6->ia_addr.sin6_addr; 1522 switch (msg->event_code) 1523 { 1524 case KEV_INET6_NEW_USER_ADDR: 1525 Log(("KEV_INET6_NEW_USER_ADDR: %RTnaipv6\n", pAddr)); 1526 goto kev_inet6_new; 1527 1528 case KEV_INET6_NEW_LL_ADDR: 1529 Log(("KEV_INET6_NEW_LL_ADDR: %RTnaipv6\n", pAddr)); 1530 /* XXX: uwe: TODO: only interface we are attached to */ 1531 goto kev_inet6_new; 1532 1533 case KEV_INET6_NEW_RTADV_ADDR: 1534 Log(("KEV_INET6_NEW_RTADV_ADDR: %RTnaipv6\n", pAddr)); 1535 goto kev_inet6_new; 1536 1537 kev_inet6_new: 1538 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1539 /* :fAdded */ true, kIntNetAddrType_IPv6, pAddr); 1540 break; 1541 1542 case KEV_INET6_ADDR_DELETED: 1543 Log(("KEV_INET6_ADDR_DELETED: %RTnaipv6\n", pAddr)); 1544 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 1545 /* :fAdded */ false, kIntNetAddrType_IPv6, pAddr); 1546 break; 1547 1548 default: 1549 Log(("KEV INET6 event %u addr %RTnaipv6\n", msg->event_code, pAddr)); 1550 break; 1551 } 1552 } 1553 else 1554 { 1555 Log(("vboxNetFltDarwinSysSockUpcall: subclass %u ignored\n", 1556 (unsigned)msg->kev_subclass)); 1557 } 1558 1559 mbuf_freem(m); 1560 } 1303 1561 } 1304 1562 … … 1314 1572 pThis->u.s.fNeedSetPromiscuous = false; 1315 1573 //pThis->u.s.MacAddr = {0}; 1574 pThis->u.s.pSysSock = NULL; 1316 1575 1317 1576 return VINF_SUCCESS; -
trunk/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
r54461 r55652 28 28 #include <linux/rtnetlink.h> 29 29 #include <linux/miscdevice.h> 30 #include <linux/inetdevice.h> 30 31 #include <linux/ip.h> 31 32 #include <linux/if_vlan.h> 33 #include <net/if_inet6.h> 34 #include <net/addrconf.h> 32 35 33 36 #include <VBox/log.h> … … 1857 1860 } 1858 1861 1862 static int vboxNetFltLinuxNotifierIPv4Callback(struct notifier_block *self, unsigned long ulEventType, void *ptr) 1863 { 1864 PVBOXNETFLTINS pThis = RT_FROM_MEMBER(self, VBOXNETFLTINS, u.s.NotifierIPv4); 1865 struct net_device *pDev; 1866 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 1867 int rc = NOTIFY_OK; 1868 1869 pDev = vboxNetFltLinuxRetainNetDev(pThis); 1870 Log(("VBoxNetFlt: %s: IPv4 event %s(0x%lx): addr %RTnaipv4 mask %RTnaipv4\n", 1871 pDev ? netdev_name(pDev) : "<???>", 1872 vboxNetFltLinuxGetNetDevEventName(ulEventType), ulEventType, 1873 ifa->ifa_address, ifa->ifa_mask)); 1874 1875 if (pDev != NULL) 1876 vboxNetFltLinuxReleaseNetDev(pThis, pDev); 1877 1878 if (pThis->pSwitchPort->pfnNotifyHostAddress) 1879 { 1880 bool fAdded; 1881 if (ulEventType == NETDEV_UP) 1882 fAdded = true; 1883 else if (ulEventType == NETDEV_DOWN) 1884 fAdded = false; 1885 else 1886 return NOTIFY_OK; 1887 1888 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, fAdded, 1889 kIntNetAddrType_IPv4, &ifa->ifa_local); 1890 } 1891 1892 return rc; 1893 } 1894 1895 1896 static int vboxNetFltLinuxNotifierIPv6Callback(struct notifier_block *self, unsigned long ulEventType, void *ptr) 1897 { 1898 PVBOXNETFLTINS pThis = RT_FROM_MEMBER(self, VBOXNETFLTINS, u.s.NotifierIPv6); 1899 struct net_device *pDev; 1900 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; 1901 int rc = NOTIFY_OK; 1902 1903 pDev = vboxNetFltLinuxRetainNetDev(pThis); 1904 Log(("VBoxNetFlt: %s: IPv6 event %s(0x%lx): %RTnaipv6\n", 1905 pDev ? netdev_name(pDev) : "<???>", 1906 vboxNetFltLinuxGetNetDevEventName(ulEventType), ulEventType, 1907 &ifa->addr)); 1908 1909 if (pDev != NULL) 1910 vboxNetFltLinuxReleaseNetDev(pThis, pDev); 1911 1912 if (pThis->pSwitchPort->pfnNotifyHostAddress) 1913 { 1914 bool fAdded; 1915 if (ulEventType == NETDEV_UP) 1916 fAdded = true; 1917 else if (ulEventType == NETDEV_DOWN) 1918 fAdded = false; 1919 else 1920 return NOTIFY_OK; 1921 1922 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, fAdded, 1923 kIntNetAddrType_IPv6, &ifa->addr); 1924 } 1925 1926 return rc; 1927 } 1928 1929 1859 1930 bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis) 1860 1931 { … … 2053 2124 dev_put(pDev); 2054 2125 } 2126 2127 unregister_inet6addr_notifier(&pThis->u.s.NotifierIPv6); 2128 unregister_inetaddr_notifier(&pThis->u.s.NotifierIPv4); 2129 2055 2130 Log(("vboxNetFltOsDeleteInstance: this=%p: Notifier removed.\n", pThis)); 2056 2131 unregister_netdevice_notifier(&pThis->u.s.Notifier); … … 2079 2154 || !try_module_get(THIS_MODULE)) 2080 2155 return VERR_INTNET_FLT_IF_FAILED; 2156 2157 if (pThis->pSwitchPort->pfnNotifyHostAddress) 2158 { 2159 struct net *net = dev_net(pThis->u.s.pDev); 2160 struct net_device *dev; 2161 2162 rcu_read_lock(); 2163 for_each_netdev_rcu(net, dev) 2164 { 2165 struct in_device *in_dev; 2166 struct inet6_dev *in6_dev; 2167 2168 /* 2169 * IPv4 2170 */ 2171 in_dev = __in_dev_get_rcu(dev); 2172 if (in_dev != NULL) 2173 { 2174 for_ifa(in_dev) { 2175 if (ifa->ifa_address == htonl(INADDR_LOOPBACK)) 2176 goto continue_netdev; 2177 2178 Log(("%s: %s: IPv4: addr %RTnaipv4 mask %RTnaipv4\n", 2179 __FUNCTION__, netdev_name(dev), 2180 ifa->ifa_address, ifa->ifa_mask)); 2181 2182 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 2183 /* :fAdded */ true, kIntNetAddrType_IPv4, &ifa->ifa_address); 2184 } endfor_ifa(in_dev); 2185 } 2186 2187 /* 2188 * IPv6 2189 */ 2190 in6_dev = __in6_dev_get(dev); 2191 if (in6_dev != NULL) 2192 { 2193 struct inet6_ifaddr *ifa; 2194 2195 read_lock_bh(&in6_dev->lock); 2196 list_for_each_entry(ifa, &in6_dev->addr_list, if_list) 2197 { 2198 Log(("%s: %s: IPv6: addr %RTnaipv6/%u\n", 2199 __FUNCTION__, netdev_name(dev), 2200 &ifa->addr, (unsigned)ifa->prefix_len)); 2201 2202 pThis->pSwitchPort->pfnNotifyHostAddress(pThis->pSwitchPort, 2203 /* :fAdded */ true, kIntNetAddrType_IPv6, &ifa->addr); 2204 } 2205 read_unlock_bh(&in6_dev->lock); 2206 } 2207 2208 continue_netdev: 2209 /* continue */; 2210 } 2211 rcu_read_unlock(); 2212 2213 Log(("%s: pfnNotifyHostAddress is set, register notifiers\n", __FUNCTION__)); 2214 2215 pThis->u.s.NotifierIPv4.notifier_call = vboxNetFltLinuxNotifierIPv4Callback; 2216 err = register_inetaddr_notifier(&pThis->u.s.NotifierIPv4); 2217 if (err) 2218 LogRel(("%s: failed to register IPv4 notifier: error %d\n", 2219 __FUNCTION__, err)); 2220 2221 pThis->u.s.NotifierIPv6.notifier_call = vboxNetFltLinuxNotifierIPv6Callback; 2222 err = register_inet6addr_notifier(&pThis->u.s.NotifierIPv6); 2223 if (err) 2224 LogRel(("%s: failed to register IPv6 notifier: error %d\n", 2225 __FUNCTION__, err)); 2226 } 2227 else 2228 Log(("%s: uwe: pfnNotifyHostAddress is NULL\n", __FUNCTION__)); 2081 2229 2082 2230 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.