|
|
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.