|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // ネットワークのホストデバイス ! 9: // ! 10: ! 11: #pragma once ! 12: ! 13: #include "hostdevice.h" ! 14: #include "macaddr.h" ! 15: #include "monitor.h" ! 16: #include "netdriver.h" ! 17: #include "spscqueue.h" ! 18: ! 19: // パケット ! 20: class NetPacket : public std::array<uint8, 1600> ! 21: { ! 22: // ジャンボフレームでないイーサネットフレームは最大 1518バイトだが ! 23: // このパケットバッファの長さは 1519 バイト以上必要。 ! 24: // vm/lance が 1518 バイトを越えたことを検出するのに使っている。 ! 25: ! 26: public: ! 27: // バッファをクリアする ! 28: void Clear() { length = 0; } ! 29: ! 30: // パケットに1バイト追加する ! 31: void Append(uint8 data) { (*this)[length++] = data; } ! 32: ! 33: // バッファ内の有効長 ! 34: int length {}; ! 35: }; ! 36: ! 37: class HostNetDevice : public HostDevice ! 38: { ! 39: using inherited = HostDevice; ! 40: using NetTxQueue = SPSCQueue<NetPacket, 32>; ! 41: using NetRxQueue = SPSCQueue<NetPacket, 64>; ! 42: ! 43: // 統計情報 ! 44: struct stat_t { ! 45: uint64 tx_pkts; ! 46: uint64 tx_bytes; ! 47: uint64 rx_pkts; ! 48: uint64 rx_bytes; ! 49: uint64 read_pkts; ! 50: uint64 read_bytes; ! 51: uint64 write_pkts; ! 52: uint64 write_bytes; ! 53: int txqfull_pkts; // キューが一杯だった回数 ! 54: uint64 txqfull_bytes; // キューに入れられなかったバイト数 ! 55: uint64 rxdisable_pkts; // 上位層が受信無効 ! 56: uint64 rxdisable_bytes; // 上位層が受信無効 ! 57: uint64 rxjumbo_pkts; // 受信したジャンボパケット数 ! 58: uint64 rxjumbo_bytes; // 受信したジャンボパケットのバイト数 ! 59: int rxqfull_pkts; // キューが一杯だった回数 ! 60: uint64 rxqfull_bytes; // キューに入れられなかったバイト数 ! 61: int rxfilter_pkts; // 受信フィルタで破棄したパケット数 ! 62: uint64 rxfilter_bytes; // フィルタされたバイト数 ! 63: ! 64: int txq_peak; // キューのおおよその最大使用量 ! 65: int rxq_peak; // キューのおおよその最大使用量 ! 66: }; ! 67: ! 68: public: ! 69: HostNetDevice(); ! 70: ~HostNetDevice() override; ! 71: ! 72: void SetLogLevel(int loglevel_) override; ! 73: bool Init() override; ! 74: ! 75: // パケットを送信する。 ! 76: // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、 ! 77: // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。 ! 78: // VM から引き取ったパケットについて tx_pkts, tx_bytes を更新すること ! 79: // 送信キューに追加できれば true、出来なければ false を返す。 ! 80: bool Tx(const NetPacket& packet); ! 81: ! 82: // パケットを引き取るために VM から呼ばれる。 ! 83: // パケットが受信キューにあるときは packet にコピーして true を返す。 ! 84: // キューが空なら false を返す。 ! 85: bool Rx(NetPacket *packet); ! 86: ! 87: // 受信キューへの投入を許可/禁止する。 ! 88: void EnableRx(bool enable); ! 89: ! 90: // 自身の MAC アドレスを設定する。 ! 91: void SetMyAddr(const macaddr_t& myaddr_); ! 92: ! 93: // プロミスキャスモードを設定する。 ! 94: void SetPromisc(bool promisc_); ! 95: ! 96: // ドライバ名を返す (ステータスパネルから呼ばれる) ! 97: const std::string GetDriverName() const; ! 98: ! 99: // 統計情報を返す (ステータスパネルから呼ばれる) ! 100: uint64 GetTXPkts() const { return stat.tx_pkts; } ! 101: uint64 GetRXPkts() const { return stat.rx_pkts; } ! 102: ! 103: // コンパイル済みのドライバ名一覧を返す ! 104: static std::vector<std::string> GetDrivers(); ! 105: ! 106: private: ! 107: bool SelectDriver(); ! 108: bool CreateNone(); ! 109: bool CreateTap(); ! 110: bool CreateBPF(); ! 111: bool CreateAFPacket(); ! 112: ! 113: int Read() override; ! 114: ! 115: // 外部への書き出し(パケットを送信) ! 116: void Write(uint32 data) override; ! 117: ! 118: DECLARE_MONITOR_CALLBACK(MonitorUpdate); ! 119: ! 120: std::unique_ptr<NetDriver> driver {}; ! 121: ! 122: bool rx_enable {}; ! 123: macaddr_t myaddr {}; // 自己 MAC アドレス ! 124: bool promisc {}; // プロミスキャスモードなら true ! 125: ! 126: // キュー ! 127: NetTxQueue txq {}; ! 128: NetRxQueue rxq {}; ! 129: ! 130: // 統計情報 ! 131: struct stat_t stat {}; ! 132: ! 133: std::string errmsg {}; ! 134: ! 135: Monitor monitor { this }; ! 136: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.