|
|
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.4 root 119: HostNetDevice(Device *parent_, uint n);
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 root 142: // ドライバ名を返す (ステータスパネルから呼ばれる)
143: const std::string GetDriverName() const;
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:
160: bool SelectDriver();
161: bool CreateNone();
1.1.1.6 ! root 162: bool CreateSlirp();
1.1 root 163: bool CreateTap();
164: bool CreateBPF();
165: bool CreateAFPacket();
166:
167: int Read() override;
168:
169: // 外部への書き出し(パケットを送信)
170: void Write(uint32 data) override;
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:
201: std::string errmsg {};
202:
1.1.1.5 root 203: Monitor *monitor {};
1.1.1.6 ! root 204:
! 205: IHWAddrFilter *ihwaddrfilter {};
1.1 root 206: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.