vmm: Add vhost-user-net support

Update vm configuration and device initial process to add
vhost-user-net support.

Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
This commit is contained in:
Cathy Zhang
2019-08-28 18:01:01 +08:00
committed by Rob Bradford
parent 633f51af9c
commit 584a2cccee
2 changed files with 126 additions and 0 deletions

View File

@@ -3,6 +3,8 @@
// SPDX-License-Identifier: Apache-2.0
//
extern crate vm_virtio;
use linux_loader::cmdline::Cmdline;
use net_util::MacAddr;
use std::convert::From;
@@ -11,6 +13,7 @@ use std::net::Ipv4Addr;
use std::path::Path;
use std::result;
use vm_memory::GuestAddress;
use vm_virtio::vhost_user::VhostUserConfig;
pub const DEFAULT_VCPUS: &str = "1";
pub const DEFAULT_MEMORY: &str = "size=512M";
@@ -58,6 +61,16 @@ pub enum Error<'a> {
ParseConsoleParam,
/// Both console and serial are tty.
ParseTTYParam,
/// Failed parsing vhost-user-net mac parameter.
ParseVuNetMacParam(&'a str),
/// Failed parsing vhost-user-net sock parameter.
ParseVuNetSockParam,
/// Failed parsing vhost-user-net queue number parameter.
ParseVuNetNumQueuesParam(std::num::ParseIntError),
/// Failed parsing vhost-user-net queue size parameter.
ParseVuNetQueueSizeParam(std::num::ParseIntError),
/// Failed parsing vhost-user-net server parameter.
ParseVuNetServerParam(std::num::ParseIntError),
}
pub type Result<'a, T> = result::Result<T, Error<'a>>;
@@ -74,6 +87,7 @@ pub struct VmParams<'a> {
pub serial: &'a str,
pub console: &'a str,
pub devices: Option<Vec<&'a str>>,
pub vhost_user_net: Option<Vec<&'a str>>,
}
fn parse_size(size: &str) -> Result<u64> {
@@ -441,6 +455,64 @@ impl<'a> DeviceConfig<'a> {
}
}
pub struct VhostUserNetConfig<'a> {
pub mac: MacAddr,
pub vu_cfg: VhostUserConfig<'a>,
}
impl<'a> VhostUserNetConfig<'a> {
pub fn parse(vhost_user_net: &'a str) -> Result<Self> {
// Split the parameters based on the comma delimiter
let params_list: Vec<&str> = vhost_user_net.split(',').collect();
let mut mac_str: &str = "";
let mut sock: &str = "";
let mut num_queues_str: &str = "";
let mut queue_size_str: &str = "";
for param in params_list.iter() {
if param.starts_with("mac=") {
mac_str = &param[4..];
} 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..];
}
}
let mut mac: MacAddr = MacAddr::local_random();
let mut num_queues: usize = 2;
let mut queue_size: u16 = 256;
if !mac_str.is_empty() {
mac = MacAddr::parse_str(mac_str).map_err(Error::ParseVuNetMacParam)?;
}
if sock.is_empty() {
return Err(Error::ParseVuNetSockParam);
}
if !num_queues_str.is_empty() {
num_queues = num_queues_str
.parse()
.map_err(Error::ParseVuNetNumQueuesParam)?;
}
if !queue_size_str.is_empty() {
queue_size = queue_size_str
.parse()
.map_err(Error::ParseVuNetQueueSizeParam)?;
}
let vu_cfg = VhostUserConfig {
sock,
num_queues,
queue_size,
};
Ok(VhostUserNetConfig { mac, vu_cfg })
}
}
pub struct VmConfig<'a> {
pub cpus: CpusConfig,
pub memory: MemoryConfig<'a>,
@@ -454,6 +526,7 @@ pub struct VmConfig<'a> {
pub serial: ConsoleConfig<'a>,
pub console: ConsoleConfig<'a>,
pub devices: Option<Vec<DeviceConfig<'a>>>,
pub vhost_user_net: Option<Vec<VhostUserNetConfig<'a>>>,
}
impl<'a> VmConfig<'a> {
@@ -509,6 +582,15 @@ impl<'a> VmConfig<'a> {
devices = Some(device_config_list);
}
let mut vhost_user_net: Option<Vec<VhostUserNetConfig>> = None;
if let Some(vhost_user_net_list) = &vm_params.vhost_user_net {
let mut vhost_user_net_config_list = Vec::new();
for item in vhost_user_net_list.iter() {
vhost_user_net_config_list.push(VhostUserNetConfig::parse(item)?);
}
vhost_user_net = Some(vhost_user_net_config_list);
}
Ok(VmConfig {
cpus: CpusConfig::parse(vm_params.cpus)?,
memory: MemoryConfig::parse(vm_params.memory)?,
@@ -522,6 +604,7 @@ impl<'a> VmConfig<'a> {
serial,
console,
devices,
vhost_user_net,
})
}
}