--- nono/host/netdriver.cpp 2026/04/29 17:04:54 1.1.1.6 +++ nono/host/netdriver.cpp 2026/04/29 17:05:11 1.1.1.8 @@ -4,36 +4,18 @@ // Licensed under nono-license.txt // +// +// ホストネットワークのドライバ (基本クラス) +// + #include "netdriver.h" -#include "autofd.h" -#include "cvprompt.h" #include "mainapp.h" -#include "mythread.h" #include -#if defined(HAVE_SYS_EVENT_H) -#include -#endif -#if defined(HAVE_KQUEUE_SYS_EVENT_H) -#include -#endif - -static void *netdriver_run(void *); - -std::unique_ptr gNetDriver; // コンストラクタ -NetDriver::NetDriver(const char *drivername_, EthernetDevice *parent_, - int loglevel_) - : inherited(std::string("HostNet") + drivername_) +NetDriver::NetDriver(HostDevice *hostdev_, const char *drivername_) + : inherited(hostdev_, drivername_) { - loglevel = loglevel_; - drivername = drivername_; - parent = parent_; - fd = -1; - - monitor.func = (MonitorCallback_t)&NetDriver::MonitorUpdate; - monitor.SetSize(30, 7); - monitor.Regist(ID_MONITOR_HOSTNET); } // デストラクタ @@ -41,51 +23,6 @@ NetDriver::~NetDriver() { } -// 初期化 -bool -NetDriver::Init() -{ - // 対応する EthernetDevice があれば受信スレッド起動。 - // NetDriverNone は連携不要なので parent == NULL になっている。 - if (parent) { - pthread_t th; - int error; - - error = pthread_create(&th, NULL, netdriver_run, NULL); - if (error) { - putmsg(0, "pthread_create: %s", strerror(error)); - return false; - } - } - return true; -} - -// モニタ -void -NetDriver::MonitorUpdate(Monitor *, TextScreen& screen) -{ - screen.Clear(); - - screen.Print(0, 0, "HostNet Driver: %s", drivername); - // 次の2行はドライバ依存情報 - MonitorUpdateMD(screen); - - screen.Print(5, 4, "%9s %9s", "Packets", "Bytes"); - screen.Print(0, 5, "Send %9" PRIu64 " %9" PRIu64, tx_pkts, tx_bytes); - screen.Print(0, 6, "Recv %9" PRIu64 " %9" PRIu64, rx_pkts, rx_bytes); -} - -// 受信スレッドのエントリポイント -void * -netdriver_run(void *dummy) -{ - PTHREAD_SETNAME("NetDriver"); - pthread_detach(pthread_self()); - - gNetDriver->ThreadRun(); - return NULL; -} - // ifup スクリプト実行 bool NetDriver::Run_ifup() @@ -156,87 +93,3 @@ NetDriver::RunScript(const char *filenam putmsg(1, "%s: %s", __func__, errmsg.c_str()); return false; } - -// VM 側の受信パケットキューにパケットを一つ追加する -void -NetDriver::RecvEnqueue(uint8 *ptr, size_t len) -{ - RXPacket packet { new qvector(ptr, ptr + len) }; - - // ホストカーネルから直接着信したパケット(というかフレームか)は - // 60バイトパディングされないまま読み出せるので、ここでパディングする。 - if (len < 60) { - for (int i = len ; i < 60; i++) { - packet->append(0); - } - } - - // CRC XXX 計算すること - for (int i = 0; i < 4; i++) { - packet->append(0); - } - - size_t n = packet->size(); - - // 受信処理に引き渡す - // ただしデバッガプロンプトで停止してる状態なら VM に干渉しない。 - if (gCVPrompt->IsPrompt() == false) { - putlog(2, "RecvPacket %zd bytes", n); - rx_pkts++; - rx_bytes += n; - parent->RecvPacket(std::move(packet)); - } -} - -// 受信スレッド -void -NetDriver::ThreadRun() -{ - struct kevent kev; - autofd kq; - int r; - - kq = kqueue(); - if (kq == -1) { - warn("NetDriver: kqueue"); - return; - } - - EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, (kevent_udata_t)0); - r = kevent_set(kq, &kev, 1); - if (r == -1) { - warn("NetDriver: kevent_set(fd=%d)", fd); - return; - } - - for (;;) { - ssize_t n; - - // 何か起きるまで待つ - r = kevent_poll(kq, &kev, 1, NULL); - if (r == -1) { - if (errno == EINTR) { - continue; - } - // XXX ? - warn("NetDriver: kevent_poll"); - break; - } - - // 自動的にデバイスに着信があったことになるはず - assert(r > 0); - - // パケットを読み込んで VM に引き渡す。 - n = RecvPacket(); - if (n == -1) { - if (errno == EINTR) { - continue; - } - warn("NetDriver: read"); - break; - } - if (n == 0) { // EOF - return; - } - } -}