Skip to content

Commit

Permalink
vmm: Sync route flags
Browse files Browse the repository at this point in the history
Signed-off-by: Zhang Tianyang <burning9699@gmail.com>
  • Loading branch information
Burning1020 committed Aug 15, 2024
1 parent 6486535 commit ab97ded
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions vmm/common/src/protos/sandbox.proto
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ message Route {
string source = 4;
uint32 scope = 5;
IPFamily family = 6;
uint32 flags = 7;
}

message UpdateInterfacesRequest {
Expand Down
1 change: 1 addition & 0 deletions vmm/sandbox/src/network/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ impl From<&crate::network::Route> for Route {
AddressFamily::Inet6 => IPFamily::v6,
_ => IPFamily::default(),
}),
flags: r.flags,
special_fields: Default::default(),
}
}
Expand Down
18 changes: 18 additions & 0 deletions vmm/sandbox/src/network/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RouteFlag>);

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 {
Expand All @@ -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;
Expand Down
46 changes: 45 additions & 1 deletion vmm/task/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,16 @@ 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()
.table_id(RouteHeader::RT_TABLE_MAIN as u32)
.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.
Expand Down Expand Up @@ -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<RouteFlag>);

impl From<u32> 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);

Expand Down

0 comments on commit ab97ded

Please sign in to comment.