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

add loopback #138

Merged
merged 1 commit into from
Aug 22, 2024
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
7 changes: 6 additions & 1 deletion apps/c/httpclient/expect_info.out
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ Initialize platform devices...
Initialize device drivers...
registered a new Net device at .\+: "virtio-net"
Initialize network subsystem...
use NIC 0: "virtio-net"
net stack: smoltcp
use NIC: "loopback"
created net interface "loopback":
ether: 00-00-00-00-00-00
ip: 127.0.0.1/24
use NIC: "virtio-net"
created net interface "eth0":
ether: 52-54-00-12-34-56
ip: 10.0.2.15/24
Expand Down
1 change: 1 addition & 0 deletions crates/driver_net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ documentation = "https://rcore-os.github.io/arceos/driver_net/index.html"

[features]
default = []
loopback = []
ixgbe = ["dep:ixgbe-driver"]

[dependencies]
Expand Down
3 changes: 3 additions & 0 deletions crates/driver_net/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ use alloc::sync::Arc;
#[cfg(feature = "ixgbe")]
/// ixgbe NIC device driver.
pub mod ixgbe;
#[cfg(feature = "loopback")]
/// loopback device driver
pub mod loopback;
mod net_buf;

use core::ptr::NonNull;
Expand Down
131 changes: 131 additions & 0 deletions crates/driver_net/src/loopback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Ruxos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
use crate::{EthernetAddress, NetBuf, NetBufBox, NetBufPool, NetBufPtr, NetDriverOps};
use alloc::collections::VecDeque;
use alloc::sync::Arc;
use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType};

extern crate alloc;

const NET_BUF_LEN: usize = 1526;

/// The VirtIO network device driver.
///
/// `QS` is the VirtIO queue size.
pub struct LoopbackDevice {
mac_address: EthernetAddress,
pub(crate) queue: VecDeque<NetBufBox>,
buf_pool: Arc<NetBufPool>,
}

unsafe impl Send for LoopbackDevice {}
unsafe impl Sync for LoopbackDevice {}

impl LoopbackDevice {
/// Creates a new driver instance and initializes the device
pub fn new(mac_address: Option<[u8; 6]>) -> Self {
let buf_pool = match NetBufPool::new(1024, NET_BUF_LEN) {
Ok(pool) => pool,
Err(_) => {
panic!("fail to create netbufpool");
}
};
Self {
mac_address: match mac_address {
Some(address) => EthernetAddress(address),
None => EthernetAddress([0; 6]),
},
queue: VecDeque::new(),
buf_pool: buf_pool,
}
}
}

impl BaseDriverOps for LoopbackDevice {
fn device_name(&self) -> &str {
"loopback"
}

fn device_type(&self) -> DeviceType {
DeviceType::Net
}
}

use log::info;

impl NetDriverOps for LoopbackDevice {
#[inline]
fn mac_address(&self) -> EthernetAddress {
EthernetAddress(self.mac_address.0)
}

#[inline]
fn can_transmit(&self) -> bool {
true
}

#[inline]
fn can_receive(&self) -> bool {
!self.queue.is_empty()
}

#[inline]
fn rx_queue_size(&self) -> usize {
self.queue.len()
}

#[inline]
fn tx_queue_size(&self) -> usize {
self.queue.len()
}

fn fill_rx_buffers(&mut self, buf_pool: &Arc<NetBufPool>) -> DevResult {
Ok(())
}

fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult {
Ok(())
}

fn recycle_tx_buffers(&mut self) -> DevResult {
Ok(())
}

fn prepare_tx_buffer(&self, tx_buf: &mut NetBuf, pkt_len: usize) -> DevResult {
Ok(())
}

fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult {
unsafe { self.queue.push_back(NetBuf::from_buf_ptr(tx_buf)) }
Ok(())
}

fn receive(&mut self) -> DevResult<NetBufPtr> {
if let Some(token) = self.queue.pop_front() {
Ok(token.into_buf_ptr())
} else {
Err(DevError::Again)
}
}

fn alloc_tx_buffer(&mut self, size: usize) -> DevResult<NetBufPtr> {
let mut net_buf = self.buf_pool.alloc_boxed().ok_or(DevError::NoMemory)?;
let pkt_len = size;

// 1. Check if the buffer is large enough.
let hdr_len = net_buf.header_len();
if hdr_len + pkt_len > net_buf.capacity() {
return Err(DevError::InvalidParam);
}
net_buf.set_packet_len(pkt_len);

// 2. Return the buffer.
Ok(net_buf.into_buf_ptr())
}
}
5 changes: 1 addition & 4 deletions crates/lwip_rust/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::path::PathBuf;

fn main() {
println!("cargo:rustc-link-lib=lwip");
println!("cargo:rerun-if-changed=custom");
Expand Down Expand Up @@ -28,9 +26,8 @@ fn generate_lwip_bindings() {
.generate()
.expect("Unable to generate bindings");

let out_path = PathBuf::from("src");
bindings
.write_to_file(out_path.join("bindings.rs"))
.write_to_file("src/bindings.rs")
.expect("Couldn't write bindings!");
}

Expand Down
4 changes: 2 additions & 2 deletions crates/lwip_rust/custom/lwipopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#define LWIP_TCP 1
#define LWIP_CALLBACK_API 1
#define LWIP_NETIF_API 0
#define LWIP_NETIF_LOOPBACK 0
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_HAVE_LOOPIF 0
#define LWIP_HAVE_SLIPIF 0
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
Expand Down
1 change: 1 addition & 0 deletions modules/ruxdriver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ virtio-9p = ["_9p","virtio", "driver_virtio/v9p"]
ramdisk = ["block", "driver_block/ramdisk"]
bcm2835-sdhci = ["block", "driver_block/bcm2835-sdhci"]
ixgbe = ["net", "driver_net/ixgbe", "dep:axalloc", "dep:ruxhal"]
loopback = ["driver_net/loopback", "dyn"]
# more devices example: e1000 = ["net", "driver_net/e1000"]

default = ["bus-mmio"]
Expand Down
2 changes: 1 addition & 1 deletion modules/ruxdriver/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* See the Mulan PSL v2 for more details.
*/

const NET_DEV_FEATURES: &[&str] = &["ixgbe", "virtio-net"];
const NET_DEV_FEATURES: &[&str] = &["ixgbe", "virtio-net", "loopback"];
const BLOCK_DEV_FEATURES: &[&str] = &["ramdisk", "bcm2835-sdhci", "virtio-blk"];
const DISPLAY_DEV_FEATURES: &[&str] = &["virtio-gpu"];
const _9P_DEV_FEATURES: &[&str] = &["virtio-9p"];
Expand Down
17 changes: 17 additions & 0 deletions modules/ruxdriver/src/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ pub trait DriverProbe {
}
}

cfg_if::cfg_if! {
if #[cfg(net_dev = "loopback")]
{
pub struct LoopbackDriver;
register_net_driver!(LoopbackDriver, driver_net::loopback::LoopbackDevice);

impl DriverProbe for LoopbackDriver {
fn probe_global() -> Option<AxDeviceEnum> {
debug!("mmc probe");
Some(AxDeviceEnum::from_net(
driver_net::loopback::LoopbackDevice::new(None),
))
}
}
}
}

#[cfg(net_dev = "virtio-net")]
register_net_driver!(
<virtio::VirtIoNet as VirtIoDevMeta>::Driver,
Expand Down
6 changes: 6 additions & 0 deletions modules/ruxdriver/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ macro_rules! for_each_drivers {
#[allow(unused_imports)]
use crate::virtio::{self, VirtIoDevMeta};

#[cfg(net_dev = "loopback")]
{
type $drv_type = crate::drivers::LoopbackDriver;
$code
}

#[cfg(net_dev = "virtio-net")]
{
type $drv_type = <virtio::VirtIoNet as VirtIoDevMeta>::Driver;
Expand Down
2 changes: 1 addition & 1 deletion modules/ruxfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ features = [ # no std
]

[dev-dependencies]
ruxdriver = { path = "../ruxdriver", features = ["block", "ramdisk"] }
ruxdriver = { path = "../ruxdriver", features = ["block", "ramdisk", "dyn"] }
driver_block = { path = "../../crates/driver_block", features = ["ramdisk"] }
axsync = { path = "../axsync", features = ["multitask"] }
ruxtask = { path = "../ruxtask", features = ["test"] }
4 changes: 3 additions & 1 deletion modules/ruxfs/tests/test_fatfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ fn test_fatfs() {
// By default, mount_points[0] will be rootfs
let mut mount_points: Vec<ruxfs::MountPoint> = Vec::new();
// setup and initialize blkfs as one mountpoint for rootfs
mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(disk)));
mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(Box::new(
disk,
))));
ruxfs::prepare_commonfs(&mut mount_points);

// setup and initialize rootfs
Expand Down
4 changes: 2 additions & 2 deletions modules/ruxfs/tests/test_ramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ fn test_ramfs() {
// By default, mount_points[0] will be rootfs
let mut mount_points: Vec<ruxfs::MountPoint> = Vec::new();
// setup and initialize blkfs as one mountpoint for rootfs
mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(
mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(Box::new(
RamDisk::default(),
)));
))));
ruxfs::prepare_commonfs(&mut mount_points);

// setup and initialize rootfs
Expand Down
3 changes: 2 additions & 1 deletion modules/ruxnet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ documentation = "https://rcore-os.github.io/arceos/ruxnet/index.html"

[features]
lwip = ["dep:lwip_rust"]
loopback = ["ruxdriver/loopback"]
smoltcp = []
default = ["smoltcp"]
default = ["smoltcp", "loopback"]

[dependencies]
log = "0.4"
Expand Down
9 changes: 6 additions & 3 deletions modules/ruxnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ use ruxdriver::{prelude::*, AxDeviceContainer};
pub fn init_network(mut net_devs: AxDeviceContainer<AxNetDevice>) {
info!("Initialize network subsystem...");

let dev = net_devs.take_one().expect("No NIC device found!");
info!(" use NIC 0: {:?}", dev.device_name());
cfg_if::cfg_if! {
if #[cfg(feature = "lwip")] {
info!(" net stack: lwip");
Expand All @@ -74,5 +72,10 @@ pub fn init_network(mut net_devs: AxDeviceContainer<AxNetDevice>) {
compile_error!("No network stack is selected");
}
}
net_impl::init(dev);
net_impl::init();
while !net_devs.is_empty() {
let dev = net_devs.take_one().expect("No NIC device found!");
info!(" use NIC: {:?}", dev.device_name());
net_impl::init_netdev(dev);
}
}
Loading
Loading