|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.8 ! root 9: #include "device.h"
1.1 root 10: #include "ethernet.h"
1.1.1.8 ! root 11: #include "monitor.h"
1.1 root 12: #include <mutex>
13: #include <condition_variable>
14:
1.1.1.8 ! root 15: class NetDriver : public Device
1.1 root 16: {
1.1.1.8 ! root 17: using inherited = Device;
! 18: protected:
1.1 root 19: // コンストラクタ
1.1.1.8 ! root 20: NetDriver(const char *name, EthernetDevice *parent, int loglevel_);
1.1 root 21:
1.1.1.8 ! root 22: public:
1.1 root 23: // デストラクタ。
1.1.1.8 ! root 24: virtual ~NetDriver() override;
1.1 root 25:
1.1.1.8 ! root 26: // デバイス初期化 & オープン。
! 27: // NetDriverSelector::InitDriver() から呼ばれる。
! 28: // この中ではログ出力が可能。まずどれが呼ばれたかを putmsg(1) で表示し
! 29: // 必要なオープン処理を行う。
1.1 root 30: // 成功すれば true、失敗すれば warn()/warnx() でメッセージを出力して
31: // false を返すこと。
1.1.1.8 ! root 32: // また、これに対応するクローズ相当の動作はなくデストラクタで行う。
! 33: virtual bool InitDriver() = 0;
1.1 root 34:
1.1.1.8 ! root 35: // こっちは Device クラス由来の Init()。VM::Init() から呼ばれる。
! 36: // ここで受信スレッドを起動する。
! 37: bool Init() override;
1.1 root 38:
39: // パケットを送信する。正常に送信できれば true を返す。
40: // EthernetDevice::SendPacket() が呼ばれると常に呼び出される。
41: // その上で、ドライバが有効かどうか(オープンされているかどうかなど) は
42: // すべてこちら(NetDriver)側の責任。
43: // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
44: // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。
45: // VM から引き取ったパケットについて tx_pkts, tx_bytes を更新すること
46: // false が返った場合の規定が不明。
47: virtual bool SendPacket(const std::vector<uint8>& data) = 0;
48:
49: // 受信スレッド。
50: // VM に引き渡せたパケットについて rx_pkts, rx_bytes を更新すること。
1.1.1.8 ! root 51: void ThreadRun();
1.1 root 52:
53: // オープンされていれば true を返す。
54: bool IsOpen() const { return fd != -1; }
55:
1.1.1.8 ! root 56: // ドライバ名を返す。
! 57: const char *GetDriverName() const { return drivername; }
! 58:
! 59: // InitDriver() 中の(主に最後の)エラーメッセージ。
! 60: // NetDriver は複数を順番に試す場合もあるし、全部エラーになっても終了する
! 61: // かどうかは設定によるので、各ドライバはエラーが発生しても各自で warnx に
! 62: // よる表示はせず、ここにエラーメッセージをセットする。必要になった時点で
! 63: // NetDriverSelector が最後の一つを warnx() で表示する。
! 64: // なお、おそらくそれだけでは大抵何も分からないのでこれとは別に
! 65: // ログレベル 1 で putmsg() は充実させておくこと。
! 66: std::string errmsg {};
! 67:
1.1.1.7 root 68: protected:
1.1.1.8 ! root 69: // 受信パケットキューにパケットを一つ追加する
! 70: void RecvEnqueue(uint8 *buf, size_t len);
! 71:
! 72: // パケットを受信する。read(2) と同じように値を返す。
! 73: virtual ssize_t RecvPacket() = 0;
! 74:
! 75: // モニタのうちドライバ依存部分の情報を書き出す。
! 76: // screen のうち (0から数えて) 1行目と2行目のみがドライバ依存部分なので
! 77: // ここだけ書き出すこと。不要なら書き出さなくてよい。Clear() しないこと。
! 78: virtual void MonitorUpdateMD(TextScreen& screen) = 0;
! 79:
! 80: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
1.1 root 81:
1.1.1.5 root 82: const char *drivername {}; // ドライバ名
83: EthernetDevice *parent {}; // 親
1.1 root 84:
1.1.1.8 ! root 85: std::string ifname {}; // (あれば)作成したインタフェース名
1.1 root 86:
87: // デバイスディスクリプタ。
88: // ディスクリプタを持つというのは共通なのでディスクリプタはここに置くが
89: // これを Open(), Close() するのはあくまで継承側の仕事で、こちらでは
90: // 初期化と IsOpen() だけ受け持つ。ちょっと責任分解点が気持ち悪いけど。
1.1.1.5 root 91: int fd {};
1.1 root 92:
93: // 統計情報
94: uint64 tx_pkts = 0;
95: uint64 rx_pkts = 0;
96: uint64 tx_bytes = 0;
97: uint64 rx_bytes = 0;
98:
99: // ifup/ifdown スクリプト実行
100: bool Run_ifup();
101: bool Run_ifdown();
102:
103: private:
104: bool RunScript(const char *filename);
1.1.1.8 ! root 105:
! 106: Monitor monitor { this };
1.1 root 107: };
108:
1.1.1.2 root 109: extern std::unique_ptr<NetDriver> gNetDriver;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.