diff --git a/Cargo.lock b/Cargo.lock index a7fd9c035..08c3d57e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1415,6 +1415,7 @@ dependencies = [ "virtio-bindings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vm-memory", "vm-virtio", + "vmm", "vmm-sys-util", ] diff --git a/tests/integration.rs b/tests/integration.rs index 7609fbd45..6047ee88a 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -444,12 +444,12 @@ mod tests { // Start the daemon let net_params = if let Some(tap_str) = tap { format!( - "tap={},ip={},mask=255.255.255.0,sock={},num_queues={},queue_size=1024", + "tap={},ip={},mask=255.255.255.0,socket={},num_queues={},queue_size=1024", tap_str, ip, vunet_socket_path, num_queues ) } else { format!( - "ip={},mask=255.255.255.0,sock={},num_queues={},queue_size=1024", + "ip={},mask=255.255.255.0,socket={},num_queues={},queue_size=1024", ip, vunet_socket_path, num_queues ) }; diff --git a/vhost_user_net/Cargo.toml b/vhost_user_net/Cargo.toml index 567897803..84fa5feec 100644 --- a/vhost_user_net/Cargo.toml +++ b/vhost_user_net/Cargo.toml @@ -15,4 +15,5 @@ vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragon virtio-bindings = "0.1.0" vm-memory = "0.2.0" vm-virtio = { path = "../vm-virtio" } +vmm = { path = "../vmm" } vmm-sys-util = ">=0.3.1" diff --git a/vhost_user_net/src/lib.rs b/vhost_user_net/src/lib.rs index d2518e3a6..bdc622947 100644 --- a/vhost_user_net/src/lib.rs +++ b/vhost_user_net/src/lib.rs @@ -11,6 +11,7 @@ extern crate net_util; extern crate vhost_rs; extern crate vhost_user_backend; extern crate vm_virtio; +extern crate vmm; use epoll; use libc::{self, EAGAIN, EFD_NONBLOCK}; @@ -31,6 +32,7 @@ use virtio_bindings::bindings::virtio_net::*; use vm_memory::GuestMemoryMmap; use vm_virtio::net_util::{open_tap, RxVirtio, TxVirtio}; use vm_virtio::Queue; +use vmm::config::{OptionParser, OptionParserError}; use vmm_sys_util::eventfd::EventFd; pub type VhostUserResult = std::result::Result; @@ -51,6 +53,8 @@ pub enum Error { EpollCreateFd, /// Failed to read Tap. FailedReadTap, + /// Failed to parse configuration string + FailedConfigParse(OptionParserError), /// Failed to signal used queue. FailedSignalingUsedQueue, /// Failed to handle event other than input event. @@ -63,22 +67,14 @@ pub enum Error { NoVringCallFdNotify, /// No memory configured. NoMemoryConfigured, - /// Failed to parse sock parameter. - ParseSockParam, - /// Failed to parse ip parameter. - ParseIpParam(std::net::AddrParseError), - /// Failed to parse mask parameter. - ParseMaskParam(std::net::AddrParseError), - /// Failed to parse queue number. - ParseQueueNumParam(std::num::ParseIntError), - /// Failed to parse queue size. - ParseQueueSizeParam(std::num::ParseIntError), /// Open tap device failed. OpenTap(vm_virtio::net_util::Error), + /// No socket provided + SocketParameterMissing, } pub const SYNTAX: &str = "vhost-user-net backend parameters \ -\"ip=,mask=,sock=,\ +\"ip=,mask=,socket=,\ num_queues=,queue_size=,tap=\""; impl fmt::Display for Error { @@ -353,71 +349,52 @@ impl VhostUserBackend for VhostUserNetBackend { } } -pub struct VhostUserNetBackendConfig<'a> { +pub struct VhostUserNetBackendConfig { pub ip: Ipv4Addr, pub mask: Ipv4Addr, - pub sock: &'a str, + pub socket: String, pub num_queues: usize, pub queue_size: u16, - pub tap: Option<&'a str>, + pub tap: Option, } -impl<'a> VhostUserNetBackendConfig<'a> { - pub fn parse(backend: &'a str) -> Result { - let params_list: Vec<&str> = backend.split(',').collect(); +impl VhostUserNetBackendConfig { + pub fn parse(backend: &str) -> Result { + let mut parser = OptionParser::new(); - let mut ip_str: &str = ""; - let mut mask_str: &str = ""; - let mut sock: &str = ""; - let mut num_queues_str: &str = ""; - let mut queue_size_str: &str = ""; - let mut tap_str: &str = ""; + parser + .add("tap") + .add("ip") + .add("mask") + .add("queue_size") + .add("num_queues") + .add("socket"); - for param in params_list.iter() { - if param.starts_with("ip=") { - ip_str = ¶m[3..]; - } else if param.starts_with("mask=") { - mask_str = ¶m[5..]; - } else if param.starts_with("sock=") { - sock = ¶m[5..]; - } else if param.starts_with("num_queues=") { - num_queues_str = ¶m[11..]; - } else if param.starts_with("queue_size=") { - queue_size_str = ¶m[11..]; - } else if param.starts_with("tap=") { - tap_str = ¶m[4..]; - } - } + parser.parse(backend).map_err(Error::FailedConfigParse)?; - let mut ip: Ipv4Addr = Ipv4Addr::new(192, 168, 100, 1); - let mut mask: Ipv4Addr = Ipv4Addr::new(255, 255, 255, 0); - let mut num_queues: usize = 2; - let mut queue_size: u16 = 256; - let mut tap: Option<&str> = None; - - if sock.is_empty() { - return Err(Error::ParseSockParam); - } - if !ip_str.is_empty() { - ip = ip_str.parse().map_err(Error::ParseIpParam)?; - } - if !mask_str.is_empty() { - mask = mask_str.parse().map_err(Error::ParseMaskParam)?; - } - if !num_queues_str.is_empty() { - num_queues = num_queues_str.parse().map_err(Error::ParseQueueNumParam)?; - } - if !queue_size_str.is_empty() { - queue_size = queue_size_str.parse().map_err(Error::ParseQueueSizeParam)?; - } - if !tap_str.is_empty() { - tap = Some(tap_str); - } + let tap = parser.get("tap"); + let ip = parser + .convert("ip") + .map_err(Error::FailedConfigParse)? + .unwrap_or_else(|| Ipv4Addr::new(192, 168, 100, 1)); + let mask = parser + .convert("mask") + .map_err(Error::FailedConfigParse)? + .unwrap_or_else(|| Ipv4Addr::new(255, 255, 255, 0)); + let queue_size = parser + .convert("queue_size") + .map_err(Error::FailedConfigParse)? + .unwrap_or(256); + let num_queues = parser + .convert("num_queues") + .map_err(Error::FailedConfigParse)? + .unwrap_or(2); + let socket = parser.get("socket").ok_or(Error::SocketParameterMissing)?; Ok(VhostUserNetBackendConfig { ip, mask, - sock, + socket, num_queues, queue_size, tap, @@ -434,20 +411,26 @@ pub fn start_net_backend(backend_command: &str) { } }; + let tap = if let Some(tap) = backend_config.tap.as_ref() { + Some(tap.as_str()) + } else { + None + }; + let net_backend = Arc::new(RwLock::new( VhostUserNetBackend::new( backend_config.ip, backend_config.mask, backend_config.num_queues, backend_config.queue_size, - backend_config.tap, + tap, ) .unwrap(), )); let mut net_daemon = VhostUserDaemon::new( "vhost-user-net-backend".to_string(), - backend_config.sock.to_string(), + backend_config.socket.to_string(), net_backend.clone(), ) .unwrap(); diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 172a6313e..ba2d3721b 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1392,7 +1392,7 @@ impl DeviceManager { .args(&[ "--net-backend", &format!( - "ip={},mask={},sock={},num_queues={},queue_size={}", + "ip={},mask={},socket={},num_queues={},queue_size={}", net_cfg.ip, net_cfg.mask, &sock, net_cfg.num_queues, net_cfg.queue_size ), ])