netnsd/src/up.rs

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)
}