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