mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 03:15:20 +00:00
net_util: Move virtio-net helpers to net_util crate
Moving helpers to the net_util crate since we don't want virtio-net common code to be split between two places. The net_util crate should be the only place to host virtio-net common code. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
f36b5f3e3c
commit
d7a69f8aa1
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -580,6 +580,8 @@ dependencies = [
|
||||
"rate_limiter",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"versionize",
|
||||
"versionize_derive",
|
||||
"virtio-bindings",
|
||||
"vm-memory",
|
||||
"vm-virtio",
|
||||
|
@ -11,6 +11,8 @@ log = "0.4.14"
|
||||
net_gen = { path = "../net_gen" }
|
||||
rate_limiter = { path = "../rate_limiter" }
|
||||
serde = "1.0.126"
|
||||
versionize = "0.1.6"
|
||||
versionize_derive = "0.1.4"
|
||||
virtio-bindings = "0.1.0"
|
||||
vm-memory = { version = "0.5.0", features = ["backend-mmap", "backend-atomic"] }
|
||||
vm-virtio = { path = "../vm-virtio" }
|
||||
|
@ -20,8 +20,17 @@ mod queue_pair;
|
||||
mod tap;
|
||||
|
||||
use std::io::Error as IoError;
|
||||
use std::os::raw::c_uint;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::{io, mem, net};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_bindings::bindings::virtio_net::{
|
||||
virtio_net_hdr_v1, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN,
|
||||
VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_TSO4,
|
||||
VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO, VIRTIO_NET_F_MAC, VIRTIO_NET_F_MQ,
|
||||
};
|
||||
use vm_memory::ByteValued;
|
||||
|
||||
pub use ctrl_queue::{CtrlQueue, Error as CtrlQueueError};
|
||||
pub use mac::{MacAddr, MAC_ADDR_LEN};
|
||||
@ -37,6 +46,20 @@ pub enum Error {
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Copy, Clone, Debug, Default, Versionize)]
|
||||
pub struct VirtioNetConfig {
|
||||
pub mac: [u8; 6],
|
||||
pub status: u16,
|
||||
pub max_virtqueue_pairs: u16,
|
||||
pub mtu: u16,
|
||||
pub speed: u32,
|
||||
pub duplex: u8,
|
||||
}
|
||||
|
||||
// Safe because it only has data and has no implicit padding.
|
||||
unsafe impl ByteValued for VirtioNetConfig {}
|
||||
|
||||
/// Create a sockaddr_in from an IPv4 address, and expose it as
|
||||
/// an opaque sockaddr suitable for usage by socket ioctls.
|
||||
fn create_sockaddr(ip_addr: net::Ipv4Addr) -> net_gen::sockaddr {
|
||||
@ -64,7 +87,6 @@ fn create_socket() -> Result<net::UdpSocket> {
|
||||
}
|
||||
|
||||
fn vnet_hdr_len() -> usize {
|
||||
use virtio_bindings::bindings::virtio_net::virtio_net_hdr_v1;
|
||||
std::mem::size_of::<virtio_net_hdr_v1>()
|
||||
}
|
||||
|
||||
@ -96,6 +118,53 @@ pub fn unregister_listener(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn build_net_config_space(
|
||||
mut config: &mut VirtioNetConfig,
|
||||
mac: MacAddr,
|
||||
num_queues: usize,
|
||||
mut avail_features: &mut u64,
|
||||
) {
|
||||
config.mac.copy_from_slice(mac.get_bytes());
|
||||
*avail_features |= 1 << VIRTIO_NET_F_MAC;
|
||||
|
||||
build_net_config_space_with_mq(&mut config, num_queues, &mut avail_features);
|
||||
}
|
||||
|
||||
pub fn build_net_config_space_with_mq(
|
||||
config: &mut VirtioNetConfig,
|
||||
num_queues: usize,
|
||||
avail_features: &mut u64,
|
||||
) {
|
||||
let num_queue_pairs = (num_queues / 2) as u16;
|
||||
if (num_queue_pairs >= VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16)
|
||||
&& (num_queue_pairs <= VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16)
|
||||
{
|
||||
config.max_virtqueue_pairs = num_queue_pairs;
|
||||
*avail_features |= 1 << VIRTIO_NET_F_MQ;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn virtio_features_to_tap_offload(features: u64) -> c_uint {
|
||||
let mut tap_offloads: c_uint = 0;
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_CSUM) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_CSUM;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_TSO4) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO4;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_TSO6) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO6;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_ECN) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO_ECN;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_UFO) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_UFO;
|
||||
}
|
||||
|
||||
tap_offloads
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -5,10 +5,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the THIRD-PARTY file.
|
||||
|
||||
use super::net_util::{
|
||||
build_net_config_space, build_net_config_space_with_mq, virtio_features_to_tap_offload,
|
||||
NetCtrl, NetCtrlEpollHandler, VirtioNetConfig,
|
||||
};
|
||||
use super::net_util::{NetCtrl, NetCtrlEpollHandler};
|
||||
use super::Error as DeviceError;
|
||||
use super::{
|
||||
ActivateError, ActivateResult, EpollHelper, EpollHelperError, EpollHelperHandler, Queue,
|
||||
@ -18,7 +15,9 @@ use super::{
|
||||
use crate::seccomp_filters::{get_seccomp_filter, Thread};
|
||||
use crate::VirtioInterrupt;
|
||||
use net_util::{
|
||||
open_tap, MacAddr, NetCounters, NetQueuePair, OpenTapError, RxVirtio, Tap, TapError, TxVirtio,
|
||||
build_net_config_space, build_net_config_space_with_mq, open_tap,
|
||||
virtio_features_to_tap_offload, MacAddr, NetCounters, NetQueuePair, OpenTapError, RxVirtio,
|
||||
Tap, TapError, TxVirtio, VirtioNetConfig,
|
||||
};
|
||||
use seccomp::{SeccompAction, SeccompFilter};
|
||||
use std::net::Ipv4Addr;
|
||||
|
@ -3,15 +3,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
use super::{EpollHelper, EpollHelperError, EpollHelperHandler, Queue, EPOLL_HELPER_EVENT_LAST};
|
||||
use net_util::MacAddr;
|
||||
use net_util::virtio_features_to_tap_offload;
|
||||
use net_util::Tap;
|
||||
use std::os::raw::c_uint;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, Barrier};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_bindings::bindings::virtio_net::*;
|
||||
use virtio_bindings::bindings::virtio_net::{
|
||||
VIRTIO_NET_CTRL_GUEST_OFFLOADS, VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ,
|
||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN,
|
||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_ERR, VIRTIO_NET_OK,
|
||||
};
|
||||
use vm_memory::{
|
||||
ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError, GuestMemoryMmap,
|
||||
};
|
||||
@ -24,20 +25,6 @@ const QUEUE_SIZE: usize = 256;
|
||||
// Event available on the control queue.
|
||||
const CTRL_QUEUE_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1;
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Copy, Clone, Debug, Default, Versionize)]
|
||||
pub struct VirtioNetConfig {
|
||||
pub mac: [u8; 6],
|
||||
pub status: u16,
|
||||
pub max_virtqueue_pairs: u16,
|
||||
pub mtu: u16,
|
||||
pub speed: u32,
|
||||
pub duplex: u8,
|
||||
}
|
||||
|
||||
// Safe because it only has data and has no implicit padding.
|
||||
unsafe impl ByteValued for VirtioNetConfig {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Read queue failed.
|
||||
@ -195,50 +182,3 @@ impl EpollHelperHandler for NetCtrlEpollHandler {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_net_config_space(
|
||||
mut config: &mut VirtioNetConfig,
|
||||
mac: MacAddr,
|
||||
num_queues: usize,
|
||||
mut avail_features: &mut u64,
|
||||
) {
|
||||
config.mac.copy_from_slice(mac.get_bytes());
|
||||
*avail_features |= 1 << VIRTIO_NET_F_MAC;
|
||||
|
||||
build_net_config_space_with_mq(&mut config, num_queues, &mut avail_features);
|
||||
}
|
||||
|
||||
pub fn build_net_config_space_with_mq(
|
||||
config: &mut VirtioNetConfig,
|
||||
num_queues: usize,
|
||||
avail_features: &mut u64,
|
||||
) {
|
||||
let num_queue_pairs = (num_queues / 2) as u16;
|
||||
if (num_queue_pairs >= VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16)
|
||||
&& (num_queue_pairs <= VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16)
|
||||
{
|
||||
config.max_virtqueue_pairs = num_queue_pairs;
|
||||
*avail_features |= 1 << VIRTIO_NET_F_MQ;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn virtio_features_to_tap_offload(features: u64) -> c_uint {
|
||||
let mut tap_offloads: c_uint = 0;
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_CSUM) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_CSUM;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_TSO4) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO4;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_TSO6) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO6;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_ECN) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_TSO_ECN;
|
||||
}
|
||||
if features & (1 << VIRTIO_NET_F_GUEST_UFO) != 0 {
|
||||
tap_offloads |= net_gen::TUN_F_UFO;
|
||||
}
|
||||
|
||||
tap_offloads
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
// Copyright 2019 Intel Corporation. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::super::net_util::{build_net_config_space, VirtioNetConfig};
|
||||
use super::super::{
|
||||
ActivateError, ActivateResult, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType,
|
||||
};
|
||||
use super::vu_common_ctrl::*;
|
||||
use super::{Error, Result};
|
||||
use crate::VirtioInterrupt;
|
||||
use net_util::MacAddr;
|
||||
use net_util::{build_net_config_space, MacAddr, VirtioNetConfig};
|
||||
use std::ops::Deref;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::os::unix::net::UnixListener;
|
||||
|
Loading…
Reference in New Issue
Block a user