diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-11-14 17:35:54 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-11-14 17:35:54 +0100 |
commit | 1c2a4a8ace82f3ed0696e112b0434301538b3500 (patch) | |
tree | cfa2eb80f7f1cbcbbc67ba6b2f7bfbb568b5cdba /src/link.rs | |
parent | e1d63ff533bd1b56ac5394635c96aa354308d859 (diff) |
initial split
Diffstat (limited to 'src/link.rs')
-rw-r--r-- | src/link.rs | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/link.rs b/src/link.rs new file mode 100644 index 0000000..d936dd9 --- /dev/null +++ b/src/link.rs @@ -0,0 +1,194 @@ +use crate::{Error, Result}; + +use std::num::NonZeroI32; +use std::thread; +use std::time::Duration; + +use futures::TryStreamExt; +use netlink_packet_route::rtnl::IFF_UP; +use rtnetlink::Error::NetlinkError; +use tokio::runtime::Runtime; + +#[derive(Clone, Copy, Debug)] +enum State { + Up, + Down, +} + +async fn set(link: String, state: State) -> Result<()> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let link = handle + .link() + .get() + .match_name(link.clone()) + .execute() + .try_next() + .await? + .ok_or(Error::LinkNotFound(link))?; + + let id = link.header.index; + + match state { + State::Up => handle.link().set(id).up(), + State::Down => handle.link().set(id).down(), + } + .execute() + .await?; + + Ok(()) +} + +// pub fn up(link: String) -> Result<()> { +// Runtime::new()?.block_on(set(link, State::Up)) +// } +// +// pub fn down(link: String) -> Result<()> { +// Runtime::new()?.block_on(set(link, State::Down)) +// } + +async fn do_is_up(link: String) -> Result<bool> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let link = handle + .link() + .get() + .match_name(link.clone()) + .execute() + .try_next() + .await? + .ok_or(Error::LinkNotFound(link))?; + + let is_up = link.header.flags & IFF_UP == IFF_UP; + Ok(is_up) +} + +// pub fn is_up(link: String) -> Result<bool> { +// Runtime::new()?.block_on(do_is_up(link)) +// } + +async fn do_set_mtu(link: String, mtu: u32) -> Result<()> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let link = handle + .link() + .get() + .match_name(link.clone()) + .execute() + .try_next() + .await? + .ok_or(Error::LinkNotFound(link))?; + + let id = link.header.index; + + handle.link().set(id).mtu(mtu).execute().await?; + Ok(()) +} + +// pub fn set_mtu(link: String, mtu: u32) -> Result<()> { +// Runtime::new()?.block_on(do_set_mtu(link, mtu)) +// } + +async fn do_add_vlan(link: String, parent: String, vlan_id: u16) -> Result<()> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let parent = handle + .link() + .get() + .match_name(parent.clone()) + .execute() + .try_next() + .await? + .ok_or(Error::LinkNotFound(parent))?; + + let parent_id = parent.header.index; + + handle + .link() + .add() + .vlan(link, parent_id, vlan_id) + .execute() + .await?; + + Ok(()) +} + +// pub fn add_vlan(link: String, parent: String, vlan_id: u16) -> Result<()> { +// Runtime::new()?.block_on(do_add_vlan(link, parent, vlan_id)) +// } + +// pub fn wait_up(link: String) -> Result<()> { +// while !match is_up(link.clone()) { +// Ok(v) => v, +// Err(e) => { +// if let Error::LinkNotFound(_) = e { +// false +// } else if let Error::RtNetlink(NetlinkError(ref msg)) = e { +// // Error -19 is "No such device". +// if msg.code == NonZeroI32::new(-19) { +// false +// } else { +// return Err(e); +// } +// } else { +// return Err(e); +// } +// } +// } { +// thread::sleep(Duration::from_secs(1)); +// } +// +// Ok(()) +// } + +async fn do_exists(link: String) -> Result<bool> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let exists = handle + .link() + .get() + .match_name(link) + .execute() + .try_next() + .await + .is_ok(); + + Ok(exists) +} + +// pub fn exists(link: String) -> Result<bool> { +// Runtime::new()?.block_on(do_exists(link)) +// } +// +// pub fn wait_exists(link: String) -> Result<()> { +// while !exists(link.clone())? { +// thread::sleep(Duration::from_secs(1)); +// } +// +// Ok(()) +// } + +async fn do_index(link: String) -> Result<u32> { + let (conn, handle, _) = rtnetlink::new_connection()?; + tokio::spawn(conn); + + let link = handle + .link() + .get() + .match_name(link.clone()) + .execute() + .try_next() + .await? + .ok_or(Error::LinkNotFound(link))?; + + Ok(link.header.index) +} + +// pub fn index(link: String) -> Result<u32> { +// Runtime::new()?.block_on(do_index(link)) +// } |