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

Commit

Permalink
netlink-packet-route/src/rtnl/link: Implement new commands property_a…
Browse files Browse the repository at this point in the history
…dd and property_del for ip link
  • Loading branch information
inemajo authored and cathay4t committed Aug 13, 2021
1 parent b4b3c46 commit cc073b3
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 1 deletion.
2 changes: 2 additions & 0 deletions netlink-packet-route/src/rtnl/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub const RTM_NEWCACHEREPORT: u16 = 96;
pub const RTM_NEWCHAIN: u16 = 100;
pub const RTM_DELCHAIN: u16 = 101;
pub const RTM_GETCHAIN: u16 = 102;
pub const RTM_NEWLINKPROP: u16 = 108;
pub const RTM_DELLINKPROP: u16 = 109;

/// Unknown route
pub const RTN_UNSPEC: u8 = 0;
Expand Down
8 changes: 8 additions & 0 deletions netlink-packet-route/src/rtnl/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub enum RtnlMessage {
DelLink(LinkMessage),
GetLink(LinkMessage),
SetLink(LinkMessage),
NewLinkProp(LinkMessage),
DelLinkProp(LinkMessage),
NewAddress(AddressMessage),
DelAddress(AddressMessage),
GetAddress(AddressMessage),
Expand Down Expand Up @@ -200,6 +202,8 @@ impl RtnlMessage {
DelLink(_) => RTM_DELLINK,
GetLink(_) => RTM_GETLINK,
SetLink(_) => RTM_SETLINK,
NewLinkProp(_) => RTM_NEWLINKPROP,
DelLinkProp(_) => RTM_DELLINKPROP,
NewAddress(_) => RTM_NEWADDR,
DelAddress(_) => RTM_DELADDR,
GetAddress(_) => RTM_GETADDR,
Expand Down Expand Up @@ -243,6 +247,8 @@ impl Emitable for RtnlMessage {
| DelLink(ref msg)
| GetLink(ref msg)
| SetLink(ref msg)
| NewLinkProp(ref msg)
| DelLinkProp(ref msg)
=> msg.buffer_len(),

| NewAddress(ref msg)
Expand Down Expand Up @@ -299,6 +305,8 @@ impl Emitable for RtnlMessage {
| DelLink(ref msg)
| GetLink(ref msg)
| SetLink(ref msg)
| NewLinkProp(ref msg)
| DelLinkProp(ref msg)
=> msg.emit(buffer),

| NewAddress(ref msg)
Expand Down
17 changes: 16 additions & 1 deletion rtnetlink/src/link/handle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use super::{LinkAddRequest, LinkDelRequest, LinkGetRequest, LinkSetRequest};
use super::{
LinkAddRequest,
LinkDelPropRequest,
LinkDelRequest,
LinkGetRequest,
LinkNewPropRequest,
LinkSetRequest,
};
use crate::Handle;

pub struct LinkHandle(Handle);
Expand All @@ -16,6 +23,14 @@ impl LinkHandle {
LinkAddRequest::new(self.0.clone())
}

pub fn property_add(&self, index: u32) -> LinkNewPropRequest {
LinkNewPropRequest::new(self.0.clone(), index)
}

pub fn property_del(&self, index: u32) -> LinkDelPropRequest {
LinkDelPropRequest::new(self.0.clone(), index)
}

pub fn del(&mut self, index: u32) -> LinkDelRequest {
LinkDelRequest::new(self.0.clone(), index)
}
Expand Down
6 changes: 6 additions & 0 deletions rtnetlink/src/link/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,11 @@ pub use self::get::*;
mod set;
pub use self::set::*;

mod property_add;
pub use self::property_add::*;

mod property_del;
pub use self::property_del::*;

#[cfg(test)]
mod test;
65 changes: 65 additions & 0 deletions rtnetlink/src/link/property_add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use crate::{
packet::{
nlas::link::{Nla, Prop},
LinkMessage,
NetlinkMessage,
NetlinkPayload,
RtnlMessage,
NLM_F_ACK,
NLM_F_APPEND,
NLM_F_CREATE,
NLM_F_EXCL,
NLM_F_REQUEST,
},
Error,
Handle,
};
use futures::stream::StreamExt;

pub struct LinkNewPropRequest {
handle: Handle,
message: LinkMessage,
}

impl LinkNewPropRequest {
pub(crate) fn new(handle: Handle, index: u32) -> Self {
let mut message = LinkMessage::default();
message.header.index = index;
LinkNewPropRequest { handle, message }
}

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

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
if let NetlinkPayload::Error(err) = message.payload {
return Err(Error::NetlinkError(err));
}
}
Ok(())
}

/// Return a mutable reference to the request
pub fn message_mut(&mut self) -> &mut LinkMessage {
&mut self.message
}

/// Add alternative name to the link. This is equivalent to `ip link property add altname
/// ALT_IFNAME dev LINK`.
pub fn alt_ifname(mut self, alt_ifnames: &[&str]) -> Self {
let mut props = Vec::new();
for alt_ifname in alt_ifnames {
props.push(Prop::AltIfName(alt_ifname.to_string()));
}

self.message.nlas.push(Nla::PropList(props));
self
}
}
63 changes: 63 additions & 0 deletions rtnetlink/src/link/property_del.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::{
packet::{
nlas::link::{Nla, Prop},
LinkMessage,
NetlinkMessage,
NetlinkPayload,
RtnlMessage,
NLM_F_ACK,
NLM_F_EXCL,
NLM_F_REQUEST,
},
Error,
Handle,
};
use futures::stream::StreamExt;

pub struct LinkDelPropRequest {
handle: Handle,
message: LinkMessage,
}

impl LinkDelPropRequest {
pub(crate) fn new(handle: Handle, index: u32) -> Self {
let mut message = LinkMessage::default();
message.header.index = index;
LinkDelPropRequest { handle, message }
}

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

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
if let NetlinkPayload::Error(err) = message.payload {
return Err(Error::NetlinkError(err));
}
}
Ok(())
}

/// Return a mutable reference to the request
pub fn message_mut(&mut self) -> &mut LinkMessage {
&mut self.message
}

/// Remove alternative name to the link. This is equivalent to `ip link property del altname
/// ALT_IFNAME dev LINK`.
pub fn alt_ifname(mut self, alt_ifnames: &[&str]) -> Self {
let mut props = Vec::new();
for alt_ifname in alt_ifnames {
props.push(Prop::AltIfName(alt_ifname.to_string()));
}

self.message.nlas.push(Nla::PropList(props));
self
}
}

0 comments on commit cc073b3

Please sign in to comment.