|
|
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: // バッファ内の有効長
41: int 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;
78: int txqfull_pkts; // キューが一杯だった回数
79: uint64 txqfull_bytes; // キューに入れられなかったバイト数
80: uint64 rxdisable_pkts; // 上位層が受信無効
81: uint64 rxdisable_bytes; // 上位層が受信無効
82: uint64 rxjumbo_pkts; // 受信したジャンボパケット数
83: uint64 rxjumbo_bytes; // 受信したジャンボパケットのバイト数
84: int rxqfull_pkts; // キューが一杯だった回数
85: uint64 rxqfull_bytes; // キューに入れられなかったバイト数
86: int rxfilter_pkts; // 受信フィルタで破棄したパケット数
87: uint64 rxfilter_bytes; // フィルタされたバイト数
88:
89: int txq_peak; // キューのおおよその最大使用量
90: int rxq_peak; // キューのおおよその最大使用量
91: };
92:
93: public:
1.1.1.2 ! root 94: HostNetDevice(Device *parent_, int n);
1.1 root 95: ~HostNetDevice() override;
96:
97: void SetLogLevel(int loglevel_) override;
98: bool Init() override;
99:
100: // パケットを送信する。
101: // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
102: // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。
103: // 送信キューに追加できれば true、出来なければ false を返す。
104: bool Tx(const NetPacket& packet);
105:
106: // パケットを引き取るために VM から呼ばれる。
107: // パケットが受信キューにあるときは packet にコピーして true を返す。
108: // キューが空なら false を返す。
109: bool Rx(NetPacket *packet);
110:
111: // 受信キューへの投入を許可/禁止する。
112: void EnableRx(bool enable);
113:
1.1.1.2 ! root 114: // 受信用の自身の MAC アドレスを設定する。
1.1 root 115: void SetMyAddr(const macaddr_t& myaddr_);
116:
117: // プロミスキャスモードを設定する。
118: void SetPromisc(bool promisc_);
119:
120: // ドライバ名を返す (ステータスパネルから呼ばれる)
121: const std::string GetDriverName() const;
122:
123: // 統計情報を返す (ステータスパネルから呼ばれる)
124: uint64 GetTXPkts() const { return stat.tx_pkts; }
125: uint64 GetRXPkts() const { return stat.rx_pkts; }
126:
127: // コンパイル済みのドライバ名一覧を返す
128: static std::vector<std::string> GetDrivers();
129:
130: private:
131: bool SelectDriver();
132: bool CreateNone();
133: bool CreateTap();
134: bool CreateBPF();
135: bool CreateAFPacket();
136:
137: int Read() override;
138:
139: // 外部への書き出し(パケットを送信)
140: void Write(uint32 data) override;
141:
142: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
143:
144: std::unique_ptr<NetDriver> driver {};
145:
146: bool rx_enable {};
1.1.1.2 ! root 147: macaddr_t myaddr {}; // 自身の MAC アドレス
1.1 root 148: bool promisc {}; // プロミスキャスモードなら true
149:
150: // キュー
151: NetTxQueue txq {};
152: NetRxQueue rxq {};
153:
154: // 統計情報
155: struct stat_t stat {};
156:
157: std::string errmsg {};
158:
159: Monitor monitor { this };
160: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.