add netlink support for networkinterfaces

This commit is contained in:
John Smith 2021-12-31 11:40:48 -05:00
parent 7ba6748cd2
commit 9612e8c7f2
2 changed files with 64 additions and 13 deletions

View File

@ -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<InterfaceAddress>,
}
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<String, NetworkInterface>,
}
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<String, NetworkInterface> {
self.interfaces.iter()
}
pub fn default_route_addresses(&self) -> Vec<IpAddr> {
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
}
}

View File

@ -68,24 +68,22 @@ 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() {
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() {
if let Some(index) = routev6.output_interface() {
//println!("*** ipv6 route: {:#?}", routev6);
if routev6.header.destination_prefix_length == 0 {
self.default_route_interfaces.insert(index);
}
}
}
}
Ok(())
}