天天看點

netcfg 程序分析

netcfg 程序 -garnet\bin\netcfg\src\main.rs

//概括而言就是通過一個watcher來監聽網卡目錄,當有新節點添加時,通過IPC調用netstack的AddEthernetDevice接口添加網口端點

fn main() 

    const ETHDIR: &str = "/dev/class/ethernet"; //常量字元串,監控的網卡目錄

    interface_ids.insert("lo".to_owned(), 1); //interface_ids為hash表;向其中加入localhost項

    let ethdir = fs::File::open(ETHDIR).xxx //打開網卡目錄

    let mut watcher = fuchsia_vfs_watcher::Watcher::new(&ethdir) //設定網卡目錄watcher

    let ethernet_device = async {……} //網卡裝置

        while let Some(fuchsia_vfs_watcher::WatchMessage { event, filename }) =

            await!(watcher.try_next()){……} //對watcher出的每個對象(每個網卡會增加一項)

                match event {……} //比對不同的事件,分别進行處理

                    fuchsia_vfs_watcher::WatchEvent::ADD_FILE | fuchsia_vfs_watcher::WatchEvent::EXISTING => {……} //添加檔案或已經現存檔案的執行流程

                        let filename = path::Path::new(ETHDIR).join(filename); //将前面的網卡目錄與發現的檔案拼接

                        let device = fs::File::open(&filename) //打開網卡檔案,這裡會觸發通用網卡層的EthDev0::DdkOpen,進而建立一個使用網卡驅動的執行個體

                        fdio::fdio_sys::fdio_get_service_handle(device, &mut client) //這裡device為網卡驅動檔案的fd,擷取的client則為可以與網卡驅動通信的句柄

                        let device = fidl::endpoints::ClientEnd::<fidl_fuchsia_hardware_ethernet::DeviceMarker,>::new(client).into_proxy()?; //TODO:此操作應該是對前面client(channel)的封裝,目的是擷取網卡裝置的IPC操作執行個體

                        if let Ok(device_info) = await!(device.get_info()) {……} //GetInfo

                            if device_info.features.is_physical() {……} //判斷是實體網卡?裡面會判斷INFO_FEATURE_SYNTH(虛拟網卡會設定)屬性。

                                let name = …… //配置檔案可配

                                let metric //hardcode

                                let mut derived_interface_config = matchers::config_for_device(……)

                                let nic_id = await!(netstack.add_ethernet_device(

                                                    &topological_path,

                                                    &mut derived_interface_config,

                                                    fidl::endpoints::ClientEnd::<

                                                        fidl_fuchsia_hardware_ethernet::DeviceMarker,

                                                    >::new(client),

                                                    )) //

                                    NetstackProxyInterface::add_ethernet_device(……) //add_ethernet_device --./out/default/fidling/gen/sdk/fidl/fuchsia.netstack/fidl_fuchsia_netstack.rs

                                        self.client.send_query(……,561491870) //561491870為IPC編碼

                                            NetstackRequest::AddEthernetDevice //後面沒跟了,應該是發IPC到netstack調用AddEthernetDevice接口了!!

                                await!(match derived_interface_config.ip_address_config {……} //配置ip

                                let () = netstack.set_interface_status(nic_id as u32, true)?; //設定網卡狀态為true

                                await!(interface_ids.lock()).insert(derived_interface_config.name, nic_id as u64); //将此實體網卡加入interface_ids的hash表

                    fuchsia_vfs_watcher::WatchEvent::IDLE | fuchsia_vfs_watcher::WatchEvent::REMOVE_FILE => {} //idle或者remove file事件,什麼都不做

                    event => {……} //error列印

    let (_success, (), (), ()) = executor.run_singlethreaded(try_join4(

        device_name,

        filter_setup,

        ethernet_device,

        fs.collect().map(Ok),

    ))?; //Run a single future to completion on a single thread。--./garnet/public/rust/fuchsia-async/src/executor.rs