virtio-devices, vmm: vhost: net: Add client mode support

Adding the support for an OVS vhost-user backend to connect as the
vhost-user client. This means we introduce with this patch a new
option to our `--net` parameter. This option is called 'server' in order
to ask the VMM to run as the server for the vhost-user socket.

Fixes #1745

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2021-05-04 10:33:35 +02:00
parent 656b9f97f9
commit b5c6b04b36
5 changed files with 80 additions and 7 deletions

View File

@@ -24,10 +24,14 @@ pub use self::vu_common_ctrl::VhostUserConfig;
#[derive(Debug)]
pub enum Error {
/// Failed accepting connection.
AcceptConnection(io::Error),
/// Invalid available address.
AvailAddress,
/// Queue number is not correct
BadQueueNum,
/// Failed binding vhost-user socket.
BindSocket(io::Error),
/// Creating kill eventfd failed.
CreateKillEventFd(io::Error),
/// Cloning kill eventfd failed.

View File

@@ -16,6 +16,7 @@ use net_util::MacAddr;
use seccomp::{SeccompAction, SeccompFilter};
use std::ops::Deref;
use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixListener;
use std::result;
use std::sync::{Arc, Barrier};
use std::thread;
@@ -46,6 +47,7 @@ pub struct Net {
seccomp_action: SeccompAction,
guest_memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
acked_protocol_features: u64,
socket_path: Option<String>,
}
impl Net {
@@ -56,9 +58,23 @@ impl Net {
mac_addr: MacAddr,
vu_cfg: VhostUserConfig,
seccomp_action: SeccompAction,
server: bool,
) -> Result<Net> {
let mut vhost_user_net = Master::connect(&vu_cfg.socket, vu_cfg.num_queues as u64)
.map_err(Error::VhostUserCreateMaster)?;
let mut socket_path: Option<String> = None;
let mut vhost_user_net = if server {
info!("Binding vhost-user-net listener...");
let listener = UnixListener::bind(&vu_cfg.socket).map_err(Error::BindSocket)?;
info!("Waiting for incoming vhost-user-net connection...");
let (stream, _) = listener.accept().map_err(Error::AcceptConnection)?;
socket_path = Some(vu_cfg.socket.clone());
Master::from_stream(stream, vu_cfg.num_queues as u64)
} else {
Master::connect(&vu_cfg.socket, vu_cfg.num_queues as u64)
.map_err(Error::VhostUserCreateMaster)?
};
// Filling device and vring features VMM supports.
let mut avail_features = 1 << virtio_net::VIRTIO_NET_F_GUEST_CSUM
@@ -166,6 +182,7 @@ impl Net {
seccomp_action,
guest_memory: None,
acked_protocol_features,
socket_path,
})
}
}
@@ -368,6 +385,11 @@ impl VirtioDevice for Net {
fn shutdown(&mut self) {
let _ = unsafe { libc::close(self.vhost_user_net.as_raw_fd()) };
// Remove socket path if needed
if let Some(socket_path) = &self.socket_path {
let _ = std::fs::remove_file(socket_path);
}
}
fn add_memory_region(