aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-08-13 20:22:58 +0200
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-08-13 20:22:58 +0200
commit06cddb0b371192f2f28eaa50c201577fa689833f (patch)
treeedd9c4f002abce6be4fc698a1bf2c12d16d7fadc /src
parent72f04e3494b4f3ba810274447235e9051f5e1749 (diff)
recreate routes instead of failing due to existing entries0.6.1
Diffstat (limited to 'src')
-rw-r--r--src/addr.rs31
-rw-r--r--src/main.rs3
-rw-r--r--src/route.rs91
3 files changed, 122 insertions, 3 deletions
diff --git a/src/addr.rs b/src/addr.rs
index 36ddea1..ceae1ec 100644
--- a/src/addr.rs
+++ b/src/addr.rs
@@ -2,9 +2,9 @@ use crate::error::{Error, Result};
use std::net::IpAddr;
+use futures::future;
use futures_util::TryStreamExt;
-use netlink_packet_route::rtnl::AddressMessage;
-use netlink_packet_route::RT_SCOPE_LINK;
+use netlink_packet_route::{AddressMessage, AF_INET6, RT_SCOPE_LINK, RT_SCOPE_UNIVERSE};
use tokio::runtime::Runtime;
async fn do_flush(link: String) -> Result<()> {
@@ -41,6 +41,33 @@ pub fn flush(link: String) -> Result<()> {
Runtime::new()?.block_on(do_flush(link))
}
+async fn do_flush6_global() -> Result<()> {
+ let (conn, handle, _) = rtnetlink::new_connection()?;
+ tokio::spawn(conn);
+
+ let addrs: Vec<AddressMessage> = handle
+ .address()
+ .get()
+ .execute()
+ .try_filter(|addr| {
+ future::ready(
+ addr.header.family == AF_INET6 as u8 && addr.header.scope == RT_SCOPE_UNIVERSE,
+ )
+ })
+ .try_collect()
+ .await?;
+
+ for addr in addrs {
+ handle.address().del(addr).execute().await?;
+ }
+
+ Ok(())
+}
+
+pub fn flush6_global() -> Result<()> {
+ Runtime::new()?.block_on(do_flush6_global())
+}
+
async fn do_add(link: String, addr: IpAddr, prefix_len: u8) -> Result<()> {
let (conn, handle, _) = rtnetlink::new_connection()?;
tokio::spawn(conn);
diff --git a/src/main.rs b/src/main.rs
index 8ea3f89..eef8154 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -157,6 +157,7 @@ fn configure_ppp0() -> Result<()> {
let ip_config: DsConfig = serde_json::from_reader(&mut file)?;
addr::flush("ppp0".into())?;
+ route::flush("ppp0".into())?;
if let Some(v4) = ip_config.v4 {
addr::add("ppp0".into(), IpAddr::V4(v4.addr), 32)?;
@@ -179,6 +180,8 @@ fn configure_ipv6() {
}
fn configure_all_v6() -> Result<()> {
+ addr::flush6_global()?;
+
let mut file = File::open(rsdsl_pd_config::LOCATION)?;
let pd_config: PdConfig = serde_json::from_reader(&mut file)?;
diff --git a/src/route.rs b/src/route.rs
index b3e7cc9..0e5cd5d 100644
--- a/src/route.rs
+++ b/src/route.rs
@@ -2,10 +2,99 @@ use crate::error::{Error, Result};
use std::net::{Ipv4Addr, Ipv6Addr};
+use futures::future;
use futures_util::TryStreamExt;
-use netlink_packet_route::rtnl::RT_SCOPE_LINK;
+use netlink_packet_route::{RouteMessage, RT_SCOPE_LINK};
+use rtnetlink::IpVersion;
use tokio::runtime::Runtime;
+async fn do_flush4(link: String) -> 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;
+
+ let routes: Vec<RouteMessage> = handle
+ .route()
+ .get(IpVersion::V4)
+ .execute()
+ .try_filter(|route| {
+ future::ready(if let Some(ifi) = route.output_interface() {
+ ifi == id
+ } else {
+ false
+ })
+ })
+ .try_collect()
+ .await?;
+
+ for route in routes {
+ handle.route().del(route).execute().await?;
+ }
+
+ Ok(())
+}
+
+pub fn flush4(link: String) -> Result<()> {
+ Runtime::new()?.block_on(do_flush4(link))
+}
+
+async fn do_flush6(link: String) -> 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;
+
+ let routes: Vec<RouteMessage> = handle
+ .route()
+ .get(IpVersion::V6)
+ .execute()
+ .try_filter(|route| {
+ future::ready(if let Some(ifi) = route.output_interface() {
+ ifi == id
+ } else {
+ false
+ })
+ })
+ .try_collect()
+ .await?;
+
+ for route in routes {
+ handle.route().del(route).execute().await?;
+ }
+
+ Ok(())
+}
+
+pub fn flush6(link: String) -> Result<()> {
+ Runtime::new()?.block_on(do_flush6(link))
+}
+
+pub fn flush(link: String) -> Result<()> {
+ flush4(link.clone())?;
+ flush6(link)?;
+
+ Ok(())
+}
+
async fn do_add4(dst: Ipv4Addr, prefix_len: u8, rtr: Option<Ipv4Addr>, link: String) -> Result<()> {
let (conn, handle, _) = rtnetlink::new_connection()?;
tokio::spawn(conn);