Annotation of nono/host/hostnet.h, revision 1.1.1.7

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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.