- all networking modules: check device receive status before sending packet
- networking modules 'slirp' and 'vnet': use device speed for timing of emulated replies.
This commit is contained in:
parent
9763643106
commit
c9af6d043d
@ -353,7 +353,11 @@ bx_fbsd_pktmover_c::rx_timer(void)
|
||||
|
||||
// filter out packets sourced from this node
|
||||
if (memcmp(bhdr + bhdr->bh_hdrlen + 6, this->fbsd_macaddr, 6)) {
|
||||
(*rxh)(this->netdev, phdr + bhdr->bh_hdrlen, bhdr->bh_caplen);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, phdr + bhdr->bh_hdrlen, bhdr->bh_caplen);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_ETH_FBSD_LOGGING
|
||||
|
@ -281,7 +281,11 @@ bx_linux_pktmover_c::rx_timer(void)
|
||||
// let through broadcast, multicast, and our mac address
|
||||
// if ((memcmp(rxbuf, broadcast_macaddr, 6) == 0) || (memcmp(rxbuf, this->linux_macaddr, 6) == 0) || rxbuf[0] & 0x01) {
|
||||
BX_DEBUG(("eth_linux: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
||||
(*rxh)(netdev, rxbuf, nbytes);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, rxbuf, nbytes);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
// }
|
||||
}
|
||||
#endif /* if BX_NETWORKING && BX_NETMOD_LINUX */
|
||||
|
@ -218,7 +218,9 @@ private:
|
||||
dhcp_cfg_t dhcp;
|
||||
|
||||
int rx_timer_index;
|
||||
unsigned netdev_speed;
|
||||
unsigned tx_time;
|
||||
|
||||
static void rx_timer_handler(void *);
|
||||
void rx_timer();
|
||||
|
||||
@ -294,11 +296,14 @@ bx_slirp_pktmover_c::bx_slirp_pktmover_c(const char *netif,
|
||||
}
|
||||
}
|
||||
|
||||
this->rxh = rxh;
|
||||
this->rxstat = rxstat;
|
||||
Bit32u status = this->rxstat(this->netdev) & BX_NETDEV_SPEED;
|
||||
this->netdev_speed = (status == BX_NETDEV_1GBIT) ? 1000 :
|
||||
(status == BX_NETDEV_100MBIT) ? 100 : 10;
|
||||
this->rx_timer_index =
|
||||
bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
|
||||
1, 1, "eth_slirp");
|
||||
this->rxh = rxh;
|
||||
this->rxstat = rxstat;
|
||||
memcpy(&dhcp.guest_macaddr[0], macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
// ensure the slirp host has a different mac address
|
||||
memcpy(&dhcp.host_macaddr[0], macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
@ -481,7 +486,7 @@ void bx_slirp_pktmover_c::sendpkt(void *buf, unsigned io_len)
|
||||
#if BX_ETH_SLIRP_LOGGING
|
||||
write_pktlog_txt(pktlog_txt, (Bit8u*)buf, io_len, 0);
|
||||
#endif
|
||||
this->tx_time = (64 + 96 + 4 * 8 + io_len * 8) / 10;
|
||||
this->tx_time = (64 + 96 + 4 * 8 + io_len * 8) / this->netdev_speed;
|
||||
switch (ntohs(ethhdr->type)) {
|
||||
case ETHERNET_TYPE_IPV4:
|
||||
if (!handle_ipv4((Bit8u*)buf, io_len)) {
|
||||
@ -508,7 +513,7 @@ void bx_slirp_pktmover_c::prepare_builtin_reply(unsigned type)
|
||||
memcpy(ethhdr->dst_mac_addr, dhcp.guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
memcpy(ethhdr->src_mac_addr, dhcp.host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||
ethhdr->type = htons(type);
|
||||
rx_time = (64 + 96 + 4 * 8 + pending_reply_size * 8) / 10;
|
||||
rx_time = (64 + 96 + 4 * 8 + pending_reply_size * 8) / this->netdev_speed;
|
||||
bx_pc_system.activate_timer(this->rx_timer_index, this->tx_time + rx_time + 100, 0);
|
||||
}
|
||||
|
||||
@ -529,7 +534,11 @@ void bx_slirp_pktmover_c::rx_timer()
|
||||
#if BX_ETH_SLIRP_LOGGING
|
||||
write_pktlog_txt(pktlog_txt, reply_buffer, pending_reply_size, 1);
|
||||
#endif
|
||||
(*rxh)(this->netdev, reply_buffer, pending_reply_size);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, reply_buffer, pending_reply_size);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
pending_reply_size = 0;
|
||||
// restore timer
|
||||
bx_pc_system.activate_timer(this->rx_timer_index, 1000, 1);
|
||||
|
@ -410,7 +410,11 @@ void bx_tap_pktmover_c::rx_timer()
|
||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
||||
nbytes = 60;
|
||||
}
|
||||
(*rxh)(netdev, rxbuf, nbytes);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, rxbuf, nbytes);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* if BX_NETWORKING && BX_NETMOD_TAP */
|
||||
|
@ -335,7 +335,11 @@ void bx_tuntap_pktmover_c::rx_timer()
|
||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
||||
nbytes = 60;
|
||||
}
|
||||
(*rxh)(this->netdev, rxbuf, nbytes);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, rxbuf, nbytes);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
|
||||
int tun_alloc(char *dev)
|
||||
|
@ -253,7 +253,11 @@ void bx_vde_pktmover_c::rx_timer()
|
||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
||||
nbytes = 60;
|
||||
}
|
||||
(*rxh)(this->netdev, rxbuf, nbytes);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, rxbuf, nbytes);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
|
||||
//enum request_type { REQ_NEW_CONTROL };
|
||||
|
@ -191,7 +191,9 @@ private:
|
||||
|
||||
static void rx_timer_handler(void *);
|
||||
void rx_timer(void);
|
||||
|
||||
int rx_timer_index;
|
||||
unsigned netdev_speed;
|
||||
unsigned tx_time;
|
||||
|
||||
#if BX_ETH_VNET_LOGGING
|
||||
@ -273,6 +275,9 @@ void bx_vnet_pktmover_c::pktmover_init(
|
||||
register_layer4_handler(0x11,INET_PORT_BOOTP_SERVER,udpipv4_dhcp_handler);
|
||||
register_layer4_handler(0x11,INET_PORT_TFTP_SERVER,udpipv4_tftp_handler);
|
||||
|
||||
Bit32u status = this->rxstat(this->netdev) & BX_NETDEV_SPEED;
|
||||
this->netdev_speed = (status == BX_NETDEV_1GBIT) ? 1000 :
|
||||
(status == BX_NETDEV_100MBIT) ? 100 : 10;
|
||||
this->rx_timer_index =
|
||||
bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
|
||||
0, 0, "eth_vnet");
|
||||
@ -321,7 +326,7 @@ void bx_vnet_pktmover_c::guest_to_host(const Bit8u *buf, unsigned io_len)
|
||||
}
|
||||
#endif
|
||||
|
||||
this->tx_time = (64 + 96 + 4 * 8 + io_len * 8) / 10;
|
||||
this->tx_time = (64 + 96 + 4 * 8 + io_len * 8) / this->netdev_speed;
|
||||
if ((io_len >= 14) &&
|
||||
(!memcmp(&buf[6],&dhcp.guest_macaddr[0],6)) &&
|
||||
(!memcmp(&buf[0],&dhcp.host_macaddr[0],6) ||
|
||||
@ -349,21 +354,25 @@ void bx_vnet_pktmover_c::rx_timer_handler(void *this_ptr)
|
||||
|
||||
void bx_vnet_pktmover_c::rx_timer(void)
|
||||
{
|
||||
this->rxh(this->netdev, (void *)packet_buffer, packet_len);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, (void *)packet_buffer, packet_len);
|
||||
#if BX_ETH_VNET_LOGGING
|
||||
write_pktlog_txt(pktlog_txt, packet_buffer, packet_len, 1);
|
||||
write_pktlog_txt(pktlog_txt, packet_buffer, packet_len, 1);
|
||||
#endif
|
||||
#if BX_ETH_VNET_PCAP_LOGGING
|
||||
if (pktlog_pcap && !ferror((FILE *)pktlog_pcap)) {
|
||||
Bit64u time = bx_pc_system.time_usec();
|
||||
pcaphdr.ts.tv_usec = time % 1000000;
|
||||
pcaphdr.ts.tv_sec = time / 1000000;
|
||||
pcaphdr.caplen = packet_len;
|
||||
pcaphdr.len = packet_len;
|
||||
pcap_dump((u_char *)pktlog_pcap, &pcaphdr, packet_buffer);
|
||||
fflush((FILE *)pktlog_pcap);
|
||||
}
|
||||
if (pktlog_pcap && !ferror((FILE *)pktlog_pcap)) {
|
||||
Bit64u time = bx_pc_system.time_usec();
|
||||
pcaphdr.ts.tv_usec = time % 1000000;
|
||||
pcaphdr.ts.tv_sec = time / 1000000;
|
||||
pcaphdr.caplen = packet_len;
|
||||
pcaphdr.len = packet_len;
|
||||
pcap_dump((u_char *)pktlog_pcap, &pcaphdr, packet_buffer);
|
||||
fflush((FILE *)pktlog_pcap);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
|
||||
void bx_vnet_pktmover_c::host_to_guest(Bit8u *buf, unsigned io_len)
|
||||
@ -384,7 +393,7 @@ void bx_vnet_pktmover_c::host_to_guest(Bit8u *buf, unsigned io_len)
|
||||
|
||||
packet_len = io_len;
|
||||
memcpy(&packet_buffer, &buf[0], io_len);
|
||||
unsigned rx_time = (64 + 96 + 4 * 8 + io_len * 8) / 10;
|
||||
unsigned rx_time = (64 + 96 + 4 * 8 + io_len * 8) / this->netdev_speed;
|
||||
bx_pc_system.activate_timer(this->rx_timer_index, this->tx_time + rx_time + 100, 0);
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,11 @@ void bx_win32_pktmover_c::rx_timer(void)
|
||||
#if BX_ETH_WIN32_LOGGING
|
||||
write_pktlog_txt(pktlog_txt, pPacket, pktlen, 1);
|
||||
#endif
|
||||
(*this->rxh)(this->netdev, pPacket, pktlen);
|
||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||
this->rxh(this->netdev, pPacket, pktlen);
|
||||
} else {
|
||||
BX_ERROR(("device not ready to receive data"));
|
||||
}
|
||||
}
|
||||
}
|
||||
iOffset = Packet_WORDALIGN(iOffset + (hdr->bh_hdrlen + hdr->bh_caplen));
|
||||
|
@ -39,9 +39,10 @@ public:
|
||||
|
||||
// device receive status definitions
|
||||
#define BX_NETDEV_RXREADY 0x0001
|
||||
#define BX_NETDEV_SPEED 0x000e
|
||||
#define BX_NETDEV_10MBIT 0x0002
|
||||
#define BX_NETDEV_100MBIT 0x0004
|
||||
#define BX_NETDEV_1GBIT 0x0006
|
||||
#define BX_NETDEV_1GBIT 0x0008
|
||||
|
||||
typedef void (*eth_rx_handler_t)(void *arg, const void *buf, unsigned len);
|
||||
typedef Bit32u (*eth_rx_status_t)(void *arg);
|
||||
|
Loading…
Reference in New Issue
Block a user