Diff for /qemu/slirp/if.c between versions 1.1.1.6 and 1.1.1.7

version 1.1.1.6, 2018/04/24 19:31:00 version 1.1.1.7, 2018/04/24 19:51:35
Line 8 Line 8
 #include <slirp.h>  #include <slirp.h>
 #include "qemu-timer.h"  #include "qemu-timer.h"
   
 #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))  
   
 static void  static void
 ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)  ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
 {  {
Line 98  if_output(struct socket *so, struct mbuf Line 96  if_output(struct socket *so, struct mbuf
                         ifs_insque(ifm, ifq->ifs_prev);                          ifs_insque(ifm, ifq->ifs_prev);
                         goto diddit;                          goto diddit;
                 }                  }
         } else          } else {
                 ifq = slirp->if_batchq.ifq_prev;                  ifq = slirp->if_batchq.ifq_prev;
                   /* Set next_m if the queue was empty so far */
                   if (slirp->next_m == &slirp->if_batchq) {
                       slirp->next_m = ifm;
                   }
           }
   
         /* Create a new doubly linked list for this session */          /* Create a new doubly linked list for this session */
         ifm->ifq_so = so;          ifm->ifq_so = so;
Line 107  if_output(struct socket *so, struct mbuf Line 110  if_output(struct socket *so, struct mbuf
         insque(ifm, ifq);          insque(ifm, ifq);
   
 diddit:  diddit:
         slirp->if_queued++;  
   
         if (so) {          if (so) {
                 /* Update *_queued */                  /* Update *_queued */
                 so->so_queued++;                  so->so_queued++;
Line 151  diddit: Line 152  diddit:
  * from the second session, then one packet from the third, then back   * from the second session, then one packet from the third, then back
  * to the first, etc. etc.   * to the first, etc. etc.
  */   */
 void  void if_start(Slirp *slirp)
 if_start(Slirp *slirp)  
 {  {
     uint64_t now = qemu_get_clock_ns(rt_clock);      uint64_t now = qemu_get_clock_ns(rt_clock);
     int requeued = 0;      bool from_batchq, next_from_batchq;
         struct mbuf *ifm, *ifqt;      struct mbuf *ifm, *ifm_next, *ifqt;
   
         DEBUG_CALL("if_start");      DEBUG_CALL("if_start");
   
         if (slirp->if_queued == 0)      if (slirp->if_start_busy) {
            return; /* Nothing to do */          return;
       }
       slirp->if_start_busy = true;
   
       if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
           ifm_next = slirp->if_fastq.ifq_next;
           next_from_batchq = false;
       } else if (slirp->next_m != &slirp->if_batchq) {
           /* Nothing on fastq, pick up from batchq via next_m */
           ifm_next = slirp->next_m;
           next_from_batchq = true;
       } else {
           ifm_next = NULL;
       }
   
  again:      while (ifm_next) {
         /* check if we can really output */          /* check if we can really output */
         if (!slirp_can_output(slirp->opaque))          if (!slirp_can_output(slirp->opaque)) {
             return;              break;
           }
   
         /*          ifm = ifm_next;
          * See which queue to get next packet from          from_batchq = next_from_batchq;
          * If there's something in the fastq, select it immediately  
          */  
         if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {  
                 ifm = slirp->if_fastq.ifq_next;  
         } else {  
                 /* Nothing on fastq, see if next_m is valid */  
                 if (slirp->next_m != &slirp->if_batchq)  
                    ifm = slirp->next_m;  
                 else  
                    ifm = slirp->if_batchq.ifq_next;  
   
                 /* Set which packet to send on next iteration */          ifm_next = ifm->ifq_next;
                 slirp->next_m = ifm->ifq_next;          if (ifm_next == &slirp->if_fastq) {
         }              /* No more packets in fastq, switch to batchq */
         /* Remove it from the queue */              ifm_next = slirp->next_m;
         ifqt = ifm->ifq_prev;              next_from_batchq = true;
         remque(ifm);          }
         slirp->if_queued--;          if (ifm_next == &slirp->if_batchq) {
               /* end of batchq */
         /* If there are more packets for this session, re-queue them */              ifm_next = NULL;
         if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {          }
                 insque(ifm->ifs_next, ifqt);  
                 ifs_remque(ifm);  
         }  
   
         /* Update so_queued */          /* Try to send packet unless it already expired */
         if (ifm->ifq_so) {          if (ifm->expiration_date >= now && !if_encap(slirp, ifm)) {
                 if (--ifm->ifq_so->so_queued == 0)              /* Packet is delayed due to pending ARP resolution */
                    /* If there's no more queued, reset nqueued */              continue;
                    ifm->ifq_so->so_nqueued = 0;          }
         }  
   
         if (ifm->expiration_date < now) {          if (ifm == slirp->next_m) {
             /* Expired */              /* Set which packet to send on next iteration */
             m_free(ifm);              slirp->next_m = ifm->ifq_next;
         } else {          }
             /* Encapsulate the packet for sending */  
             if (if_encap(slirp, ifm)) {          /* Remove it from the queue */
                 m_free(ifm);          ifqt = ifm->ifq_prev;
             } else {          remque(ifm);
                 /* re-queue */  
                 insque(ifm, ifqt);          /* If there are more packets for this session, re-queue them */
                 requeued++;          if (ifm->ifs_next != ifm) {
               struct mbuf *next = ifm->ifs_next;
   
               insque(next, ifqt);
               ifs_remque(ifm);
   
               if (!from_batchq) {
                   /* Next packet in fastq is from the same session */
                   ifm_next = next;
                   next_from_batchq = false;
               } else if (slirp->next_m == &slirp->if_batchq) {
                   /* Set next_m and ifm_next if the session packet is now the
                    * only one on batchq */
                   slirp->next_m = ifm_next = next;
             }              }
         }          }
   
         if (slirp->if_queued)          /* Update so_queued */
            goto again;          if (ifm->ifq_so && --ifm->ifq_so->so_queued == 0) {
               /* If there's no more queued, reset nqueued */
               ifm->ifq_so->so_nqueued = 0;
           }
   
           m_free(ifm);
       }
   
         slirp->if_queued = requeued;      slirp->if_start_busy = false;
 }  }

Removed from v.1.1.1.6  
changed lines
  Added in v.1.1.1.7


unix.superglobalmegacorp.com