- Timestamp:
- Sep 17, 2009 11:00:13 AM (15 years ago)
- Location:
- trunk/src/VBox/HostDrivers/VBoxNetAdp
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetAdp/Makefile.kmk
r23079 r23082 47 47 . 48 48 VBoxNetAdp_SOURCES.darwin = \ 49 darwin/VBoxNetAdp-darwin.cpp 49 darwin/VBoxNetAdp-darwin.cpp \ 50 VBoxNetAdp.c 50 51 VBoxNetAdp_SOURCES.solaris = \ 51 52 solaris/VBoxNetAdp-solaris.c -
trunk/src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h
r22875 r23082 79 79 kVBoxNetAdpState_Invalid, 80 80 kVBoxNetAdpState_Transitional, 81 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT82 kVBoxNetAdpState_Available,83 kVBoxNetAdpState_Connected,84 #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */85 81 kVBoxNetAdpState_Active, 86 82 kVBoxNetAdpState_U32Hack = 0xFFFFFFFF … … 90 86 struct VBoxNetAdapter 91 87 { 92 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT93 /** The spinlock protecting the state variables and host interface handle. */94 RTSPINLOCK hSpinlock;95 96 /* --- Protected with spinlock. --- */97 98 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */99 88 /** Denotes availability of this slot in adapter array. */ 100 89 VBOXNETADPSTATE enmState; 101 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT102 103 /* --- Unprotected. Atomic access. --- */104 105 /** Reference count. */106 uint32_t volatile cRefs;107 /** The busy count.108 * This counts the number of current callers and pending packet. */109 uint32_t volatile cBusy;110 111 /* --- Unprotected. Do not modify when cBusy > 0. --- */112 113 /** Our RJ-45 port.114 * This is what the internal network plugs into. */115 INTNETTRUNKIFPORT MyPort;116 /** The RJ-45 port on the INTNET "switch".117 * This is what we're connected to. */118 PINTNETTRUNKSWPORT pSwitchPort;119 /** Pointer to the globals. */120 PVBOXNETADPGLOBALS pGlobals;121 /** The event that is signaled when we go idle and that pfnWaitForIdle blocks on. */122 RTSEMEVENT hEventIdle;123 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */124 90 /** Corresponds to the digit at the end of device name. */ 125 91 uint32_t uUnit; … … 182 148 DECLHIDDEN(int) vboxNetAdpDestroy(PVBOXNETADP pThis); 183 149 DECLHIDDEN(PVBOXNETADP) vboxNetAdpFindByName(const char *pszName); 150 DECLHIDDEN(void) vboxNetAdpComposeMACAddress(PVBOXNETADP pThis, PRTMAC pMac); 184 151 185 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT186 /**187 * The global data of the VBox filter driver.188 *189 * This contains the bit required for communicating with support driver, VBoxDrv190 * (start out as SupDrv).191 */192 typedef struct VBOXNETADPGLOBALS193 {194 /** Mutex protecting the list of instances and state changes. */195 RTSEMFASTMUTEX hFastMtx;196 /** Array of adapter instances. */197 VBOXNETADP aAdapters[VBOXNETADP_MAX_INSTANCES];198 199 /** The INTNET trunk network interface factory. */200 INTNETTRUNKFACTORY TrunkFactory;201 /** The SUPDRV component factory registration. */202 SUPDRVFACTORY SupDrvFactory;203 /** The number of current factory references. */204 int32_t volatile cFactoryRefs;205 /** The SUPDRV IDC handle (opaque struct). */206 SUPDRVIDCHANDLE SupDrvIDC;207 } VBOXNETADPGLOBALS;208 209 210 DECLHIDDEN(void) vboxNetAdpComposeMACAddress(PVBOXNETADP pThis, PRTMAC pMac);211 DECLHIDDEN(void) vboxNetAdpReceive(PVBOXNETADP pThis, PINTNETSG pSG);212 DECLHIDDEN(bool) vboxNetAdpPrepareToReceive(PVBOXNETADP pThis);213 DECLHIDDEN(void) vboxNetAdpCancelReceive(PVBOXNETADP pThis);214 215 DECLHIDDEN(int) vboxNetAdpInitGlobals(PVBOXNETADPGLOBALS pGlobals);216 DECLHIDDEN(int) vboxNetAdpTryDeleteGlobals(PVBOXNETADPGLOBALS pGlobals);217 DECLHIDDEN(bool) vboxNetAdpCanUnload(PVBOXNETADPGLOBALS pGlobals);218 219 DECLHIDDEN(void) vboxNetAdpRetain(PVBOXNETADP pThis);220 DECLHIDDEN(void) vboxNetAdpRelease(PVBOXNETADP pThis);221 DECLHIDDEN(void) vboxNetAdpBusy(PVBOXNETADP pThis);222 DECLHIDDEN(void) vboxNetAdpIdle(PVBOXNETADP pThis);223 224 DECLHIDDEN(int) vboxNetAdpInitGlobalsBase(PVBOXNETADPGLOBALS pGlobals);225 DECLHIDDEN(int) vboxNetAdpInitIdc(PVBOXNETADPGLOBALS pGlobals);226 DECLHIDDEN(void) vboxNetAdpDeleteGlobalsBase(PVBOXNETADPGLOBALS pGlobals);227 DECLHIDDEN(int) vboxNetAdpTryDeleteIdc(PVBOXNETADPGLOBALS pGlobals);228 229 230 231 /** @name The OS specific interface.232 * @{ */233 /**234 * Transmits a frame.235 *236 * @return IPRT status code.237 * @param pThis The new instance.238 * @param pSG The (scatter/)gather list.239 * @param fDst The destination mask. At least one bit will be set.240 *241 * @remarks Owns the out-bound trunk port semaphore.242 */243 DECLHIDDEN(int) vboxNetAdpPortOsXmit(PVBOXNETADP pThis, PINTNETSG pSG, uint32_t fDst);244 245 /**246 * Checks if the interface is in promiscuous mode from the host perspective.247 *248 * If it is, then the internal networking switch will send frames249 * heading for the wire to the host as well.250 *251 * @see INTNETTRUNKIFPORT::pfnIsPromiscuous for more details.252 *253 * @returns true / false accordingly.254 * @param pThis The instance.255 *256 * @remarks Owns the network lock and the out-bound trunk port semaphores.257 */258 DECLHIDDEN(bool) vboxNetAdpPortOsIsPromiscuous(PVBOXNETADP pThis);259 260 /**261 * Get the MAC address of the interface we're attached to.262 *263 * Used by the internal networking switch for implementing the264 * shared-MAC-on-the-wire mode.265 *266 * @param pThis The instance.267 * @param pMac Where to store the MAC address.268 * If you don't know, set all the bits except the first (the multicast one).269 *270 * @remarks Owns the network lock and the out-bound trunk port semaphores.271 */272 DECLHIDDEN(void) vboxNetAdpPortOsGetMacAddress(PVBOXNETADP pThis, PRTMAC pMac);273 274 /**275 * Checks if the specified MAC address is for any of the host interfaces.276 *277 * Used by the internal networking switch to decide the destination(s)278 * of a frame.279 *280 * @returns true / false accordingly.281 * @param pThis The instance.282 * @param pMac The MAC address.283 *284 * @remarks Owns the network lock and the out-bound trunk port semaphores.285 */286 DECLHIDDEN(bool) vboxNetAdpPortOsIsHostMac(PVBOXNETADP pThis, PCRTMAC pMac);287 288 /**289 * This is called to when disconnecting from a network.290 *291 * @return IPRT status code.292 * @param pThis The new instance.293 *294 * @remarks May own the semaphores for the global list, the network lock and the out-bound trunk port.295 */296 DECLHIDDEN(int) vboxNetAdpOsDisconnectIt(PVBOXNETADP pThis);297 298 /**299 * This is called to when connecting to a network.300 *301 * @return IPRT status code.302 * @param pThis The new instance.303 *304 * @remarks Owns the semaphores for the global list, the network lock and the out-bound trunk port.305 */306 DECLHIDDEN(int) vboxNetAdpOsConnectIt(PVBOXNETADP pThis);307 308 /** @} */309 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */310 152 311 153 /** -
trunk/src/VBox/HostDrivers/VBoxNetAdp/darwin/VBoxNetAdp-darwin.cpp
r23068 r23082 124 124 * The (common) global data. 125 125 */ 126 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT127 static VBOXNETADPGLOBALS g_VBoxNetAdpGlobals;128 129 #else /* !VBOXANETADP_DO_NOT_USE_NETFLT */130 131 126 static int g_nCtlDev = -1; /* Major dev number */ 132 127 static void *g_hCtlDev = 0; /* FS dev handle */ … … 153 148 }; 154 149 155 /**156 * Generate a suitable MAC address.157 *158 * @param pThis The instance.159 * @param pMac Where to return the MAC address.160 */161 DECLHIDDEN(void) vboxNetAdpComposeMACAddress(PVBOXNETADP pThis, PRTMAC pMac)162 {163 #if 0 /* Use a locally administered version of the OUI we use for the guest NICs. */164 pMac->au8[0] = 0x08 | 2;165 pMac->au8[1] = 0x00;166 pMac->au8[2] = 0x27;167 #else /* this is what \0vb comes down to. It seems to be unassigned atm. */168 pMac->au8[0] = 0;169 pMac->au8[1] = 0x76;170 pMac->au8[2] = 0x62;171 #endif172 173 pMac->au8[3] = 0; /* pThis->uUnit >> 16; */174 pMac->au8[4] = 0; /* pThis->uUnit >> 8; */175 pMac->au8[5] = pThis->uUnit;176 }177 178 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */179 180 181 150 182 151 … … 192 161 } 193 162 194 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT195 /**196 * Reads and retains the host interface handle.197 *198 * @returns The handle, NULL if detached.199 * @param pThis200 */201 DECLINLINE(ifnet_t) vboxNetAdpDarwinRetainIfNet(PVBOXNETADP pThis)202 {203 if (pThis->u.s.pIface)204 ifnet_reference(pThis->u.s.pIface);205 206 return pThis->u.s.pIface;207 }208 209 210 /**211 * Release the host interface handle previously retained212 * by vboxNetAdpDarwinRetainIfNet.213 *214 * @param pThis The instance.215 * @param pIfNet The vboxNetAdpDarwinRetainIfNet return value, NULL is fine.216 */217 DECLINLINE(void) vboxNetAdpDarwinReleaseIfNet(PVBOXNETADP pThis, ifnet_t pIfNet)218 {219 NOREF(pThis);220 if (pIfNet)221 ifnet_release(pIfNet);222 }223 224 /**225 * Internal worker that create a darwin mbuf for a (scatter/)gather list.226 *227 * Taken from VBoxNetAdp-darwin.cpp.228 *229 * @returns Pointer to the mbuf.230 * @param pThis The instance.231 * @param pSG The (scatter/)gather list.232 */233 static mbuf_t vboxNetAdpDarwinMBufFromSG(PVBOXNETADP pThis, PINTNETSG pSG)234 {235 /// @todo future? mbuf_how_t How = preemtion enabled ? MBUF_DONTWAIT : MBUF_WAITOK;236 mbuf_how_t How = MBUF_WAITOK;237 238 /*239 * We can't make use of the physical addresses on darwin because the way the240 * mbuf / cluster stuffe works (see mbuf_data_to_physical and mcl_to_paddr).241 * So, because we're lazy, we will ASSUME that all SGs coming from INTNET242 * will only contain one single segment.243 */244 Assert(pSG->cSegsUsed == 1);245 Assert(pSG->cbTotal == pSG->aSegs[0].cb);246 Assert(pSG->cbTotal > 0);247 248 /*249 * We need some way of getting back to our instance data when250 * the mbuf is freed, so use pvUserData for this.251 * -- this is not relevant anylonger! --252 */253 Assert(!pSG->pvUserData || pSG->pvUserData == pThis);254 Assert(!pSG->pvUserData2);255 pSG->pvUserData = pThis;256 257 /*258 * Allocate a packet and copy over the data.259 *260 * Using mbuf_attachcluster() here would've been nice but there are two261 * issues with it: (1) it's 10.5.x only, and (2) the documentation indicates262 * that it's not supposed to be used for really external buffers. The 2nd263 * point might be argued against considering that the only m_clattach user264 * is mallocs memory for the ext mbuf and not doing what's stated in the docs.265 * However, it's hard to tell if these m_clattach buffers actually makes it266 * to the NICs or not, and even if they did, the NIC would need the physical267 * addresses for the pages they contain and might end up copying the data268 * to a new mbuf anyway.269 *270 * So, in the end it's better to just do it the simple way that will work271 * 100%, even if it involes some extra work (alloc + copy) we really wished272 * to avoid.273 */274 mbuf_t pPkt = NULL;275 errno_t err = mbuf_allocpacket(How, pSG->cbTotal, NULL, &pPkt);276 if (!err)277 {278 /* Skip zero sized memory buffers (paranoia). */279 mbuf_t pCur = pPkt;280 while (pCur && !mbuf_maxlen(pCur))281 pCur = mbuf_next(pCur);282 Assert(pCur);283 284 /* Set the required packet header attributes. */285 mbuf_pkthdr_setlen(pPkt, pSG->cbTotal);286 mbuf_pkthdr_setheader(pPkt, mbuf_data(pCur));287 288 /* Special case the single buffer copy. */289 if ( mbuf_next(pCur)290 && mbuf_maxlen(pCur) >= pSG->cbTotal)291 {292 mbuf_setlen(pCur, pSG->cbTotal);293 memcpy(mbuf_data(pCur), pSG->aSegs[0].pv, pSG->cbTotal);294 }295 else296 {297 /* Multi buffer copying. */298 size_t cbSrc = pSG->cbTotal;299 uint8_t const *pbSrc = (uint8_t const *)pSG->aSegs[0].pv;300 while (cbSrc > 0 && pCur)301 {302 size_t cb = mbuf_maxlen(pCur);303 if (cbSrc < cb)304 cb = cbSrc;305 mbuf_setlen(pCur, cb);306 memcpy(mbuf_data(pCur), pbSrc, cb);307 308 /* advance */309 pbSrc += cb;310 cbSrc -= cb;311 pCur = mbuf_next(pCur);312 }313 }314 if (!err)315 return pPkt;316 317 mbuf_freem(pPkt);318 }319 else320 AssertMsg(err == ENOMEM || err == EWOULDBLOCK, ("err=%d\n", err));321 pSG->pvUserData = NULL;322 323 return NULL;324 }325 326 327 /**328 * Calculates the number of segments required to represent the mbuf.329 *330 * Taken from VBoxNetAdp-darwin.cpp.331 *332 * @returns Number of segments.333 * @param pThis The instance.334 * @param pMBuf The mbuf.335 * @param pvFrame The frame pointer, optional.336 */337 DECLINLINE(unsigned) vboxNetAdpDarwinMBufCalcSGSegs(PVBOXNETADP pThis, mbuf_t pMBuf, void *pvFrame)338 {339 NOREF(pThis);340 341 /*342 * Count the buffers in the chain.343 */344 unsigned cSegs = 0;345 for (mbuf_t pCur = pMBuf; pCur; pCur = mbuf_next(pCur))346 if (mbuf_len(pCur))347 cSegs++;348 else if ( !cSegs349 && pvFrame350 && (uintptr_t)pvFrame - (uintptr_t)mbuf_datastart(pMBuf) < mbuf_maxlen(pMBuf))351 cSegs++;352 353 #ifdef PADD_RUNT_FRAMES_FROM_HOST354 /*355 * Add one buffer if the total is less than the ethernet minimum 60 bytes.356 * This may allocate a segment too much if the ethernet header is separated,357 * but that shouldn't harm us much.358 */359 if (mbuf_pkthdr_len(pMBuf) < 60)360 cSegs++;361 #endif362 363 #ifdef VBOXNETFLT_DARWIN_TEST_SEG_SIZE364 /* maximize the number of segments. */365 cSegs = RT_MAX(VBOXNETFLT_DARWIN_MAX_SEGS - 1, cSegs);366 #endif367 368 return cSegs ? cSegs : 1;369 }370 371 372 /**373 * Initializes a SG list from an mbuf.374 *375 * Taken from VBoxNetAdp-darwin.cpp.376 *377 * @returns Number of segments.378 * @param pThis The instance.379 * @param pMBuf The mbuf.380 * @param pSG The SG.381 * @param pvFrame The frame pointer, optional.382 * @param cSegs The number of segments allocated for the SG.383 * This should match the number in the mbuf exactly!384 * @param fSrc The source of the frame.385 */386 DECLINLINE(void) vboxNetAdpDarwinMBufToSG(PVBOXNETADP pThis, mbuf_t pMBuf, void *pvFrame, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)387 {388 NOREF(pThis);389 390 pSG->pvOwnerData = NULL;391 pSG->pvUserData = NULL;392 pSG->pvUserData2 = NULL;393 pSG->cUsers = 1;394 pSG->fFlags = INTNETSG_FLAGS_TEMP;395 pSG->cSegsAlloc = cSegs;396 397 /*398 * Walk the chain and convert the buffers to segments.399 */400 unsigned iSeg = 0;401 pSG->cbTotal = 0;402 for (mbuf_t pCur = pMBuf; pCur; pCur = mbuf_next(pCur))403 {404 size_t cbSeg = mbuf_len(pCur);405 if (cbSeg)406 {407 void *pvSeg = mbuf_data(pCur);408 409 /* deal with pvFrame */410 if (!iSeg && pvFrame && pvFrame != pvSeg)411 {412 void *pvStart = mbuf_datastart(pMBuf);413 uintptr_t offSeg = (uintptr_t)pvSeg - (uintptr_t)pvStart;414 uintptr_t offSegEnd = offSeg + cbSeg;415 Assert(pvStart && pvSeg && offSeg < mbuf_maxlen(pMBuf) && offSegEnd <= mbuf_maxlen(pMBuf)); NOREF(offSegEnd);416 uintptr_t offFrame = (uintptr_t)pvFrame - (uintptr_t)pvStart;417 if (RT_LIKELY(offFrame < offSeg))418 {419 pvSeg = pvFrame;420 cbSeg += offSeg - offFrame;421 }422 else423 AssertMsgFailed(("pvFrame=%p pvStart=%p pvSeg=%p offSeg=%p cbSeg=%#zx offSegEnd=%p offFrame=%p maxlen=%#zx\n",424 pvFrame, pvStart, pvSeg, offSeg, cbSeg, offSegEnd, offFrame, mbuf_maxlen(pMBuf)));425 pvFrame = NULL;426 }427 428 AssertBreak(iSeg < cSegs);429 pSG->cbTotal += cbSeg;430 pSG->aSegs[iSeg].cb = cbSeg;431 pSG->aSegs[iSeg].pv = pvSeg;432 pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;433 iSeg++;434 }435 /* The pvFrame might be in a now empty buffer. */436 else if ( !iSeg437 && pvFrame438 && (uintptr_t)pvFrame - (uintptr_t)mbuf_datastart(pMBuf) < mbuf_maxlen(pMBuf))439 {440 cbSeg = (uintptr_t)mbuf_datastart(pMBuf) + mbuf_maxlen(pMBuf) - (uintptr_t)pvFrame;441 pSG->cbTotal += cbSeg;442 pSG->aSegs[iSeg].cb = cbSeg;443 pSG->aSegs[iSeg].pv = pvFrame;444 pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;445 iSeg++;446 pvFrame = NULL;447 }448 }449 450 Assert(iSeg && iSeg <= cSegs);451 pSG->cSegsUsed = iSeg;452 453 #ifdef PADD_RUNT_FRAMES_FROM_HOST454 /*455 * Add a trailer if the frame is too small.456 *457 * Since we're getting to the packet before it is framed, it has not458 * yet been padded. The current solution is to add a segment pointing459 * to a buffer containing all zeros and pray that works for all frames...460 */461 if (pSG->cbTotal < 60 && (fSrc & INTNETTRUNKDIR_HOST))462 {463 AssertReturnVoid(iSeg < cSegs);464 465 static uint8_t const s_abZero[128] = {0};466 pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;467 pSG->aSegs[iSeg].pv = (void *)&s_abZero[0];468 pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal;469 pSG->cbTotal = 60;470 pSG->cSegsUsed++;471 }472 #endif473 474 #ifdef VBOXNETFLT_DARWIN_TEST_SEG_SIZE475 /*476 * Redistribute the segments.477 */478 if (pSG->cSegsUsed < pSG->cSegsAlloc)479 {480 /* copy the segments to the end. */481 int iSrc = pSG->cSegsUsed;482 int iDst = pSG->cSegsAlloc;483 while (iSrc > 0)484 {485 iDst--;486 iSrc--;487 pSG->aSegs[iDst] = pSG->aSegs[iSrc];488 }489 490 /* create small segments from the start. */491 pSG->cSegsUsed = pSG->cSegsAlloc;492 iSrc = iDst;493 iDst = 0;494 while ( iDst < iSrc495 && iDst < pSG->cSegsAlloc)496 {497 pSG->aSegs[iDst].Phys = NIL_RTHCPHYS;498 pSG->aSegs[iDst].pv = pSG->aSegs[iSrc].pv;499 pSG->aSegs[iDst].cb = RT_MIN(pSG->aSegs[iSrc].cb, VBOXNETFLT_DARWIN_TEST_SEG_SIZE);500 if (pSG->aSegs[iDst].cb != pSG->aSegs[iSrc].cb)501 {502 pSG->aSegs[iSrc].cb -= pSG->aSegs[iDst].cb;503 pSG->aSegs[iSrc].pv = (uint8_t *)pSG->aSegs[iSrc].pv + pSG->aSegs[iDst].cb;504 }505 else if (++iSrc >= pSG->cSegsAlloc)506 {507 pSG->cSegsUsed = iDst + 1;508 break;509 }510 iDst++;511 }512 }513 #endif514 515 AssertMsg(!pvFrame, ("pvFrame=%p pMBuf=%p iSeg=%d\n", pvFrame, pMBuf, iSeg));516 }517 518 #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */519 163 static errno_t vboxNetAdpDarwinOutput(ifnet_t pIface, mbuf_t pMBuf) 520 164 { 521 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT522 PVBOXNETADP pThis = VBOXNETADP_FROM_IFACE(pIface);523 Assert(pThis);524 if (vboxNetAdpPrepareToReceive(pThis))525 {526 unsigned cSegs = vboxNetAdpDarwinMBufCalcSGSegs(pThis, pMBuf, NULL);527 if (cSegs < VBOXNETADP_DARWIN_MAX_SEGS)528 {529 PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));530 vboxNetAdpDarwinMBufToSG(pThis, pMBuf, NULL, pSG, cSegs, INTNETTRUNKDIR_HOST);531 vboxNetAdpReceive(pThis, pSG);532 }533 else534 vboxNetAdpCancelReceive(pThis);535 }536 #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */537 165 mbuf_freem_list(pMBuf); 538 166 return 0; … … 584 212 RTSemEventSignal(pThis->u.s.hEvtDetached); 585 213 } 586 587 588 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT589 590 int vboxNetAdpPortOsXmit(PVBOXNETADP pThis, PINTNETSG pSG, uint32_t fDst)591 {592 int rc = VINF_SUCCESS;593 ifnet_t pIfNet = vboxNetAdpDarwinRetainIfNet(pThis); // Really need a wrapper?594 if (pIfNet)595 {596 /*597 * Create a mbuf for the gather list and push it onto the host stack.598 */599 mbuf_t pMBuf = vboxNetAdpDarwinMBufFromSG(pThis, pSG);600 if (pMBuf)601 {602 /* This is what IONetworkInterface::inputPacket does. */603 unsigned const cbEthHdr = 14;604 mbuf_pkthdr_setheader(pMBuf, mbuf_data(pMBuf));605 mbuf_pkthdr_setlen(pMBuf, mbuf_pkthdr_len(pMBuf) - cbEthHdr);606 mbuf_setdata(pMBuf, (uint8_t *)mbuf_data(pMBuf) + cbEthHdr, mbuf_len(pMBuf) - cbEthHdr);607 mbuf_pkthdr_setrcvif(pMBuf, pIfNet); /* will crash without this. */608 609 Log(("vboxNetAdpPortOsXmit: calling ifnet_input()\n"));610 errno_t err = ifnet_input(pIfNet, pMBuf, NULL);611 if (err)612 rc = RTErrConvertFromErrno(err);613 }614 else615 {616 Log(("vboxNetAdpPortOsXmit: failed to convert SG to mbuf.\n"));617 rc = VERR_NO_MEMORY;618 }619 620 vboxNetAdpDarwinReleaseIfNet(pThis, pIfNet);621 }622 else623 Log(("vboxNetAdpPortOsXmit: failed to retain the interface.\n"));624 625 return rc;626 }627 628 bool vboxNetAdpPortOsIsPromiscuous(PVBOXNETADP pThis)629 {630 uint16_t fIf = 0;631 ifnet_t pIfNet = vboxNetAdpDarwinRetainIfNet(pThis);632 if (pIfNet)633 {634 /* gather the data */635 fIf = ifnet_flags(pIfNet);636 vboxNetAdpDarwinReleaseIfNet(pThis, pIfNet);637 }638 return fIf & IFF_PROMISC;639 }640 641 642 void vboxNetAdpPortOsGetMacAddress(PVBOXNETADP pThis, PRTMAC pMac)643 {644 *pMac = pThis->u.s.Mac;645 }646 647 648 bool vboxNetAdpPortOsIsHostMac(PVBOXNETADP pThis, PCRTMAC pMac)649 {650 /* ASSUMES that the MAC address never changes. */651 return pThis->u.s.Mac.au16[0] == pMac->au16[0]652 && pThis->u.s.Mac.au16[1] == pMac->au16[1]653 && pThis->u.s.Mac.au16[2] == pMac->au16[2];654 }655 656 int vboxNetAdpOsDisconnectIt(PVBOXNETADP pThis)657 {658 /* Nothing to do here. */659 return VINF_SUCCESS;660 }661 662 663 int vboxNetAdpOsConnectIt(PVBOXNETADP pThis)664 {665 /* Nothing to do here. */666 return VINF_SUCCESS;667 }668 #else /* !VBOXANETADP_DO_NOT_USE_NETFLT */669 //VBOXNETADP g_vboxnet0;670 VBOXNETADP g_aAdapters[VBOXNETADP_MAX_INSTANCES];671 672 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */673 674 214 675 215 … … 783 323 } 784 324 785 int vboxNetAdpCreate (PVBOXNETADP *ppNew)786 {787 int rc;788 unsigned i;789 for (i = 0; i < RT_ELEMENTS(g_aAdapters); i++)790 {791 PVBOXNETADP pThis = &g_aAdapters[i];792 793 if (ASMAtomicCmpXchgU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Transitional, kVBoxNetAdpState_Invalid))794 {795 /* Found an empty slot -- use it. */796 Log(("vboxNetAdpCreate: found empty slot: %d\n", i));797 RTMAC Mac;798 vboxNetAdpComposeMACAddress(pThis, &Mac);799 rc = vboxNetAdpOsCreate(pThis, &Mac);800 if (RT_SUCCESS(rc))801 {802 *ppNew = pThis;803 ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Active);804 }805 else806 {807 ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Invalid);808 Log(("vboxNetAdpCreate: vboxNetAdpOsCreate failed with '%Rrc'.\n", rc));809 }810 return rc;811 }812 }813 Log(("vboxNetAdpCreate: no empty slots!\n"));814 815 /* All slots in adapter array are busy. */816 return VERR_OUT_OF_RESOURCES;817 }818 819 int vboxNetAdpDestroy (PVBOXNETADP pThis)820 {821 int rc = VINF_SUCCESS;822 823 if (!ASMAtomicCmpXchgU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Transitional, kVBoxNetAdpState_Active))824 return VERR_INTNET_FLT_IF_BUSY;825 826 vboxNetAdpOsDestroy(pThis);827 828 ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmState, kVBoxNetAdpState_Invalid);829 830 return rc;831 }832 833 325 /** 834 326 * Device open. Called on open /dev/vboxnetctl … … 921 413 * Init the darwin specific members. 922 414 */ 923 pThis->enmState = kVBoxNetAdpState_Invalid;924 415 pThis->u.s.pIface = NULL; 925 416 pThis->u.s.hEvtDetached = NIL_RTSEMEVENT; … … 944 435 { 945 436 Log(("VBoxNetAdpDarwinStart\n")); 946 /* 947 * Initialize the globals and connect to the support driver. 948 * 949 * This will call back vboxNetAdpOsOpenSupDrv (and maybe vboxNetAdpOsCloseSupDrv) 950 * for establishing the connect to the support driver. 951 */ 952 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT 953 memset(&g_VBoxNetAdpGlobals, 0, sizeof(g_VBoxNetAdpGlobals)); 954 rc = vboxNetAdpInitGlobals(&g_VBoxNetAdpGlobals); 955 #else /* !VBOXANETADP_DO_NOT_USE_NETFLT */ 956 for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++) 957 { 958 g_aAdapters[i].uUnit = i; 959 vboxNetAdpOsInit(&g_aAdapters[i]); 960 } 961 962 PVBOXNETADP pVboxnet0; 963 rc = vboxNetAdpCreate(&pVboxnet0); 437 rc = vboxNetAdpInit(); 964 438 if (RT_SUCCESS(rc)) 965 439 { … … 982 456 } 983 457 984 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */985 458 if (RT_SUCCESS(rc)) 986 459 { … … 995 468 printf("VBoxAdpDrv: failed to initialize IPRT (rc=%d)\n", rc); 996 469 997 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT998 memset(&g_VBoxNetAdpGlobals, 0, sizeof(g_VBoxNetAdpGlobals));999 #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */1000 470 return KMOD_RETURN_FAILURE; 1001 471 } … … 1009 479 Log(("VBoxNetAdpDarwinStop\n")); 1010 480 1011 /* 1012 * Refuse to unload if anyone is currently using the filter driver. 1013 * This is important as I/O kit / xnu will to be able to do usage 1014 * tracking for us! 1015 */ 1016 #ifdef VBOXANETADP_DO_NOT_USE_NETFLT 1017 int rc = vboxNetAdpTryDeleteGlobals(&g_VBoxNetAdpGlobals); 1018 if (RT_FAILURE(rc)) 1019 { 1020 Log(("VBoxNetAdpDarwinStop - failed, busy.\n")); 1021 return KMOD_RETURN_FAILURE; 1022 } 1023 1024 /* 1025 * Undo the work done during start (in reverse order). 1026 */ 1027 memset(&g_VBoxNetAdpGlobals, 0, sizeof(g_VBoxNetAdpGlobals)); 1028 #else /* !VBOXANETADP_DO_NOT_USE_NETFLT */ 1029 /* Remove virtual adapters */ 1030 for (unsigned i = 0; i < RT_ELEMENTS(g_aAdapters); i++) 1031 vboxNetAdpDestroy(&g_aAdapters[i]); 481 vboxNetAdpShutdown(); 1032 482 /* Remove control device */ 1033 483 devfs_remove(g_hCtlDev); 1034 484 cdevsw_remove(g_nCtlDev, &g_ChDev); 1035 #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */1036 485 1037 486 RTR0Term();
Note:
See TracChangeset
for help on using the changeset viewer.