async fn add_new_device<D: devices::Device>(
        &mut self,
        filepath: &path::PathBuf,
        stable_name: bool,
    ) -> Result<(), devices::AddDeviceError> {
        let (topological_path, device_instance) = D::get_topo_path_and_device(filepath)
            .await
            .context("error getting topological path and device")?;

        info!("{} {} has topological path {}", D::NAME, filepath.display(), topological_path);

        let info = D::get_device_info(&device_instance)
            .await
            .context("error getting device info and MAC")?;

        let DeviceInfo { mac, is_synthetic, device_class: _ } = &info;

        if !self.allow_virtual_devices && *is_synthetic {
            warn!("{} at {} is not a physical device, skipping", D::NAME, filepath.display());
            return Ok(());
        }

        let mac = mac.ok_or_else(|| {
            warn!("devices without mac address not supported yet");
            devices::AddDeviceError::Other(errors::Error::NonFatal(anyhow::anyhow!(
                "device without mac not supported"
            )))
        })?;

        let interface_type = info.interface_type();
        let metric = match interface_type {
            InterfaceType::Wlan => self.interface_metrics.wlan_metric,
            InterfaceType::Ethernet => self.interface_metrics.eth_metric,
        }
        .into();
        let interface_name = if stable_name {
            match self.persisted_interface_config.generate_stable_name(
                &topological_path, /* TODO(tamird): we can probably do
                                    * better with std::borrow::Cow. */
                mac,
                interface_type,
            ) {
                Ok(name) => name.to_string(),
                Err(interface::NameGenerationError::FileUpdateError { name, err }) => {
                    warn!("failed to update interface (topo path = {}, mac = {}, interface_type = {:?}) with new name = {}: {}", topological_path, mac, interface_type, name, err);
                    name.to_string()
                }
                Err(interface::NameGenerationError::GenerationError(e)) => {
                    return Err(devices::AddDeviceError::Other(errors::Error::Fatal(
                        e.context("error getting stable name"),
                    )))
                }
            }
        } else {
            self.persisted_interface_config.generate_temporary_name(interface_type)
        };

        info!(
            "adding {} at {} to stack with name = {}",
            D::NAME,
            filepath.display(),
            interface_name
        );

        let mut interface_config = fidl_fuchsia_netstack::InterfaceConfig {
            name: interface_name.clone(),
            filepath: format!("{:?}", filepath),
            metric,
        };

        let interface_id =
            D::add_to_stack(self, topological_path.clone(), &mut interface_config, device_instance)
                .await
                .context("error adding to stack")?;

        self.configure_eth_interface(interface_id, &topological_path, interface_name, &info)
            .await
            .context("error configuring ethernet interface")
            .map_err(devices::AddDeviceError::Other)
    }
/// Add a device at `filepath` to the netstack.
Add a device at `filepath` to the netstack.
Add a device at ` filepath ` to the netstack .
async fn add_new_device<D: devices::Device>(
        &mut self,
        filepath: &path::PathBuf,
        stable_name: bool,
    ) -> Result<(), devices::AddDeviceError> {
        let (topological_path, device_instance) = D::get_topo_path_and_device(filepath)
            .await
            .context("error getting topological path and device")?;
        info!("{} {} has topological path {}", D::NAME, filepath.display(), topological_path);
        let info = D::get_device_info(&device_instance)
            .await
            .context("error getting device info and MAC")?;
        let DeviceInfo { mac, is_synthetic, device_class: _ } = &info;
        if !self.allow_virtual_devices && *is_synthetic {
            warn!("{} at {} is not a physical device, skipping", D::NAME, filepath.display());
            return Ok(());
        }
        let mac = mac.ok_or_else(|| {
            warn!("devices without mac address not supported yet");
            devices::AddDeviceError::Other(errors::Error::NonFatal(anyhow::anyhow!(
                "device without mac not supported"
            )))
        })?;
        let interface_type = info.interface_type();
        let metric = match interface_type {
            InterfaceType::Wlan => self.interface_metrics.wlan_metric,
            InterfaceType::Ethernet => self.interface_metrics.eth_metric,
        }
        .into();
        let interface_name = if stable_name {
            match self.persisted_interface_config.generate_stable_name(
                &topological_path, /* TODO(tamird): we can probably do
                                    * better with std::borrow::Cow. */
                mac,
                interface_type,
            ) {
                Ok(name) => name.to_string(),
                Err(interface::NameGenerationError::FileUpdateError { name, err }) => {
                    warn!("failed to update interface (topo path = {}, mac = {}, interface_type = {:?}) with new name = {}: {}", topological_path, mac, interface_type, name, err);
                    name.to_string()
                }
                Err(interface::NameGenerationError::GenerationError(e)) => {
                    return Err(devices::AddDeviceError::Other(errors::Error::Fatal(
                        e.context("error getting stable name"),
                    )))
                }
            }
        } else {
            self.persisted_interface_config.generate_temporary_name(interface_type)
        };
        info!(
            "adding {} at {} to stack with name = {}",
            D::NAME,
            filepath.display(),
            interface_name
        );
        let mut interface_config = fidl_fuchsia_netstack::InterfaceConfig {
            name: interface_name.clone(),
            filepath: format!("{:?}", filepath),
            metric,
        };
        let interface_id =
            D::add_to_stack(self, topological_path.clone(), &mut interface_config, device_instance)
                .await
                .context("error adding to stack")?;
        self.configure_eth_interface(interface_id, &topological_path, interface_name, &info)
            .await
            .context("error configuring ethernet interface")
            .map_err(devices::AddDeviceError::Other)
    }
async fn add_new_device < D : devices :: Device > ( & mut self , filepath : & path :: PathBuf , stable_name : bool , ) -> Result < ( ) , devices :: AddDeviceError > { let ( topological_path , device_instance ) = D :: get_topo_path_and_device ( filepath ) . await . context ( " " ) ? ; info ! ( " " D NAME filepath display ( ) topological_path ) ; let info = D :: get_device_info ( & device_instance ) . await . context ( " " ) ? ; let DeviceInfo { mac , is_synthetic , device_class : _ } = & info ; if ! self . allow_virtual_devices && * is_synthetic { warn ! ( " " D NAME filepath display ( ) ) ; return Ok ( ( ) ) ; } let mac = mac . ok_or_else ( | | { warn ! ( " " ) ; devices :: AddDeviceError :: Other ( errors :: Error :: NonFatal ( anyhow :: anyhow ! ( " " ) ) ) } ) ? ; let interface_type = info . interface_type ( ) ; let metric = match interface_type { InterfaceType :: Wlan => self . interface_metrics . wlan_metric , InterfaceType :: Ethernet => self . interface_metrics . eth_metric , } . into ( ) ; let interface_name = if stable_name { match self . persisted_interface_config . generate_stable_name ( & topological_path , /* TODO(tamird): we can probably do
                                    * better with std::borrow::Cow. */ mac , interface_type , ) { Ok ( name ) => name . to_string ( ) , Err ( interface :: NameGenerationError :: FileUpdateError { name , err } ) => { warn ! ( " " topological_path mac interface_type name err ) ; name . to_string ( ) } Err ( interface :: NameGenerationError :: GenerationError ( e ) ) => { return Err ( devices :: AddDeviceError :: Other ( errors :: Error :: Fatal ( e . context ( " " ) , ) ) ) } } } else { self . persisted_interface_config . generate_temporary_name ( interface_type ) } ; info ! ( " " D NAME filepath display ( ) interface_name ) ; let mut interface_config = fidl_fuchsia_netstack :: InterfaceConfig { name : interface_name . clone ( ) , filepath : format ! ( " " filepath ) , metric , } ; let interface_id = D :: add_to_stack ( self , topological_path . clone ( ) , & mut interface_config , device_instance ) . await . context ( " " ) ? ; self . configure_eth_interface ( interface_id , & topological_path , interface_name , & info ) . await . context ( " " ) . map_err ( devices :: AddDeviceError :: Other ) }
Add a device at `filepath` to the netstack.
Add a device at ` filepath ` to the netstack .
&mut self
filepath
&path::PathBuf
stable_name
bool
&mut self
filepath
&path::PathBuf
stable_name
bool