mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-08-06 12:39:51 +00:00
refactor: add shared nic backend skeleton
Introduce SharedVirtualNicMember as the per-instance handle for a shared virtual NIC and add a registry helper to create members. Add NicBackend so NicCtx can later choose between dedicated VirtualNic and shared member-backed tunnel creation without changing the existing dedicated path.
This commit is contained in:
@@ -6,7 +6,9 @@ use std::{
|
||||
};
|
||||
|
||||
use cidr::{Ipv4Inet, Ipv6Inet};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::{Mutex, Notify};
|
||||
|
||||
use crate::{common::error::Error, tunnel::Tunnel};
|
||||
|
||||
use super::virtual_nic::{VirtualNic, VirtualNicConfig};
|
||||
|
||||
@@ -270,6 +272,43 @@ impl SharedVirtualNic {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SharedVirtualNicMember {
|
||||
member_id: SharedVirtualNicMemberId,
|
||||
shared_nic: Arc<Mutex<SharedVirtualNic>>,
|
||||
close_notifier: Arc<Notify>,
|
||||
}
|
||||
|
||||
impl SharedVirtualNicMember {
|
||||
pub fn new(
|
||||
member_id: SharedVirtualNicMemberId,
|
||||
shared_nic: Arc<Mutex<SharedVirtualNic>>,
|
||||
close_notifier: Arc<Notify>,
|
||||
) -> Self {
|
||||
Self {
|
||||
member_id,
|
||||
shared_nic,
|
||||
close_notifier,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn member_id(&self) -> SharedVirtualNicMemberId {
|
||||
self.member_id.clone()
|
||||
}
|
||||
|
||||
pub fn shared_nic(&self) -> Arc<Mutex<SharedVirtualNic>> {
|
||||
self.shared_nic.clone()
|
||||
}
|
||||
|
||||
pub fn close_notifier(&self) -> Arc<Notify> {
|
||||
self.close_notifier.clone()
|
||||
}
|
||||
|
||||
pub async fn create_dev(&self) -> Result<Box<dyn Tunnel>, Error> {
|
||||
Err(anyhow::anyhow!("shared virtual nic member tunnel is not implemented").into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SharedVirtualNicRegistry {
|
||||
nics: BTreeMap<String, SharedVirtualNicRegistryEntry>,
|
||||
@@ -323,6 +362,17 @@ impl SharedVirtualNicRegistry {
|
||||
self.nics.insert(dev_name, entry);
|
||||
nic
|
||||
}
|
||||
|
||||
pub fn create_member(
|
||||
&mut self,
|
||||
dev_name: String,
|
||||
config: VirtualNicConfig,
|
||||
member_id: SharedVirtualNicMemberId,
|
||||
close_notifier: Arc<Notify>,
|
||||
) -> SharedVirtualNicMember {
|
||||
let shared_nic = self.get_or_create(dev_name, config);
|
||||
SharedVirtualNicMember::new(member_id, shared_nic, close_notifier)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_owned_items<T>(
|
||||
@@ -439,6 +489,7 @@ mod tests {
|
||||
use std::str::FromStr as _;
|
||||
|
||||
use crate::common::netns::NetNS;
|
||||
use tokio::sync::Notify;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -591,4 +642,21 @@ mod tests {
|
||||
.is_some_and(|nic| Arc::ptr_eq(&nic, &second))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_create_member_uses_registered_shared_virtual_nic() {
|
||||
let mut registry = SharedVirtualNicRegistry::new();
|
||||
let member_id = member_id(1);
|
||||
|
||||
let member = registry.create_member(
|
||||
"et0".to_string(),
|
||||
virtual_nic_config(),
|
||||
member_id,
|
||||
Arc::new(Notify::new()),
|
||||
);
|
||||
let shared_nic = registry.get("et0").unwrap();
|
||||
|
||||
assert_eq!(member.member_id(), member_id);
|
||||
assert!(Arc::ptr_eq(&member.shared_nic(), &shared_nic));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ use zerocopy::{NativeEndian, NetworkEndian};
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::common::ifcfg::RegistryManager;
|
||||
|
||||
use super::shared_virtual_nic::SharedVirtualNicMember;
|
||||
|
||||
pin_project! {
|
||||
pub struct TunStream {
|
||||
#[pin]
|
||||
@@ -803,6 +805,51 @@ impl VirtualNic {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum NicBackend {
|
||||
Dedicated(Arc<Mutex<VirtualNic>>),
|
||||
Shared(SharedVirtualNicMember),
|
||||
}
|
||||
|
||||
impl NicBackend {
|
||||
pub fn dedicated(nic: Arc<Mutex<VirtualNic>>) -> Self {
|
||||
Self::Dedicated(nic)
|
||||
}
|
||||
|
||||
pub fn shared(member: SharedVirtualNicMember) -> Self {
|
||||
Self::Shared(member)
|
||||
}
|
||||
|
||||
pub async fn create_dev(&self) -> Result<Box<dyn Tunnel>, Error> {
|
||||
match self {
|
||||
Self::Dedicated(nic) => nic.lock().await.create_dev().await,
|
||||
Self::Shared(member) => member.create_dev().await,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn ifname(&self) -> Option<String> {
|
||||
match self {
|
||||
Self::Dedicated(nic) => nic
|
||||
.lock()
|
||||
.await
|
||||
.ifname
|
||||
.as_ref()
|
||||
.map(|ifname| ifname.to_owned()),
|
||||
Self::Shared(member) => {
|
||||
let shared_nic = member.shared_nic();
|
||||
let nic = {
|
||||
let shared_nic = shared_nic.lock().await;
|
||||
shared_nic.nic()
|
||||
};
|
||||
nic.lock()
|
||||
.await
|
||||
.ifname
|
||||
.as_ref()
|
||||
.map(|ifname| ifname.to_owned())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NicCtx {
|
||||
global_ctx: ArcGlobalCtx,
|
||||
peer_mgr: Weak<PeerManager>,
|
||||
|
||||
Reference in New Issue
Block a user