Poll the correct iface in irq handler

This commit is contained in:
jiangjianfeng 2025-04-22 03:26:16 +00:00 committed by Ruihan Li
parent bf4950965b
commit 961ad73847
6 changed files with 39 additions and 30 deletions

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use alloc::{borrow::ToOwned, sync::Arc}; use alloc::{borrow::ToOwned, sync::Arc};
use core::slice::Iter;
use aster_bigtcp::{ use aster_bigtcp::{
device::WithDevice, device::WithDevice,
@ -12,7 +13,19 @@ use spin::Once;
use super::{poll::poll_ifaces, Iface}; use super::{poll::poll_ifaces, Iface};
use crate::{net::iface::sched::PollScheduler, prelude::*}; use crate::{net::iface::sched::PollScheduler, prelude::*};
pub static IFACES: Once<Vec<Arc<Iface>>> = Once::new(); static IFACES: Once<Vec<Arc<Iface>>> = Once::new();
pub fn loopback_iface() -> &'static Arc<Iface> {
&IFACES.get().unwrap()[0]
}
pub fn virtio_iface() -> Option<&'static Arc<Iface>> {
IFACES.get().unwrap().get(1)
}
pub fn iter_all_ifaces() -> Iter<'static, Arc<Iface>> {
IFACES.get().unwrap().iter()
}
pub fn init() { pub fn init() {
IFACES.call_once(|| { IFACES.call_once(|| {
@ -29,15 +42,14 @@ pub fn init() {
ifaces ifaces
}); });
if let Some(iface_virtio) = virtio_iface() {
for (name, _) in aster_network::all_devices() { for (name, _) in aster_network::all_devices() {
let callback = || {
// TODO: further check that the irq num is the same as iface's irq num // TODO: further check that the irq num is the same as iface's irq num
let iface_virtio = &IFACES.get().unwrap()[0]; let callback = || iface_virtio.poll();
iface_virtio.poll();
};
aster_network::register_recv_callback(&name, callback); aster_network::register_recv_callback(&name, callback);
aster_network::register_send_callback(&name, callback); aster_network::register_send_callback(&name, callback);
} }
}
poll_ifaces(); poll_ifaces();
} }

View File

@ -5,7 +5,7 @@ mod init;
mod poll; mod poll;
mod sched; mod sched;
pub use init::{init, IFACES}; pub use init::{init, iter_all_ifaces, loopback_iface, virtio_iface};
pub use poll::lazy_init; pub use poll::lazy_init;
pub type Iface = dyn aster_bigtcp::iface::Iface<ext::BigtcpExt>; pub type Iface = dyn aster_bigtcp::iface::Iface<ext::BigtcpExt>;

View File

@ -6,7 +6,7 @@ use core::time::Duration;
use log::trace; use log::trace;
use ostd::timer::Jiffies; use ostd::timer::Jiffies;
use super::{Iface, IFACES}; use super::{iter_all_ifaces, Iface};
use crate::{ use crate::{
sched::{Nice, SchedPolicy}, sched::{Nice, SchedPolicy},
thread::kernel_thread::ThreadOptions, thread::kernel_thread::ThreadOptions,
@ -14,15 +14,13 @@ use crate::{
}; };
pub fn lazy_init() { pub fn lazy_init() {
for iface in IFACES.get().unwrap() { for iface in iter_all_ifaces() {
spawn_background_poll_thread(iface.clone()); spawn_background_poll_thread(iface.clone());
} }
} }
pub(super) fn poll_ifaces() { pub(super) fn poll_ifaces() {
let ifaces = IFACES.get().unwrap(); for iface in iter_all_ifaces() {
for iface in ifaces.iter() {
iface.poll(); iface.poll();
} }
} }

View File

@ -7,15 +7,13 @@ use aster_bigtcp::{
}; };
use crate::{ use crate::{
net::iface::{BoundPort, Iface, IFACES}, net::iface::{iter_all_ifaces, loopback_iface, virtio_iface, BoundPort, Iface},
prelude::*, prelude::*,
}; };
pub(super) fn get_iface_to_bind(ip_addr: &IpAddress) -> Option<Arc<Iface>> { pub(super) fn get_iface_to_bind(ip_addr: &IpAddress) -> Option<Arc<Iface>> {
let ifaces = IFACES.get().unwrap();
let IpAddress::Ipv4(ipv4_addr) = ip_addr; let IpAddress::Ipv4(ipv4_addr) = ip_addr;
ifaces iter_all_ifaces()
.iter()
.find(|iface| { .find(|iface| {
if let Some(iface_ipv4_addr) = iface.ipv4_addr() { if let Some(iface_ipv4_addr) = iface.ipv4_addr() {
iface_ipv4_addr == *ipv4_addr iface_ipv4_addr == *ipv4_addr
@ -30,9 +28,8 @@ pub(super) fn get_iface_to_bind(ip_addr: &IpAddress) -> Option<Arc<Iface>> {
/// If the remote address is the same as that of some iface, we will use the iface. /// If the remote address is the same as that of some iface, we will use the iface.
/// Otherwise, we will use a default interface. /// Otherwise, we will use a default interface.
fn get_ephemeral_iface(remote_ip_addr: &IpAddress) -> Arc<Iface> { fn get_ephemeral_iface(remote_ip_addr: &IpAddress) -> Arc<Iface> {
let ifaces = IFACES.get().unwrap();
let IpAddress::Ipv4(remote_ipv4_addr) = remote_ip_addr; let IpAddress::Ipv4(remote_ipv4_addr) = remote_ip_addr;
if let Some(iface) = ifaces.iter().find(|iface| { if let Some(iface) = iter_all_ifaces().find(|iface| {
if let Some(iface_ipv4_addr) = iface.ipv4_addr() { if let Some(iface_ipv4_addr) = iface.ipv4_addr() {
iface_ipv4_addr == *remote_ipv4_addr iface_ipv4_addr == *remote_ipv4_addr
} else { } else {
@ -41,8 +38,14 @@ fn get_ephemeral_iface(remote_ip_addr: &IpAddress) -> Arc<Iface> {
}) { }) {
return iface.clone(); return iface.clone();
} }
// FIXME: use the virtio-net as the default interface
ifaces[0].clone() // FIXME: Instead of hardcoding the rules here, we should choose the
// default interface according to the routing table.
if let Some(virtio_iface) = virtio_iface() {
virtio_iface.clone()
} else {
loopback_iface().clone()
}
} }
pub(super) fn bind_port(endpoint: &IpEndpoint, can_reuse: bool) -> Result<BoundPort> { pub(super) fn bind_port(endpoint: &IpEndpoint, can_reuse: bool) -> Result<BoundPort> {

View File

@ -7,7 +7,7 @@ use core::num::NonZeroU32;
use super::util::finish_response; use super::util::finish_response;
use crate::{ use crate::{
net::{ net::{
iface::{Iface, IFACES}, iface::{iter_all_ifaces, Iface},
socket::netlink::{ socket::netlink::{
message::{CMsgSegHdr, CSegmentType, GetRequestFlags, SegHdrCommonFlags}, message::{CMsgSegHdr, CSegmentType, GetRequestFlags, SegHdrCommonFlags},
route::message::{ route::message::{
@ -28,9 +28,7 @@ pub(super) fn do_get_addr(request_segment: &AddrSegment) -> Result<Vec<RtnlSegme
return_errno_with_message!(Errno::EOPNOTSUPP, "GETADDR only supports dump requests"); return_errno_with_message!(Errno::EOPNOTSUPP, "GETADDR only supports dump requests");
} }
let ifaces = IFACES.get().unwrap(); let mut response_segments: Vec<RtnlSegment> = iter_all_ifaces()
let mut response_segments: Vec<RtnlSegment> = ifaces
.iter()
// GETADDR only supports dump mode, so we're going to report all addresses. // GETADDR only supports dump mode, so we're going to report all addresses.
.filter_map(|iface| iface_to_new_addr(request_segment.header(), iface)) .filter_map(|iface| iface_to_new_addr(request_segment.header(), iface))
.map(RtnlSegment::NewAddr) .map(RtnlSegment::NewAddr)

View File

@ -9,7 +9,7 @@ use aster_bigtcp::iface::InterfaceType;
use super::util::finish_response; use super::util::finish_response;
use crate::{ use crate::{
net::{ net::{
iface::{Iface, IFACES}, iface::{iter_all_ifaces, Iface},
socket::netlink::{ socket::netlink::{
message::{CMsgSegHdr, CSegmentType, GetRequestFlags, SegHdrCommonFlags}, message::{CMsgSegHdr, CSegmentType, GetRequestFlags, SegHdrCommonFlags},
route::message::{LinkAttr, LinkSegment, LinkSegmentBody, RtnlSegment}, route::message::{LinkAttr, LinkSegment, LinkSegmentBody, RtnlSegment},
@ -22,9 +22,7 @@ use crate::{
pub(super) fn do_get_link(request_segment: &LinkSegment) -> Result<Vec<RtnlSegment>> { pub(super) fn do_get_link(request_segment: &LinkSegment) -> Result<Vec<RtnlSegment>> {
let filter_by = FilterBy::from_request(request_segment)?; let filter_by = FilterBy::from_request(request_segment)?;
let ifaces = IFACES.get().unwrap(); let mut response_segments: Vec<RtnlSegment> = iter_all_ifaces()
let mut response_segments: Vec<RtnlSegment> = ifaces
.iter()
// Filter to include only requested links. // Filter to include only requested links.
.filter(|iface| match &filter_by { .filter(|iface| match &filter_by {
FilterBy::Index(index) => *index == iface.index(), FilterBy::Index(index) => *index == iface.index(),