mirror of https://github.com/xemu-project/xemu.git
net: add return value to packet receive handler
This allows us to handle queue full conditions rather than dropping the packet on the floor. Signed-off-by: Mark McLoughlin <markmc@redhat.com>
This commit is contained in:
parent
e3f5ec2b5e
commit
4f1c942b7f
|
@ -725,7 +725,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
|
||||||
return -1;
|
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];
|
uint16_t data[10];
|
||||||
dp8393xState *s = vc->opaque;
|
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);
|
packet_type = receive_filter(s, buf, size);
|
||||||
if (packet_type < 0) {
|
if (packet_type < 0) {
|
||||||
DPRINTF("packet not for netcard\n");
|
DPRINTF("packet not for netcard\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: Check byte ordering */
|
/* 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);
|
s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
|
||||||
if (data[0 * width] & 0x1) {
|
if (data[0 * width] & 0x1) {
|
||||||
/* Still EOL ; stop reception */
|
/* Still EOL ; stop reception */
|
||||||
return;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
|
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 */
|
/* Done */
|
||||||
dp8393x_update_irq(s);
|
dp8393x_update_irq(s);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nic_reset(void *opaque)
|
static void nic_reset(void *opaque)
|
||||||
|
|
14
hw/e1000.c
14
hw/e1000.c
|
@ -599,7 +599,7 @@ e1000_can_receive(VLANClientState *vc)
|
||||||
return (s->mac_reg[RCTL] & E1000_RCTL_EN);
|
return (s->mac_reg[RCTL] & E1000_RCTL_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static ssize_t
|
||||||
e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
E1000State *s = vc->opaque;
|
E1000State *s = vc->opaque;
|
||||||
|
@ -611,16 +611,16 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
uint8_t vlan_status = 0, vlan_offset = 0;
|
uint8_t vlan_status = 0, vlan_offset = 0;
|
||||||
|
|
||||||
if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
|
if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
if (size > s->rxbuf_size) {
|
if (size > s->rxbuf_size) {
|
||||||
DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
|
DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
|
||||||
(unsigned long)size, s->rxbuf_size);
|
(unsigned long)size, s->rxbuf_size);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!receive_filter(s, buf, size))
|
if (!receive_filter(s, buf, size))
|
||||||
return;
|
return size;
|
||||||
|
|
||||||
if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
|
if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
|
||||||
vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
|
vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
|
||||||
|
@ -635,7 +635,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
do {
|
do {
|
||||||
if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
|
if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
|
||||||
set_ics(s, 0, E1000_ICS_RXO);
|
set_ics(s, 0, E1000_ICS_RXO);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
|
base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
|
||||||
sizeof(desc) * s->mac_reg[RDH];
|
sizeof(desc) * s->mac_reg[RDH];
|
||||||
|
@ -659,7 +659,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
||||||
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
||||||
set_ics(s, 0, E1000_ICS_RXO);
|
set_ics(s, 0, E1000_ICS_RXO);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (desc.buffer_addr == 0);
|
} while (desc.buffer_addr == 0);
|
||||||
|
|
||||||
|
@ -677,6 +677,8 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
n |= E1000_ICS_RXDMT0;
|
n |= E1000_ICS_RXDMT0;
|
||||||
|
|
||||||
set_ics(s, 0, n);
|
set_ics(s, 0, n);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
|
|
|
@ -1441,7 +1441,7 @@ static int nic_can_receive(VLANClientState *vc)
|
||||||
//~ return !eepro100_buffer_full(s);
|
//~ 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:
|
/* TODO:
|
||||||
* - Magic packets should set bit 30 in power management driver register.
|
* - 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) {
|
if (s->configuration[8] & 0x80) {
|
||||||
/* CSMA is disabled. */
|
/* CSMA is disabled. */
|
||||||
logout("%p received while CSMA is disabled\n", s);
|
logout("%p received while CSMA is disabled\n", s);
|
||||||
return;
|
return -1;
|
||||||
} else if (size < 64 && (s->configuration[7] & 1)) {
|
} else if (size < 64 && (s->configuration[7] & 1)) {
|
||||||
/* Short frame and configuration byte 7/0 (discard short receive) set:
|
/* Short frame and configuration byte 7/0 (discard short receive) set:
|
||||||
* Short frame is discarded */
|
* Short frame is discarded */
|
||||||
logout("%p received short frame (%d byte)\n", s, size);
|
logout("%p received short frame (%d byte)\n", s, size);
|
||||||
s->statistics.rx_short_frame_errors++;
|
s->statistics.rx_short_frame_errors++;
|
||||||
//~ return;
|
//~ return -1;
|
||||||
} else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
|
} 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 frame and configuration byte 18/3 (long receive ok) not set:
|
||||||
* Long frames are discarded. */
|
* Long frames are discarded. */
|
||||||
logout("%p received long frame (%d byte), ignored\n", s, size);
|
logout("%p received long frame (%d byte), ignored\n", s, size);
|
||||||
return;
|
return -1;
|
||||||
} else if (memcmp(buf, s->macaddr, 6) == 0) { // !!!
|
} else if (memcmp(buf, s->macaddr, 6) == 0) { // !!!
|
||||||
/* Frame matches individual address. */
|
/* Frame matches individual address. */
|
||||||
/* TODO: check configuration byte 15/4 (ignore U/L). */
|
/* 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)));
|
assert(!(s->configuration[21] & BIT(3)));
|
||||||
int mcast_idx = compute_mcast_idx(buf);
|
int mcast_idx = compute_mcast_idx(buf);
|
||||||
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
|
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
rfd_status |= 0x0002;
|
rfd_status |= 0x0002;
|
||||||
} else if (s->configuration[15] & 1) {
|
} else if (s->configuration[15] & 1) {
|
||||||
|
@ -1495,7 +1495,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
|
||||||
} else {
|
} else {
|
||||||
logout("%p received frame, ignored, len=%d,%s\n", s, size,
|
logout("%p received frame, ignored, len=%d,%s\n", s, size,
|
||||||
nic_dump(buf, size));
|
nic_dump(buf, size));
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_ru_state(s) != ru_ready) {
|
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));
|
logout("no ressources, state=%u\n", get_ru_state(s));
|
||||||
s->statistics.rx_resource_errors++;
|
s->statistics.rx_resource_errors++;
|
||||||
//~ assert(!"no ressources");
|
//~ 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>}}
|
//~ $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. */
|
/* S bit is set. */
|
||||||
set_ru_state(s, ru_suspended);
|
set_ru_state(s, ru_suspended);
|
||||||
}
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nic_load(QEMUFile * f, void *opaque, int version_id)
|
static int nic_load(QEMUFile * f, void *opaque, int version_id)
|
||||||
|
|
|
@ -501,7 +501,7 @@ static int eth_can_receive(VLANClientState *vc)
|
||||||
return 1;
|
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 };
|
unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
struct fs_eth *eth = vc->opaque;
|
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;
|
int r_bcast = eth->regs[RW_REC_CTRL] & 8;
|
||||||
|
|
||||||
if (size < 12)
|
if (size < 12)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
|
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],
|
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))
|
&& (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
|
||||||
&& (!r_bcast || memcmp(buf, sa_bcast, 6))
|
&& (!r_bcast || memcmp(buf, sa_bcast, 6))
|
||||||
&& !eth_match_groupaddr(eth, buf))
|
&& !eth_match_groupaddr(eth, buf))
|
||||||
return;
|
return size;
|
||||||
|
|
||||||
/* FIXME: Find another way to pass on the fake csum. */
|
/* FIXME: Find another way to pass on the fake csum. */
|
||||||
etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1);
|
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)
|
static int eth_tx_push(void *opaque, unsigned char *buf, int len)
|
||||||
|
|
|
@ -353,7 +353,7 @@ static int mcf_fec_can_receive(VLANClientState *vc)
|
||||||
return s->rx_enabled;
|
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_state *s = vc->opaque;
|
||||||
mcf_fec_bd bd;
|
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;
|
s->rx_descriptor = addr;
|
||||||
mcf_fec_enable_rx(s);
|
mcf_fec_enable_rx(s);
|
||||||
mcf_fec_update(s);
|
mcf_fec_update(s);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *mcf_fec_readfn[] = {
|
static CPUReadMemoryFunc *mcf_fec_readfn[] = {
|
||||||
|
|
|
@ -75,7 +75,7 @@ static int mipsnet_can_receive(VLANClientState *vc)
|
||||||
return !mipsnet_buffer_full(s);
|
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;
|
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);
|
printf("mipsnet: receiving len=%d\n", size);
|
||||||
#endif
|
#endif
|
||||||
if (!mipsnet_can_receive(vc))
|
if (!mipsnet_can_receive(vc))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
s->busy = 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. */
|
/* Now we can signal we have received something. */
|
||||||
s->intctl |= MIPSNET_INTCTL_RXDONE;
|
s->intctl |= MIPSNET_INTCTL_RXDONE;
|
||||||
mipsnet_update_irq(s);
|
mipsnet_update_irq(s);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr)
|
static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr)
|
||||||
|
|
|
@ -562,7 +562,7 @@ static int eth_can_receive(VLANClientState *vc)
|
||||||
return 1;
|
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;
|
mv88w8618_eth_state *s = vc->opaque;
|
||||||
uint32_t desc_addr;
|
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)
|
if (s->icr & s->imr)
|
||||||
qemu_irq_raise(s->irq);
|
qemu_irq_raise(s->irq);
|
||||||
eth_rx_desc_put(desc_addr, &desc);
|
eth_rx_desc_put(desc_addr, &desc);
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
desc_addr = desc.next;
|
desc_addr = desc.next;
|
||||||
} while (desc_addr != s->rx_queue[i]);
|
} while (desc_addr != s->rx_queue[i]);
|
||||||
}
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
|
static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
|
||||||
|
|
15
hw/ne2000.c
15
hw/ne2000.c
|
@ -224,9 +224,10 @@ static int ne2000_can_receive(VLANClientState *vc)
|
||||||
|
|
||||||
#define MIN_BUF_SIZE 60
|
#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;
|
NE2000State *s = vc->opaque;
|
||||||
|
int size = size_;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
unsigned int total_len, next, avail, len, index, mcast_idx;
|
unsigned int total_len, next, avail, len, index, mcast_idx;
|
||||||
uint8_t buf1[60];
|
uint8_t buf1[60];
|
||||||
|
@ -238,7 +239,7 @@ static void ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
|
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/* XXX: check this */
|
/* XXX: check this */
|
||||||
if (s->rxcr & 0x10) {
|
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)) {
|
if (!memcmp(buf, broadcast_macaddr, 6)) {
|
||||||
/* broadcast address */
|
/* broadcast address */
|
||||||
if (!(s->rxcr & 0x04))
|
if (!(s->rxcr & 0x04))
|
||||||
return;
|
return size;
|
||||||
} else if (buf[0] & 0x01) {
|
} else if (buf[0] & 0x01) {
|
||||||
/* multicast */
|
/* multicast */
|
||||||
if (!(s->rxcr & 0x08))
|
if (!(s->rxcr & 0x08))
|
||||||
return;
|
return size;
|
||||||
mcast_idx = compute_mcast_idx(buf);
|
mcast_idx = compute_mcast_idx(buf);
|
||||||
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
|
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
|
||||||
return;
|
return size;
|
||||||
} else if (s->mem[0] == buf[0] &&
|
} else if (s->mem[0] == buf[0] &&
|
||||||
s->mem[2] == buf[1] &&
|
s->mem[2] == buf[1] &&
|
||||||
s->mem[4] == buf[2] &&
|
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]) {
|
s->mem[10] == buf[5]) {
|
||||||
/* match */
|
/* match */
|
||||||
} else {
|
} 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 */
|
/* now we can signal we have received something */
|
||||||
s->isr |= ENISR_RX;
|
s->isr |= ENISR_RX;
|
||||||
ne2000_update_irq(s);
|
ne2000_update_irq(s);
|
||||||
|
|
||||||
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
|
|
@ -1076,16 +1076,17 @@ static int pcnet_can_receive(VLANClientState *vc)
|
||||||
|
|
||||||
#define MIN_BUF_SIZE 60
|
#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;
|
PCNetState *s = vc->opaque;
|
||||||
int is_padr = 0, is_bcast = 0, is_ladr = 0;
|
int is_padr = 0, is_bcast = 0, is_ladr = 0;
|
||||||
uint8_t buf1[60];
|
uint8_t buf1[60];
|
||||||
int remaining;
|
int remaining;
|
||||||
int crc_err = 0;
|
int crc_err = 0;
|
||||||
|
int size = size_;
|
||||||
|
|
||||||
if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
|
if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
#ifdef PCNET_DEBUG
|
#ifdef PCNET_DEBUG
|
||||||
printf("pcnet_receive size=%d\n", size);
|
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_poll(s);
|
||||||
pcnet_update_irq(s);
|
pcnet_update_irq(s);
|
||||||
|
|
||||||
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcnet_transmit(PCNetState *s)
|
static void pcnet_transmit(PCNetState *s)
|
||||||
|
|
29
hw/rtl8139.c
29
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;
|
RTL8139State *s = vc->opaque;
|
||||||
|
int size = size_;
|
||||||
|
|
||||||
uint32_t packet_header = 0;
|
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)
|
if (!s->clock_enabled)
|
||||||
{
|
{
|
||||||
DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
|
DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first check if receiver is enabled */
|
/* 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))
|
if (!rtl8139_receiver_enabled(s))
|
||||||
{
|
{
|
||||||
DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
|
DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: check this */
|
/* XXX: check this */
|
||||||
|
@ -854,7 +855,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
|
||||||
/* update tally counter */
|
/* update tally counter */
|
||||||
++s->tally_counters.RxERR;
|
++s->tally_counters.RxERR;
|
||||||
|
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_header |= RxBroadcast;
|
packet_header |= RxBroadcast;
|
||||||
|
@ -873,7 +874,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
|
||||||
/* update tally counter */
|
/* update tally counter */
|
||||||
++s->tally_counters.RxERR;
|
++s->tally_counters.RxERR;
|
||||||
|
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mcast_idx = compute_mcast_idx(buf);
|
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 */
|
/* update tally counter */
|
||||||
++s->tally_counters.RxERR;
|
++s->tally_counters.RxERR;
|
||||||
|
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_header |= RxMulticast;
|
packet_header |= RxMulticast;
|
||||||
|
@ -909,7 +910,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
|
||||||
/* update tally counter */
|
/* update tally counter */
|
||||||
++s->tally_counters.RxERR;
|
++s->tally_counters.RxERR;
|
||||||
|
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_header |= RxPhysical;
|
packet_header |= RxPhysical;
|
||||||
|
@ -926,7 +927,7 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
|
||||||
/* update tally counter */
|
/* update tally counter */
|
||||||
++s->tally_counters.RxERR;
|
++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;
|
++s->tally_counters.MissPkt;
|
||||||
|
|
||||||
rtl8139_update_irq(s);
|
rtl8139_update_irq(s);
|
||||||
return;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
|
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;
|
++s->tally_counters.MissPkt;
|
||||||
|
|
||||||
rtl8139_update_irq(s);
|
rtl8139_update_irq(s);
|
||||||
return;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
|
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->IntrStatus |= RxOverflow;
|
||||||
++s->RxMissed;
|
++s->RxMissed;
|
||||||
rtl8139_update_irq(s);
|
rtl8139_update_irq(s);
|
||||||
return;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_header |= RxStatusOK;
|
packet_header |= RxStatusOK;
|
||||||
|
@ -1156,11 +1157,13 @@ static void rtl8139_do_receive(VLANClientState *vc, const uint8_t *buf, int size
|
||||||
{
|
{
|
||||||
rtl8139_update_irq(s);
|
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)
|
static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
|
||||||
|
|
|
@ -602,7 +602,7 @@ static int smc91c111_can_receive(VLANClientState *vc)
|
||||||
return 1;
|
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;
|
smc91c111_state *s = vc->opaque;
|
||||||
int status;
|
int status;
|
||||||
|
@ -612,7 +612,7 @@ static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t si
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
|
||||||
if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
|
if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
|
||||||
return;
|
return -1;
|
||||||
/* Short packets are padded with zeros. Receiving a packet
|
/* Short packets are padded with zeros. Receiving a packet
|
||||||
< 64 bytes long is considered an error condition. */
|
< 64 bytes long is considered an error condition. */
|
||||||
if (size < 64)
|
if (size < 64)
|
||||||
|
@ -625,10 +625,10 @@ static void smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t si
|
||||||
packetsize += 4;
|
packetsize += 4;
|
||||||
/* TODO: Flag overrun and receive errors. */
|
/* TODO: Flag overrun and receive errors. */
|
||||||
if (packetsize > 2048)
|
if (packetsize > 2048)
|
||||||
return;
|
return -1;
|
||||||
packetnum = smc91c111_allocate_packet(s);
|
packetnum = smc91c111_allocate_packet(s);
|
||||||
if (packetnum == 0x80)
|
if (packetnum == 0x80)
|
||||||
return;
|
return -1;
|
||||||
s->rx_fifo[s->rx_fifo_len++] = packetnum;
|
s->rx_fifo[s->rx_fifo_len++] = packetnum;
|
||||||
|
|
||||||
p = &s->data[packetnum][0];
|
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? */
|
/* TODO: Raise early RX interrupt? */
|
||||||
s->int_level |= INT_RCV;
|
s->int_level |= INT_RCV;
|
||||||
smc91c111_update(s);
|
smc91c111_update(s);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *smc91c111_readfn[] = {
|
static CPUReadMemoryFunc *smc91c111_readfn[] = {
|
||||||
|
|
|
@ -78,7 +78,7 @@ static void stellaris_enet_update(stellaris_enet_state *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Implement MAC address filtering. */
|
/* 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;
|
stellaris_enet_state *s = vc->opaque;
|
||||||
int n;
|
int n;
|
||||||
|
@ -86,10 +86,10 @@ static void stellaris_enet_receive(VLANClientState *vc, const uint8_t *buf, size
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
|
|
||||||
if ((s->rctl & SE_RCTL_RXEN) == 0)
|
if ((s->rctl & SE_RCTL_RXEN) == 0)
|
||||||
return;
|
return -1;
|
||||||
if (s->np >= 31) {
|
if (s->np >= 31) {
|
||||||
DPRINTF("Packet dropped\n");
|
DPRINTF("Packet dropped\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF("Received packet len=%d\n", size);
|
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;
|
s->ris |= SE_INT_RX;
|
||||||
stellaris_enet_update(s);
|
stellaris_enet_update(s);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stellaris_enet_can_receive(VLANClientState *vc)
|
static int stellaris_enet_can_receive(VLANClientState *vc)
|
||||||
|
|
|
@ -1369,7 +1369,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
|
||||||
return ret;
|
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;
|
USBNetState *s = vc->opaque;
|
||||||
struct rndis_packet_msg_type *msg;
|
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) {
|
if (s->rndis) {
|
||||||
msg = (struct rndis_packet_msg_type *) s->in_buf;
|
msg = (struct rndis_packet_msg_type *) s->in_buf;
|
||||||
if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
|
if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
|
||||||
return;
|
return -1;
|
||||||
if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
|
if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
memset(msg, 0, sizeof(struct rndis_packet_msg_type));
|
memset(msg, 0, sizeof(struct rndis_packet_msg_type));
|
||||||
msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
|
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);
|
s->in_len = size + sizeof(struct rndis_packet_msg_type);
|
||||||
} else {
|
} else {
|
||||||
if (size > sizeof(s->in_buf))
|
if (size > sizeof(s->in_buf))
|
||||||
return;
|
return -1;
|
||||||
memcpy(s->in_buf, buf, size);
|
memcpy(s->in_buf, buf, size);
|
||||||
s->in_len = size;
|
s->in_len = size;
|
||||||
}
|
}
|
||||||
s->in_ptr = 0;
|
s->in_ptr = 0;
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usbnet_can_receive(VLANClientState *vc)
|
static int usbnet_can_receive(VLANClientState *vc)
|
||||||
|
|
|
@ -361,17 +361,17 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
|
||||||
return 0;
|
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;
|
VirtIONet *n = vc->opaque;
|
||||||
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
|
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
|
||||||
size_t hdr_len, offset, i;
|
size_t hdr_len, offset, i;
|
||||||
|
|
||||||
if (!do_virtio_net_can_receive(n, size))
|
if (!do_virtio_net_can_receive(n, size))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
if (!receive_filter(n, buf, size))
|
if (!receive_filter(n, buf, size))
|
||||||
return;
|
return size;
|
||||||
|
|
||||||
/* hdr_len refers to the header we supply to the guest */
|
/* hdr_len refers to the header we supply to the guest */
|
||||||
hdr_len = n->mergeable_rx_bufs ?
|
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) ||
|
if ((i != 0 && !n->mergeable_rx_bufs) ||
|
||||||
virtqueue_pop(n->rx_vq, &elem) == 0) {
|
virtqueue_pop(n->rx_vq, &elem) == 0) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return;
|
return -1;
|
||||||
fprintf(stderr, "virtio-net truncating packet\n");
|
fprintf(stderr, "virtio-net truncating packet\n");
|
||||||
exit(1);
|
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);
|
virtqueue_flush(n->rx_vq, i);
|
||||||
virtio_notify(&n->vdev, n->rx_vq);
|
virtio_notify(&n->vdev, n->rx_vq);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TX */
|
/* TX */
|
||||||
|
|
12
hw/xen_nic.c
12
hw/xen_nic.c
|
@ -243,7 +243,7 @@ static int net_rx_ok(VLANClientState *vc)
|
||||||
return 1;
|
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;
|
struct XenNetDev *netdev = vc->opaque;
|
||||||
netif_rx_request_t rxreq;
|
netif_rx_request_t rxreq;
|
||||||
|
@ -251,7 +251,7 @@ static void net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
void *page;
|
void *page;
|
||||||
|
|
||||||
if (netdev->xendev.be_state != XenbusStateConnected)
|
if (netdev->xendev.be_state != XenbusStateConnected)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
rc = netdev->rx_ring.req_cons;
|
rc = netdev->rx_ring.req_cons;
|
||||||
rp = netdev->rx_ring.sring->req_prod;
|
rp = netdev->rx_ring.sring->req_prod;
|
||||||
|
@ -259,12 +259,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)) {
|
if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
|
||||||
xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
|
xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
|
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
|
xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
|
||||||
(unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
|
(unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
|
memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
|
||||||
|
@ -277,11 +277,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",
|
xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
|
||||||
rxreq.gref);
|
rxreq.gref);
|
||||||
net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
|
net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(page + NET_IP_ALIGN, buf, size);
|
memcpy(page + NET_IP_ALIGN, buf, size);
|
||||||
xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
|
xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
|
||||||
net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
|
net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
54
net.c
54
net.c
|
@ -593,13 +593,14 @@ int slirp_is_inited(void)
|
||||||
return slirp_inited;
|
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
|
#ifdef DEBUG_SLIRP
|
||||||
printf("slirp input:\n");
|
printf("slirp input:\n");
|
||||||
hex_dump(stdout, buf, size);
|
hex_dump(stdout, buf, size);
|
||||||
#endif
|
#endif
|
||||||
slirp_input(buf, size);
|
slirp_input(buf, size);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int slirp_in_use;
|
static int slirp_in_use;
|
||||||
|
@ -945,17 +946,16 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
|
||||||
return len;
|
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;
|
TAPState *s = vc->opaque;
|
||||||
int ret;
|
ssize_t len;
|
||||||
for(;;) {
|
|
||||||
ret = write(s->fd, buf, size);
|
do {
|
||||||
if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
|
len = write(s->fd, buf, size);
|
||||||
} else {
|
} while (len == -1 && (errno == EINTR || errno == EAGAIN));
|
||||||
break;
|
|
||||||
}
|
return len;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tap_can_send(void *opaque)
|
static int tap_can_send(void *opaque)
|
||||||
|
@ -1311,17 +1311,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;
|
VDEState *s = vc->opaque;
|
||||||
int ret;
|
ssize ret;
|
||||||
for(;;) {
|
|
||||||
ret = vde_send(s->vde, (const char *)buf, size, 0);
|
do {
|
||||||
if (ret < 0 && errno == EINTR) {
|
ret = vde_send(s->vde, (const char *)buf, size, 0);
|
||||||
} else {
|
} while (ret < 0 && errno == EINTR);
|
||||||
break;
|
|
||||||
}
|
return ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vde_cleanup(VLANClientState *vc)
|
static void vde_cleanup(VLANClientState *vc)
|
||||||
|
@ -1380,21 +1379,22 @@ typedef struct NetSocketListenState {
|
||||||
} NetSocketListenState;
|
} NetSocketListenState;
|
||||||
|
|
||||||
/* XXX: we consider we can send the whole packet without blocking */
|
/* 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;
|
NetSocketState *s = vc->opaque;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
len = htonl(size);
|
len = htonl(size);
|
||||||
|
|
||||||
send_all(s->fd, (const uint8_t *)&len, sizeof(len));
|
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;
|
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)
|
static void net_socket_send(void *opaque)
|
||||||
|
@ -1831,7 +1831,7 @@ struct pcap_sf_pkthdr {
|
||||||
uint32_t len;
|
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;
|
DumpState *s = vc->opaque;
|
||||||
struct pcap_sf_pkthdr hdr;
|
struct pcap_sf_pkthdr hdr;
|
||||||
|
@ -1840,7 +1840,7 @@ static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
|
|
||||||
/* Early return in case of previous error. */
|
/* Early return in case of previous error. */
|
||||||
if (s->fd < 0) {
|
if (s->fd < 0) {
|
||||||
return;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts = muldiv64(qemu_get_clock(vm_clock), 1000000, ticks_per_sec);
|
ts = muldiv64(qemu_get_clock(vm_clock), 1000000, ticks_per_sec);
|
||||||
|
@ -1856,6 +1856,8 @@ static void dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void net_dump_cleanup(VLANClientState *vc)
|
static void net_dump_cleanup(VLANClientState *vc)
|
||||||
|
|
2
net.h
2
net.h
|
@ -8,7 +8,7 @@
|
||||||
typedef struct VLANClientState VLANClientState;
|
typedef struct VLANClientState VLANClientState;
|
||||||
|
|
||||||
typedef int (NetCanReceive)(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 ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
|
||||||
typedef void (NetCleanup) (VLANClientState *);
|
typedef void (NetCleanup) (VLANClientState *);
|
||||||
typedef void (LinkStatusChanged)(VLANClientState *);
|
typedef void (LinkStatusChanged)(VLANClientState *);
|
||||||
|
|
|
@ -650,11 +650,11 @@ static void tap_cleanup(VLANClientState *vc)
|
||||||
qemu_free(s);
|
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)
|
static void tap_win32_send(void *opaque)
|
||||||
|
|
Loading…
Reference in New Issue