--- nono/host/hostnet.cpp 2026/04/29 17:05:26 1.1.1.4 +++ nono/host/hostnet.cpp 2026/04/29 17:05:34 1.1.1.6 @@ -22,6 +22,7 @@ #include "hostnet.h" #include "config.h" +#include "monitor.h" #include "netdriver_none.h" #if defined(HAVE_HOSTNET_AFPACKET) #include "netdriver_afpacket.h" @@ -55,12 +56,12 @@ HostNetDevice::GetDrivers() // コンストラクタ -HostNetDevice::HostNetDevice(Device *parent_, int n) +HostNetDevice::HostNetDevice(Device *parent_, uint n) : inherited(parent_, OBJ_HOSTNET(n)) { - monitor.func = ToMonitorCallback(&HostNetDevice::MonitorUpdate); - monitor.SetSize(48, 22); - monitor.Regist(ID_MONITOR_HOSTNET(n)); + monitor = gMonitorManager->Regist(ID_MONITOR_HOSTNET(n), this); + monitor->func = ToMonitorCallback(&HostNetDevice::MonitorUpdate); + monitor->SetSize(48, 23); } // デストラクタ @@ -268,6 +269,14 @@ HostNetDevice::CreateAFPacket() bool HostNetDevice::Tx(const NetPacket& packet) { + // 長さ 0 のパケットは破棄する。バグでもないと通常は起きない。 + // runt frame はどうするか? + if (packet.length < 1) { + stat.txzero_pkts++; + putlog(1, "Tx: drop empty packet"); + return true; + } + // 送信キューに入れて.. if (txq.Enqueue(packet) == false) { stat.txqfull_pkts++; @@ -280,17 +289,29 @@ HostNetDevice::Tx(const NetPacket& packe stat.tx_bytes += packet.length; // ざっくりピーク値 - stat.txq_peak = std::max((int)txq.Length(), stat.txq_peak); + stat.txq_peak = std::max((uint)txq.Length(), stat.txq_peak); // パイプに通知 (値はダミー) return WritePipe(0); } -// rxq への投入を行う場合は true +// rxq への投入を行う場合は true。 +// VM スレッドから呼ばれる。 void HostNetDevice::EnableRx(bool enable) { rx_enable = enable; + + // 受信を停止した時はキューに残っているのを破棄する。 + // (ゲスト再起動によるデバイスリセット時とか) + if (rx_enable == false) { + // 統計情報に足すためだけに一旦取り出す。 + NetPacket drop; + while (rxq.Dequeue(&drop)) { + stat.rxdisable_pkts++; + stat.rxdisable_bytes += drop.length; + } + } } // 受信用の自身の MAC アドレスを設定する。 @@ -326,10 +347,10 @@ HostNetDevice::Rx(NetPacket *dst) stat.rx_pkts++; stat.rx_bytes += dst->length; if (__predict_false(loglevel >= 2)) { - putlogn("Recv %d bytes", dst->length); + putlogn("Recv %u bytes", dst->length); if (loglevel >= 3) { std::string buf; - for (int i = 0; i < dst->length; i++) { + for (uint i = 0; i < dst->length; i++) { if (i % 16 == 0) { buf += string_format("%04x:", i); } @@ -426,7 +447,7 @@ HostNetDevice::Read() // 宛先アドレスの CRC32 を計算する。 // イーサネットの CRC は zlib の crc32() と同じもの。 - ulong crc = crc32(0, Z_NULL, 0); + uint32 crc = crc32(0, Z_NULL, 0); crc = crc32(crc, &packet[0], 6); // crc の上位6ビットをとりだして検査ビット位置とする(=pos)。 @@ -469,7 +490,7 @@ HostNetDevice::Read() } while (left > 0); // ざっくりピーク値 - stat.rxq_peak = std::max((int)rxq.Length(), stat.rxq_peak); + stat.rxq_peak = std::max((uint)rxq.Length(), stat.rxq_peak); return queued; } @@ -487,10 +508,10 @@ HostNetDevice::Write(uint32 data) const NetPacket& packet = *p; if (__predict_false(loglevel >= 2)) { - putlogn("Send %d bytes", packet.length); + putlogn("Send %u bytes", packet.length); if (loglevel >= 3) { std::string buf; - for (int i = 0; i < packet.length; i++) { + for (uint i = 0; i < packet.length; i++) { if (i % 16 == 0) { buf += string_format("%04x:", i); } @@ -549,6 +570,9 @@ HostNetDevice::MonitorUpdate(Monitor *, screen.Print(0, y++, "%-17s%13s %17s", "Write to host", format_number(stat.write_pkts).c_str(), format_number(stat.write_bytes).c_str()); + screen.Print(0, y++, "%-17s%13s %17s", "Drop:Empty Frame", + format_number(stat.txzero_pkts).c_str(), + "0"); screen.Print(0, y++, "%-17s%13s %17s", "Drop:TxQ Full", format_number(stat.txqfull_pkts).c_str(), format_number(stat.txqfull_bytes).c_str()); @@ -579,8 +603,8 @@ HostNetDevice::MonitorUpdate(Monitor *, y++; screen.Print(5, y++, "Capacity Peak"); - screen.Print(0, y++, "TxQ %4d/%4d %4d", - (int)txq.Length(), (int)txq.Capacity(), stat.txq_peak); - screen.Print(0, y++, "RxQ %4d/%4d %4d", - (int)rxq.Length(), (int)rxq.Capacity(), stat.rxq_peak); + screen.Print(0, y++, "TxQ %4u/%4u %4u", + (uint)txq.Length(), (uint)txq.Capacity(), stat.txq_peak); + screen.Print(0, y++, "RxQ %4u/%4u %4u", + (uint)rxq.Length(), (uint)rxq.Capacity(), stat.rxq_peak); }