Files
krata/network/src/lib.rs

116 lines
3.1 KiB
Rust
Raw Normal View History

2024-03-04 07:04:32 +00:00
use std::{collections::HashMap, time::Duration};
use anyhow::Result;
use autonet::{AutoNetworkChangeset, AutoNetworkCollector, NetworkMetadata};
2024-02-13 10:03:28 +00:00
use futures::{future::join_all, TryFutureExt};
2024-03-03 13:36:39 +00:00
use hbridge::HostBridge;
2024-02-13 10:03:28 +00:00
use log::warn;
use tokio::{task::JoinHandle, time::sleep};
2024-02-13 10:03:28 +00:00
use uuid::Uuid;
use vbridge::VirtualBridge;
2024-02-09 08:04:23 +00:00
use crate::backend::NetworkBackend;
pub mod autonet;
2024-02-10 21:13:47 +00:00
pub mod backend;
pub mod chandev;
2024-03-03 13:36:39 +00:00
pub mod hbridge;
2024-02-10 21:13:47 +00:00
pub mod icmp;
pub mod nat;
pub mod pkt;
2024-02-10 21:13:47 +00:00
pub mod proxynat;
pub mod raw_socket;
pub mod vbridge;
pub const FORCE_MTU: usize = 65521;
2024-03-04 07:04:32 +00:00
pub struct NetworkService {
pub backends: HashMap<Uuid, JoinHandle<()>>,
pub bridge: VirtualBridge,
2024-03-03 13:36:39 +00:00
pub hbridge: HostBridge,
}
impl NetworkService {
2024-03-03 13:36:39 +00:00
pub async fn new() -> Result<NetworkService> {
let bridge = VirtualBridge::new()?;
2024-03-04 07:04:32 +00:00
let hbridge = HostBridge::new(FORCE_MTU, "krata0".to_string(), &bridge).await?;
Ok(NetworkService {
backends: HashMap::new(),
2024-03-03 13:36:39 +00:00
bridge,
hbridge,
})
}
}
impl NetworkService {
pub async fn watch(&mut self) -> Result<()> {
2024-02-23 04:37:53 +00:00
let mut collector = AutoNetworkCollector::new().await?;
loop {
2024-02-23 04:37:53 +00:00
let changeset = collector.read_changes().await?;
2024-03-04 07:04:32 +00:00
self.process_network_changeset(&mut collector, changeset)
.await?;
sleep(Duration::from_secs(2)).await;
}
}
2024-03-04 07:04:32 +00:00
async fn process_network_changeset(
2024-02-13 10:03:28 +00:00
&mut self,
collector: &mut AutoNetworkCollector,
changeset: AutoNetworkChangeset,
) -> Result<()> {
for removal in &changeset.removed {
if let Some(handle) = self.backends.remove(&removal.uuid) {
handle.abort();
}
}
2024-02-13 10:03:28 +00:00
let futures = changeset
.added
.iter()
.map(|metadata| {
self.add_network_backend(metadata)
2024-02-13 10:03:28 +00:00
.map_err(|x| (metadata.clone(), x))
})
.collect::<Vec<_>>();
2024-03-04 07:04:32 +00:00
sleep(Duration::from_secs(1)).await;
let mut failed: Vec<Uuid> = Vec::new();
let mut launched: Vec<(Uuid, JoinHandle<()>)> = Vec::new();
let results = join_all(futures).await;
for result in results {
match result {
Ok(launch) => {
launched.push(launch);
}
2024-03-04 07:04:32 +00:00
Err((metadata, error)) => {
warn!(
"failed to launch network backend for krata guest {}: {}",
metadata.uuid, error
);
failed.push(metadata.uuid);
}
};
}
2024-02-13 10:03:28 +00:00
for (uuid, handle) in launched {
self.backends.insert(uuid, handle);
}
2024-02-13 10:03:28 +00:00
for uuid in failed {
collector.mark_unknown(uuid)?;
}
Ok(())
}
async fn add_network_backend(
&self,
metadata: &NetworkMetadata,
) -> Result<(Uuid, JoinHandle<()>)> {
let mut network = NetworkBackend::new(metadata.clone(), self.bridge.clone())?;
network.init().await?;
Ok((metadata.uuid, network.launch().await?))
}
}