Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Commit

Permalink
rtnetlink: add replace option to Add*Request
Browse files Browse the repository at this point in the history
This option sets the NLM_F_REPLACE instead of the NLM_F_EXCL flag,
allowing "create or update" patterns.
  • Loading branch information
Alexis Bauvin committed Nov 25, 2021
1 parent d3be2ce commit e4b41a6
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 7 deletions.
20 changes: 18 additions & 2 deletions rtnetlink/src/addr/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use netlink_packet_route::{
NLM_F_ACK,
NLM_F_CREATE,
NLM_F_EXCL,
NLM_F_REPLACE,
NLM_F_REQUEST,
};

Expand All @@ -22,6 +23,7 @@ use crate::{try_nl, Error, Handle};
pub struct AddressAddRequest {
handle: Handle,
message: AddressMessage,
replace: bool,
}

impl AddressAddRequest {
Expand Down Expand Up @@ -68,17 +70,31 @@ impl AddressAddRequest {
message.nlas.push(Nla::Broadcast(brd.octets().to_vec()));
};
}
AddressAddRequest { handle, message }
AddressAddRequest {
handle,
message,
replace: false,
}
}

/// Replace existing matching address.
pub fn replace(self) -> Self {
Self {
replace: true,
..self
}
}

/// Execute the request.
pub async fn execute(self) -> Result<(), Error> {
let AddressAddRequest {
mut handle,
message,
replace,
} = self;
let mut req = NetlinkMessage::from(RtnlMessage::NewAddress(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down
15 changes: 14 additions & 1 deletion rtnetlink/src/link/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
NLM_F_ACK,
NLM_F_CREATE,
NLM_F_EXCL,
NLM_F_REPLACE,
NLM_F_REQUEST,
},
try_nl,
Expand Down Expand Up @@ -246,13 +247,15 @@ impl VxlanAddRequest {
pub struct LinkAddRequest {
handle: Handle,
message: LinkMessage,
replace: bool,
}

impl LinkAddRequest {
pub(crate) fn new(handle: Handle) -> Self {
LinkAddRequest {
handle,
message: LinkMessage::default(),
replace: false,
}
}

Expand All @@ -261,9 +264,11 @@ impl LinkAddRequest {
let LinkAddRequest {
mut handle,
message,
replace,
} = self;
let mut req = NetlinkMessage::from(RtnlMessage::NewLink(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down Expand Up @@ -369,6 +374,14 @@ impl LinkAddRequest {
.append_nla(Nla::IfName(name))
}

/// Replace existing matching link.
pub fn replace(self) -> Self {
Self {
replace: true,
..self
}
}

fn up(mut self) -> Self {
self.message.header.flags = IFF_UP;
self.message.header.change_mask = IFF_UP;
Expand Down
19 changes: 17 additions & 2 deletions rtnetlink/src/neighbour/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::net::IpAddr;
pub struct NeighbourAddRequest {
handle: Handle,
message: NeighbourMessage,
replace: bool,
}

impl NeighbourAddRequest {
Expand All @@ -37,7 +38,11 @@ impl NeighbourAddRequest {
IpAddr::V6(v6) => v6.octets().to_vec(),
}));

NeighbourAddRequest { handle, message }
NeighbourAddRequest {
handle,
message,
replace: false,
}
}

/// Set a bitmask of states for the neighbor cache entry.
Expand Down Expand Up @@ -67,15 +72,25 @@ impl NeighbourAddRequest {
self
}

/// Replace existing matching neighbor.
pub fn replace(self) -> Self {
Self {
replace: true,
..self
}
}

/// Execute the request.
pub async fn execute(self) -> Result<(), Error> {
let NeighbourAddRequest {
mut handle,
message,
replace,
} = self;

let mut req = NetlinkMessage::from(RtnlMessage::NewNeighbour(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down
16 changes: 15 additions & 1 deletion rtnetlink/src/route/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{try_nl, Error, Handle};
pub struct RouteAddRequest<T = ()> {
handle: Handle,
message: RouteMessage,
replace: bool,
_phantom: PhantomData<T>,
}

Expand All @@ -35,6 +36,7 @@ impl<T> RouteAddRequest<T> {
RouteAddRequest {
handle,
message,
replace: false,
_phantom: Default::default(),
}
}
Expand Down Expand Up @@ -89,6 +91,7 @@ impl<T> RouteAddRequest<T> {
RouteAddRequest {
handle: self.handle,
message: self.message,
replace: false,
_phantom: Default::default(),
}
}
Expand All @@ -99,19 +102,30 @@ impl<T> RouteAddRequest<T> {
RouteAddRequest {
handle: self.handle,
message: self.message,
replace: false,
_phantom: Default::default(),
}
}

/// Replace existing matching route.
pub fn replace(self) -> Self {
Self {
replace: true,
..self
}
}

/// Execute the request.
pub async fn execute(self) -> Result<(), Error> {
let RouteAddRequest {
mut handle,
message,
replace,
..
} = self;
let mut req = NetlinkMessage::from(RtnlMessage::NewRoute(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down
16 changes: 15 additions & 1 deletion rtnetlink/src/rule/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{try_nl, Error, Handle};
pub struct RuleAddRequest<T = ()> {
handle: Handle,
message: RuleMessage,
replace: bool,
_phantom: PhantomData<T>,
}

Expand All @@ -33,6 +34,7 @@ impl<T> RuleAddRequest<T> {
RuleAddRequest {
handle,
message,
replace: false,
_phantom: Default::default(),
}
}
Expand Down Expand Up @@ -75,6 +77,7 @@ impl<T> RuleAddRequest<T> {
RuleAddRequest {
handle: self.handle,
message: self.message,
replace: false,
_phantom: Default::default(),
}
}
Expand All @@ -85,19 +88,30 @@ impl<T> RuleAddRequest<T> {
RuleAddRequest {
handle: self.handle,
message: self.message,
replace: false,
_phantom: Default::default(),
}
}

/// Replace existing matching rule.
pub fn replace(self) -> Self {
Self {
replace: true,
..self
}
}

/// Execute the request.
pub async fn execute(self) -> Result<(), Error> {
let RuleAddRequest {
mut handle,
message,
replace,
..
} = self;
let mut req = NetlinkMessage::from(RtnlMessage::NewRule(message));
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down

0 comments on commit e4b41a6

Please sign in to comment.