Introduce IfaceExt

This commit is contained in:
Ruihan Li
2024-09-05 23:49:14 +08:00
committed by Tate, Hongliang Tian
parent 538065b42f
commit dd2cde3aee
12 changed files with 216 additions and 144 deletions

View File

@ -1,12 +1,12 @@
// SPDX-License-Identifier: MPL-2.0
use ostd::sync::WaitQueue;
use self::common::IfaceCommon;
use crate::prelude::*;
mod any_socket;
mod common;
mod ext;
mod init;
mod loopback;
mod time;
mod util;
@ -16,6 +16,7 @@ pub use any_socket::{
AnyBoundSocket, AnyUnboundSocket, RawTcpSocket, RawUdpSocket, TCP_RECV_BUF_LEN,
TCP_SEND_BUF_LEN, UDP_RECV_PAYLOAD_LEN, UDP_SEND_PAYLOAD_LEN,
};
pub use init::{init, lazy_init, poll_ifaces, IFACES};
pub use loopback::IfaceLoopback;
pub use smoltcp::wire::EthernetAddress;
pub use util::{spawn_background_poll_thread, BindPortConfig};
@ -29,17 +30,21 @@ use crate::net::socket::ip::Ipv4Address;
/// computer to a network. Network interfaces can be physical components like Ethernet ports or
/// wireless adapters. They can also be virtual interfaces created by software, such as virtual
/// private network (VPN) connections.
pub trait Iface: internal::IfaceInternal + Send + Sync {
/// Gets the name of the iface.
///
/// In Linux, the name is usually the driver name followed by a unit number.
fn name(&self) -> &str;
pub trait Iface<E = ext::IfaceExt>: internal::IfaceInternal<E> + Send + Sync {
/// Transmits or receives packets queued in the iface, and updates socket status accordingly.
fn poll(&self);
///
/// The `schedule_next_poll` callback is invoked with the time at which the next poll should be
/// performed, or `None` if no next poll is required. It's up to the caller to determine the
/// mechanism to ensure that the next poll happens at the right time (e.g. by setting a timer).
fn raw_poll(&self, schedule_next_poll: &dyn Fn(Option<u64>));
}
impl dyn Iface {
impl<E> dyn Iface<E> {
/// Gets the extension of the iface.
pub fn ext(&self) -> &E {
self.common().ext()
}
/// Binds a socket to the iface.
///
/// After binding the socket to the iface, the iface will handle all packets to and from the
@ -55,7 +60,7 @@ impl dyn Iface {
self: &Arc<Self>,
socket: Box<AnyUnboundSocket>,
config: BindPortConfig,
) -> core::result::Result<AnyBoundSocket, (Error, Box<AnyUnboundSocket>)> {
) -> core::result::Result<AnyBoundSocket<E>, (Error, Box<AnyUnboundSocket>)> {
let common = self.common();
common.bind_socket(self.clone(), socket, config)
}
@ -66,23 +71,13 @@ impl dyn Iface {
pub fn ipv4_addr(&self) -> Option<Ipv4Address> {
self.common().ipv4_addr()
}
/// Gets the wait queue that the background polling thread will sleep on.
fn polling_wait_queue(&self) -> &WaitQueue {
self.common().polling_wait_queue()
}
/// Gets the time when we should perform another poll.
fn next_poll_at_ms(&self) -> Option<u64> {
self.common().next_poll_at_ms()
}
}
mod internal {
use super::*;
/// An internal trait that abstracts the common part of different ifaces.
pub trait IfaceInternal {
fn common(&self) -> &IfaceCommon;
pub trait IfaceInternal<E> {
fn common(&self) -> &IfaceCommon<E>;
}
}