qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 08/13] net: add return value to packet receive handl


From: Mark McLoughlin
Subject: [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler
Date: Tue, 19 May 2009 10:55:30 +0100

This allows us to handle queue full conditions rather than dropping
the packet on the floor.

Signed-off-by: Mark McLoughlin <address@hidden>
---
 hw/dp8393x.c        |    8 ++++--
 hw/e1000.c          |   14 +++++++-----
 hw/eepro100.c       |   15 +++++++------
 hw/etraxfs_eth.c    |    8 ++++--
 hw/mcf_fec.c        |    3 +-
 hw/mipsnet.c        |    6 +++-
 hw/musicpal.c       |    5 ++-
 hw/ne2000.c         |   15 ++++++++-----
 hw/pcnet.c          |    7 ++++-
 hw/rtl8139.c        |   29 +++++++++++++++------------
 hw/smc91c111.c      |   10 +++++---
 hw/stellaris_enet.c |    8 ++++--
 hw/usb-net.c        |    9 ++++---
 hw/virtio-net.c     |   10 +++++---
 hw/xen_nic.c        |   12 ++++++----
 net.c               |   54 ++++++++++++++++++++++++++------------------------
 net.h               |    2 +-
 tap-win32.c         |    6 ++--
 18 files changed, 126 insertions(+), 95 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 91850bc..563cbad 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -725,7 +725,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * 
buf, int size)
     return -1;
 }
 
-static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
+static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t 
size)
 {
     uint16_t data[10];
     dp8393xState *s = vc->opaque;
@@ -742,7 +742,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t 
* buf, size_t size)
     packet_type = receive_filter(s, buf, size);
     if (packet_type < 0) {
         DPRINTF("packet not for netcard\n");
-        return;
+        return -1;
     }
 
     /* XXX: Check byte ordering */
@@ -755,7 +755,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t 
* buf, size_t size)
         s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
         if (data[0 * width] & 0x1) {
             /* Still EOL ; stop reception */
-            return;
+            return -1;
         } else {
             s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
         }
@@ -833,6 +833,8 @@ static void nic_receive(VLANClientState *vc, const uint8_t 
* buf, size_t size)
 
     /* Done */
     dp8393x_update_irq(s);
+
+    return size;
 }
 
 static void nic_reset(void *opaque)
diff --git a/hw/e1000.c b/hw/e1000.c
index 689c48e..ef33a4e 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -592,7 +592,7 @@ e1000_can_receive(VLANClientState *vc)
     return (s->mac_reg[RCTL] & E1000_RCTL_EN);
 }
 
-static void
+static ssize_t
 e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
 {
     E1000State *s = vc->opaque;
@@ -604,16 +604,16 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
     uint8_t vlan_status = 0, vlan_offset = 0;
 
     if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
-        return;
+        return -1;
 
     if (size > s->rxbuf_size) {
         DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
                (unsigned long)size, s->rxbuf_size);
-        return;
+        return -1;
     }
 
     if (!receive_filter(s, buf, size))
-        return;
+        return size;
 
     if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
         vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
@@ -628,7 +628,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
     do {
         if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
             set_ics(s, 0, E1000_ICS_RXO);
-            return;
+            return -1;
         }
         base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
                sizeof(desc) * s->mac_reg[RDH];
@@ -652,7 +652,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
             DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
                    rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
             set_ics(s, 0, E1000_ICS_RXO);
-            return;
+            return -1;
         }
     } while (desc.buffer_addr == 0);
 
@@ -670,6 +670,8 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
         n |= E1000_ICS_RXDMT0;
 
     set_ics(s, 0, n);
+
+    return size;
 }
 
 static uint32_t
diff --git a/hw/eepro100.c b/hw/eepro100.c
index ef977a9..1440d00 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1441,7 +1441,7 @@ static int nic_can_receive(VLANClientState *vc)
     //~ return !eepro100_buffer_full(s);
 }
 
-static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
+static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t 
size)
 {
     /* TODO:
      * - Magic packets should set bit 30 in power management driver register.
@@ -1458,18 +1458,18 @@ static void nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size)
     if (s->configuration[8] & 0x80) {
         /* CSMA is disabled. */
         logout("%p received while CSMA is disabled\n", s);
-        return;
+        return -1;
     } else if (size < 64 && (s->configuration[7] & 1)) {
         /* Short frame and configuration byte 7/0 (discard short receive) set:
          * Short frame is discarded */
         logout("%p received short frame (%d byte)\n", s, size);
         s->statistics.rx_short_frame_errors++;
-        //~ return;
+        //~ return -1;
     } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) 
{
         /* Long frame and configuration byte 18/3 (long receive ok) not set:
          * Long frames are discarded. */
         logout("%p received long frame (%d byte), ignored\n", s, size);
-        return;
+        return -1;
     } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!
         /* Frame matches individual address. */
         /* TODO: check configuration byte 15/4 (ignore U/L). */
@@ -1485,7 +1485,7 @@ static void nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size)
         assert(!(s->configuration[21] & BIT(3)));
         int mcast_idx = compute_mcast_idx(buf);
         if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
-            return;
+            return size;
         }
         rfd_status |= 0x0002;
     } else if (s->configuration[15] & 1) {
@@ -1495,7 +1495,7 @@ static void nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size)
     } else {
         logout("%p received frame, ignored, len=%d,%s\n", s, size,
                nic_dump(buf, size));
-        return;
+        return size;
     }
 
     if (get_ru_state(s) != ru_ready) {
@@ -1503,7 +1503,7 @@ static void nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size)
         logout("no ressources, state=%u\n", get_ru_state(s));
         s->statistics.rx_resource_errors++;
         //~ assert(!"no ressources");
-        return;
+        return -1;
     }
     //~ !!!
 //~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 
0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
@@ -1540,6 +1540,7 @@ static void nic_receive(VLANClientState *vc, const 
uint8_t * buf, size_t size)
         /* S bit is set. */
         set_ru_state(s, ru_suspended);
     }
+    return size;
 }
 
 static int nic_load(QEMUFile * f, void *opaque, int version_id)
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 78af76b..c7df44e 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -501,7 +501,7 @@ static int eth_can_receive(VLANClientState *vc)
        return 1;
 }
 
-static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t eth_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
        unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        struct fs_eth *eth = vc->opaque;
@@ -510,7 +510,7 @@ static void eth_receive(VLANClientState *vc, const uint8_t 
*buf, size_t size)
        int r_bcast = eth->regs[RW_REC_CTRL] & 8;
 
        if (size < 12)
-               return;
+               return -1;
 
        D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
                 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
@@ -521,10 +521,12 @@ static void eth_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
            && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
            && (!r_bcast || memcmp(buf, sa_bcast, 6))
            && !eth_match_groupaddr(eth, buf))
-               return;
+               return size;
 
        /* FIXME: Find another way to pass on the fake csum.  */
        etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1);
+
+        return size;
 }
 
 static int eth_tx_push(void *opaque, unsigned char *buf, int len)
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index d2534d0..179ec19 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -353,7 +353,7 @@ static int mcf_fec_can_receive(VLANClientState *vc)
     return s->rx_enabled;
 }
 
-static void mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     mcf_fec_state *s = vc->opaque;
     mcf_fec_bd bd;
@@ -426,6 +426,7 @@ static void mcf_fec_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size
     s->rx_descriptor = addr;
     mcf_fec_enable_rx(s);
     mcf_fec_update(s);
+    return size;
 }
 
 static CPUReadMemoryFunc *mcf_fec_readfn[] = {
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index e9128cb..8035229 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -75,7 +75,7 @@ static int mipsnet_can_receive(VLANClientState *vc)
     return !mipsnet_buffer_full(s);
 }
 
-static void mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t mipsnet_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     MIPSnetState *s = vc->opaque;
 
@@ -83,7 +83,7 @@ static void mipsnet_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size
     printf("mipsnet: receiving len=%d\n", size);
 #endif
     if (!mipsnet_can_receive(vc))
-        return;
+        return -1;
 
     s->busy = 1;
 
@@ -98,6 +98,8 @@ static void mipsnet_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size
     /* Now we can signal we have received something. */
     s->intctl |= MIPSNET_INTCTL_RXDONE;
     mipsnet_update_irq(s);
+
+    return size;
 }
 
 static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 943dc6f..9bc4f3d 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -562,7 +562,7 @@ static int eth_can_receive(VLANClientState *vc)
     return 1;
 }
 
-static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t eth_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     mv88w8618_eth_state *s = vc->opaque;
     uint32_t desc_addr;
@@ -586,11 +586,12 @@ static void eth_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
                 if (s->icr & s->imr)
                     qemu_irq_raise(s->irq);
                 eth_rx_desc_put(desc_addr, &desc);
-                return;
+                return size;
             }
             desc_addr = desc.next;
         } while (desc_addr != s->rx_queue[i]);
     }
+    return size;
 }
 
 static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index c0fc34c..f5ae9d7 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -224,9 +224,10 @@ static int ne2000_can_receive(VLANClientState *vc)
 
 #define MIN_BUF_SIZE 60
 
-static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size_)
 {
     NE2000State *s = vc->opaque;
+    int size = size_;
     uint8_t *p;
     unsigned int total_len, next, avail, len, index, mcast_idx;
     uint8_t buf1[60];
@@ -238,7 +239,7 @@ static void ne2000_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 #endif
 
     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
-        return;
+        return -1;
 
     /* XXX: check this */
     if (s->rxcr & 0x10) {
@@ -247,14 +248,14 @@ static void ne2000_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
         if (!memcmp(buf,  broadcast_macaddr, 6)) {
             /* broadcast address */
             if (!(s->rxcr & 0x04))
-                return;
+                return size;
         } else if (buf[0] & 0x01) {
             /* multicast */
             if (!(s->rxcr & 0x08))
-                return;
+                return size;
             mcast_idx = compute_mcast_idx(buf);
             if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
-                return;
+                return size;
         } else if (s->mem[0] == buf[0] &&
                    s->mem[2] == buf[1] &&
                    s->mem[4] == buf[2] &&
@@ -263,7 +264,7 @@ static void ne2000_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
                    s->mem[10] == buf[5]) {
             /* match */
         } else {
-            return;
+            return size;
         }
     }
 
@@ -316,6 +317,8 @@ static void ne2000_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
     /* now we can signal we have received something */
     s->isr |= ENISR_RX;
     ne2000_update_irq(s);
+
+    return size_;
 }
 
 static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 1ab731c..4afbc0f 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1076,16 +1076,17 @@ static int pcnet_can_receive(VLANClientState *vc)
 
 #define MIN_BUF_SIZE 60
 
-static void pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size_)
 {
     PCNetState *s = vc->opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
     uint8_t buf1[60];
     int remaining;
     int crc_err = 0;
+    int size = size_;
 
     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
-        return;
+        return -1;
 
 #ifdef PCNET_DEBUG
     printf("pcnet_receive size=%d\n", size);
@@ -1252,6 +1253,8 @@ static void pcnet_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 
     pcnet_poll(s);
     pcnet_update_irq(s);
+
+    return size_;
 }
 
 static void pcnet_transmit(PCNetState *s)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 8626d5e..c86b782 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -812,9 +812,10 @@ static int rtl8139_can_receive(VLANClientState *vc)
     }
 }
 
-static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int 
size, int do_interrupt)
+static ssize_t rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size_, int do_interrupt)
 {
     RTL8139State *s = vc->opaque;
+    int size = size_;
 
     uint32_t packet_header = 0;
 
@@ -828,7 +829,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
     if (!s->clock_enabled)
     {
         DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
-        return;
+        return -1;
     }
 
     /* first check if receiver is enabled */
@@ -836,7 +837,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
     if (!rtl8139_receiver_enabled(s))
     {
         DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
-        return;
+        return -1;
     }
 
     /* XXX: check this */
@@ -854,7 +855,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxBroadcast;
@@ -873,7 +874,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             int mcast_idx = compute_mcast_idx(buf);
@@ -885,7 +886,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxMulticast;
@@ -909,7 +910,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
 
-                return;
+                return size;
             }
 
             packet_header |= RxPhysical;
@@ -926,7 +927,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
             /* update tally counter */
             ++s->tally_counters.RxERR;
 
-            return;
+            return size;
         }
     }
 
@@ -993,7 +994,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
             ++s->tally_counters.MissPkt;
 
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
@@ -1013,7 +1014,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
             ++s->tally_counters.MissPkt;
 
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
@@ -1118,7 +1119,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const 
uint8_t *buf, int size
             s->IntrStatus |= RxOverflow;
             ++s->RxMissed;
             rtl8139_update_irq(s);
-            return;
+            return size_;
         }
 
         packet_header |= RxStatusOK;
@@ -1156,11 +1157,13 @@ static void rtl8139_do_receive(VLANClientState *vc, 
const uint8_t *buf, int size
     {
         rtl8139_update_irq(s);
     }
+
+    return size_;
 }
 
-static void rtl8139_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t rtl8139_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
-    rtl8139_do_receive(vc, buf, size, 1);
+    return rtl8139_do_receive(vc, buf, size, 1);
 }
 
 static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 383f0b7..93a1fae 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -602,7 +602,7 @@ static int smc91c111_can_receive(VLANClientState *vc)
     return 1;
 }
 
-static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t smc91c111_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
 {
     smc91c111_state *s = vc->opaque;
     int status;
@@ -612,7 +612,7 @@ static void smc91c111_receive(VLANClientState *vc, const 
uint8_t *buf, size_t si
     uint8_t *p;
 
     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
-        return;
+        return -1;
     /* Short packets are padded with zeros.  Receiving a packet
        < 64 bytes long is considered an error condition.  */
     if (size < 64)
@@ -625,10 +625,10 @@ static void smc91c111_receive(VLANClientState *vc, const 
uint8_t *buf, size_t si
         packetsize += 4;
     /* TODO: Flag overrun and receive errors.  */
     if (packetsize > 2048)
-        return;
+        return -1;
     packetnum = smc91c111_allocate_packet(s);
     if (packetnum == 0x80)
-        return;
+        return -1;
     s->rx_fifo[s->rx_fifo_len++] = packetnum;
 
     p = &s->data[packetnum][0];
@@ -676,6 +676,8 @@ static void smc91c111_receive(VLANClientState *vc, const 
uint8_t *buf, size_t si
     /* TODO: Raise early RX interrupt?  */
     s->int_level |= INT_RCV;
     smc91c111_update(s);
+
+    return size;
 }
 
 static CPUReadMemoryFunc *smc91c111_readfn[] = {
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 7f30829..f5b83e4 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -78,7 +78,7 @@ static void stellaris_enet_update(stellaris_enet_state *s)
 }
 
 /* TODO: Implement MAC address filtering.  */
-static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
+static ssize_t stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
 {
     stellaris_enet_state *s = vc->opaque;
     int n;
@@ -86,10 +86,10 @@ static void stellaris_enet_receive(VLANClientState *vc, 
const uint8_t *buf, size
     uint32_t crc;
 
     if ((s->rctl & SE_RCTL_RXEN) == 0)
-        return;
+        return -1;
     if (s->np >= 31) {
         DPRINTF("Packet dropped\n");
-        return;
+        return -1;
     }
 
     DPRINTF("Received packet len=%d\n", size);
@@ -116,6 +116,8 @@ static void stellaris_enet_receive(VLANClientState *vc, 
const uint8_t *buf, size
 
     s->ris |= SE_INT_RX;
     stellaris_enet_update(s);
+
+    return size;
 }
 
 static int stellaris_enet_can_receive(VLANClientState *vc)
diff --git a/hw/usb-net.c b/hw/usb-net.c
index d8d5e77..0e80ca6 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1369,7 +1369,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket 
*p)
     return ret;
 }
 
-static void usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t usbnet_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     USBNetState *s = vc->opaque;
     struct rndis_packet_msg_type *msg;
@@ -1377,9 +1377,9 @@ static void usbnet_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
     if (s->rndis) {
         msg = (struct rndis_packet_msg_type *) s->in_buf;
         if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
-            return;
+            return -1;
         if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
-            return;
+            return -1;
 
         memset(msg, 0, sizeof(struct rndis_packet_msg_type));
         msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
@@ -1398,11 +1398,12 @@ static void usbnet_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
         s->in_len = size + sizeof(struct rndis_packet_msg_type);
     } else {
         if (size > sizeof(s->in_buf))
-            return;
+            return -1;
         memcpy(s->in_buf, buf, size);
         s->in_len = size;
     }
     s->in_ptr = 0;
+    return size;
 }
 
 static int usbnet_can_receive(VLANClientState *vc)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 1ffebac..6b34c5a 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -361,17 +361,17 @@ static int receive_filter(VirtIONet *n, const uint8_t 
*buf, int size)
     return 0;
 }
 
-static void virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t virtio_net_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
 {
     VirtIONet *n = vc->opaque;
     struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
     size_t hdr_len, offset, i;
 
     if (!do_virtio_net_can_receive(n, size))
-        return;
+        return -1;
 
     if (!receive_filter(n, buf, size))
-        return;
+        return size;
 
     /* hdr_len refers to the header we supply to the guest */
     hdr_len = n->mergeable_rx_bufs ?
@@ -389,7 +389,7 @@ static void virtio_net_receive(VLANClientState *vc, const 
uint8_t *buf, size_t s
         if ((i != 0 && !n->mergeable_rx_bufs) ||
             virtqueue_pop(n->rx_vq, &elem) == 0) {
             if (i == 0)
-                return;
+                return -1;
             fprintf(stderr, "virtio-net truncating packet\n");
             exit(1);
         }
@@ -431,6 +431,8 @@ static void virtio_net_receive(VLANClientState *vc, const 
uint8_t *buf, size_t s
 
     virtqueue_flush(n->rx_vq, i);
     virtio_notify(&n->vdev, n->rx_vq);
+
+    return size;
 }
 
 /* TX */
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index d2d5a4b..8a55c29 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -245,7 +245,7 @@ static int net_rx_ok(VLANClientState *vc)
     return 1;
 }
 
-static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     struct XenNetDev *netdev = vc->opaque;
     netif_rx_request_t rxreq;
@@ -253,7 +253,7 @@ static void net_rx_packet(VLANClientState *vc, const 
uint8_t *buf, size_t size)
     void *page;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-       return;
+       return -1;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
@@ -261,12 +261,12 @@ static void net_rx_packet(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
        xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
-       return;
+       return -1;
     }
     if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
        xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
                      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
-       return;
+       return -1;
     }
 
     memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
@@ -279,11 +279,13 @@ static void net_rx_packet(VLANClientState *vc, const 
uint8_t *buf, size_t size)
        xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed 
(%d)\n",
                       rxreq.gref);
        net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
-       return;
+       return -1;
     }
     memcpy(page + NET_IP_ALIGN, buf, size);
     xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
     net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
+
+    return size;
 }
 
 /* ------------------------------------------------------------- */
diff --git a/net.c b/net.c
index a3af42d..7d0a428 100644
--- a/net.c
+++ b/net.c
@@ -568,13 +568,14 @@ int slirp_is_inited(void)
     return slirp_inited;
 }
 
-static void slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
 #ifdef DEBUG_SLIRP
     printf("slirp input:\n");
     hex_dump(stdout, buf, size);
 #endif
     slirp_input(buf, size);
+    return size;
 }
 
 static int slirp_in_use;
@@ -800,17 +801,16 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const 
struct iovec *iov,
     return len;
 }
 
-static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     TAPState *s = vc->opaque;
-    int ret;
-    for(;;) {
-        ret = write(s->fd, buf, size);
-        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
-        } else {
-            break;
-        }
-    }
+    ssize_t len;
+
+    do {
+        len = write(s->fd, buf, size);
+    } while (len == -1 && (errno == EINTR || errno == EAGAIN));
+
+    return len;
 }
 
 static int tap_can_send(void *opaque)
@@ -1158,17 +1158,16 @@ static void vde_to_qemu(void *opaque)
     }
 }
 
-static void vde_receive(VLANClientState *vc, const uint8_t *buf, int size)
+static ssize_t vde_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     VDEState *s = vc->opaque;
-    int ret;
-    for(;;) {
-        ret = vde_send(s->vde, (const char *)buf, size, 0);
-        if (ret < 0 && errno == EINTR) {
-        } else {
-            break;
-        }
-    }
+    ssize ret;
+
+    do {
+      ret = vde_send(s->vde, (const char *)buf, size, 0);
+    } while (ret < 0 && errno == EINTR);
+
+    return ret;
 }
 
 static void vde_cleanup(VLANClientState *vc)
@@ -1227,21 +1226,22 @@ typedef struct NetSocketListenState {
 } NetSocketListenState;
 
 /* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
+static ssize_t net_socket_receive(VLANClientState *vc, const uint8_t *buf, 
size_t size)
 {
     NetSocketState *s = vc->opaque;
     uint32_t len;
     len = htonl(size);
 
     send_all(s->fd, (const uint8_t *)&len, sizeof(len));
-    send_all(s->fd, buf, size);
+    return send_all(s->fd, buf, size);
 }
 
-static void net_socket_receive_dgram(VLANClientState *vc, const uint8_t *buf, 
size_t size)
+static ssize_t net_socket_receive_dgram(VLANClientState *vc, const uint8_t 
*buf, size_t size)
 {
     NetSocketState *s = vc->opaque;
-    sendto(s->fd, buf, size, 0,
-           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
+
+    return sendto(s->fd, buf, size, 0,
+                  (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
 }
 
 static void net_socket_send(void *opaque)
@@ -1678,7 +1678,7 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t dump_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
     DumpState *s = vc->opaque;
     struct pcap_sf_pkthdr hdr;
@@ -1687,7 +1687,7 @@ static void dump_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
 
     /* Early return in case of previous error. */
     if (s->fd < 0) {
-        return;
+        return size;
     }
 
     ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
@@ -1703,6 +1703,8 @@ static void dump_receive(VLANClientState *vc, const 
uint8_t *buf, size_t size)
         close(s->fd);
         s->fd = -1;
     }
+
+    return size;
 }
 
 static void net_dump_cleanup(VLANClientState *vc)
diff --git a/net.h b/net.h
index 2e308c9..766edbe 100644
--- a/net.h
+++ b/net.h
@@ -8,7 +8,7 @@
 typedef struct VLANClientState VLANClientState;
 
 typedef int (NetCanReceive)(VLANClientState *);
-typedef void (NetReceive)(VLANClientState *, const uint8_t *, size_t);
+typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
diff --git a/tap-win32.c b/tap-win32.c
index ff1e1ed..ba93355 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -650,11 +650,11 @@ static void tap_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t 
size)
 {
-    TAPState *s = opaque;
+    TAPState *s = vc->opaque;
 
-    tap_win32_write(s->handle, buf, size);
+    return tap_win32_write(s->handle, buf, size);
 }
 
 static void tap_win32_send(void *opaque)
-- 
1.6.0.6





reply via email to

[Prev in Thread] Current Thread [Next in Thread]