Annotation of nono/host/netdriver_selector.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2021 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: // NetDriver セレクタ
                      8: //
                      9: // ログレベルを受け取るために他のデバイスとかと同様最初に作成されて、
                     10: // InitDriver() で実際に使うドライバを選択・作成するだけ。
                     11: 
                     12: #include "netdriver_selector.h"
                     13: #include "config.h"
                     14: #include "netdriver_none.h"
                     15: #if defined(HAVE_HOSTNET_AFPACKET)
                     16: #include "netdriver_afpacket.h"
                     17: #endif
                     18: #if defined(HAVE_HOSTNET_BPF)
                     19: #include "netdriver_bpf.h"
                     20: #endif
                     21: #if defined(HAVE_HOSTNET_TAP)
                     22: #include "netdriver_tap.h"
                     23: #endif
                     24: 
                     25: std::unique_ptr<NetDriverSelector> gNetDriverSelector;
                     26: 
                     27: // コンパイル済みのドライバ名一覧を返す
                     28: // (MainApp から呼ばれる)
                     29: /*static*/ std::vector<std::string>
                     30: NetDriverSelector::GetDrivers()
                     31: {
                     32:        std::vector<std::string> list;
                     33: 
                     34: #if defined(HAVE_HOSTNET_AFPACKET)
                     35:        list.emplace_back("afpacket");
                     36: #endif
                     37: #if defined(HAVE_HOSTNET_BPF)
                     38:        list.emplace_back("bpf");
                     39: #endif
                     40: #if defined(HAVE_HOSTNET_TAP)
                     41:        list.emplace_back("tap");
                     42: #endif
                     43: 
                     44:        return list;
                     45: }
                     46: 
                     47: // コンストラクタ
                     48: // (ここのログ名 HostNet がコマンドラインで指定するやつになるので
                     49: // HostNetSelector とかに変えないように)
                     50: NetDriverSelector::NetDriverSelector(EthernetDevice *parent_)
                     51:        : inherited("HostNet")
                     52: {
                     53:        parent = parent_;
                     54: 
                     55:        AddAlias("NetDriver");
                     56: }
                     57: 
                     58: // デストラクタ
                     59: NetDriverSelector::~NetDriverSelector()
                     60: {
                     61: }
                     62: 
                     63: // ここで実際の NetDriver を用意する (MainApp::Init1() から呼ばれる)。
                     64: // ここでは putmsg() が使える。また作成した NetDriver クラスも
                     65: // (NetDriverSelector のログレベルをコピーするので) putmsg() が使える。
                     66: // 成功すれば作成した NetDriver を返す。
                     67: // 終了する場合は warnx() を出力してから NULL を返す。
                     68: //
                     69: // 起動時のフェーズは Create() はログが使えない、Init() はログが使える、と
                     70: // 分かれており、ここもログが使えるので Init を冠しているが、やってることは
                     71: // Create なので関数名とメッセージ中の単語のずれは気持ち悪いけど仕方がない。
                     72: NetDriver *
                     73: NetDriverSelector::InitDriver()
                     74: {
                     75:        const ConfigItem& item = gConfig->Find("hostnet-driver");
                     76:        const std::string& type = item.AsString();
                     77:        bool fallback = gConfig->Find("hostnet-fallback").AsInt();
                     78:        NetDriver *driver;
                     79: 
                     80:        driver = NULL;
                     81: 
                     82:        if (type == "none") {
                     83:                driver = InitNone();
                     84: 
                     85:        } else if (type == "tap") {
                     86: #if defined(HAVE_HOSTNET_TAP)
                     87:                driver = InitTap();
                     88: #else
                     89:                item.Err("hostnet driver %s not compiled", type.c_str());
                     90: #endif
                     91: 
                     92:        } else if (type == "bpf") {
                     93: #if defined(HAVE_HOSTNET_BPF)
                     94:                driver = InitBPF();
                     95: #else
                     96:                item.Err("hostnet driver %s not compiled", type.c_str());
                     97: #endif
                     98: 
                     99:        } else if (type == "afpacket") {
                    100: #if defined(HAVE_HOSTNET_AFPACKET)
                    101:                driver = InitAFPacket();
                    102: #else
                    103:                item.Err("hostnet driver %s not compiled", type.c_str());
                    104: #endif
                    105: 
                    106:        } else if (type == "auto") {
                    107:                // auto なら Tap -> { BPF, AFPacket } の順で試す。
                    108:                //
                    109:                // Tap は事前の準備が面倒だが制約がない。
                    110:                // BPF, AFPacket (この2つは OS の違いだけでほぼ同じもの) は
                    111:                // 準備に手間がかからないが自ホストと通信できない制約がある。
                    112:                // そのためどの環境でも Tap が使えれば Tap を、そうでなければ
                    113:                // BPF, AFPacket を使う、という順にしておく。
                    114: 
                    115:                driver = InitTap();
                    116:                if (driver == NULL) {
                    117:                        driver = InitAFPacket();
                    118:                }
                    119:                if (driver == NULL) {
                    120:                        driver = InitBPF();
                    121:                }
                    122: 
                    123:        } else {
                    124:                // 知らないドライバ種別
                    125:                item.Err();
                    126:        }
                    127: 
                    128:        if (driver == NULL) {
                    129:                putmsg(1, "hostnet-fallback=%d", fallback ? 1 : 0);
                    130: 
                    131:                if (fallback) {
                    132:                        // 出来てない場合でフォールバックが指示されていれば
                    133:                        // None へフォールバックする
                    134:                        driver = InitNone();
                    135:                } else {
                    136:                        errmsg = "No host network driver found";
                    137:                        putmsg(1, "%s", errmsg.c_str());
                    138:                        warnx("%s (See details with options -C -Lhostnet=1)",
                    139:                                errmsg.c_str());
                    140: 
                    141:                        // NULL を返すと終了する
                    142:                        return NULL;
                    143:                }
                    144:        }
                    145: 
                    146:        // ドライバ名は Capitalize だがログはほぼ小文字なので雰囲気を揃える…
                    147:        putmsg(1, "selected host driver: %s",
                    148:                string_tolower(driver->GetDriverName()).c_str());
                    149: 
                    150:        return driver;
                    151: }
                    152: 
                    153: // None の場合
                    154: NetDriver *
                    155: NetDriverSelector::InitNone()
                    156: {
                    157:        NetDriverNone *driver = new NetDriverNone(loglevel);
                    158:        // 失敗しても出来ることはあまりなさげ
                    159:        assert(driver);
                    160:        driver->InitDriver();
                    161:        return driver;
                    162: }
                    163: 
                    164: // Tap の場合
                    165: NetDriver *
                    166: NetDriverSelector::InitTap()
                    167: {
                    168: #if defined(HAVE_HOSTNET_TAP)
                    169:        const ConfigItem& item = gConfig->Find("hostnet-tap-devpath");
                    170:        const std::string& devpath = item.AsString();
                    171: 
                    172:        NetDriverTap *driver = NULL;
                    173:        try {
                    174:                driver = new NetDriverTap(parent, loglevel, devpath);
                    175:                if (driver->InitDriver()) {
                    176:                        // 成功
                    177:                        return driver;
                    178:                }
                    179:                errmsg = driver->errmsg;
                    180:                delete driver;
                    181:        } catch (...) {
                    182:                errmsg = "Creating NetDriverTap failed";
                    183:        }
                    184: #endif
                    185:        return NULL;
                    186: }
                    187: 
                    188: // bpf の場合
                    189: NetDriver *
                    190: NetDriverSelector::InitBPF()
                    191: {
                    192: #if defined(HAVE_HOSTNET_BPF)
                    193:        const ConfigItem& item = gConfig->Find("hostnet-bpf-ifname");
                    194:        const std::string& ifname = item.AsString();
                    195: 
                    196:        NetDriverBPF *driver = NULL;
                    197:        try {
                    198:                driver = new NetDriverBPF(parent, loglevel, ifname);
                    199:                if (driver->InitDriver()) {
                    200:                        // 成功
                    201:                        return driver;
                    202:                }
                    203:                errmsg = driver->errmsg;
                    204:                delete driver;
                    205:        } catch (...) {
                    206:                errmsg = "Creating NetDriverBPF failed";
                    207:        }
                    208: #endif
                    209:        return NULL;
                    210: }
                    211: 
                    212: // AFPacket の場合
                    213: NetDriver *
                    214: NetDriverSelector::InitAFPacket()
                    215: {
                    216: #if defined(HAVE_HOSTNET_AFPACKET)
                    217:        const ConfigItem& item = gConfig->Find("hostnet-afpacket-ifname");
                    218:        const std::string& ifname = item.AsString();
                    219: 
                    220:        NetDriverAFPacket *driver = NULL;
                    221:        try {
                    222:                driver = new NetDriverAFPacket(parent, loglevel, ifname);
                    223:                if (driver->InitDriver()) {
                    224:                        // 成功
                    225:                        return driver;
                    226:                }
                    227:                errmsg = driver->errmsg;
                    228:                delete driver;
                    229:        } catch (...) {
                    230:                errmsg = "Creating NetDriverAFPacket failed";
                    231:        }
                    232: #endif
                    233:        return NULL;
                    234: }

unix.superglobalmegacorp.com

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