Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/network/dhcpv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ pub async fn add_ipv6_route(
prefix_length: u8,
gateway: Option<Ipv6Addr>,
metric: u32,
route_type: RouteType,
) -> Result<(), Error> {
let mut links = handle
.link()
Expand All @@ -950,24 +951,25 @@ pub async fn add_ipv6_route(
};

let mut route_add_request = handle.route().add();

let route_msg = route_add_request.message_mut();

route_msg.header.address_family = AddressFamily::Inet6;
route_msg.header.scope = RouteScope::Universe;
route_msg.header.protocol = RouteProtocol::Static;
route_msg.header.kind = RouteType::Unicast;
route_msg.header.kind = route_type;
route_msg.header.destination_prefix_length = prefix_length;
route_msg.header.table = RouteHeader::RT_TABLE_MAIN;

route_msg
.attributes
.push(RouteAttribute::Destination(RouteAddress::from(destination)));

if let Some(gw) = gateway {
route_msg
.attributes
.push(RouteAttribute::Gateway(RouteAddress::from(gw)));
if route_type == RouteType::Unicast {
if let Some(gw) = gateway {
route_msg
.attributes
.push(RouteAttribute::Gateway(RouteAddress::from(gw)));
}
}

route_msg
Expand Down
46 changes: 23 additions & 23 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use log::{debug, error, info};
use netlink_packet_route::route::RouteType;
use rtnetlink::new_connection;
use std::collections::HashMap;
use std::net::Ipv6Addr;
Expand All @@ -17,7 +18,7 @@ use crate::network::dhcpv6::{
};
use radv::start_radv_server;
pub use utils::_configure_sriov;
pub use utils::configure_network_devices;
pub use utils::{configure_network_devices, INTERFACE_NAME};

#[derive(Debug)]
pub enum Error {
Expand Down Expand Up @@ -125,32 +126,31 @@ impl Manager {
})
};

let mut instances = self.instances.lock().unwrap();
instances.insert(
id,
Handles {
radv_handle: Arc::new(radv_handle),
dhcpv6_handle: Arc::new(dhcpv6_handle),
},
);
{
let mut instances = self.instances.lock().unwrap();
instances.insert(
id,
Handles {
radv_handle: Arc::new(radv_handle),
dhcpv6_handle: Arc::new(dhcpv6_handle),
},
);
}

let (connection, handle, _) = new_connection().map_err(|_| Error::Failed)?;
spawn(connection);

spawn(async move {
if let Err(e) = add_ipv6_route(
&handle,
&interface_name,
adjusted_base_ip,
new_prefix_length,
None,
1024,
)
.await
{
error!("Failed to add ipv6 route: {}", e);
}
});
add_ipv6_route(
&handle,
&interface_name,
adjusted_base_ip,
new_prefix_length,
None,
1024,
RouteType::Unicast,
)
.await
.map_err(|_| Error::Failed)?;

Ok(())
}
Expand Down
87 changes: 58 additions & 29 deletions src/network/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::io::Write;

use crate::network::dhcpv6::*;
use futures::stream::TryStreamExt;
use log::{debug, info, warn};
use log::{debug, error, info, warn};
use rtnetlink::{new_connection, Handle, IpVersion};
use std::net::Ipv6Addr;
use tokio::fs::{read_link, OpenOptions};
Expand All @@ -22,9 +22,9 @@ use pnet::packet::udp::UdpPacket;
use pnet::packet::Packet;

use netlink_packet_route::neighbour::*;
use netlink_packet_route::route::{RouteAddress, RouteAttribute};
use netlink_packet_route::route::{RouteAddress, RouteAttribute, RouteType};

const INTERFACE_NAME: &str = "eth0";
pub const INTERFACE_NAME: &str = "eth0";

pub async fn configure_network_devices() -> Result<Option<(Ipv6Addr, u8)>, String> {
let ignore_ra_flag = true; // Till the RA has the correct flags (O or M), ignore the flag
Expand Down Expand Up @@ -124,6 +124,19 @@ pub async fn configure_network_devices() -> Result<Option<(Ipv6Addr, u8)>, Strin
delegated_prefix, prefix_length
);
delegated_prefix_option = Some((delegated_prefix, prefix_length));
if let Err(e) = add_ipv6_route(
&handle,
INTERFACE_NAME,
delegated_prefix,
prefix_length,
None,
1024,
RouteType::Unreachable,
)
.await
{
error!("Failed to add unreachable IPv6 route: {}", e);
}
} else {
info!("No prefix delegation received.");
}
Expand Down Expand Up @@ -227,36 +240,35 @@ async fn _print_ipv6_routes(
}
}

RouteAttribute::Gateway(gw) => {
match gw {
RouteAddress::Inet6(addr) => {
gateway = Some(addr.to_string());
debug!("Parsed IPv6 Gateway: {}", addr);
}
RouteAddress::Other(v) => {
// Some other form of gateway, handle if needed
if v.is_empty() {
debug!("Parsed Empty Gateway");
} else {
let hex_str = v
.iter()
.map(|b| format!("{:02x}", b))
.collect::<Vec<String>>()
.join(":");
gateway = Some(format!("unknown({})", hex_str));
debug!("Parsed Unknown Gateway: {}", hex_str);
}
}
_ => {
debug!("Unhandled Gateway variant");
RouteAttribute::Gateway(gw) => match gw {
RouteAddress::Inet6(addr) => {
gateway = Some(addr.to_string());
debug!("Parsed IPv6 Gateway: {}", addr);
}
RouteAddress::Other(v) => {
if v.is_empty() {
debug!("Parsed Empty Gateway");
} else {
let hex_str = v
.iter()
.map(|b| format!("{:02x}", b))
.collect::<Vec<String>>()
.join(":");
gateway = Some(format!("unknown({})", hex_str));
debug!("Parsed Unknown Gateway: {}", hex_str);
}
}
}
_ => {
debug!("Unhandled Gateway variant");
}
},
_ => {}
}
}

if oif != Some(iface_index) {
let is_unreachable = route_msg.header.kind == RouteType::Unreachable;

if !is_unreachable && oif != Some(iface_index) {
debug!(
"Skipping route not associated with interface '{}'",
interface_name
Expand All @@ -269,12 +281,29 @@ async fn _print_ipv6_routes(
debug!("Default route detected (no destination attribute)");
}

let dest_str = destination.unwrap_or_else(|| "unknown".to_string());
let dest_str = destination.unwrap_or_else(|| {
if is_unreachable {
"unreachable".to_string()
} else {
"unknown".to_string()
}
});

let mut route_str = dest_str.to_string();

if let Some(gw) = gateway {
route_str.push_str(&format!(" via {}", gw));
}
route_str.push_str(&format!(" dev {}", interface_name));

if oif.is_some() {
if is_unreachable {
route_str.push_str(&format!(" dev {} [unreachable]", interface_name));
} else {
route_str.push_str(&format!(" dev {}", interface_name));
}
} else if is_unreachable {
route_str.push_str(" [unreachable]");
}

info!("- {}", route_str);
}
Expand Down
Loading