mirror of
https://codeberg.org/icewind/netnsd.git
synced 2026-06-03 17:14:06 +02:00
minor link handling improvements
This commit is contained in:
parent
41258f44bd
commit
35c8f5cc6c
2 changed files with 28 additions and 30 deletions
42
src/link.rs
42
src/link.rs
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::namespace::{NamespaceEnterError, NamespaceHandle};
|
|
||||||
use neli::consts::nl::NlmF;
|
use neli::consts::nl::NlmF;
|
||||||
use neli::consts::rtnl::Ifla;
|
use neli::consts::rtnl::Ifla;
|
||||||
use neli::consts::rtnl::RtAddrFamily;
|
use neli::consts::rtnl::RtAddrFamily;
|
||||||
|
|
@ -12,25 +11,28 @@ use neli::rtnl::{Ifinfomsg, RtattrBuilder};
|
||||||
use neli::types::{Buffer, RtBuffer};
|
use neli::types::{Buffer, RtBuffer};
|
||||||
use neli::utils::Groups;
|
use neli::utils::Groups;
|
||||||
use nix::libc::c_int;
|
use nix::libc::c_int;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum LinkError {
|
pub enum LinkError {
|
||||||
#[error("failed to communicate with netlink")]
|
#[error("Failed to communicate with netlink:")]
|
||||||
Netlink,
|
Netlink(String),
|
||||||
#[error("failed to code netlink response")]
|
#[error("Failed to parse netlink response")]
|
||||||
Parse,
|
Parse(String),
|
||||||
#[error("Link not found: {0}")]
|
#[error("Link not found: {0}")]
|
||||||
NotFound(String),
|
NotFound(String),
|
||||||
#[error(transparent)]
|
|
||||||
Enter(#[from] NamespaceEnterError),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, P> From<RouterError<T, P>> for LinkError {
|
impl<T, P> From<RouterError<T, P>> for LinkError
|
||||||
fn from(_value: RouterError<T, P>) -> Self {
|
where
|
||||||
LinkError::Netlink
|
T: Debug,
|
||||||
|
P: Debug,
|
||||||
|
{
|
||||||
|
fn from(value: RouterError<T, P>) -> Self {
|
||||||
|
LinkError::Netlink(value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +91,7 @@ impl LinkManager {
|
||||||
.rtattrs()
|
.rtattrs()
|
||||||
.get_attr_handle()
|
.get_attr_handle()
|
||||||
.get_attr_payload_as_with_len::<String>(Ifla::Ifname)
|
.get_attr_payload_as_with_len::<String>(Ifla::Ifname)
|
||||||
.map_err(|_| LinkError::Parse)?;
|
.map_err(|e| LinkError::Parse(e.to_string()))?;
|
||||||
Ok(Some(Link {
|
Ok(Some(Link {
|
||||||
family: *payload.ifi_family(),
|
family: *payload.ifi_family(),
|
||||||
index: *payload.ifi_index(),
|
index: *payload.ifi_index(),
|
||||||
|
|
@ -103,7 +105,7 @@ impl LinkManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move a link to a namespace
|
/// Move a link to a namespace
|
||||||
pub fn move_link<Fd: AsRawFd>(&self, link: &Link, namespace: Fd) -> Result<(), LinkError> {
|
pub fn move_link<Fd: AsRawFd>(&self, link: &Link, namespace: &Fd) -> Result<(), LinkError> {
|
||||||
let ns_handle = namespace.as_raw_fd();
|
let ns_handle = namespace.as_raw_fd();
|
||||||
|
|
||||||
let mut info_attrs = RtBuffer::<Ifla, Buffer>::new();
|
let mut info_attrs = RtBuffer::<Ifla, Buffer>::new();
|
||||||
|
|
@ -143,27 +145,21 @@ pub fn link_up(link_name: &str) -> Result<(), LinkError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move a link into a namespace
|
/// Move a link into a namespace
|
||||||
pub fn move_link_into(link_name: &str, namespace: &NamespaceHandle) -> Result<(), LinkError> {
|
pub fn move_link_into<Fd: AsRawFd>(link_name: &str, namespace: &Fd) -> Result<(), LinkError> {
|
||||||
let manager = LinkManager::new()?;
|
let manager = LinkManager::new()?;
|
||||||
let link = manager.get_link(link_name)?;
|
let link = manager.get_link(link_name)?;
|
||||||
info!(name = &link.name, "moving link into namespace");
|
info!(name = &link.name, "moving link into namespace");
|
||||||
manager.move_link(&link, namespace)
|
manager.move_link(&link, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move all links out of a namespace, except for lo
|
/// Move all links from the current namespace (except lo) into a namespace
|
||||||
pub fn move_all_links_out(
|
pub fn move_all_links<Fd: AsRawFd>(namespace: &Fd) -> Result<(), LinkError> {
|
||||||
namespace: &NamespaceHandle,
|
|
||||||
parent: &NamespaceHandle,
|
|
||||||
) -> Result<(), LinkError> {
|
|
||||||
namespace.run_in(|| {
|
|
||||||
let manager = LinkManager::new()?;
|
let manager = LinkManager::new()?;
|
||||||
for link in manager.get_links()?.flatten() {
|
for link in manager.get_links()?.flatten() {
|
||||||
if link.name != "lo" {
|
if link.name != "lo" {
|
||||||
info!(name = &link.name, "moving link out of namespace");
|
info!(name = &link.name, "moving link");
|
||||||
manager.move_link(&link, parent)?
|
manager.move_link(&link, namespace)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok::<_, LinkError>(())
|
Ok::<_, LinkError>(())
|
||||||
})??;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ mod handle;
|
||||||
mod raw;
|
mod raw;
|
||||||
|
|
||||||
use crate::config::{DeviceName, NamespaceName};
|
use crate::config::{DeviceName, NamespaceName};
|
||||||
use crate::link::{link_up, move_all_links_out, move_link_into, LinkError};
|
use crate::link::{link_up, move_all_links, move_link_into, LinkError};
|
||||||
pub use crate::namespace::handle::{NamespaceHandle, NamespaceHandleError};
|
pub use crate::namespace::handle::{NamespaceHandle, NamespaceHandleError};
|
||||||
use crate::namespace::raw::{create_network_namespace, NamespaceSetupError};
|
use crate::namespace::raw::{create_network_namespace, NamespaceSetupError};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
|
@ -162,7 +162,9 @@ impl NetNs {
|
||||||
pub fn delete(self) -> Result<(), NamespaceError> {
|
pub fn delete(self) -> Result<(), NamespaceError> {
|
||||||
let parent_namespace = NamespaceHandle::parent()?;
|
let parent_namespace = NamespaceHandle::parent()?;
|
||||||
|
|
||||||
move_all_links_out(self.handle(), &parent_namespace)?;
|
self.handle.run_in(|| {
|
||||||
|
move_all_links(&parent_namespace)
|
||||||
|
})??;
|
||||||
let name = self.path.file_name().unwrap().to_str().unwrap();
|
let name = self.path.file_name().unwrap().to_str().unwrap();
|
||||||
info!(name, "deleting network namespace");
|
info!(name, "deleting network namespace");
|
||||||
match umount2(&self.path, MntFlags::MNT_DETACH) {
|
match umount2(&self.path, MntFlags::MNT_DETACH) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue