diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs index 6c214871ed..5a5ab90cc5 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -use crate::{DeviceConfig, DiskConfig, FsConfig, VmConfig, VsockConfig}; +use crate::{DeviceConfig, DiskConfig, FsConfig, NetConfig, VmConfig, VsockConfig}; use anyhow::{anyhow, Result}; use api_client::simple_api_full_command_and_response; @@ -100,6 +100,24 @@ pub async fn cloud_hypervisor_vm_blockdev_add( .await? } +pub async fn cloud_hypervisor_vm_netdev_add( + mut socket: UnixStream, + net_config: NetConfig, +) -> Result> { + task::spawn_blocking(move || -> Result> { + let response = simple_api_full_command_and_response( + &mut socket, + "PUT", + "vm.add-net", + Some(&serde_json::to_string(&net_config)?), + ) + .map_err(|e| anyhow!(e))?; + + Ok(response) + }) + .await? +} + pub async fn cloud_hypervisor_vm_device_add( mut socket: UnixStream, device_config: DeviceConfig, 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 9d4c0dc4c8..54daf6134f 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs @@ -9,6 +9,7 @@ use crate::device::DeviceType; use crate::BlockDevice; use crate::HybridVsockDevice; use crate::NetworkConfig; +use crate::NetworkDevice; use crate::PciPath; use crate::ShareFsConfig; use crate::ShareFsDevice; @@ -18,7 +19,8 @@ use anyhow::{anyhow, Context, Result}; use ch_config::ch_api::cloud_hypervisor_vm_device_add; use ch_config::ch_api::{ cloud_hypervisor_vm_blockdev_add, cloud_hypervisor_vm_device_remove, - cloud_hypervisor_vm_fs_add, cloud_hypervisor_vm_vsock_add, PciDeviceInfo, VmRemoveDeviceData, + cloud_hypervisor_vm_fs_add, cloud_hypervisor_vm_netdev_add, cloud_hypervisor_vm_vsock_add, + PciDeviceInfo, VmRemoveDeviceData, }; use ch_config::convert::{DEFAULT_DISK_QUEUES, DEFAULT_DISK_QUEUE_SIZE, DEFAULT_NUM_PCI_SEGMENTS}; use ch_config::DiskConfig; @@ -79,6 +81,7 @@ impl CloudHypervisorInner { DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(hvsock).await, DeviceType::Block(block) => self.handle_block_device(block).await, DeviceType::Vfio(vfiodev) => self.handle_vfio_device(vfiodev).await, + DeviceType::Network(netdev) => self.handle_network_device(netdev).await, _ => Err(anyhow!("unhandled device: {:?}", device)), } } @@ -341,6 +344,30 @@ impl CloudHypervisorInner { Ok(DeviceType::Block(block_dev)) } + async fn handle_network_device(&mut self, device: NetworkDevice) -> Result { + let netdev = device.clone(); + + let socket = self + .api_socket + .as_ref() + .ok_or("missing socket") + .map_err(|e| anyhow!(e))?; + + let clh_net_config = NetConfig::try_from(device.config)?; + + let response = cloud_hypervisor_vm_netdev_add( + socket.try_clone().context("failed to clone socket")?, + clh_net_config, + ) + .await?; + + if let Some(detail) = response { + debug!(sl!(), "netdev add response: {:?}", detail); + } + + Ok(DeviceType::Network(netdev)) + } + pub(crate) async fn get_shared_devices( &mut self, ) -> Result<(Option>, Option>)> {