vhost_user_net: Use config::OptionParser to simplify net backend parsing

Switch to using the recently added OptionParser in the code that parses
the network backend.

Whilst doing this also update the net-backend syntax to use "sock"
rather than socket.

Fixes: #1092
Partially fixes: #1091

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2020-05-08 16:43:56 +01:00
committed by Sebastien Boeuf
parent f3f398eb44
commit 592de97fbd
5 changed files with 53 additions and 68 deletions
Generated
+1
View File
@@ -1415,6 +1415,7 @@ dependencies = [
"virtio-bindings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "virtio-bindings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vm-memory", "vm-memory",
"vm-virtio", "vm-virtio",
"vmm",
"vmm-sys-util", "vmm-sys-util",
] ]
+2 -2
View File
@@ -444,12 +444,12 @@ mod tests {
// Start the daemon // Start the daemon
let net_params = if let Some(tap_str) = tap { let net_params = if let Some(tap_str) = tap {
format!( 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 tap_str, ip, vunet_socket_path, num_queues
) )
} else { } else {
format!( 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 ip, vunet_socket_path, num_queues
) )
}; };
+1
View File
@@ -15,4 +15,5 @@ vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragon
virtio-bindings = "0.1.0" virtio-bindings = "0.1.0"
vm-memory = "0.2.0" vm-memory = "0.2.0"
vm-virtio = { path = "../vm-virtio" } vm-virtio = { path = "../vm-virtio" }
vmm = { path = "../vmm" }
vmm-sys-util = ">=0.3.1" vmm-sys-util = ">=0.3.1"
+48 -65
View File
@@ -11,6 +11,7 @@ extern crate net_util;
extern crate vhost_rs; extern crate vhost_rs;
extern crate vhost_user_backend; extern crate vhost_user_backend;
extern crate vm_virtio; extern crate vm_virtio;
extern crate vmm;
use epoll; use epoll;
use libc::{self, EAGAIN, EFD_NONBLOCK}; use libc::{self, EAGAIN, EFD_NONBLOCK};
@@ -31,6 +32,7 @@ use virtio_bindings::bindings::virtio_net::*;
use vm_memory::GuestMemoryMmap; use vm_memory::GuestMemoryMmap;
use vm_virtio::net_util::{open_tap, RxVirtio, TxVirtio}; use vm_virtio::net_util::{open_tap, RxVirtio, TxVirtio};
use vm_virtio::Queue; use vm_virtio::Queue;
use vmm::config::{OptionParser, OptionParserError};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
pub type VhostUserResult<T> = std::result::Result<T, VhostUserError>; pub type VhostUserResult<T> = std::result::Result<T, VhostUserError>;
@@ -51,6 +53,8 @@ pub enum Error {
EpollCreateFd, EpollCreateFd,
/// Failed to read Tap. /// Failed to read Tap.
FailedReadTap, FailedReadTap,
/// Failed to parse configuration string
FailedConfigParse(OptionParserError),
/// Failed to signal used queue. /// Failed to signal used queue.
FailedSignalingUsedQueue, FailedSignalingUsedQueue,
/// Failed to handle event other than input event. /// Failed to handle event other than input event.
@@ -63,22 +67,14 @@ pub enum Error {
NoVringCallFdNotify, NoVringCallFdNotify,
/// No memory configured. /// No memory configured.
NoMemoryConfigured, 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. /// Open tap device failed.
OpenTap(vm_virtio::net_util::Error), OpenTap(vm_virtio::net_util::Error),
/// No socket provided
SocketParameterMissing,
} }
pub const SYNTAX: &str = "vhost-user-net backend parameters \ pub const SYNTAX: &str = "vhost-user-net backend parameters \
\"ip=<ip_addr>,mask=<net_mask>,sock=<socket_path>,\ \"ip=<ip_addr>,mask=<net_mask>,socket=<socket_path>,\
num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,tap=<if_name>\""; num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,tap=<if_name>\"";
impl fmt::Display for Error { impl fmt::Display for Error {
@@ -353,71 +349,52 @@ impl VhostUserBackend for VhostUserNetBackend {
} }
} }
pub struct VhostUserNetBackendConfig<'a> { pub struct VhostUserNetBackendConfig {
pub ip: Ipv4Addr, pub ip: Ipv4Addr,
pub mask: Ipv4Addr, pub mask: Ipv4Addr,
pub sock: &'a str, pub socket: String,
pub num_queues: usize, pub num_queues: usize,
pub queue_size: u16, pub queue_size: u16,
pub tap: Option<&'a str>, pub tap: Option<String>,
} }
impl<'a> VhostUserNetBackendConfig<'a> { impl VhostUserNetBackendConfig {
pub fn parse(backend: &'a str) -> Result<Self> { pub fn parse(backend: &str) -> Result<Self> {
let params_list: Vec<&str> = backend.split(',').collect(); let mut parser = OptionParser::new();
let mut ip_str: &str = ""; parser
let mut mask_str: &str = ""; .add("tap")
let mut sock: &str = ""; .add("ip")
let mut num_queues_str: &str = ""; .add("mask")
let mut queue_size_str: &str = ""; .add("queue_size")
let mut tap_str: &str = ""; .add("num_queues")
.add("socket");
for param in params_list.iter() { parser.parse(backend).map_err(Error::FailedConfigParse)?;
if param.starts_with("ip=") {
ip_str = &param[3..];
} else if param.starts_with("mask=") {
mask_str = &param[5..];
} else if param.starts_with("sock=") {
sock = &param[5..];
} else if param.starts_with("num_queues=") {
num_queues_str = &param[11..];
} else if param.starts_with("queue_size=") {
queue_size_str = &param[11..];
} else if param.starts_with("tap=") {
tap_str = &param[4..];
}
}
let mut ip: Ipv4Addr = Ipv4Addr::new(192, 168, 100, 1); let tap = parser.get("tap");
let mut mask: Ipv4Addr = Ipv4Addr::new(255, 255, 255, 0); let ip = parser
let mut num_queues: usize = 2; .convert("ip")
let mut queue_size: u16 = 256; .map_err(Error::FailedConfigParse)?
let mut tap: Option<&str> = None; .unwrap_or_else(|| Ipv4Addr::new(192, 168, 100, 1));
let mask = parser
if sock.is_empty() { .convert("mask")
return Err(Error::ParseSockParam); .map_err(Error::FailedConfigParse)?
} .unwrap_or_else(|| Ipv4Addr::new(255, 255, 255, 0));
if !ip_str.is_empty() { let queue_size = parser
ip = ip_str.parse().map_err(Error::ParseIpParam)?; .convert("queue_size")
} .map_err(Error::FailedConfigParse)?
if !mask_str.is_empty() { .unwrap_or(256);
mask = mask_str.parse().map_err(Error::ParseMaskParam)?; let num_queues = parser
} .convert("num_queues")
if !num_queues_str.is_empty() { .map_err(Error::FailedConfigParse)?
num_queues = num_queues_str.parse().map_err(Error::ParseQueueNumParam)?; .unwrap_or(2);
} let socket = parser.get("socket").ok_or(Error::SocketParameterMissing)?;
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);
}
Ok(VhostUserNetBackendConfig { Ok(VhostUserNetBackendConfig {
ip, ip,
mask, mask,
sock, socket,
num_queues, num_queues,
queue_size, queue_size,
tap, 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( let net_backend = Arc::new(RwLock::new(
VhostUserNetBackend::new( VhostUserNetBackend::new(
backend_config.ip, backend_config.ip,
backend_config.mask, backend_config.mask,
backend_config.num_queues, backend_config.num_queues,
backend_config.queue_size, backend_config.queue_size,
backend_config.tap, tap,
) )
.unwrap(), .unwrap(),
)); ));
let mut net_daemon = VhostUserDaemon::new( let mut net_daemon = VhostUserDaemon::new(
"vhost-user-net-backend".to_string(), "vhost-user-net-backend".to_string(),
backend_config.sock.to_string(), backend_config.socket.to_string(),
net_backend.clone(), net_backend.clone(),
) )
.unwrap(); .unwrap();
+1 -1
View File
@@ -1392,7 +1392,7 @@ impl DeviceManager {
.args(&[ .args(&[
"--net-backend", "--net-backend",
&format!( &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 net_cfg.ip, net_cfg.mask, &sock, net_cfg.num_queues, net_cfg.queue_size
), ),
]) ])