mirror of
https://codeberg.org/icewind/netnsd.git
synced 2026-06-03 09:04:07 +02:00
47 lines
1.5 KiB
Rust
47 lines
1.5 KiB
Rust
use crate::config::{Config, NamespaceName};
|
|
use crate::link::{LinkError, LinkManager};
|
|
use crate::namespace::NetNs;
|
|
use main_error::MainResult;
|
|
use tracing::error;
|
|
|
|
pub fn up(config: Config) -> MainResult {
|
|
let mut namespaces = NetNs::existing(false)?
|
|
.map(NetNs::new)
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
|
|
for removed in namespaces.extract_if(.., |namespace| {
|
|
config.get_namespace(namespace.name()).is_none()
|
|
}) {
|
|
removed.delete()?;
|
|
}
|
|
|
|
for new in config.namespaces {
|
|
if !has_namespace(&namespaces, &new.name) {
|
|
namespaces.push(NetNs::new(new.name.clone())?);
|
|
}
|
|
let namespace = get_namespace(&namespaces, &new.name).expect("namespace is just created");
|
|
for device in new.devices {
|
|
if let Err(error) = namespace.move_device(&device) {
|
|
error!(%error, "failed to move device into namespace");
|
|
}
|
|
}
|
|
for route in new.routes {
|
|
namespace.handle().run_in(|| {
|
|
let manager = LinkManager::new()?;
|
|
let link = manager.get_link(&route.device)?;
|
|
manager.add_route(&link, route.destination)?;
|
|
Ok::<_, LinkError>(())
|
|
})??;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn has_namespace(namespaces: &[NetNs], name: &NamespaceName) -> bool {
|
|
namespaces.iter().any(|existing| existing.name() == name)
|
|
}
|
|
|
|
fn get_namespace<'a>(namespaces: &'a [NetNs], name: &NamespaceName) -> Option<&'a NetNs> {
|
|
namespaces.iter().find(|existing| existing.name() == name)
|
|
}
|