vmm: Add support for multiple virtio-net devices

Until now, the VMM was only accepting a single instance of virtio-net
device. This commit extends the virtio-net support by allowing several
devices to be created for a single VM.

Fixes #71

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2019-07-08 15:31:13 -07:00
committed by Rob Bradford
parent a2947f9a9f
commit f0a76ad424
4 changed files with 103 additions and 42 deletions

View File

@@ -59,7 +59,7 @@ pub struct VmParams<'a> {
pub kernel: &'a str,
pub cmdline: Option<&'a str>,
pub disks: Vec<&'a str>,
pub net: Option<&'a str>,
pub net: Option<Vec<&'a str>>,
pub rng: &'a str,
pub fs: Option<Vec<&'a str>>,
pub pmem: Option<Vec<&'a str>>,
@@ -192,13 +192,9 @@ pub struct NetConfig<'a> {
}
impl<'a> NetConfig<'a> {
pub fn parse(net: Option<&'a str>) -> Result<Option<Self>> {
if net.is_none() {
return Ok(None);
}
pub fn parse(net: &'a str) -> Result<Self> {
// Split the parameters based on the comma delimiter
let params_list: Vec<&str> = net.unwrap().split(',').collect();
let params_list: Vec<&str> = net.split(',').collect();
let mut tap_str: &str = "";
let mut ip_str: &str = "";
@@ -235,7 +231,7 @@ impl<'a> NetConfig<'a> {
mac = MacAddr::parse_str(mac_str).map_err(Error::ParseNetMacParam)?;
}
Ok(Some(NetConfig { tap, ip, mask, mac }))
Ok(NetConfig { tap, ip, mask, mac })
}
}
@@ -348,7 +344,7 @@ pub struct VmConfig<'a> {
pub kernel: KernelConfig<'a>,
pub cmdline: CmdlineConfig,
pub disks: Vec<DiskConfig<'a>>,
pub net: Option<NetConfig<'a>>,
pub net: Option<Vec<NetConfig<'a>>>,
pub rng: RngConfig<'a>,
pub fs: Option<Vec<FsConfig<'a>>>,
pub pmem: Option<Vec<PmemConfig<'a>>>,
@@ -361,6 +357,15 @@ impl<'a> VmConfig<'a> {
disks.push(DiskConfig::parse(disk)?);
}
let mut net: Option<Vec<NetConfig>> = None;
if let Some(net_list) = &vm_params.net {
let mut net_config_list = Vec::new();
for item in net_list.iter() {
net_config_list.push(NetConfig::parse(item)?);
}
net = Some(net_config_list);
}
let mut fs: Option<Vec<FsConfig>> = None;
if let Some(fs_list) = &vm_params.fs {
let mut fs_config_list = Vec::new();
@@ -385,7 +390,7 @@ impl<'a> VmConfig<'a> {
kernel: KernelConfig::parse(vm_params.kernel)?,
cmdline: CmdlineConfig::parse(vm_params.cmdline)?,
disks,
net: NetConfig::parse(vm_params.net)?,
net,
rng: RngConfig::parse(vm_params.rng)?,
fs,
pmem,

View File

@@ -567,28 +567,30 @@ impl DeviceManager {
}
// Add virtio-net if required
if let Some(net_cfg) = &vm_cfg.net {
let mut virtio_net_device: vm_virtio::Net;
if let Some(net_list_cfg) = &vm_cfg.net {
for net_cfg in net_list_cfg.iter() {
let mut virtio_net_device: vm_virtio::Net;
if let Some(tap_if_name) = net_cfg.tap {
let tap = Tap::open_named(tap_if_name).map_err(DeviceManagerError::OpenTap)?;
virtio_net_device = vm_virtio::Net::new_with_tap(tap, Some(&net_cfg.mac))
.map_err(DeviceManagerError::CreateVirtioNet)?;
} else {
virtio_net_device =
vm_virtio::Net::new(net_cfg.ip, net_cfg.mask, Some(&net_cfg.mac))
if let Some(tap_if_name) = net_cfg.tap {
let tap = Tap::open_named(tap_if_name).map_err(DeviceManagerError::OpenTap)?;
virtio_net_device = vm_virtio::Net::new_with_tap(tap, Some(&net_cfg.mac))
.map_err(DeviceManagerError::CreateVirtioNet)?;
}
} else {
virtio_net_device =
vm_virtio::Net::new(net_cfg.ip, net_cfg.mask, Some(&net_cfg.mac))
.map_err(DeviceManagerError::CreateVirtioNet)?;
}
DeviceManager::add_virtio_pci_device(
Box::new(virtio_net_device),
memory.clone(),
allocator,
vm_fd,
&mut pci,
&mut mmio_bus,
&interrupt_info,
)?;
DeviceManager::add_virtio_pci_device(
Box::new(virtio_net_device),
memory.clone(),
allocator,
vm_fd,
&mut pci,
&mut mmio_bus,
&interrupt_info,
)?;
}
}
// Add virtio-rng if required