From 9612e8c7f2e8468e59db39f5120a52c181c36f63 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 31 Dec 2021 11:40:48 -0500 Subject: [PATCH] add netlink support for networkinterfaces --- .../native/utils/network_interfaces/mod.rs | 59 ++++++++++++++++++- .../utils/network_interfaces/netlink.rs | 18 +++--- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/veilid-core/src/intf/native/utils/network_interfaces/mod.rs b/veilid-core/src/intf/native/utils/network_interfaces/mod.rs index a5bf066b..17a2636f 100644 --- a/veilid-core/src/intf/native/utils/network_interfaces/mod.rs +++ b/veilid-core/src/intf/native/utils/network_interfaces/mod.rs @@ -1,5 +1,6 @@ use crate::xx::*; use crate::*; +use core::fmt; mod tools; cfg_if::cfg_if! { @@ -109,13 +110,28 @@ impl InterfaceAddress { } } -#[derive(PartialEq, Eq, Clone, Debug)] +#[derive(PartialEq, Eq, Clone)] pub struct NetworkInterface { pub name: String, pub flags: InterfaceFlags, pub addrs: Vec, } +impl fmt::Debug for NetworkInterface { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("NetworkInterface") + .field("name", &self.name) + .field("flags", &self.flags) + .field("addrs", &self.addrs) + .finish()?; + if f.alternate() { + writeln!(f)?; + writeln!(f, "// primary_ipv4: {:?}", self.primary_ipv4())?; + writeln!(f, "// primary_ipv6: {:?}", self.primary_ipv6())?; + } + Ok(()) + } +} #[allow(dead_code)] impl NetworkInterface { pub fn new(name: String, flags: InterfaceFlags) -> Self { @@ -171,12 +187,30 @@ impl NetworkInterface { } } -#[derive(PartialEq, Eq, Clone, Debug)] +#[derive(PartialEq, Eq, Clone)] pub struct NetworkInterfaces { valid: bool, interfaces: BTreeMap, } +impl fmt::Debug for NetworkInterfaces { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("NetworkInterfaces") + .field("valid", &self.valid) + .field("interfaces", &self.interfaces) + .finish()?; + if f.alternate() { + writeln!(f)?; + writeln!( + f, + "// default_route_addresses: {:?}", + self.default_route_addresses() + )?; + } + Ok(()) + } +} + #[allow(dead_code)] impl NetworkInterfaces { pub fn new() -> Self { @@ -205,7 +239,11 @@ impl NetworkInterfaces { self.valid = true; - Ok(last_interfaces != self.interfaces) + let changed = last_interfaces != self.interfaces; + if changed { + trace!("NetworkInterfaces refreshed: {:#?}?", self); + } + Ok(changed) } pub fn len(&self) -> usize { self.interfaces.len() @@ -213,4 +251,19 @@ impl NetworkInterfaces { pub fn iter(&self) -> std::collections::btree_map::Iter { self.interfaces.iter() } + + pub fn default_route_addresses(&self) -> Vec { + let mut out = Vec::new(); + for intf in self.interfaces.values() { + if intf.is_running() && intf.has_default_route() && !intf.is_loopback() { + if let Some(pipv4) = intf.primary_ipv4() { + out.push(IpAddr::V4(pipv4)); + } + if let Some(pipv6) = intf.primary_ipv6() { + out.push(IpAddr::V6(pipv6)); + } + } + } + out + } } diff --git a/veilid-core/src/intf/native/utils/network_interfaces/netlink.rs b/veilid-core/src/intf/native/utils/network_interfaces/netlink.rs index 296fc49a..2d47a29a 100644 --- a/veilid-core/src/intf/native/utils/network_interfaces/netlink.rs +++ b/veilid-core/src/intf/native/utils/network_interfaces/netlink.rs @@ -68,21 +68,19 @@ impl PlatformSupportNetlink { self.default_route_interfaces.clear(); let mut routesv4 = self.handle.route().get(IpVersion::V4).execute(); while let Some(routev4) = routesv4.try_next().await.unwrap_or_default() { - if let Some(index) = routev4.input_interface() { - if let Some((dest, prefix)) = routev4.destination_prefix() { - if prefix == 0 && dest.is_unspecified() { - self.default_route_interfaces.insert(index); - } + if let Some(index) = routev4.output_interface() { + //println!("*** ipv4 route: {:#?}", routev4); + if routev4.header.destination_prefix_length == 0 { + self.default_route_interfaces.insert(index); } } } let mut routesv6 = self.handle.route().get(IpVersion::V6).execute(); while let Some(routev6) = routesv6.try_next().await.unwrap_or_default() { - if let Some(index) = routev6.input_interface() { - if let Some((dest, prefix)) = routev6.destination_prefix() { - if prefix == 0 && dest.is_unspecified() { - self.default_route_interfaces.insert(index); - } + if let Some(index) = routev6.output_interface() { + //println!("*** ipv6 route: {:#?}", routev6); + if routev6.header.destination_prefix_length == 0 { + self.default_route_interfaces.insert(index); } } }