|
|
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:
1.1.1.2 root 27: NetPacket() {
28: Clear();
29: }
30:
1.1 root 31: // バッファをクリアする
1.1.1.2 root 32: void Clear() {
33: length = 0;
34: Seek(0);
35: }
1.1 root 36:
37: // パケットに1バイト追加する
38: void Append(uint8 data) { (*this)[length++] = data; }
39:
40: // バッファ内の有効長
1.1.1.4 ! root 41: uint length {};
1.1.1.2 root 42:
43: // 現在の読み出し位置
44: int offset {};
45:
46: // 読み出し開始位置を設定
47: void Seek(int offset_) { offset = offset_; }
48:
49: // 読み出しの残りバイト数を返す
50: int GetRemain() const { return length - offset; }
51:
52: // 1バイト読み出す。EOP なら -1 を返す
53: uint32 Read() {
54: if (offset < length) {
55: return (*this)[offset++];
56: } else {
57: return (uint32)-1;
58: }
59: }
1.1 root 60: };
61:
62: class HostNetDevice : public HostDevice
63: {
64: using inherited = HostDevice;
65: using NetTxQueue = SPSCQueue<NetPacket, 32>;
66: using NetRxQueue = SPSCQueue<NetPacket, 64>;
67:
68: // 統計情報
69: struct stat_t {
70: uint64 tx_pkts;
71: uint64 tx_bytes;
72: uint64 rx_pkts;
73: uint64 rx_bytes;
74: uint64 read_pkts;
75: uint64 read_bytes;
76: uint64 write_pkts;
77: uint64 write_bytes;
1.1.1.4 ! root 78: uint64 txzero_pkts; // 送信長0で破棄したパケット数
1.1.1.3 root 79: uint64 txqfull_pkts; // キューが一杯だった回数
1.1 root 80: uint64 txqfull_bytes; // キューに入れられなかったバイト数
81: uint64 rxdisable_pkts; // 上位層が受信無効
82: uint64 rxdisable_bytes; // 上位層が受信無効
83: uint64 rxjumbo_pkts; // 受信したジャンボパケット数
84: uint64 rxjumbo_bytes; // 受信したジャンボパケットのバイト数
1.1.1.3 root 85: uint64 rxqfull_pkts; // キューが一杯だった回数
1.1 root 86: uint64 rxqfull_bytes; // キューに入れられなかったバイト数
1.1.1.3 root 87: uint64 rxnotme_pkts; // ユニキャストで破棄したパケット数
88: uint64 rxnotme_bytes; // フィルタされたバイト数
89: uint64 rxmcast_pkts; // マルチキャストで破棄したパケット数
90: uint64 rxmcast_bytes; // フィルタされたバイト数
1.1 root 91:
1.1.1.4 ! root 92: uint txq_peak; // キューのおおよその最大使用量
! 93: uint rxq_peak; // キューのおおよその最大使用量
1.1 root 94: };
95:
96: public:
1.1.1.4 ! root 97: HostNetDevice(Device *parent_, uint n);
1.1 root 98: ~HostNetDevice() override;
99:
100: void SetLogLevel(int loglevel_) override;
101: bool Init() override;
102:
103: // パケットを送信する。
104: // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
105: // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。
106: // 送信キューに追加できれば true、出来なければ false を返す。
107: bool Tx(const NetPacket& packet);
108:
109: // パケットを引き取るために VM から呼ばれる。
110: // パケットが受信キューにあるときは packet にコピーして true を返す。
111: // キューが空なら false を返す。
112: bool Rx(NetPacket *packet);
113:
114: // 受信キューへの投入を許可/禁止する。
115: void EnableRx(bool enable);
116:
1.1.1.2 root 117: // 受信用の自身の MAC アドレスを設定する。
1.1 root 118: void SetMyAddr(const macaddr_t& myaddr_);
119:
120: // プロミスキャスモードを設定する。
121: void SetPromisc(bool promisc_);
122:
1.1.1.3 root 123: // マルチキャストフィルタを設定する。
124: void SetMCastFilter(uint64 filter);
125:
1.1 root 126: // ドライバ名を返す (ステータスパネルから呼ばれる)
127: const std::string GetDriverName() const;
128:
129: // 統計情報を返す (ステータスパネルから呼ばれる)
130: uint64 GetTXPkts() const { return stat.tx_pkts; }
131: uint64 GetRXPkts() const { return stat.rx_pkts; }
132:
133: // コンパイル済みのドライバ名一覧を返す
134: static std::vector<std::string> GetDrivers();
135:
136: private:
137: bool SelectDriver();
138: bool CreateNone();
139: bool CreateTap();
140: bool CreateBPF();
141: bool CreateAFPacket();
142:
143: int Read() override;
144:
145: // 外部への書き出し(パケットを送信)
146: void Write(uint32 data) override;
147:
148: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
149:
150: std::unique_ptr<NetDriver> driver {};
151:
152: bool rx_enable {};
1.1.1.2 root 153: macaddr_t myaddr {}; // 自身の MAC アドレス
1.1 root 154: bool promisc {}; // プロミスキャスモードなら true
155:
1.1.1.3 root 156: // マルチキャストフィルタ。
157: // 64ビットのうち、LSB 側を0番目、MSB 側を63番目となるようにしたもの。
158: uint64 multicast_filter {};
159:
1.1 root 160: // キュー
161: NetTxQueue txq {};
162: NetRxQueue rxq {};
163:
164: // 統計情報
165: struct stat_t stat {};
166:
167: std::string errmsg {};
168:
169: Monitor monitor { this };
170: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.