netlink route add should be exclusive (#596)

This commit is contained in:
Sijie.Sun
2025-02-04 23:01:13 +08:00
committed by GitHub
parent 66051967fe
commit 1e821a03fe

View File

@@ -11,7 +11,7 @@ use async_trait::async_trait;
use cidr::IpInet; use cidr::IpInet;
use netlink_packet_core::{ use netlink_packet_core::{
NetlinkDeserializable, NetlinkHeader, NetlinkMessage, NetlinkPayload, NetlinkSerializable, NetlinkDeserializable, NetlinkHeader, NetlinkMessage, NetlinkPayload, NetlinkSerializable,
NLM_F_ACK, NLM_F_CREATE, NLM_F_DUMP, NLM_F_REQUEST, NLM_F_ACK, NLM_F_CREATE, NLM_F_DUMP, NLM_F_EXCL, NLM_F_REQUEST,
}; };
use netlink_packet_route::{ use netlink_packet_route::{
address::{AddressAttribute, AddressMessage}, address::{AddressAttribute, AddressMessage},
@@ -70,8 +70,12 @@ fn send_netlink_req<T: NetlinkDeserializable + NetlinkSerializable + Debug>(
fn send_netlink_req_and_wait_one_resp<T: NetlinkDeserializable + NetlinkSerializable + Debug>( fn send_netlink_req_and_wait_one_resp<T: NetlinkDeserializable + NetlinkSerializable + Debug>(
req: T, req: T,
is_remove: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let socket = send_netlink_req(req, NLM_F_ACK | NLM_F_CREATE | NLM_F_REQUEST)?; let socket = send_netlink_req(
req,
NLM_F_ACK | NLM_F_CREATE | NLM_F_REQUEST | if !is_remove { NLM_F_EXCL } else { 0 },
)?;
let resp = socket.recv_from_full()?; let resp = socket.recv_from_full()?;
let ret = NetlinkMessage::<T>::deserialize(&resp.0) let ret = NetlinkMessage::<T>::deserialize(&resp.0)
.with_context(|| "Failed to deserialize netlink message")?; .with_context(|| "Failed to deserialize netlink message")?;
@@ -184,9 +188,10 @@ impl NetlinkIfConfiger {
.attributes .attributes
.push(AddressAttribute::Address(std::net::IpAddr::V4(ip))); .push(AddressAttribute::Address(std::net::IpAddr::V4(ip)));
send_netlink_req_and_wait_one_resp::<RouteNetlinkMessage>(RouteNetlinkMessage::DelAddress( send_netlink_req_and_wait_one_resp::<RouteNetlinkMessage>(
message, RouteNetlinkMessage::DelAddress(message),
)) true,
)
} }
pub(crate) fn mtu_op<T: TryInto<Ioctl>>( pub(crate) fn mtu_op<T: TryInto<Ioctl>>(
@@ -367,7 +372,7 @@ impl IfConfiguerTrait for NetlinkIfConfiger {
.attributes .attributes
.push(RouteAttribute::Destination(RouteAddress::Inet(address))); .push(RouteAttribute::Destination(RouteAddress::Inet(address)));
send_netlink_req_and_wait_one_resp(RouteNetlinkMessage::NewRoute(message)) send_netlink_req_and_wait_one_resp(RouteNetlinkMessage::NewRoute(message), false)
} }
async fn remove_ipv4_route( async fn remove_ipv4_route(
@@ -383,7 +388,7 @@ impl IfConfiguerTrait for NetlinkIfConfiger {
if other_route.destination == std::net::IpAddr::V4(address) if other_route.destination == std::net::IpAddr::V4(address)
&& other_route.prefix == cidr_prefix && other_route.prefix == cidr_prefix
{ {
send_netlink_req_and_wait_one_resp(RouteNetlinkMessage::DelRoute(msg))?; send_netlink_req_and_wait_one_resp(RouteNetlinkMessage::DelRoute(msg), true)?;
return Ok(()); return Ok(());
} }
} }
@@ -424,9 +429,10 @@ impl IfConfiguerTrait for NetlinkIfConfiger {
message.attributes.push(AddressAttribute::Broadcast(brd)); message.attributes.push(AddressAttribute::Broadcast(brd));
}; };
send_netlink_req_and_wait_one_resp::<RouteNetlinkMessage>(RouteNetlinkMessage::NewAddress( send_netlink_req_and_wait_one_resp::<RouteNetlinkMessage>(
message, RouteNetlinkMessage::NewAddress(message),
)) false,
)
} }
async fn set_link_status(&self, name: &str, up: bool) -> Result<(), Error> { async fn set_link_status(&self, name: &str, up: bool) -> Result<(), Error> {