- Timestamp:
- Oct 1, 2009 5:42:19 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 53061
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r23163 r23462 166 166 /** thread delivering packets for receiving by the guest */ 167 167 PPDMTHREAD pRecvThread; 168 /** thread delivering urg packets for receiving by the guest */ 169 PPDMTHREAD pUrgRecvThread; 168 170 /** event to wakeup the guest receive thread */ 169 171 RTSEMEVENT EventRecv; 172 /** event to wakeup the guest urgent receive thread */ 173 RTSEMEVENT EventUrgRecv; 170 174 /** Receive Req queue (deliver packets to the guest) */ 171 175 PRTREQQUEUE pRecvReqQueue; 176 /** Receive Urgent Req queue (deliver packets to the guest) */ 177 PRTREQQUEUE pUrgRecvReqQueue; 178 179 /* makes access to device func RecvAvail and Recv atomical */ 180 RTCRITSECT csDevAccess; 181 volatile uint32_t cUrgPkt; 182 volatile uint32_t cPkt; 183 PTMTIMERR3 pTmrSlow; 184 PTMTIMERR3 pTmrFast; 172 185 } DRVNAT; 173 186 AssertCompileMemberAlignment(DRVNAT, StatNATRecvWakeups, 8); … … 193 206 194 207 static void drvNATNotifyNATThread(PDRVNAT pThis); 208 static DECLCALLBACK(void) drvNATSlowTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser); 209 static DECLCALLBACK(void) drvNATFast(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser); 195 210 196 211 … … 198 213 #define PDMINETWORKCONNECTOR_2_DRVNAT(pInterface) ( (PDRVNAT)((uintptr_t)pInterface - RT_OFFSETOF(DRVNAT, INetworkConnector)) ) 199 214 215 static DECLCALLBACK(void) drvNATSlowTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser) 216 { 217 Assert(pvUser); 218 PDRVNAT pThis = (PDRVNAT)pvUser; 219 drvNATNotifyNATThread(pThis); 220 } 221 222 static DECLCALLBACK(void) drvNATFastTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser) 223 { 224 Assert(pvUser); 225 PDRVNAT pThis = (PDRVNAT)pvUser; 226 drvNATNotifyNATThread(pThis); 227 } 200 228 201 229 202 230 static DECLCALLBACK(int) drvNATRecv(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 203 231 { 204 232 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 205 233 … … 210 238 { 211 239 RTReqProcess(pThis->pRecvReqQueue, 0); 212 RTSemEventWait(pThis->EventRecv, RT_INDEFINITE_WAIT); 240 if (ASMAtomicReadU32(&pThis->cPkt) == 0) 241 RTSemEventWait(pThis->EventRecv, RT_INDEFINITE_WAIT); 213 242 } 214 243 return VINF_SUCCESS; … … 226 255 } 227 256 228 229 static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb) 257 static DECLCALLBACK(int) drvNATUrgRecv(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 258 { 259 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 260 261 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 262 return VINF_SUCCESS; 263 264 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 265 { 266 RTReqProcess(pThis->pUrgRecvReqQueue, 0); 267 if (ASMAtomicReadU32(&pThis->cUrgPkt) == 0) 268 RTSemEventWait(pThis->EventUrgRecv, RT_INDEFINITE_WAIT); 269 } 270 return VINF_SUCCESS; 271 } 272 static DECLCALLBACK(int) drvNATUrgRecvWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 273 { 274 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 275 int rc = RTSemEventSignal(pThis->EventUrgRecv); 276 277 AssertReleaseRC(rc); 278 return VINF_SUCCESS; 279 } 280 281 static DECLCALLBACK(void) drvNATUrgRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, void *pvArg) 282 { 283 int rc = RTCritSectEnter(&pThis->csDevAccess); 284 AssertReleaseRC(rc); 285 rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, RT_INDEFINITE_WAIT); 286 if (RT_SUCCESS(rc)) 287 { 288 rc = pThis->pPort->pfnReceive(pThis->pPort, pu8Buf, cb); 289 rc = RTCritSectLeave(&pThis->csDevAccess); 290 AssertReleaseRC(rc); 291 slirp_ext_m_free(pThis->pNATState, pvArg); 292 } 293 else if ( RT_FAILURE(rc) 294 && ( rc == VERR_TIMEOUT 295 || rc == VERR_INTERRUPTED)) 296 { 297 rc = RTCritSectLeave(&pThis->csDevAccess); 298 slirp_ext_m_free(pThis->pNATState, pvArg); 299 } 300 else 301 { 302 rc = RTCritSectLeave(&pThis->csDevAccess); 303 slirp_ext_m_free(pThis->pNATState, pvArg); 304 AssertReleaseRC(rc); 305 } 306 if (ASMAtomicDecU32(&pThis->cUrgPkt) == 0) 307 { 308 drvNATRecvWakeup(pThis->pDrvIns, pThis->pRecvThread); 309 drvNATNotifyNATThread(pThis); 310 } 311 } 312 313 314 static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, void *pvArg) 230 315 { 231 316 STAM_PROFILE_START(&pThis->StatNATRecv, a); 232 317 233 318 STAM_PROFILE_START(&pThis->StatNATRecvWait, b); 234 int rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, RT_INDEFINITE_WAIT); 235 AssertMsgRC(rc, ("NAT: No RX available even on indefinite wait; rc=%Rrc", rc)); 319 320 while(ASMAtomicReadU32(&pThis->cUrgPkt) != 0) 321 RTSemEventWait(pThis->EventRecv, RT_INDEFINITE_WAIT); 322 323 int rc = RTCritSectEnter(&pThis->csDevAccess); 324 rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, RT_INDEFINITE_WAIT); 325 if (RT_SUCCESS(rc)) 326 { 327 rc = pThis->pPort->pfnReceive(pThis->pPort, pu8Buf, cb); 328 AssertReleaseRC(rc); 329 rc = RTCritSectLeave(&pThis->csDevAccess); 330 AssertReleaseRC(rc); 331 slirp_ext_m_free(pThis->pNATState, pvArg); 332 } 333 else if ( RT_FAILURE(rc) 334 && ( rc == VERR_TIMEOUT 335 || rc == VERR_INTERRUPTED)) 336 { 337 rc = RTCritSectLeave(&pThis->csDevAccess); 338 AssertReleaseRC(rc); 339 slirp_ext_m_free(pThis->pNATState, pvArg); 340 } 341 else 342 { 343 rc = RTCritSectLeave(&pThis->csDevAccess); 344 slirp_ext_m_free(pThis->pNATState, pvArg); 345 AssertReleaseRC(rc); 346 } 347 ASMAtomicDecU32(&pThis->cPkt); 348 349 drvNATNotifyNATThread(pThis); 236 350 237 351 STAM_PROFILE_STOP(&pThis->StatNATRecvWait, b); 238 239 rc = pThis->pPort->pfnReceive(pThis->pPort, pu8Buf, cb);240 AssertRC(rc);241 RTMemFree(pu8Buf);242 243 352 STAM_PROFILE_STOP(&pThis->StatNATRecv, a); 244 353 } … … 248 357 * @thread "NAT" thread. 249 358 */ 250 static void drvNATSendWorker(PDRVNAT pThis, constvoid *pvBuf, size_t cb)359 static void drvNATSendWorker(PDRVNAT pThis, void *pvBuf, size_t cb) 251 360 { 252 361 Assert(pThis->enmLinkState == PDMNETWORKLINKSTATE_UP); 253 362 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) 254 slirp_input(pThis->pNATState, (uint8_t *)pvBuf, cb);363 slirp_input(pThis->pNATState, pvBuf); 255 364 } 256 365 … … 288 397 289 398 /* @todo: Here we should get mbuf instead temporal buffer */ 399 #if 0 290 400 buf = RTMemAlloc(cb); 291 401 if (buf == NULL) … … 295 405 } 296 406 memcpy(buf, pvBuf, cb); 407 #else 408 void *pvmBuf = slirp_ext_m_get(pThis->pNATState); 409 Assert(pvmBuf); 410 slirp_ext_m_append(pThis->pNATState, pvmBuf, (uint8_t *)pvBuf, cb); 411 #endif 297 412 298 413 pReq->u.Internal.pfn = (PFNRT)drvNATSendWorker; 299 pReq->u.Internal.cArgs = 3;414 pReq->u.Internal.cArgs = 2; 300 415 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 301 pReq->u.Internal.aArgs[1] = (uintptr_t)buf; 302 pReq->u.Internal.aArgs[2] = (uintptr_t)cb; 416 pReq->u.Internal.aArgs[1] = (uintptr_t)pvmBuf; 303 417 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 304 418 … … 459 573 /* don't pass the managemant pipe */ 460 574 slirp_select_fill(pThis->pNATState, &nFDs, &polls[1]); 575 #if 0 461 576 ms = slirp_get_timeout_ms(pThis->pNATState); 577 #else 578 ms = 0; 579 #endif 462 580 463 581 polls[0].fd = pThis->PipeRead; … … 509 627 #else /* RT_OS_WINDOWS */ 510 628 slirp_select_fill(pThis->pNATState, &nFDs); 629 #if 0 511 630 ms = slirp_get_timeout_ms(pThis->pNATState); 631 #else 632 ms = 0; 633 #endif 512 634 struct timeval tv = { 0, ms*1000 }; 513 635 event = WSAWaitForMultipleEvents(nFDs, phEvents, FALSE, ms ? ms : WSA_INFINITE, FALSE); … … 585 707 #endif /* VBOX_WITH_SLIRP_MT */ 586 708 709 void slirp_arm_fast_timer(void *pvUser) 710 { 711 PDRVNAT pThis = (PDRVNAT)pvUser; 712 Assert(pThis); 713 TMTimerSetMillies(pThis->pTmrFast, 2); 714 } 715 716 void slirp_arm_slow_timer(void *pvUser) 717 { 718 PDRVNAT pThis = (PDRVNAT)pvUser; 719 Assert(pThis); 720 TMTimerSetMillies(pThis->pTmrSlow, 500); 721 } 587 722 588 723 /** … … 596 731 } 597 732 598 /** 599 * Function called by slirp to feed incoming data to the network port. 600 */ 601 void slirp_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb) 733 void slirp_push_recv_thread(void *pvUser) 602 734 { 603 735 PDRVNAT pThis = (PDRVNAT)pvUser; 604 736 Assert(pThis); 605 606 LogFlow(("slirp_output BEGIN %x %d\n", pu8Buf, cb)); 607 Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n%.*Rhxd\n", pu8Buf, cb, pThis, cb, pu8Buf)); 737 drvNATUrgRecvWakeup(pThis->pDrvIns, pThis->pUrgRecvThread); 738 } 739 740 void slirp_urg_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb) 741 { 742 PDRVNAT pThis = (PDRVNAT)pvUser; 743 Assert(pThis); 744 ASMAtomicIncU32(&pThis->cUrgPkt); 608 745 609 746 PRTREQ pReq = NULL; … … 613 750 return; 614 751 615 int rc = RTReqAlloc(pThis->p RecvReqQueue, &pReq, RTREQTYPE_INTERNAL);752 int rc = RTReqAlloc(pThis->pUrgRecvReqQueue, &pReq, RTREQTYPE_INTERNAL); 616 753 AssertReleaseRC(rc); 617 pReq->u.Internal.pfn = (PFNRT)drvNAT RecvWorker;618 pReq->u.Internal.cArgs = 3;754 pReq->u.Internal.pfn = (PFNRT)drvNATUrgRecvWorker; 755 pReq->u.Internal.cArgs = 4; 619 756 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 620 757 pReq->u.Internal.aArgs[1] = (uintptr_t)pu8Buf; 621 758 pReq->u.Internal.aArgs[2] = (uintptr_t)cb; 759 pReq->u.Internal.aArgs[3] = (uintptr_t)pvArg; 760 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 761 rc = RTReqQueue(pReq, 0); 762 AssertReleaseRC(rc); 763 drvNATUrgRecvWakeup(pThis->pDrvIns, pThis->pUrgRecvThread); 764 } 765 766 /** 767 * Function called by slirp to feed incoming data to the network port. 768 */ 769 void slirp_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb) 770 { 771 PDRVNAT pThis = (PDRVNAT)pvUser; 772 Assert(pThis); 773 774 LogFlow(("slirp_output BEGIN %x %d\n", pu8Buf, cb)); 775 Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n%.*Rhxd\n", pu8Buf, cb, pThis, cb, pu8Buf)); 776 777 PRTREQ pReq = NULL; 778 779 /* don't queue new requests when the NAT thread is about to stop */ 780 if (pThis->pSlirpThread->enmState != PDMTHREADSTATE_RUNNING) 781 return; 782 783 int rc = RTReqAlloc(pThis->pRecvReqQueue, &pReq, RTREQTYPE_INTERNAL); 784 AssertReleaseRC(rc); 785 ASMAtomicIncU32(&pThis->cPkt); 786 pReq->u.Internal.pfn = (PFNRT)drvNATRecvWorker; 787 pReq->u.Internal.cArgs = 4; 788 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 789 pReq->u.Internal.aArgs[1] = (uintptr_t)pu8Buf; 790 pReq->u.Internal.aArgs[2] = (uintptr_t)cb; 791 pReq->u.Internal.aArgs[3] = (uintptr_t)pvArg; 622 792 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 623 793 rc = RTReqQueue(pReq, 0); … … 951 1121 return rc; 952 1122 } 1123 rc = RTReqCreateQueue(&pThis->pUrgRecvReqQueue); 1124 if (RT_FAILURE(rc)) 1125 { 1126 LogRel(("NAT: Can't create request queue\n")); 1127 return rc; 1128 } 953 1129 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pRecvThread, pThis, drvNATRecv, 954 1130 drvNATRecvWakeup, 128 * _1K, RTTHREADTYPE_IO, "NATRX"); 955 1131 AssertReleaseRC(rc); 956 1132 rc = RTSemEventCreate(&pThis->EventRecv); 1133 1134 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pUrgRecvThread, pThis, drvNATUrgRecv, 1135 drvNATUrgRecvWakeup, 128 * _1K, RTTHREADTYPE_IO, "NATURGRX"); 1136 AssertReleaseRC(rc); 1137 rc = RTSemEventCreate(&pThis->EventRecv); 1138 rc = RTSemEventCreate(&pThis->EventUrgRecv); 1139 rc = RTCritSectInit(&pThis->csDevAccess); 1140 rc = PDMDrvHlpTMTimerCreate(pThis->pDrvIns, TMCLOCK_REAL/*enmClock*/, drvNATSlowTimer, 1141 pThis, TMTIMER_FLAGS_NO_CRIT_SECT/*flags*/, "NATSlowTmr", &pThis->pTmrSlow); 1142 rc = PDMDrvHlpTMTimerCreate(pThis->pDrvIns, TMCLOCK_REAL/*enmClock*/, drvNATFastTimer, 1143 pThis, TMTIMER_FLAGS_NO_CRIT_SECT/*flags*/, "NATFastTmr", &pThis->pTmrFast); 957 1144 958 1145 #ifndef RT_OS_WINDOWS -
trunk/src/VBox/Devices/Network/slirp/counters.h
r23154 r23462 104 104 COUNTING_COUNTER(IOSBAppendSB_w_ge_r, "SB: AppendSB (sb_wptr >= sb_rptr)"); 105 105 COUNTING_COUNTER(IOSBAppendSB_w_alter, "SB: AppendSB (altering of sb_wptr)"); 106 COUNTING_COUNTER(MBufAllocation,"MBUF::shows number of mbufs in used list"); 106 107 107 108 COUNTING_COUNTER(TCP_retransmit, "TCP::retransmit"); -
trunk/src/VBox/Devices/Network/slirp/if.c
r23369 r23462 280 280 } 281 281 282 if_encap(pData, ETH_P_IP, ifm );282 if_encap(pData, ETH_P_IP, ifm, 0); 283 283 284 284 if (!if_queued) -
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r23369 r23462 515 515 #endif 516 516 517 if (type!=ICMP_UNREACH && type!=ICMP_TIMXCEED )517 if (type!=ICMP_UNREACH && type!=ICMP_TIMXCEED && type != ICMP_SOURCEQUENCH) 518 518 goto end_error; 519 519 … … 531 531 } 532 532 #endif 533 if (ip->ip_off & IP_OFFMASK )533 if (ip->ip_off & IP_OFFMASK && type != ICMP_SOURCEQUENCH) 534 534 goto end_error; /* Only reply to fragment 0 */ 535 535 … … 657 657 ip->ip_src = alias_addr; 658 658 659 (void ) ip_output (pData, (struct socket *)NULL, m);659 (void ) ip_output0(pData, (struct socket *)NULL, m, 1); 660 660 661 661 icmpstat.icps_reflect++; -
trunk/src/VBox/Devices/Network/slirp/ip_output.c
r23369 r23462 81 81 ip_output(PNATState pData, struct socket *so, struct mbuf *m0) 82 82 { 83 return ip_output0(pData, so, m0, 0); 84 } 85 86 int 87 ip_output0(PNATState pData, struct socket *so, struct mbuf *m0, int urg) 88 { 83 89 register struct ip *ip; 84 90 register struct mbuf *m = m0; … … 200 206 memcpy(eh->h_source, eth_dst, ETH_ALEN); 201 207 208 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 202 209 if_output(pData, so, m); 210 #else 211 if_encap(pData, ETH_P_IP, m, urg? ETH_ENCAP_URG : 0); 212 #endif 203 213 goto done; 204 214 } … … 381 391 memcpy(eh->h_source, eth_dst, ETH_ALEN); 382 392 393 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 383 394 if_output(pData, so, m); 395 #else 396 if_encap(pData, ETH_P_IP, m, 0); 397 #endif 384 398 } 385 399 else -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r23369 r23462 48 48 #endif /* !RT_OS_WINDOWS */ 49 49 50 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 50 51 void slirp_input(PNATState pData, const uint8_t *pkt, int pkt_len); 52 #else 53 void slirp_input(PNATState pData, void *pvData); 54 #endif 51 55 void slirp_set_ethaddr(PNATState pData, const uint8_t *ethaddr); 52 56 53 57 /* you must provide the following functions: */ 58 void slirp_arm_fast_timer(void *pvUser); 59 void slirp_arm_slow_timer(void *pvUser); 54 60 int slirp_can_output(void * pvUser); 55 61 void slirp_output(void * pvUser, void *pvArg, const uint8_t *pkt, int pkt_len); 62 void slirp_urg_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb); 56 63 void slirp_post_sent(PNATState pData, void *pvArg); 57 64 … … 111 118 void *slirp_get_queue(PNATState pData); 112 119 #endif 120 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 121 void *slirp_ext_m_get(PNATState pData); 122 void slirp_ext_m_free(PNATState pData, void *); 123 void slirp_ext_m_append(PNATState pData, void *, uint8_t *, size_t); 124 void slirp_push_recv_thread(void *pvUser); 125 #endif 113 126 114 127 /* -
trunk/src/VBox/Devices/Network/slirp/main.h
r18902 r23462 9 9 #include <sys/select.h> 10 10 #endif 11 12 void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m );11 #define ETH_ENCAP_URG 1 12 void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m, int flags); -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r23369 r23462 15 15 * the flags 16 16 */ 17 18 17 #include <slirp.h> 19 18 19 #define MBUF_ZONE_SIZE 100 20 static int mbuf_zone_init(PNATState pData) 21 { 22 int limit; 23 struct mbuf_zone *mzone; 24 int i; 25 struct mbuf *m; 26 uint8_t *zone = RTMemAlloc(msize * MBUF_ZONE_SIZE); 27 if (zone == NULL) 28 { 29 LogRel(("NAT: can't allocate new zone\n")); 30 return -1; 31 } 32 mzone = RTMemAllocZ(sizeof (struct mbuf_zone)); 33 if (mzone == NULL) 34 { 35 RTMemFree(zone); 36 LogRel(("NAT: can't allocate zone descriptor\n")); 37 return -1; 38 } 39 40 for(i = 0; i < MBUF_ZONE_SIZE; ++i) 41 { 42 m = (struct mbuf *)((char *)zone + i*msize); 43 #ifdef M_BUF_DEBUG 44 m->m_hdr.mh_id = pData->mbuf_zone_count * MBUF_ZONE_SIZE + i; 45 #endif 46 insque(pData, m, &m_freelist); 47 } 48 mzone->mbuf_zone_base_addr = zone; 49 LIST_INSERT_HEAD(&pData->mbuf_zone_head, mzone, list); 50 pData->mbuf_zone_count++; 51 pData->mbuf_water_line_limit = pData->mbuf_zone_count * MBUF_ZONE_SIZE; 52 return 0; 53 } 54 55 void m_fini(PNATState pData) 56 { 57 struct mbuf_zone *mz; 58 struct mbuf *m; 59 int i; 60 void *zone; 61 while(!LIST_EMPTY(&pData->mbuf_zone_head)) 62 { 63 mz = LIST_FIRST(&pData->mbuf_zone_head); 64 zone = mz->mbuf_zone_base_addr; 65 for(i = 0; i < MBUF_ZONE_SIZE; ++i) 66 { 67 m = (struct mbuf *)((char *)zone + i*msize); 68 if ( (m->m_flags & M_EXT) 69 && m->m_ext != NULL) 70 RTMemFree(m->m_ext); 71 } 72 RTMemFree(zone); 73 LIST_REMOVE(mz, list); 74 RTMemFree(mz); 75 } 76 } 20 77 21 78 void 22 79 m_init(PNATState pData) 23 80 { 81 int i; 82 struct mbuf *m; 83 int rc = 0; 24 84 m_freelist.m_next = m_freelist.m_prev = &m_freelist; 25 85 m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; 26 86 mbuf_alloced = 0; 27 87 msize_init(pData); 88 #if 1 89 rc = RTCritSectInit(&pData->cs_mbuf_zone); 90 AssertReleaseRC(rc); 91 rc = mbuf_zone_init(pData); 92 Assert((rc == 0)); 93 #endif 28 94 } 29 95 … … 38 104 + if_maxlinkhdr ; 39 105 } 40 106 #ifdef m_get 107 # undef m_get 108 #endif 109 110 #ifdef m_free 111 # undef m_free 112 #endif 41 113 /* 42 114 * Get an mbuf from the free list, if there are none … … 52 124 register struct mbuf *m; 53 125 int flags = 0; 126 int rc = 0; 54 127 55 128 DEBUG_CALL("m_get"); 56 129 130 rc = RTCritSectEnter(&pData->cs_mbuf_zone); 131 AssertReleaseRC(rc); 132 133 recheck_zone: 57 134 if (m_freelist.m_next == &m_freelist) 58 135 { 136 #if 1 137 int rc = mbuf_zone_init(pData); 138 if (rc == 0) 139 goto recheck_zone; 140 AssertMsgFailed(("No mbufs on free list\n")); 141 return NULL; 142 #else 59 143 m = (struct mbuf *)RTMemAlloc(msize); 60 144 if (m == NULL) … … 65 149 if (mbuf_alloced > mbuf_max) 66 150 mbuf_max = mbuf_alloced; 151 #endif 67 152 } 68 153 else … … 72 157 } 73 158 159 STAM_COUNTER_INC(&pData->StatMBufAllocation); 74 160 /* Insert it in the used list */ 161 mbuf_alloced++; 162 if (mbuf_alloced >= MBUF_ZONE_SIZE/2) 163 { 164 pData->fmbuf_water_line = 1; 165 } 75 166 insque(pData, m, &m_usedlist); 76 167 m->m_flags = (flags | M_USEDLIST); … … 87 178 end_error: 88 179 DEBUG_ARG("m = %lx", (long )m); 180 rc = RTCritSectLeave(&pData->cs_mbuf_zone); 181 AssertReleaseRC(rc); 89 182 return m; 90 183 } … … 93 186 m_free(PNATState pData, struct mbuf *m) 94 187 { 95 188 int rc; 96 189 DEBUG_CALL("m_free"); 97 190 DEBUG_ARG("m = %lx", (long )m); 98 191 192 rc = RTCritSectEnter(&pData->cs_mbuf_zone); 193 AssertReleaseRC(rc); 194 mbuf_alloced--; 99 195 if(m) 100 196 { … … 112 208 if (m->m_flags & M_DOFREE) 113 209 { 210 #if 1 211 if ((m->m_flags & M_EXT) == 0) 212 memset(m->m_dat, 0, if_mtu); 213 insque(pData, m, &m_freelist); 214 m->m_flags = M_FREELIST; /* Clobber other flags */ 215 #else 114 216 RTMemFree(m); 217 #endif 115 218 mbuf_alloced--; 116 219 } … … 120 223 m->m_flags = M_FREELIST; /* Clobber other flags */ 121 224 } 225 STAM_COUNTER_INC(&pData->StatMBufAllocation); 122 226 } /* if(m) */ 123 } 227 rc = RTCritSectLeave(&pData->cs_mbuf_zone); 228 AssertReleaseRC(rc); 229 } 230 231 /* update macros for m_get/m_free*/ 232 #undef m_get 233 #undef m_free 234 #include "mbuf.h" 124 235 125 236 /* … … 254 365 return (struct mbuf *)0; 255 366 } 367 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 368 void *slirp_ext_m_get(PNATState pData) 369 { 370 return (void *)m_get(pData); 371 } 372 373 void slirp_ext_m_free(PNATState pData, void *arg) 374 { 375 struct mbuf *m = (struct mbuf *)arg; 376 m_free(pData, m); 377 } 378 void slirp_ext_m_append(PNATState pData, void *arg, uint8_t *pu8Buf, size_t cbBuf) 379 { 380 char *c; 381 struct mbuf *m = (struct mbuf *)arg; 382 if (cbBuf > M_FREEROOM(m)) 383 { 384 m_inc(m, cbBuf); 385 } 386 c = mtod(m, char *); 387 memcpy(c, pu8Buf, cbBuf); 388 m->m_len = cbBuf; 389 } 390 #endif -
trunk/src/VBox/Devices/Network/slirp/mbuf.h
r23154 r23462 38 38 #define _MBUF_H_ 39 39 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 40 /* #define M_BUF_DEBUG */ 40 41 41 42 #define m_freem m_free … … 76 77 int mh_len; /* Amount of data in this mbuf */ 77 78 struct libalias *mh_la; /*Real freebsd store hocksin similar way*/ 79 #ifdef M_BUF_DEBUG 80 int mh_id; 81 char *mh_allocation_at_file; 82 int mh_allocation_at_line; 83 #endif 78 84 }; 79 85 … … 135 141 136 142 void m_init (PNATState); 143 void m_fini(PNATState pData); 137 144 void msize_init (PNATState); 138 145 struct mbuf * m_get (PNATState); … … 150 157 151 158 #define MBUF_IP_HEADER(m) (caddr_t)(MBUF_HEAD(m) + if_maxlinkhdr) 152 153 159 #else 154 160 # include "bsd/sys/mbuf.h" 155 161 #endif 156 162 #endif 163 164 #if defined(M_BUF_DEBUG) && !defined(RT_OS_WINDOWS) 165 # define m_get(x) \ 166 ({ \ 167 struct mbuf *mdb = m_get((x)); \ 168 if(mdb) \ 169 { \ 170 mdb->m_hdr.mh_allocation_at_file = __FILE__; \ 171 mdb->m_hdr.mh_allocation_at_line = __LINE__; \ 172 } \ 173 LogRel(("NAT:m(id:%d, ptr: %p) allocated at: %s:%d\n", (mdb?mdb->m_hdr.mh_id:-1), mdb, __FILE__, __LINE__));\ 174 mdb; \ 175 }) 176 177 # define m_free(x, m) \ 178 ({ \ 179 (m)->m_hdr.mh_allocation_at_file = NULL; \ 180 (m)->m_hdr.mh_allocation_at_line = 0; \ 181 LogRel(("NAT:m(id:%d, ptr: %p) freed at: %s:%d\n", (m)->m_hdr.mh_id, (m), __FILE__, __LINE__)); \ 182 m_free((x),(m)); \ 183 }) 184 #endif -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r23369 r23462 697 697 } 698 698 bootp_dhcp_fini(pData); 699 m_fini(pData); 699 700 #ifdef RT_OS_WINDOWS 700 701 WSACleanup(); … … 770 771 if (!link_up) 771 772 goto done; 773 772 774 /* 773 775 * *_slowtimo needs calling if there are IP fragments … … 785 787 { 786 788 do_slowtimo = 1; 789 slirp_arm_slow_timer(pData->pvUser); 787 790 break; 788 791 } … … 799 802 so->so_poll_index = -1; 800 803 #endif 804 if (pData->fmbuf_water_line == 1) 805 { 806 if (mbuf_alloced < pData->mbuf_water_line_limit/2) 807 { 808 pData->fmbuf_water_warn_sent = 0; 809 pData->fmbuf_water_line = 0; 810 } 811 #ifndef RT_OS_WINDOWS 812 poll_index = 0; 813 #endif 814 goto done; 815 } 801 816 STAM_COUNTER_INC(&pData->StatTCP); 802 817 … … 807 822 && so->so_tcpcb != NULL 808 823 && so->so_tcpcb->t_flags & TF_DELACK) 824 { 809 825 time_fasttimo = curtime; /* Flag when we want a fasttimo */ 826 slirp_arm_fast_timer(pData->pvUser); 827 } 810 828 811 829 /* … … 867 885 /* { */ 868 886 887 if (pData->fmbuf_water_line == 1) 888 { 889 if (mbuf_alloced < pData->mbuf_water_line_limit/2) 890 { 891 pData->fmbuf_water_line = 0; 892 pData->fmbuf_water_warn_sent = 0; 893 } 894 #ifndef RT_OS_WINDOWS 895 poll_index = 0; 896 #endif 897 goto done; 898 } 869 899 STAM_COUNTER_INC(&pData->StatUDP); 870 900 #if !defined(RT_OS_WINDOWS) … … 892 922 } 893 923 else 924 { 894 925 do_slowtimo = 1; /* Let socket expire */ 926 slirp_arm_slow_timer(pData->pvUser); 927 } 895 928 } 896 929 … … 992 1025 QSOCKET_FOREACH(so, so_next, tcp) 993 1026 /* { */ 1027 if (pData->fmbuf_water_line == 1) 1028 { 1029 if (mbuf_alloced < pData->mbuf_water_line_limit/2) 1030 { 1031 pData->fmbuf_water_line = 0; 1032 pData->fmbuf_water_warn_sent = 0; 1033 } 1034 goto done; 1035 } 994 1036 995 1037 #ifdef VBOX_WITH_SLIRP_MT … … 1280 1322 QSOCKET_FOREACH(so, so_next, udp) 1281 1323 /* { */ 1324 if (pData->fmbuf_water_line == 1) 1325 { 1326 if (mbuf_alloced < pData->mbuf_water_line_limit/2) 1327 { 1328 pData->fmbuf_water_line = 0; 1329 pData->fmbuf_water_warn_sent = 0; 1330 } 1331 goto done; 1332 } 1282 1333 #ifdef VBOX_WITH_SLIRP_MT 1283 1334 if ( so->so_state & SS_NOFDREF … … 1322 1373 1323 1374 done: 1324 #if ndef VBOX_WITH_SLIRP_MT1375 #if 0 1325 1376 /* 1326 1377 * See if we can start outputting … … 1410 1461 } 1411 1462 } 1463 m_free(pData, m); 1464 m_free(pData, mr); 1412 1465 return; 1413 1466 arp_ok: … … 1431 1484 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); 1432 1485 memcpy(rah->ar_tip, ah->ar_sip, 4); 1433 if_encap(pData, ETH_P_ARP, mr );1486 if_encap(pData, ETH_P_ARP, mr, ETH_ENCAP_URG); 1434 1487 m_free(pData, m); 1435 1488 } … … 1472 1525 } 1473 1526 1527 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1474 1528 void slirp_input(PNATState pData, const uint8_t *pkt, int pkt_len) 1529 #else 1530 void slirp_input(PNATState pData, void *pvArg) 1531 #endif 1475 1532 { 1476 1533 struct mbuf *m; 1477 1534 int proto; 1478 1535 static bool fWarnedIpv6; 1536 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1479 1537 struct ethhdr *eh = (struct ethhdr*)pkt; 1480 #ifdef VBOX_WITH_SLIRP_BSD_MBUF1481 1538 int size = 0; 1482 #endif 1483 1539 #else 1540 struct ethhdr *eh; 1541 #endif 1542 1543 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 1544 m = (struct mbuf *)pvArg; 1545 if (m->m_len < ETH_HLEN) 1546 { 1547 LogRel(("NAT: packet having size %d has been ingnored\n", m->m_len)); 1548 m_free(pData, m); 1549 return; 1550 } 1551 eh = mtod(m, struct ethhdr *); 1552 proto = ntohs(eh->h_proto); 1553 #else 1484 1554 Log2(("NAT: slirp_input %d\n", pkt_len)); 1485 1555 if (pkt_len < ETH_HLEN) … … 1498 1568 } 1499 1569 1500 #ifndef VBOX_WITH_SLIRP_BSD_MBUF1501 m = m_get(pData);1502 #else1503 1570 if (pkt_len < MSIZE) 1504 1571 { … … 1522 1589 } 1523 1590 m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size); 1524 #endif1525 1591 if (!m) 1526 1592 { … … 1530 1596 } 1531 1597 1532 /* Note: we add to align the IP header */1533 1534 #ifndef VBOX_WITH_SLIRP_BSD_MBUF1535 if (M_FREEROOM(m) < pkt_len)1536 m_inc(m, pkt_len);1537 #endif1538 1539 1598 m->m_len = pkt_len ; 1540 1599 memcpy(m->m_data, pkt, pkt_len); 1600 proto = ntohs(*(uint16_t *)(pkt + 12)); 1601 #endif 1602 /* Note: we add to align the IP header */ 1603 1541 1604 1542 1605 if (pData->port_forwarding_activated == 0) 1543 1606 activate_port_forwarding(pData, mtod(m, struct ethhdr *)); 1544 1607 1545 proto = ntohs(*(uint16_t *)(pkt + 12));1546 1608 switch(proto) 1547 1609 { … … 1558 1620 m->m_pkthdr.header = mtod(m, void *); 1559 1621 #endif 1622 #if 1 1623 if ( pData->fmbuf_water_line 1624 && pData->fmbuf_water_warn_sent == 0 1625 && (curtime - pData->tsmbuf_water_warn_sent) > 500) 1626 { 1627 icmp_error(pData, m, ICMP_SOURCEQUENCH, 0, 0, "Out of resources!!!"); 1628 pData->fmbuf_water_warn_sent = 1; 1629 pData->tsmbuf_water_warn_sent = curtime; 1630 } 1631 #endif 1560 1632 ip_input(pData, m); 1561 1633 break; … … 1573 1645 break; 1574 1646 } 1647 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1575 1648 RTMemFree((void *)pkt); 1649 #endif 1576 1650 } 1577 1651 1578 1652 /* output the IP packet to the ethernet device */ 1579 void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m )1653 void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m, int flags) 1580 1654 { 1581 1655 struct ethhdr *eh; … … 1616 1690 #else 1617 1691 mlen = m_length(m, NULL); 1618 #endif1619 1692 buf = RTMemAlloc(mlen); 1620 1693 if (buf == NULL) … … 1623 1696 goto done; 1624 1697 } 1698 #endif 1625 1699 eh->h_proto = htons(eth_proto); 1626 #if ndef VBOX_WITH_SLIRP_BSD_MBUF1627 m emcpy(buf, mtod(m, uint8_t *), mlen);1700 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1701 m_copydata(m, 0, mlen, (char *)buf); 1628 1702 #else 1629 m_copydata(m, 0, mlen, (char *)buf); 1630 #endif 1631 slirp_output(pData->pvUser, NULL, buf, mlen); 1703 if (flags & ETH_ENCAP_URG) 1704 slirp_urg_output(pData->pvUser, m, mtod(m, char *), mlen); 1705 else 1706 slirp_output(pData->pvUser, m, mtod(m, char *), mlen); 1707 #endif 1632 1708 done: 1633 1709 STAM_PROFILE_STOP(&pData->StatIF_encap, a); 1710 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1634 1711 m_free(pData, m); 1712 #endif 1635 1713 } 1636 1714 … … 2028 2106 m->m_len = sizeof(struct arphdr) + ETH_HLEN; 2029 2107 #endif 2030 if_encap(pData, ETH_P_ARP, m );2108 if_encap(pData, ETH_P_ARP, m, ETH_ENCAP_URG); 2031 2109 Log(("NAT: ARP request sent\n")); 2032 2110 } -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r23369 r23462 286 286 /* ip_output.c */ 287 287 int ip_output (PNATState, struct socket *, struct mbuf *); 288 int ip_output0 (PNATState, struct socket *, struct mbuf *, int urg); 288 289 289 290 /* tcp_input.c */ -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r23369 r23462 23 23 24 24 #include <iprt/req.h> 25 #include <iprt/critsect.h> 25 26 26 27 #define COUNTERS_INIT … … 93 94 }; 94 95 LIST_HEAD(port_forward_rule_list, port_forward_rule); 96 97 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 98 struct mbuf_zone 99 { 100 LIST_ENTRY(mbuf_zone) list; 101 uint8_t *mbuf_zone_base_addr; 102 }; 103 LIST_HEAD(mbuf_zone_list, mbuf_zone); 104 #endif 105 95 106 96 107 /* forward declaration */ … … 133 144 int msize; 134 145 struct mbuf m_freelist, m_usedlist; 146 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 147 struct mbuf_zone_list mbuf_zone_head; 148 RTCRITSECT cs_mbuf_zone; 149 int fmbuf_water_line; 150 int mbuf_water_line_limit; 151 int mbuf_zone_count; 152 int fmbuf_water_warn_sent; 153 uint32_t tsmbuf_water_warn_sent; 154 #endif 135 155 /* Stuff from slirp.c */ 136 156 void *pvUser; -
trunk/src/VBox/Devices/Network/slirp/tcp_output.c
r23369 r23462 686 686 } 687 687 #endif 688 if (m != NULL) 689 m_free(pData, m); 688 690 return (error); 689 691 }
Note:
See TracChangeset
for help on using the changeset viewer.