aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2025-03-18 11:37:15 +0100
committerHimbeer <himbeer@disroot.org>2025-03-18 14:40:40 +0100
commitfd5925655015d6be9f3cfe7b6927f1bc270af28c (patch)
tree087c64f5faabcde27b148661f7aa019586e0855c
parent3234da2962dc0bfc8fb6d6f5c3d402171d494507 (diff)
Rework route configuration options
Route configuration is now passed using structs for future extensibility. The "link" scope is now only applied if explicitly requested. The table and metric can now be specified.
-rw-r--r--src/blocking.rs6
-rw-r--r--src/route.rs96
2 files changed, 75 insertions, 27 deletions
diff --git a/src/blocking.rs b/src/blocking.rs
index 71483ef..7cc90d3 100644
--- a/src/blocking.rs
+++ b/src/blocking.rs
@@ -97,13 +97,13 @@ pub mod link {
pub mod route {
use super::Connection;
- use std::net::{Ipv4Addr, Ipv6Addr};
+ use crate::route::{Route4, Route6};
impl Connection {
blockify!(route_flush4, link: String);
blockify!(route_flush6, link: String);
blockify!(route_flush, link: String);
- blockify!(route_add4, dst: Ipv4Addr, prefix_len: u8, rtr: Option<Ipv4Addr>, link: String);
- blockify!(route_add6, dst: Ipv6Addr, prefix_len: u8, rtr: Option<Ipv6Addr>, link: String);
+ blockify!(route_add4, r: Route4);
+ blockify!(route_add6, r: Route6);
}
}
diff --git a/src/route.rs b/src/route.rs
index 2283072..b5a03c6 100644
--- a/src/route.rs
+++ b/src/route.rs
@@ -8,6 +8,46 @@ use futures::{future, TryStreamExt};
use netlink_packet_route::route::{RouteAttribute, RouteMessage, RouteScope};
use rtnetlink::IpVersion;
+/// An IPv4 route configuration.
+#[derive(Debug)]
+pub struct Route4 {
+ /// The destination prefix this route applies to.
+ pub dst: Ipv4Addr,
+ /// The length of the destination prefix this route applies to.
+ pub prefix_len: u8,
+ /// The (optional) router to send packets to.
+ pub rtr: Option<Ipv4Addr>,
+ /// Whether to apply the link scope to this route.
+ pub on_link: bool,
+ /// The table this route belongs to. Defaults to `main`.
+ pub table: Option<u32>,
+ /// The metric (priority) of this route. `None` causes the kernel default
+ /// to be used.
+ pub metric: Option<u32>,
+ /// The network interface to send packets over.
+ pub link: String,
+}
+
+/// An IPv6 route configuration.
+#[derive(Debug)]
+pub struct Route6 {
+ /// The destination prefix this route applies to.
+ pub dst: Ipv6Addr,
+ /// The length of the destination prefix this route applies to.
+ pub prefix_len: u8,
+ /// The (optional) router to send packets to.
+ pub rtr: Option<Ipv6Addr>,
+ /// Whether to apply the link scope to this route.
+ pub on_link: bool,
+ /// The table this route belongs to. Defaults to `main`.
+ pub table: Option<u32>,
+ /// The metric (priority) of this route. `None` causes the kernel default
+ /// to be used.
+ pub metric: Option<u32>,
+ /// The network interface to send packets over.
+ pub link: String,
+}
+
impl Connection {
/// Flushes all IPv4 routes from an interface.
pub async fn route_flush4(&self, link: String) -> Result<()> {
@@ -106,22 +146,16 @@ impl Connection {
}
/// Adds a simple IPv4 route with an optional gateway.
- pub async fn route_add4(
- &self,
- dst: Ipv4Addr,
- prefix_len: u8,
- rtr: Option<Ipv4Addr>,
- link: String,
- ) -> Result<()> {
+ pub async fn route_add4(&self, r: Route4) -> Result<()> {
let link = self
.handle()
.link()
.get()
- .match_name(link.clone())
+ .match_name(r.link.clone())
.execute()
.try_next()
.await?
- .ok_or(Error::LinkNotFound(link))?;
+ .ok_or(Error::LinkNotFound(r.link))?;
let id = link.header.index;
@@ -130,36 +164,40 @@ impl Connection {
.route()
.add()
.v4()
- .destination_prefix(dst, prefix_len)
+ .destination_prefix(r.dst, r.prefix_len)
.output_interface(id);
- if let Some(rtr) = rtr {
+ if let Some(rtr) = r.rtr {
add = add.gateway(rtr);
- } else {
+ }
+
+ if r.on_link {
add = add.scope(RouteScope::Link);
}
+ if let Some(table) = r.table {
+ add = add.table_id(table);
+ }
+
+ if let Some(metric) = r.metric {
+ add = add.priority(metric);
+ }
+
add.execute().await?;
Ok(())
}
/// Adds a simple IPv6 route with an optional gateway.
- pub async fn route_add6(
- &self,
- dst: Ipv6Addr,
- prefix_len: u8,
- rtr: Option<Ipv6Addr>,
- link: String,
- ) -> Result<()> {
+ pub async fn route_add6(&self, r: Route6) -> Result<()> {
let link = self
.handle()
.link()
.get()
- .match_name(link.clone())
+ .match_name(r.link.clone())
.execute()
.try_next()
.await?
- .ok_or(Error::LinkNotFound(link))?;
+ .ok_or(Error::LinkNotFound(r.link))?;
let id = link.header.index;
@@ -168,15 +206,25 @@ impl Connection {
.route()
.add()
.v6()
- .destination_prefix(dst, prefix_len)
+ .destination_prefix(r.dst, r.prefix_len)
.output_interface(id);
- if let Some(rtr) = rtr {
+ if let Some(rtr) = r.rtr {
add = add.gateway(rtr);
- } else {
+ }
+
+ if r.on_link {
add = add.scope(RouteScope::Link);
}
+ if let Some(table) = r.table {
+ add = add.table_id(table);
+ }
+
+ if let Some(metric) = r.metric {
+ add = add.priority(metric);
+ }
+
add.execute().await?;
Ok(())
}