Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce VirtIONetRaw to allow custom NIC buffer management and used buffer notification suppression #111

Merged
merged 14 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion examples/aarch64/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use virtio_drivers::{
blk::VirtIOBlk,
console::VirtIOConsole,
gpu::VirtIOGpu,
net::VirtIONetRaw,
socket::{
VirtIOSocket, VsockAddr, VsockConnectionManager, VsockEventType, VMADDR_CID_HOST,
},
Expand Down Expand Up @@ -137,7 +138,7 @@ fn virtio_device(transport: impl Transport) {
match transport.device_type() {
DeviceType::Block => virtio_blk(transport),
DeviceType::GPU => virtio_gpu(transport),
// DeviceType::Network => virtio_net(transport), // currently is unsupported without alloc
DeviceType::Network => virtio_net(transport),
DeviceType::Console => virtio_console(transport),
DeviceType::Socket => match virtio_socket(transport) {
Ok(()) => info!("virtio-socket test finished successfully"),
Expand Down Expand Up @@ -192,6 +193,20 @@ fn virtio_gpu<T: Transport>(transport: T) {
info!("virtio-gpu test finished");
}

fn virtio_net<T: Transport>(transport: T) {
let mut net =
VirtIONetRaw::<HalImpl, T, 16>::new(transport).expect("failed to create net driver");
let mut buf = [0u8; 2048];
let (hdr_len, pkt_len) = net.receive_wait(&mut buf).expect("failed to recv");
info!(
"recv {} bytes: {:02x?}",
pkt_len,
&buf[hdr_len..hdr_len + pkt_len]
);
net.send(&buf[..hdr_len + pkt_len]).expect("failed to send");
info!("virtio-net test finished");
}

fn virtio_console<T: Transport>(transport: T) {
let mut console =
VirtIOConsole::<HalImpl, T>::new(transport).expect("Failed to create console driver");
Expand Down
45 changes: 24 additions & 21 deletions examples/riscv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use core::ptr::NonNull;
use fdt::{node::FdtNode, standard_nodes::Compatible, Fdt};
use log::LevelFilter;
use virtio_drivers::{
device::{blk::VirtIOBlk, gpu::VirtIOGpu, input::VirtIOInput, net::VirtIONet},
device::{blk::VirtIOBlk, gpu::VirtIOGpu, input::VirtIOInput},
transport::{
mmio::{MmioTransport, VirtIOHeader},
DeviceType, Transport,
Expand All @@ -26,7 +26,6 @@ mod virtio_impl;
#[cfg(feature = "tcp")]
mod tcp;

const NET_BUFFER_LEN: usize = 2048;
const NET_QUEUE_SIZE: usize = 16;

#[no_mangle]
Expand Down Expand Up @@ -146,29 +145,33 @@ fn virtio_input<T: Transport>(transport: T) {
}

fn virtio_net<T: Transport>(transport: T) {
let net = VirtIONet::<HalImpl, T, NET_QUEUE_SIZE>::new(transport, NET_BUFFER_LEN)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());

#[cfg(not(feature = "tcp"))]
{
let mut net = net;
loop {
match net.receive() {
Ok(buf) => {
info!("RECV {} bytes: {:02x?}", buf.packet_len(), buf.packet());
let tx_buf = virtio_drivers::device::net::TxBuffer::from(buf.packet());
net.send(tx_buf).expect("failed to send");
net.recycle_rx_buffer(buf).unwrap();
break;
}
Err(virtio_drivers::Error::NotReady) => continue,
Err(err) => panic!("failed to recv: {:?}", err),
}
}
let mut net =
virtio_drivers::device::net::VirtIONetRaw::<HalImpl, T, NET_QUEUE_SIZE>::new(transport)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());

let mut buf = [0u8; 2048];
let (hdr_len, pkt_len) = net.receive_wait(&mut buf).expect("failed to recv");
info!(
"recv {} bytes: {:02x?}",
pkt_len,
&buf[hdr_len..hdr_len + pkt_len]
);
net.send(&buf[..hdr_len + pkt_len]).expect("failed to send");
info!("virtio-net test finished");
}

#[cfg(feature = "tcp")]
tcp::test_echo_server(net);
{
const NET_BUFFER_LEN: usize = 2048;
let net = virtio_drivers::device::net::VirtIONet::<HalImpl, T, NET_QUEUE_SIZE>::new(
transport,
NET_BUFFER_LEN,
)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());
tcp::test_echo_server(net);
}
}
4 changes: 2 additions & 2 deletions examples/riscv/src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use smoltcp::iface::{Config, Interface, SocketSet};
use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use smoltcp::{socket::tcp, time::Instant};
use virtio_drivers::device::net::{RxBuffer, VirtIONet};
use virtio_drivers::device::net::{NetBuffer, VirtIONet};
use virtio_drivers::{transport::Transport, Error};

use super::{HalImpl, NET_QUEUE_SIZE};
Expand Down Expand Up @@ -64,7 +64,7 @@ impl<T: Transport> Device for DeviceWrapper<T> {
}
}

struct VirtioRxToken<T: Transport>(Rc<RefCell<DeviceImpl<T>>>, RxBuffer);
struct VirtioRxToken<T: Transport>(Rc<RefCell<DeviceImpl<T>>>, NetBuffer);
struct VirtioTxToken<T: Transport>(Rc<RefCell<DeviceImpl<T>>>);

impl<T: Transport> RxToken for VirtioRxToken<T> {
Expand Down
7 changes: 1 addition & 6 deletions examples/x86_64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ target := x86_64-unknown-none
mode := release
kernel := target/$(target)/$(mode)/$(arch)
img := target/$(target)/$(mode)/img
accel := on
accel ?= on
tcp ?= off

sysroot := $(shell rustc --print sysroot)
Expand All @@ -20,11 +20,6 @@ else
BUILD_ARGS += --no-default-features
endif

VSOCK_BUILD_ARGS =
ifeq ($(mode), release)
VSOCK_BUILD_ARGS += --release
endif

QEMU_ARGS += \
-machine q35 \
-serial mon:stdio \
Expand Down
45 changes: 24 additions & 21 deletions examples/x86_64/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod tcp;

use self::hal::HalImpl;
use virtio_drivers::{
device::{blk::VirtIOBlk, gpu::VirtIOGpu, net::VirtIONet},
device::{blk::VirtIOBlk, gpu::VirtIOGpu},
transport::{
pci::{
bus::{BarInfo, Cam, Command, DeviceFunction, PciRoot},
Expand All @@ -35,7 +35,6 @@ use virtio_drivers::{
/// TODO: get it from ACPI MCFG table.
const MMCONFIG_BASE: usize = 0xB000_0000;

const NET_BUFFER_LEN: usize = 2048;
const NET_QUEUE_SIZE: usize = 16;

fn system_off() -> ! {
Expand Down Expand Up @@ -117,31 +116,35 @@ fn virtio_gpu<T: Transport>(transport: T) {
}

fn virtio_net<T: Transport>(transport: T) {
let net = VirtIONet::<HalImpl, T, NET_QUEUE_SIZE>::new(transport, NET_BUFFER_LEN)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());

#[cfg(not(feature = "tcp"))]
{
let mut net = net;
loop {
match net.receive() {
Ok(buf) => {
info!("RECV {} bytes: {:02x?}", buf.packet_len(), buf.packet());
let tx_buf = virtio_drivers::device::net::TxBuffer::from(buf.packet());
net.send(tx_buf).expect("failed to send");
net.recycle_rx_buffer(buf).unwrap();
break;
}
Err(virtio_drivers::Error::NotReady) => continue,
Err(err) => panic!("failed to recv: {:?}", err),
}
}
let mut net =
virtio_drivers::device::net::VirtIONetRaw::<HalImpl, T, NET_QUEUE_SIZE>::new(transport)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());

let mut buf = [0u8; 2048];
let (hdr_len, pkt_len) = net.receive_wait(&mut buf).expect("failed to recv");
info!(
"recv {} bytes: {:02x?}",
pkt_len,
&buf[hdr_len..hdr_len + pkt_len]
);
net.send(&buf[..hdr_len + pkt_len]).expect("failed to send");
info!("virtio-net test finished");
}

#[cfg(feature = "tcp")]
tcp::test_echo_server(net);
{
const NET_BUFFER_LEN: usize = 2048;
let net = virtio_drivers::device::net::VirtIONet::<HalImpl, T, NET_QUEUE_SIZE>::new(
transport,
NET_BUFFER_LEN,
)
.expect("failed to create net driver");
info!("MAC address: {:02x?}", net.mac_address());
tcp::test_echo_server(net);
}
}

fn enumerate_pci(mmconfig_base: *mut u8) {
Expand Down
4 changes: 2 additions & 2 deletions examples/x86_64/src/tcp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Simple echo server over TCP.
//!
//! Ref: https://github.com/smoltcp-rs/smoltcp/blob/master/examples/server.rs
//! Ref: <https://github.com/smoltcp-rs/smoltcp/blob/master/examples/server.rs>

use alloc::{borrow::ToOwned, rc::Rc, vec, vec::Vec};
use core::{cell::RefCell, str::FromStr};
Expand Down Expand Up @@ -93,7 +93,7 @@ impl<T: Transport> TxToken for VirtioTxToken<T> {
let mut tx_buf = dev.new_tx_buffer(len);
let result = f(tx_buf.packet_mut());
trace!("SEND {} bytes: {:02X?}", len, tx_buf.packet());
dev.send(tx_buf).unwrap();
dev.transmit(tx_buf).unwrap();
result
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ pub mod console;
pub mod gpu;
#[cfg(feature = "alloc")]
pub mod input;
#[cfg(feature = "alloc")]

pub mod net;

pub mod socket;

pub(crate) mod common;
Loading
Loading