From b60536b918e94c7cb758f039b09f0fccfba9fe38 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Fri, 1 Nov 2024 12:43:10 +0900 Subject: [PATCH] netlink-packet-route upgrade to stop choking on vxlans --- Cargo.lock | 7 +++-- Cargo.toml | 2 +- src/netlink/route.rs | 67 ++++++++++++++++++++------------------------ 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee30fc0..0c730a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,14 +260,15 @@ dependencies = [ [[package]] name = "netlink-packet-route" -version = "0.17.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" +checksum = "483325d4bfef65699214858f097d504eb812c38ce7077d165f301ec406c3066e" dependencies = [ "anyhow", - "bitflags 1.3.2", + "bitflags 2.6.0", "byteorder", "libc", + "log", "netlink-packet-core", "netlink-packet-utils", ] diff --git a/Cargo.toml b/Cargo.toml index 6908d0f..b3f364f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ anyhow = "1.0.86" itertools = "0.13.0" netlink-packet-core = "=0.7.0" netlink-packet-generic = "0.3.3" -netlink-packet-route = "=0.17.1" +netlink-packet-route = "=0.21.0" netlink-packet-sock-diag = "=0.4.2" netlink-packet-wireguard = "0.2.3" netlink-sys = "=0.8.5" diff --git a/src/netlink/route.rs b/src/netlink/route.rs index 18b9010..9910a00 100644 --- a/src/netlink/route.rs +++ b/src/netlink/route.rs @@ -4,11 +4,9 @@ use netlink_packet_core::{ NetlinkHeader, NetlinkMessage, NetlinkPayload, NLM_F_DUMP, NLM_F_REQUEST, }; use netlink_packet_route::{ - constants::*, - link::nlas::Nla as LinkNla, - nlas::link::{Info, InfoKind}, - route::nlas::Nla as RouteNla, - LinkMessage, RouteMessage, RtnlMessage, + link::{InfoKind, LinkAttribute, LinkExtentMask, LinkInfo, LinkMessage}, + route::{RouteAddress, RouteAttribute, RouteMessage, RouteType}, + RouteNetlinkMessage, }; use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr}; use std::{cmp::Reverse, collections::HashMap, net::IpAddr}; @@ -20,9 +18,14 @@ pub struct Interfaces { } pub fn interface_names(socket: &Socket) -> Result { + let mut get_link = LinkMessage::default(); + get_link + .attributes + .push(LinkAttribute::ExtMask(vec![LinkExtentMask::SkipStats])); + // get_link.header.interface_family = AddressFamily::Bridge; let mut packet = NetlinkMessage::new( NetlinkHeader::default(), - NetlinkPayload::from(RtnlMessage::GetLink(LinkMessage::default())), + NetlinkPayload::from(RouteNetlinkMessage::GetLink(get_link)), ); packet.header.flags = NLM_F_DUMP | NLM_F_REQUEST; packet.header.sequence_number = 1; @@ -30,15 +33,15 @@ pub fn interface_names(socket: &Socket) -> Result { let mut map = HashMap::new(); let mut wg_ids = Vec::new(); drive_req(packet, socket, |inner| { - if let RtnlMessage::NewLink(nl) = inner { - for nla in nl.nlas { + if let RouteNetlinkMessage::NewLink(nl) = inner { + for nla in nl.attributes { match nla { - LinkNla::IfName(name) => { + LinkAttribute::IfName(name) => { map.insert(nl.header.index, name); } - LinkNla::Info(infos) => { + LinkAttribute::LinkInfo(infos) => { for info in infos { - if info == Info::Kind(InfoKind::Wireguard) { + if info == LinkInfo::Kind(InfoKind::Wireguard) { wg_ids.push(nl.header.index); } } @@ -145,45 +148,37 @@ impl Rtbl { } pub fn local_routes(socket: &Socket) -> Result { + const RT_TABLE_LOCAL: u8 = 0; let mut route_message = RouteMessage::default(); route_message.header.table = RT_TABLE_LOCAL; // This is respected - route_message.header.kind = RTN_LOCAL; // This is not respected + route_message.header.kind = RouteType::Local; // This is not respected let packet = NetlinkMessage::new( nl_hdr_flags(NLM_F_REQUEST | NLM_F_DUMP), - NetlinkPayload::from(RtnlMessage::GetRoute(route_message)), + NetlinkPayload::from(RouteNetlinkMessage::GetRoute(route_message)), ); let mut ret = Vec::new(); drive_req(packet, socket, |inner| { - if let RtnlMessage::NewRoute(route) = inner { - if route.header.table == RT_TABLE_LOCAL && route.header.kind == RTN_LOCAL { - let iface = route.nlas.iter().find_map(|nla| match nla { - RouteNla::Oif(ifc) => Some(ifc), + if let RouteNetlinkMessage::NewRoute(route) = inner { + if route.header.table == RT_TABLE_LOCAL && route.header.kind == RouteType::Local { + let iface = route.attributes.iter().find_map(|nla| match nla { + RouteAttribute::Oif(ifc) => Some(ifc), _ => None, }); - let dst = route.nlas.iter().find_map(|nla| match nla { - RouteNla::Destination(bits) => Some(bits), + let dst = route.attributes.iter().find_map(|nla| match nla { + RouteAttribute::Destination(bits) => Some(bits), _ => None, }); if let (Some(&iface), Some(dst)) = (iface, dst) { // TODO: more anyhow, less expect/unreachable - ret.push(Route { - iface, - pfx: Prefix { - bits: route.header.destination_prefix_length, - dst: match route.header.address_family as u16 { - AF_INET => <[u8; 4]>::try_from(&dst[..]) - .expect("4 byte ipv4 addr?") - .into(), - AF_INET6 => <[u8; 16]>::try_from(&dst[..]) - .expect("16 byte ipv6 addr?") - .into(), - _ => unreachable!( - "Unknown address family. Have nanites caused IPv8?" - ), - }, - }, - }); + let dst = match *dst { + RouteAddress::Inet(a) => IpAddr::from(a), + RouteAddress::Inet6(a) => IpAddr::from(a), + _ => unreachable!("Unknown address family. Have nanites caused IPv8?"), + }; + let bits = route.header.destination_prefix_length; + let pfx = Prefix { bits, dst }; + ret.push(Route { iface, pfx }); } } }