关于socket与iface的资源管理关系

在asterinas中,其一个iface对应自身的一个socketset以及端口占用表。是否需要重新设计内核中socket与iface的资源关系?
现有的端口占用表是全局的,应该将其与网卡相绑定

但是如果将socketset与iface绑定,那么对应的sockethandle的管理也会与iface绑定,那系统统计socket状态与数量的话似乎只能一个个iface轮询过去?就不能再统一地管理socket了;同时沿用从前的信息传递的实现的话,仍然需要轮询所有网卡而非进程打开的socket对应的网卡,那么对于解决 同一时间只能由一个进程访问socketset 的问题意义不大?
或者说,需要引入机制,使得进程只会poll对应bind或listen的socket所在的iface,从而限制进程占用的资源的范围?
@atm7718 你怎么看

我现在尝试引入 IfaceCommon 来解耦 iface 的实现,并把 SocketSet 分离进 IfaceCommon

pub trait Iface: crate::driver::base::device::Device {
    /// # `common`
    /// 获取网卡的公共信息
    fn common(&self) -> &IfaceCommon;

    /// # `mac` 
    /// 获取网卡的MAC地址
    fn mac(&self) -> smoltcp::wire::EthernetAddress;

    /// # `name`
    /// 获取网卡名
    fn name(&self) -> String;

    /// # `nic_id` 
    /// 获取网卡id
    fn nic_id(&self) -> usize {
        self.common().iface_id
    }

    /// # `poll` 
    /// 用于轮询接口的状态。
    /// ## 参数
    /// - `sockets` :一个可变引用到 `smoltcp::iface::SocketSet`,表示要轮询的套接字集
    /// ## 返回值
    /// - 成功返回 `Ok(())`
    /// - 如果轮询失败,返回 `Err(SystemError::EAGAIN_OR_EWOULDBLOCK)`,表示需要再次尝试或者操作会阻塞
    fn poll(&self) -> Result<(), SystemError>;

    /// # `update_ip_addrs` 
    /// 用于更新接口的 IP 地址
    /// ## 参数
    /// - `ip_addrs` :一个包含 `smoltcp::wire::IpCidr` 的切片,表示要设置的 IP 地址和子网掩码
    /// ## 返回值
    /// - 如果 `ip_addrs` 的长度不为 1,返回 `Err(SystemError::EINVAL)`,表示输入参数无效
    fn update_ip_addrs(&self, ip_addrs: &[smoltcp::wire::IpCidr]) -> Result<(), SystemError> {
        self.common().update_ip_addrs(ip_addrs)
    }

    /// @brief 获取smoltcp的网卡接口类型
    #[inline(always)]
    fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
        &self.common().iface
    }
    // fn as_any_ref(&'static self) -> &'static dyn core::any::Any;

    /// # `sockets`
    /// 获取网卡的套接字集
    fn sockets(&self) -> &SpinLock<smoltcp::iface::SocketSet<'static>> {
        &self.common().sockets
    }

    /// # `port_manager`
    /// 用于管理网卡的端口
    fn port_manager(&self) -> &crate::net::socket::PortManager {
        &self.common().port_manager
    }
}

pub struct IfaceCommon {
    iface_id: usize,
    iface: SpinLock<smoltcp::iface::Interface>,
    sockets: SpinLock<smoltcp::iface::SocketSet<'static>>,
    port_manager: crate::net::socket::PortManager,
    _poll_at_ms: core::sync::atomic::AtomicU64,
}

impl fmt::Debug for IfaceCommon {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("IfaceCommon")
            .field("iface_id", &self.iface_id)
            .field("sockets", &self.sockets)
            .field("port_manager", &self.port_manager)
            .field("_poll_at_ms", &self._poll_at_ms)
            .finish()
    }
}

impl IfaceCommon {
    pub fn new(iface_id: usize, iface: smoltcp::iface::Interface) -> Self {
        IfaceCommon {
            iface_id,
            iface: SpinLock::new(iface),
            sockets: SpinLock::new(smoltcp::iface::SocketSet::new(vec![])),
            port_manager: crate::net::socket::PortManager::new(),
            _poll_at_ms: core::sync::atomic::AtomicU64::new(0),
        }
    }

    pub fn poll<D>(&self, device: &mut D) -> Result<(), SystemError>
    where
        D: smoltcp::phy::Device + ?Sized,
    {
        let timestamp = crate::time::Instant::now().into();
        let mut sockets = self.sockets.lock();
        if self.iface.lock().poll(timestamp, device, &mut sockets) {
            return Ok(());
        } else {
            return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
        }
    }

    pub fn update_ip_addrs(&self, ip_addrs: &[smoltcp::wire::IpCidr]) -> Result<(), SystemError> {
        if ip_addrs.len() != 1 {
            return Err(SystemError::EINVAL);
        }

        self.iface.lock().update_ip_addrs(|addrs| {
            let dest = addrs.iter_mut().next();

            if let Some(dest) = dest {
                *dest = ip_addrs[0];
            } else {
                addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
            }
        });
        return Ok(());
    }
}

但是我发现紧接着 SocketHandle 也会因此与网卡相绑定;那么 Iface 还需要管理 Socket,耦合反而严重了……?

@GnoCiYeH 你怎么看这个问题