|
|
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:
1.1.1.6 root 61: // MAC アドレスフィルタ。
62: // VM 側デバイスはこれを多重継承して実装すること。
63: class IHWAddrFilter
64: {
65: // インタフェース風にするため、メンバ変数を持たせないこと。
66: public:
67: enum {
68: HPF_PASS = 0, // このフレームを受信する。
69: HPF_DROP_UNICAST, // このユニキャストフレームを破棄する。
70: HPF_DROP_MULTICAST, // このマルチキャストフレームを破棄する。
71: };
72:
73: public:
74: virtual ~IHWAddrFilter();
75:
76: // デバイスがこの dstaddr 宛のフレームを受け付けるかどうかを返す。
77: // デバイスは、自分宛て、ブロードキャスト、マルチキャスト
78: // (おそらくハッシュ)、プロミスキャスなどの状態を考慮すること。
79: virtual int HWAddrFilter(const MacAddr& dstaddr) const = 0;
80: };
81:
1.1 root 82: class HostNetDevice : public HostDevice
83: {
84: using inherited = HostDevice;
85: using NetTxQueue = SPSCQueue<NetPacket, 32>;
86: using NetRxQueue = SPSCQueue<NetPacket, 64>;
87:
88: // 統計情報
89: struct stat_t {
90: uint64 tx_pkts;
91: uint64 tx_bytes;
92: uint64 rx_pkts;
93: uint64 rx_bytes;
94: uint64 read_pkts;
95: uint64 read_bytes;
96: uint64 write_pkts;
97: uint64 write_bytes;
1.1.1.4 root 98: uint64 txzero_pkts; // 送信長0で破棄したパケット数
1.1.1.6 root 99: uint64 txunsupp_pkts; // 送信先が未対応で破棄したパケット数
100: uint64 txunsupp_bytes; // 送信先が未対応で破棄したバイト数
1.1.1.3 root 101: uint64 txqfull_pkts; // キューが一杯だった回数
1.1 root 102: uint64 txqfull_bytes; // キューに入れられなかったバイト数
103: uint64 rxdisable_pkts; // 上位層が受信無効
104: uint64 rxdisable_bytes; // 上位層が受信無効
105: uint64 rxjumbo_pkts; // 受信したジャンボパケット数
106: uint64 rxjumbo_bytes; // 受信したジャンボパケットのバイト数
1.1.1.3 root 107: uint64 rxqfull_pkts; // キューが一杯だった回数
1.1 root 108: uint64 rxqfull_bytes; // キューに入れられなかったバイト数
1.1.1.3 root 109: uint64 rxnotme_pkts; // ユニキャストで破棄したパケット数
110: uint64 rxnotme_bytes; // フィルタされたバイト数
111: uint64 rxmcast_pkts; // マルチキャストで破棄したパケット数
112: uint64 rxmcast_bytes; // フィルタされたバイト数
1.1 root 113:
1.1.1.4 root 114: uint txq_peak; // キューのおおよその最大使用量
115: uint rxq_peak; // キューのおおよその最大使用量
1.1 root 116: };
117:
118: public:
1.1.1.7 ! root 119: HostNetDevice(Device *parent_, uint n, const std::string& portname_);
1.1 root 120: ~HostNetDevice() override;
121:
122: void SetLogLevel(int loglevel_) override;
1.1.1.6 root 123: bool Create2() override;
1.1 root 124:
125: // パケットを送信する。
126: // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
127: // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。
128: // 送信キューに追加できれば true、出来なければ false を返す。
129: bool Tx(const NetPacket& packet);
130:
131: // パケットを引き取るために VM から呼ばれる。
132: // パケットが受信キューにあるときは packet にコピーして true を返す。
133: // キューが空なら false を返す。
134: bool Rx(NetPacket *packet);
135:
136: // 受信キューへの投入を許可/禁止する。
137: void EnableRx(bool enable);
138:
1.1.1.3 root 139: // マルチキャストフィルタを設定する。
140: void SetMCastFilter(uint64 filter);
141:
1.1.1.7 ! root 142: // ドライバ名を返す。
! 143: const std::string GetDriverName();
1.1 root 144:
145: // 統計情報を返す (ステータスパネルから呼ばれる)
146: uint64 GetTXPkts() const { return stat.tx_pkts; }
147: uint64 GetRXPkts() const { return stat.rx_pkts; }
148:
1.1.1.6 root 149: // 統計情報に1パケット分加算する (これだけ SLIRP の裏スレッドから呼ばれる)
150: void CountTXUnsupp(size_t bytes);
151:
1.1 root 152: // コンパイル済みのドライバ名一覧を返す
153: static std::vector<std::string> GetDrivers();
154:
1.1.1.6 root 155: // デバッグ用。
156: static std::vector<std::string> DumpHex(const void *, size_t);
157: static std::vector<std::string> DumpFrame(const void *, size_t);
158:
1.1 root 159: private:
1.1.1.7 ! root 160: bool SelectDriver(bool startup) override;
! 161: void CreateNone();
! 162: void CreateSlirp(bool startup);
! 163: void CreateTap();
! 164: void CreateBPF();
! 165: void CreateAFPacket();
1.1 root 166:
167: int Read() override;
168:
169: // 外部への書き出し(パケットを送信)
1.1.1.7 ! root 170: void Write() override;
1.1 root 171:
172: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
173:
1.1.1.6 root 174: // デバッグ用 (下請け)
175: static std::vector<std::string> DumpARP(const void *, size_t);
176: static std::vector<std::string> DumpIPv4(const void *, size_t);
177: static std::vector<std::string> DumpICMPv4(const char *, const char *,
178: const void *, size_t);
179: static std::vector<std::string> DumpTCPv4(const char *, const char *,
180: const void *, size_t);
181: static std::vector<std::string> DumpUDPv4(const char *, const char *,
182: const void *, size_t);
183: static std::vector<std::string> DumpDHCP(const void *, size_t);
184: static std::vector<std::string> DumpIPv6(const void *, size_t);
185: static std::vector<std::string> DumpICMPv6(const char *, const char *,
186: const void *, size_t);
187: static std::string DumpDHCPAddrList(const uint8 *, size_t);
188: static std::string GetServByPort(uint16 port_be, const char *protoname);
189:
1.1 root 190: std::unique_ptr<NetDriver> driver {};
191:
192: bool rx_enable {};
1.1.1.3 root 193:
1.1 root 194: // キュー
195: NetTxQueue txq {};
196: NetRxQueue rxq {};
197:
198: // 統計情報
199: struct stat_t stat {};
200:
1.1.1.5 root 201: Monitor *monitor {};
1.1.1.6 root 202:
203: IHWAddrFilter *ihwaddrfilter {};
1.1 root 204: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.