VirtualBox

Changeset 15890 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jan 12, 2009 6:26:43 AM (16 years ago)
Author:
vboxsync
Message:

NAT: 1. wo sync enhancement branch is still functional (was corrupted with using ICMP file handler in select(1))

  1. after sending send queue doesn't need to synchronize with NAT thread to free mbuf instead NAT queue used to call freeing slirp routine.
  2. no more copying on slirp to guest sent.


Location:
trunk/src/VBox/Devices/Network
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r15788 r15890  
    102102    PDMQUEUEITEMCORE    Core;
    103103    /** The buffer for output to guest. */
    104     const uint8_t            *pu8Buf;
     104    const uint8_t       *pu8Buf;
    105105    /* size of buffer */
    106     size_t             cb;
     106    size_t              cb;
     107    void                *mbuf;
    107108} DRVNATQUEUITEM, *PDRVNATQUEUITEM;
    108109
     
    452453 * Function called by slirp to feed incoming data to the network port.
    453454 */
     455#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     456void slirp_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb)
     457#else
    454458void slirp_output(void *pvUser, const uint8_t *pu8Buf, int cb)
     459#endif
    455460{
    456461    PDRVNAT pThis = (PDRVNAT)pvUser;
     
    476481        pItem->pu8Buf = pu8Buf;
    477482        pItem->cb = cb;
     483        pItem->mbuf = pvArg;
    478484        Log2(("pItem:%p %.Rhxd\n", pItem, pItem->pu8Buf));
    479485        PDMQueueInsert(pThis->pSendQueue, &pItem->Core);
     
    496502    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    497503    PDRVNATQUEUITEM pItem = (PDRVNATQUEUITEM)pItemCore;
     504    PRTREQ pReq = NULL;
    498505    Log(("drvNATQueueConsumer(pItem:%p, pu8Buf:%p, cb:%d)\n", pItem, pItem->pu8Buf, pItem->cb));
    499506    Log2(("drvNATQueueConsumer: pu8Buf:\n%.Rhxd\n", pItem->pu8Buf));
     
    502509        return false;
    503510    rc = pThis->pPort->pfnReceive(pThis->pPort, pItem->pu8Buf, pItem->cb);
     511
     512    rc = RTReqAlloc(pThis->pReqQueue, &pReq, RTREQTYPE_INTERNAL);
     513    AssertReleaseRC(rc);
     514    pReq->u.Internal.pfn      = (PFNRT)slirp_post_sent;
     515    pReq->u.Internal.cArgs    = 2;
     516    pReq->u.Internal.aArgs[0] = (uintptr_t)pThis->pNATState;
     517    pReq->u.Internal.aArgs[1] = (uintptr_t)pItem->mbuf;
     518    pReq->fFlags              = RTREQFLAGS_VOID;
    504519    AssertRC(rc);
    505     RTMemFree((void *)pItem->pu8Buf); /* XXX: shouldn't free buffer here */
    506520    return RT_SUCCESS(rc);
    507521}
  • trunk/src/VBox/Devices/Network/slirp/bootp.c

    r15845 r15890  
    166166    if ((m = m_get(pData)) == NULL)
    167167        return;
    168     m->m_data += if_maxlinkhdr;
    169     rbp = (struct bootp_t *)m->m_data;
     168    m->m_data += if_maxlinkhdr; /*reserve ether header */
     169    rbp = mtod(m, struct bootp_t *);
     170    memset(rbp, 0, sizeof(struct bootp_t));
     171#ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    170172    m->m_data += sizeof(struct udpiphdr);
    171     memset(rbp, 0, sizeof(struct bootp_t));
     173#endif
    172174
    173175    if (dhcp_msg_type == DHCPDISCOVER)
     
    310312             - sizeof(struct ip)
    311313             - sizeof(struct udphdr);
     314#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     315    m->m_data += sizeof(struct udphdr)
     316             + sizeof(struct ip);
     317#endif
    312318    /* Reply to the broadcast address, as some clients perform paranoid checks. */
    313319    daddr.sin_addr.s_addr = INADDR_BROADCAST;
  • trunk/src/VBox/Devices/Network/slirp/if.c

    r15768 r15890  
    2828if_init(PNATState pData)
    2929{
     30#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     31    /* 14 for ethernet */
     32    if_maxlinkhdr =  14;
     33#else
    3034    /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
    31     if_maxlinkhdr = 2 + 14 + 40;
     35    if_maxlinkhdr =  2 + 14 + 40;
     36#endif
    3237    if_queued = 0;
    3338    if_thresh = 10;
     
    224229        }
    225230
    226         /* Encapsulate the packet for sending */
    227         if_encap(pData, ETH_P_IP, (const uint8_t *)ifm->m_data, ifm->m_len);
    228 
     231#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     232        if_encap(pData, ETH_P_IP, ifm);
     233#else
     234        if_encap(pData,  mtod(ifm, uint8_t *), ifm->m_len);
    229235        m_free(pData, ifm);
     236#endif
    230237
    231238        if (!if_queued)
  • trunk/src/VBox/Devices/Network/slirp/ip_icmp.c

    r15791 r15890  
    521521    {
    522522        int new_m_size;
     523        m->m_data += if_maxlinkhdr;
    523524        new_m_size = sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN;
    524525        if (new_m_size>m->m_size)
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r15638 r15890  
    4747/* you must provide the following functions: */
    4848int slirp_can_output(void * pvUser);
     49#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     50void slirp_output(void * pvUser, void *pvArg, const uint8_t *pkt, int pkt_len);
     51void slirp_post_sent(PNATState pData, void *pvArg);
     52#else
    4953void slirp_output(void * pvUser, const uint8_t *pkt, int pkt_len);
     54#endif
    5055
    5156int slirp_redir(PNATState pData, int is_udp, int host_port,
  • trunk/src/VBox/Devices/Network/slirp/main.h

    r15768 r15890  
    1010#endif
    1111
    12 void if_encap(PNATState pData, uint16_t eth_proto, const uint8_t *ip_data, int ip_data_len);
     12#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     13void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m);
     14#else
     15void if_encap(PNATState pData, const uint8_t *ip_data, int ip_data_len);
     16#endif
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r15792 r15890  
    3333# define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
    3434
    35 # define ICMP_ENGAGE_EVENT(so, fdset)               \
     35# ifndef RT_OS_WINDOWS
     36#  define ICMP_ENGAGE_EVENT(so, fdset)               \
    3637    do {                                             \
    3738        if (pData->icmp_socket.s != -1)              \
    3839            DO_ENGAGE_EVENT1((so), (fdset), ICMP);   \
    3940    } while (0)
     41# else /* !RT_OS_WINDOWS */
     42#  define ICMP_ENGAGE_EVENT(so, fdset) do {} while(0)
     43#endif /* RT_OS_WINDOWS */
    4044
    4145#else /* defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS) */
     
    585589            if (so->so_state & SS_ISFCONNECTING)
    586590            {
     591                Log2(("connecting %R[natsock] engaged\n",so));
    587592                STAM_REL_COUNTER_INC(&pData->StatTCPHot);
    588593                TCP_ENGAGE_EVENT1(so, writefds);
     
    808813                if (so->so_state & SS_ISFCONNECTING)
    809814                {
     815                    Log2(("connecting %R[natsock] catched\n", so));
    810816                    /* Connected */
    811817                    so->so_state &= ~SS_ISFCONNECTING;
     
    960966
    961967static
     968#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    962969void arp_input(PNATState pData, struct mbuf *m)
    963 {
    964     struct ethhdr *eh = mtod(m, struct ethhdr *);
    965     struct arphdr *ah = (struct arphdr *)&eh[1];
    966     uint8_t arp_reply[sizeof(struct arphdr)];
     970#else
     971void arp_input(PNATState pData, const uint8_t *pkt, int pkt_len)
     972#endif
     973{
     974    struct ethhdr *eh;
     975    struct ethhdr *reh;
     976    struct arphdr *ah;
    967977    struct arphdr *rah;
    968978    int ar_op;
    969979    struct ex_list *ex_ptr;
    970     uint32_t htip = ntohl(*(uint32_t*)ah->ar_tip);
    971 
    972     rah = (struct arphdr *)arp_reply;
     980    uint32_t htip;
     981#ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     982    uint8_t arp_reply[sizeof(struct arphdr) + ETH_HLEN];
     983    eh = (struct ethhdr *)pkt;
     984#else
     985    struct mbuf *mr;
     986    eh = mtod(m, struct ethhdr *);
     987#endif
     988    ah = (struct arphdr *)&eh[1];
     989    htip = ntohl(*(uint32_t*)ah->ar_tip);
     990
     991#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     992    mr = m_get(pData);
     993    mr->m_data += if_maxlinkhdr;
     994    mr->m_len = sizeof(struct arphdr);
     995    rah = mtod(mr, struct arphdr *);
     996#else
     997    reh = (struct ethhdr *)arp_reply;
     998    rah = (struct arphdr *)&reh[1];
     999#endif
    9731000
    9741001    ar_op = ntohs(ah->ar_op);
     
    9891016        arp_ok:
    9901017
     1018#ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     1019                memcpy(reh->h_dest, eh->h_source, ETH_ALEN);
     1020                memcpy(reh->h_source, &special_addr, ETH_ALEN);
     1021                reh->h_source[5] = ah->ar_tip[3];
     1022                reh->h_proto = htons(ETH_P_ARP);
     1023#endif
    9911024                rah->ar_hrd = htons(1);
    9921025                rah->ar_pro = htons(ETH_P_IP);
     
    9951028                rah->ar_op = htons(ARPOP_REPLY);
    9961029                memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN);
     1030
    9971031                switch (htip & ~pData->netmask)
    9981032                {
     
    10081042                memcpy(rah->ar_tip, ah->ar_sip, 4);
    10091043#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    1010                 if_encap(pData, ETH_P_ARP, arp_reply, sizeof(struct arphdr));
     1044                if_encap(pData, ETH_P_ARP, mr);
    10111045                m_free(pData, m);
    10121046#else
     
    10381072    /* Note: we add to align the IP header */
    10391073
    1040     if (M_FREEROOM(m) < pkt_len)
    1041     {
    1042        m_inc(m, pkt_len);
    1043     }
    1044     m->m_len = pkt_len;
    1045     memcpy(m->m_data, pkt, pkt_len);
     1074    if (M_FREEROOM(m) < pkt_len + 2)
     1075    {
     1076       m_inc(m, pkt_len + 2);
     1077    }
     1078    m->m_len = pkt_len + 2;
     1079    memcpy(m->m_data + 2, pkt, pkt_len);
    10461080
    10471081    proto = ntohs(*(uint16_t *)(pkt + 12));
     
    10491083    {
    10501084        case ETH_P_ARP:
     1085#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    10511086            arp_input(pData, m);
     1087#else
     1088            arp_input(pData, pkt, pkt_len);
     1089            m_free(pData, m);
     1090#endif
    10521091            break;
    10531092        case ETH_P_IP:
     
    10551094             * the first outgoing connection gets an incorrect timestamp. */
    10561095            updtime(pData);
    1057             m->m_data += ETH_HLEN;
    1058             m->m_len -= ETH_HLEN;
     1096            m->m_data += ETH_HLEN + 2;
     1097            m->m_len -= ETH_HLEN + 2;
    10591098            ip_input(pData, m);
    10601099            break;
     
    10671106
    10681107/* output the IP packet to the ethernet device */
    1069 void if_encap(PNATState pData, uint16_t eth_proto, const uint8_t *ip_data, int ip_data_len)
    1070 {
    10711108#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    1072     uint8_t *buf = RTMemAlloc(1600); /* XXX:temporal solution */
    1073     struct ethhdr *eh = (struct ethhdr *)buf;
    1074 
    1075     if (ip_data_len + ETH_HLEN > 1600)
    1076         return;
     1109void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m)
     1110#else
     1111void if_encap(PNATState pData, uint8_t *ip_data, int ip_data_len)
     1112#endif
     1113{
     1114#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     1115    struct ethhdr *eh;
     1116    m->m_data -= if_maxlinkhdr;
     1117    m->m_len += ETH_HLEN;
     1118    eh = mtod(m, struct ethhdr *);
    10771119#else
    10781120    uint8_t buf[1600];
     
    10811123    if (ip_data_len + ETH_HLEN > sizeof(buf))
    10821124        return;
     1125   
     1126    memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
    10831127#endif
    10841128
     
    10881132    /* XXX: not correct */
    10891133    eh->h_source[5] = CTL_ALIAS;
     1134#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    10901135    eh->h_proto = htons(eth_proto);
    1091     memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
     1136    slirp_output(pData->pvUser, m, mtod(m, uint8_t *), m->m_len);
     1137#else
     1138    eh->h_proto = htons(ETH_P_IP);
    10921139    slirp_output(pData->pvUser, buf, ip_data_len + ETH_HLEN);
     1140#endif
    10931141}
    10941142
     
    11451193    return 0;
    11461194}
     1195
     1196/*
     1197 * this function called from NAT thread
     1198 */
     1199void slirp_post_sent(PNATState pData, void *pvArg)
     1200{
     1201    struct socket *so = 0;
     1202    struct tcpcb *tp = 0;
     1203    struct mbuf *m = (struct mbuf *)pvArg;
     1204    m_free(pData, m);
     1205}
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r15792 r15890  
    461461            return;
    462462        m->m_data += if_maxlinkhdr;
     463#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     464        m->m_data += sizeof(struct udphdr)
     465                    + sizeof(struct ip); /*XXX: no options atm*/
     466#endif
    463467
    464468        /*
  • trunk/src/VBox/Devices/Network/slirp/tcp_input.c

    r15845 r15890  
    323323    {
    324324        tcpstat.tcps_rcvbadsum++;
     325        Log2(("checksum is invalid => drop\n"));
    325326        goto drop;
    326327    }
     
    335336    {
    336337        tcpstat.tcps_rcvbadoff++;
     338        Log2(("ti_off(tlen(%d)<%d<(tcphdr(%d))) is invalid =>drop\n", tlen, off, sizeof(struct tcphdr)));
    337339        goto drop;
    338340    }
     
    447449     * or something else, we nuke it.
    448450     */
    449     if (so->so_state & SS_ISFCONNECTING)
     451    if (so->so_state & SS_ISFCONNECTING)
     452    {
     453        Log2(("so_state(%x) of %R[natsock] is still connecting =>drop\n", so->so_state, so));
    450454        goto drop;
     455    }
    451456
    452457    tp = sototcpcb(so);
     
    456461        goto dropwithreset;
    457462    if (tp->t_state == TCPS_CLOSED)
     463    {
     464        Log2(("t_state(%x) is closed =>drop\n", tp->t_state));
    458465        goto drop;
     466    }
    459467
    460468    /* Unscale the window into a 32-bit value. */
     
    654662        case TCPS_LISTEN:
    655663        {
    656             if (tiflags & TH_RST)
     664            if (tiflags & TH_RST) {
     665                Log2(("RST(%x) is on listen =>drop\n", tiflags));
    657666                goto drop;
     667            }
    658668            if (tiflags & TH_ACK)
    659669                goto dropwithreset;
    660             if ((tiflags & TH_SYN) == 0)
     670            if ((tiflags & TH_SYN) == 0)
     671            {
     672                Log2(("SYN(%x) is off on listen =>drop\n", tiflags));
    661673                goto drop;
     674            }
    662675
    663676            /*
     
    768781                if (tiflags & TH_ACK)
    769782                    tp = tcp_drop(pData, tp,0); /* XXX Check t_softerror! */
     783                Log2(("RST(%x) is on SYN_SENT =>drop\n", tiflags));
    770784                goto drop;
    771785            }
    772786
    773             if ((tiflags & TH_SYN) == 0)
     787            if ((tiflags & TH_SYN) == 0)
     788            {
     789                Log2(("SYN(%x) bit is off on SYN_SENT =>drop\n", tiflags));
    774790                goto drop;
     791            }
    775792            if (tiflags & TH_ACK)
    776793            {
     
    10201037/*              so->so_error = ECONNRESET; */
    10211038close:
     1039                Log2(("closing...=>drop\n", tp->t_state));
    10221040                tp->t_state = TCPS_CLOSED;
    10231041                tcpstat.tcps_drops++;
     
    10281046            case TCPS_LAST_ACK:
    10291047            case TCPS_TIME_WAIT:
     1048                Log2(("t_state is (%x) sort of close =>drop\n", tp->t_state));
    10301049                tp = tcp_close(pData, tp);
    10311050                goto drop;
     
    10451064     * If the ACK bit is off we drop the segment and return.
    10461065     */
    1047     if ((tiflags & TH_ACK) == 0)
     1066    if ((tiflags & TH_ACK) == 0)
     1067    {
     1068        Log2(("ACK(%x) bit is off =>drop\n", tiflags));
    10481069        goto drop;
     1070    }
    10491071
    10501072    /*
     
    11541176                        if (SEQ_GT(onxt, tp->snd_nxt))
    11551177                            tp->snd_nxt = onxt;
     1178                        Log2(("t_dupacks(%d) == tcprexmtthresh(%d)=>drop\n", tp->t_dupacks, tcprexmtthresh));
    11561179                        goto drop;
    11571180                    }
     
    11601183                        tp->snd_cwnd += tp->t_maxseg;
    11611184                        (void) tcp_output(pData, tp);
     1185                        Log2(("t_dupacks(%d) > tcprexmtthresh(%d)=>drop\n", tp->t_dupacks, tcprexmtthresh));
    11621186                        goto drop;
    11631187                    }
     
    13051329                    if (ourfinisacked)
    13061330                    {
     1331                        Log2(("ourfinisacked=>drop\n"));
    13071332                        tp = tcp_close(pData, tp);
    13081333                        goto drop;
     
    15281553
    15291554dropafterack:
     1555    Log2(("drop after ack\n"));
    15301556    /*
    15311557     * Generate an ACK dropping incoming segment if it occupies
     
    15411567dropwithreset:
    15421568    /* reuses m if m!=NULL, m_free() unnecessary */
     1569    Log2(("drop with reset\n"));
    15431570    if (tiflags & TH_ACK)
    15441571        tcp_respond(pData, tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
     
    15561583     * Drop space held by incoming segment and return.
    15571584     */
     1585    Log2(("drop\n"));
    15581586    m_free(pData, m);
    15591587
  • trunk/src/VBox/Devices/Network/slirp/tcp_output.c

    r15074 r15890  
    428428        }
    429429        m->m_data += if_maxlinkhdr;
     430#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     431        m->m_data += sizeof(struct ip)
     432            + sizeof(struct tcphdr);
     433#endif
    430434        m->m_len = hdrlen;
    431435    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette