From ab97ded368cad62c7bded0184d5f1fc34d2f2489 Mon Sep 17 00:00:00 2001 From: Zhang Tianyang Date: Thu, 15 Aug 2024 17:15:07 +0800 Subject: [PATCH] vmm: Sync route flags Signed-off-by: Zhang Tianyang --- vmm/common/src/protos/sandbox.proto | 1 + vmm/sandbox/src/network/convert.rs | 1 + vmm/sandbox/src/network/route.rs | 18 +++++++++++ vmm/task/src/netlink.rs | 46 ++++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/vmm/common/src/protos/sandbox.proto b/vmm/common/src/protos/sandbox.proto index f49f66c0..49bb6ed2 100644 --- a/vmm/common/src/protos/sandbox.proto +++ b/vmm/common/src/protos/sandbox.proto @@ -102,6 +102,7 @@ message Route { string source = 4; uint32 scope = 5; IPFamily family = 6; + uint32 flags = 7; } message UpdateInterfacesRequest { diff --git a/vmm/sandbox/src/network/convert.rs b/vmm/sandbox/src/network/convert.rs index 053113f8..4ee040b0 100644 --- a/vmm/sandbox/src/network/convert.rs +++ b/vmm/sandbox/src/network/convert.rs @@ -63,6 +63,7 @@ impl From<&crate::network::Route> for Route { AddressFamily::Inet6 => IPFamily::v6, _ => IPFamily::default(), }), + flags: r.flags, special_fields: Default::default(), } } diff --git a/vmm/sandbox/src/network/route.rs b/vmm/sandbox/src/network/route.rs index d41bb8d4..df4baa90 100644 --- a/vmm/sandbox/src/network/route.rs +++ b/vmm/sandbox/src/network/route.rs @@ -35,6 +35,23 @@ pub struct Route { pub scope: u8, #[serde(default)] pub family: u8, + #[serde(default)] + pub flags: u32, +} + +use netlink_packet_route::route::RouteFlag; + +// netlink-packet-route-0.19.0/src/route/flags.rs:87 +pub(crate) struct VecRouteFlag(pub(crate) Vec); + +impl From<&VecRouteFlag> for u32 { + fn from(v: &VecRouteFlag) -> u32 { + let mut d: u32 = 0; + for flag in &v.0 { + d += u32::from(*flag); + } + d + } } impl Route { @@ -45,6 +62,7 @@ impl Route { let mut route = Route { scope: msg.header.scope.into(), family: msg.header.address_family.into(), + flags: u32::from(&VecRouteFlag(msg.header.flags)), ..Route::default() }; use netlink_packet_route::route::RouteAttribute; diff --git a/vmm/task/src/netlink.rs b/vmm/task/src/netlink.rs index c267eb5b..0fcd5ceb 100644 --- a/vmm/task/src/netlink.rs +++ b/vmm/task/src/netlink.rs @@ -320,7 +320,7 @@ impl Handle { let link = self.find_link(LinkFilter::Name(&route.device)).await?; // Build a common indeterminate ip request - let request = self + let mut request = self .handle .route() .add() @@ -328,6 +328,8 @@ impl Handle { .kind(RouteType::Unicast) .protocol(RouteProtocol::Boot) .scope(RouteScope::from(route.scope as u8)); + // Override the existing flags, as the flags sent by the client should take precedence. + request.message_mut().header.flags = VecRouteFlag::from(route.flags).0; // `rtnetlink` offers a separate request builders for different IP versions (IP v4 and v6). // This if branch is a bit clumsy because it does almost the same. @@ -473,6 +475,48 @@ impl Handle { } } +use netlink_packet_route::route::RouteFlag; + +// netlink-packet-route-0.19.0/src/route/flags.rs:42 +const ALL_ROUTE_FLAGS: [RouteFlag; 16] = [ + RouteFlag::Dead, + RouteFlag::Pervasive, + RouteFlag::Onlink, + RouteFlag::Offload, + RouteFlag::Linkdown, + RouteFlag::Unresolved, + RouteFlag::Trap, + RouteFlag::Notify, + RouteFlag::Cloned, + RouteFlag::Equalize, + RouteFlag::Prefix, + RouteFlag::LookupTable, + RouteFlag::FibMatch, + RouteFlag::RtOffload, + RouteFlag::RtTrap, + RouteFlag::OffloadFailed, +]; + +// netlink-packet-route-0.19.0/src/route/flags.rs:87 +pub(crate) struct VecRouteFlag(pub(crate) Vec); + +impl From for VecRouteFlag { + fn from(d: u32) -> Self { + let mut got: u32 = 0; + let mut ret = Vec::new(); + for flag in ALL_ROUTE_FLAGS { + if (d & (u32::from(flag))) > 0 { + ret.push(flag); + got += u32::from(flag); + } + } + if got != d { + ret.push(RouteFlag::Other(d - got)); + } + Self(ret) + } +} + /// Wraps external type with the local one, so we can implement various extensions and type conversions. struct Link(LinkMessage);