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

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: 
1.1.1.9 ! root       18: // パケット。
        !            19: class NetPacket
1.1       root       20: {
                     21:  public:
1.1.1.2   root       22:        NetPacket() {
                     23:                Clear();
                     24:        }
                     25: 
1.1       root       26:        // バッファをクリアする
1.1.1.2   root       27:        void Clear() {
                     28:                length = 0;
1.1.1.9 ! root       29:                readpos = 0;
1.1.1.2   root       30:        }
1.1       root       31: 
1.1.1.9 ! root       32:        // このパケットの内容を置き換える。
        !            33:        void Assign(const void *src, uint srclen);
        !            34: 
        !            35:        // バッファサイズ (パケット長) を変更する。
        !            36:        void Resize(uint newlength);
        !            37: 
1.1       root       38:        // パケットに1バイト追加する
1.1.1.9 ! root       39:        void Append(uint8 data);
1.1       root       40: 
1.1.1.2   root       41:        // 読み出し開始位置を設定
1.1.1.9 ! root       42:        void Seek(size_t readpos_) { readpos = readpos_; }
        !            43: 
        !            44:        // バッファの先頭を返す。
        !            45:        uint8 *Data() { return buf.data(); }
        !            46:        const uint8 *Data() const { return buf.data(); }
        !            47: 
        !            48:        // パケットサイズを取得。
        !            49:        // NetDriver で受信してから HostNet で破棄されるまでの間だけ
        !            50:        // Length() が buf.size() を上回ることを許容する。
        !            51:        // データは buf に収まる分だけ書いておくが、実際には Length バイトの
        !            52:        // パケットだったことを示す。どのみち捨てられるのでデータが尻切れなことは
        !            53:        // 気にしない。あわよくばモニタ上で長いパケットだと示唆できるかも知れない
        !            54:        // という程度。
        !            55:        uint Length() const { return length; }
1.1.1.2   root       56: 
                     57:        // 読み出しの残りバイト数を返す
1.1.1.9 ! root       58:        uint GetRemain() const { return Length() - readpos; }
1.1.1.2   root       59: 
                     60:        // 1バイト読み出す。EOP なら -1 を返す
                     61:        uint32 Read() {
1.1.1.9 ! root       62:                if (readpos < Length()) {
        !            63:                        return buf[readpos++];
1.1.1.2   root       64:                } else {
                     65:                        return (uint32)-1;
                     66:                }
                     67:        }
1.1.1.5   root       68: 
1.1.1.9 ! root       69:        // ポインタを進めず指定の位置のデータを読み出す。
        !            70:        // pos が不正なら -1 を返す。
        !            71:        uint32 Peek(uint pos) const {
        !            72:                if (pos < Length()) {
        !            73:                        return buf[pos];
        !            74:                } else {
        !            75:                        return (uint32)-1;
        !            76:                }
        !            77:        }
1.1.1.5   root       78: 
1.1.1.9 ! root       79:  private:
        !            80:        // 有効長
        !            81:        uint length {};
1.1.1.5   root       82:        // 現在の読み出し位置
1.1.1.9 ! root       83:        uint readpos {};
        !            84: 
        !            85:        std::array<uint8, 1536> buf {};
1.1       root       86: };
                     87: 
1.1.1.6   root       88: // MAC アドレスフィルタ。
                     89: // VM 側デバイスはこれを多重継承して実装すること。
                     90: class IHWAddrFilter
                     91: {
                     92:        // インタフェース風にするため、メンバ変数を持たせないこと。
                     93:  public:
                     94:        enum {
                     95:                HPF_PASS = 0,           // このフレームを受信する。
                     96:                HPF_DROP_UNICAST,       // このユニキャストフレームを破棄する。
                     97:                HPF_DROP_MULTICAST,     // このマルチキャストフレームを破棄する。
                     98:        };
                     99: 
                    100:  public:
                    101:        virtual ~IHWAddrFilter();
                    102: 
                    103:        // デバイスがこの dstaddr 宛のフレームを受け付けるかどうかを返す。
                    104:        // デバイスは、自分宛て、ブロードキャスト、マルチキャスト
                    105:        // (おそらくハッシュ)、プロミスキャスなどの状態を考慮すること。
                    106:        virtual int HWAddrFilter(const MacAddr& dstaddr) const = 0;
                    107: };
                    108: 
1.1       root      109: class HostNetDevice : public HostDevice
                    110: {
                    111:        using inherited = HostDevice;
                    112:        using NetTxQueue = SPSCQueue<NetPacket, 32>;
                    113:        using NetRxQueue = SPSCQueue<NetPacket, 64>;
                    114: 
                    115:        // 統計情報
                    116:        struct stat_t {
                    117:                uint64 tx_pkts;
                    118:                uint64 tx_bytes;
                    119:                uint64 rx_pkts;
                    120:                uint64 rx_bytes;
                    121:                uint64 read_pkts;
                    122:                uint64 read_bytes;
                    123:                uint64 write_pkts;
                    124:                uint64 write_bytes;
1.1.1.4   root      125:                uint64 txzero_pkts;                     // 送信長0で破棄したパケット数
1.1.1.6   root      126:                uint64 txunsupp_pkts;           // 送信先が未対応で破棄したパケット数
                    127:                uint64 txunsupp_bytes;          // 送信先が未対応で破棄したバイト数
1.1.1.3   root      128:                uint64 txqfull_pkts;            // キューが一杯だった回数
1.1       root      129:                uint64 txqfull_bytes;           // キューに入れられなかったバイト数
                    130:                uint64 rxdisable_pkts;          // 上位層が受信無効
                    131:                uint64 rxdisable_bytes;         // 上位層が受信無効
                    132:                uint64 rxjumbo_pkts;            // 受信したジャンボパケット数
                    133:                uint64 rxjumbo_bytes;           // 受信したジャンボパケットのバイト数
1.1.1.3   root      134:                uint64 rxqfull_pkts;            // キューが一杯だった回数
1.1       root      135:                uint64 rxqfull_bytes;           // キューに入れられなかったバイト数
1.1.1.3   root      136:                uint64 rxnotme_pkts;            // ユニキャストで破棄したパケット数
                    137:                uint64 rxnotme_bytes;           // フィルタされたバイト数
                    138:                uint64 rxmcast_pkts;            // マルチキャストで破棄したパケット数
                    139:                uint64 rxmcast_bytes;           // フィルタされたバイト数
1.1       root      140: 
1.1.1.4   root      141:                uint txq_peak;                          // キューのおおよその最大使用量
                    142:                uint rxq_peak;                          // キューのおおよその最大使用量
1.1       root      143:        };
                    144: 
                    145:  public:
1.1.1.7   root      146:        HostNetDevice(Device *parent_, uint n, const std::string& portname_);
1.1       root      147:        ~HostNetDevice() override;
                    148: 
                    149:        void SetLogLevel(int loglevel_) override;
1.1.1.6   root      150:        bool Create2() override;
1.1       root      151: 
                    152:        // パケットを送信する。
                    153:        // data はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、
                    154:        // データ(46-1500バイト) からなる。FCS(CRC) (4バイト) は含まない。
                    155:        // 送信キューに追加できれば true、出来なければ false を返す。
                    156:        bool Tx(const NetPacket& packet);
                    157: 
                    158:        // パケットを引き取るために VM から呼ばれる。
                    159:        // パケットが受信キューにあるときは packet にコピーして true を返す。
                    160:        // キューが空なら false を返す。
                    161:        bool Rx(NetPacket *packet);
                    162: 
                    163:        // 受信キューへの投入を許可/禁止する。
                    164:        void EnableRx(bool enable);
                    165: 
1.1.1.3   root      166:        // マルチキャストフィルタを設定する。
                    167:        void SetMCastFilter(uint64 filter);
                    168: 
1.1.1.7   root      169:        // ドライバ名を返す。
1.1.1.8   root      170:        const std::string& GetDriverName();
1.1       root      171: 
                    172:        // 統計情報を返す (ステータスパネルから呼ばれる)
                    173:        uint64 GetTXPkts() const { return stat.tx_pkts; }
                    174:        uint64 GetRXPkts() const { return stat.rx_pkts; }
                    175: 
1.1.1.6   root      176:        // 統計情報に1パケット分加算する (これだけ SLIRP の裏スレッドから呼ばれる)
                    177:        void CountTXUnsupp(size_t bytes);
                    178: 
1.1       root      179:        // コンパイル済みのドライバ名一覧を返す
                    180:        static std::vector<std::string> GetDrivers();
                    181: 
1.1.1.8   root      182:        // libslirp のバージョン文字列を返す
                    183:        static const char *GetSlirpVersion();
                    184: 
1.1.1.6   root      185:        // デバッグ用。
                    186:        static std::vector<std::string> DumpHex(const void *, size_t);
                    187:        static std::vector<std::string> DumpFrame(const void *, size_t);
                    188: 
1.1       root      189:  private:
1.1.1.7   root      190:        bool SelectDriver(bool startup) override;
                    191:        void CreateNone();
                    192:        void CreateSlirp(bool startup);
                    193:        void CreateTap();
                    194:        void CreateBPF();
                    195:        void CreateAFPacket();
1.1       root      196: 
                    197:        int Read() override;
                    198: 
                    199:        // 外部への書き出し(パケットを送信)
1.1.1.7   root      200:        void Write() override;
1.1       root      201: 
1.1.1.9 ! root      202:        DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1       root      203: 
1.1.1.6   root      204:        // デバッグ用 (下請け)
                    205:        static std::vector<std::string> DumpARP(const void *, size_t);
                    206:        static std::vector<std::string> DumpIPv4(const void *, size_t);
                    207:        static std::vector<std::string> DumpICMPv4(const char *, const char *,
                    208:                const void *, size_t);
                    209:        static std::vector<std::string> DumpTCPv4(const char *, const char *,
                    210:                const void *, size_t);
                    211:        static std::vector<std::string> DumpUDPv4(const char *, const char *,
                    212:                const void *, size_t);
                    213:        static std::vector<std::string> DumpDHCP(const void *, size_t);
                    214:        static std::vector<std::string> DumpIPv6(const void *, size_t);
                    215:        static std::vector<std::string> DumpICMPv6(const char *, const char *,
                    216:                const void *, size_t);
                    217:        static std::string DumpDHCPAddrList(const uint8 *, size_t);
                    218:        static std::string GetServByPort(uint16 port_be, const char *protoname);
                    219: 
1.1       root      220:        std::unique_ptr<NetDriver> driver {};
                    221: 
                    222:        bool rx_enable {};
1.1.1.3   root      223: 
1.1       root      224:        // キュー
                    225:        NetTxQueue txq {};
                    226:        NetRxQueue rxq {};
                    227: 
                    228:        // 統計情報
                    229:        struct stat_t stat {};
                    230: 
1.1.1.5   root      231:        Monitor *monitor {};
1.1.1.6   root      232: 
                    233:        IHWAddrFilter *ihwaddrfilter {};
1.1       root      234: };

unix.superglobalmegacorp.com

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