diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs index 809c260524d9..638a333560c0 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs @@ -58,6 +58,7 @@ impl TryFrom for VmConfig { }; let fs = n.shared_fs_devices; + let net = n.network_devices; let cpus = CpusConfig::try_from(cfg.cpu_info).map_err(VmConfigError::CPUError)?; @@ -129,6 +130,7 @@ impl TryFrom for VmConfig { console, payload, fs, + net, pmem, disks, vsock: Some(vsock), diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs index 9d6214a77988..fd5b228f502e 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs @@ -492,4 +492,5 @@ pub struct NamedHypervisorConfig { pub tdx_enabled: bool, pub shared_fs_devices: Option>, + pub network_devices: Option>, } diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner.rs index 23b076b16cfc..6be9df282611 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner.rs @@ -44,7 +44,7 @@ pub struct CloudHypervisorInner { pub(crate) jailer_root: String, /// List of devices that will be added to the VM once it boots - pub(crate) pending_devices: Option>, + pub(crate) pending_devices: Vec, pub(crate) _capabilities: Capabilities, @@ -81,7 +81,7 @@ impl CloudHypervisorInner { vm_path: String::default(), run_dir: String::default(), netns: None, - pending_devices: None, + pending_devices: vec![], _capabilities: capabilities, shutdown_tx: Some(tx), shutdown_rx: Some(rx), diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs index d876b310930d..a6f4a9d02132 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs @@ -8,12 +8,13 @@ use super::inner::CloudHypervisorInner; use crate::device::DeviceType; use crate::BlockConfig; use crate::HybridVsockConfig; +use crate::NetworkConfig; use crate::ShareFsDeviceConfig; use crate::VmmState; use anyhow::{anyhow, Context, Result}; use ch_config::ch_api::{cloud_hypervisor_vm_blockdev_add, cloud_hypervisor_vm_fs_add}; use ch_config::DiskConfig; -use ch_config::FsConfig; +use ch_config::{net_util::MacAddr, FsConfig, NetConfig}; use safe_path::scoped_join; use std::convert::TryFrom; use std::path::PathBuf; @@ -25,15 +26,7 @@ const DEFAULT_DISK_QUEUE_SIZE: u16 = 1024; impl CloudHypervisorInner { pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> { if self.state != VmmState::VmRunning { - let mut devices: Vec = if let Some(devices) = self.pending_devices.take() { - devices - } else { - vec![] - }; - - devices.insert(0, device); - - self.pending_devices = Some(devices); + self.pending_devices.insert(0, device); return Ok(()); } @@ -63,10 +56,8 @@ impl CloudHypervisorInner { )); } - if let Some(mut devices) = self.pending_devices.take() { - while let Some(dev) = devices.pop() { - self.add_device(dev).await.context("add_device")?; - } + while let Some(dev) = self.pending_devices.pop() { + self.add_device(dev).await.context("add_device")?; } Ok(()) @@ -161,32 +152,53 @@ impl CloudHypervisorInner { Ok(()) } - pub(crate) async fn get_shared_fs_devices(&mut self) -> Result>> { - let pending_root_devices = self.pending_devices.take(); - - let mut root_devices = Vec::::new(); + pub(crate) async fn get_shared_devices( + &mut self, + ) -> Result<(Option>, Option>)> { + let mut shared_fs_devices = Vec::::new(); + let mut network_devices = Vec::::new(); + + while let Some(dev) = self.pending_devices.pop() { + match dev { + DeviceType::ShareFs(dev) => { + let settings = ShareFsSettings::new(dev.config, self.vm_path.clone()); + + let fs_cfg = FsConfig::try_from(settings)?; + + shared_fs_devices.push(fs_cfg); + } + DeviceType::Network(net_device) => { + let net_config = NetConfig::try_from(net_device.config)?; + network_devices.push(net_config); + } + _ => continue, + } + } - if let Some(devices) = pending_root_devices { - for dev in devices { - match dev { - DeviceType::ShareFs(dev) => { - let settings = ShareFsSettings::new(dev.config, self.vm_path.clone()); + Ok((Some(shared_fs_devices), Some(network_devices))) + } +} - let fs_cfg = FsConfig::try_from(settings)?; +impl TryFrom for NetConfig { + type Error = anyhow::Error; - root_devices.push(fs_cfg); - } - _ => continue, - }; - } + fn try_from(cfg: NetworkConfig) -> Result { + if let Some(mac) = cfg.guest_mac { + let net_config = NetConfig { + tap: Some(cfg.host_dev_name.clone()), + id: Some(cfg.virt_iface_name.clone()), + num_queues: cfg.queue_num, + queue_size: cfg.queue_size as u16, + mac: MacAddr { bytes: mac.0 }, + ..Default::default() + }; - Ok(Some(root_devices)) - } else { - Ok(None) + return Ok(net_config); } + + Err(anyhow!("Missing mac address for network device")) } } - #[derive(Debug)] pub struct ShareFsSettings { cfg: ShareFsDeviceConfig, @@ -235,3 +247,44 @@ impl TryFrom for FsConfig { Ok(fs_cfg) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::Address; + + #[test] + fn test_networkconfig_to_netconfig() { + let mut cfg = NetworkConfig { + host_dev_name: String::from("tap0"), + virt_iface_name: String::from("eth0"), + queue_size: 256, + queue_num: 2, + guest_mac: None, + index: 1, + }; + + let net = NetConfig::try_from(cfg.clone()); + assert_eq!( + net.unwrap_err().to_string(), + "Missing mac address for network device" + ); + + let v: [u8; 6] = [10, 11, 128, 3, 4, 5]; + let mac_address = Address(v); + cfg.guest_mac = Some(mac_address.clone()); + + let expected = NetConfig { + tap: Some(cfg.host_dev_name.clone()), + id: Some(cfg.virt_iface_name.clone()), + num_queues: cfg.queue_num, + queue_size: cfg.queue_size as u16, + mac: MacAddr { bytes: v }, + ..Default::default() + }; + + let net = NetConfig::try_from(cfg); + assert!(net.is_ok()); + assert_eq!(net.unwrap(), expected); + } +} diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs index 106d461e6c56..bd34fd0be457 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs @@ -107,7 +107,7 @@ impl CloudHypervisorInner { } async fn boot_vm(&mut self) -> Result<()> { - let shared_fs_devices = self.get_shared_fs_devices().await?; + let (shared_fs_devices, network_devices) = self.get_shared_devices().await?; let socket = self .api_socket @@ -147,6 +147,7 @@ impl CloudHypervisorInner { cfg: hypervisor_config.clone(), tdx_enabled, shared_fs_devices, + network_devices, }; let cfg = VmConfig::try_from(named_cfg)?;