Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ futures-channel = "0.3.11"
log = "0.4.8"
thiserror = "1"
netlink-sys = { version = "0.8" }
netlink-packet-route = { version = "0.28" }
netlink-packet-route = { version = "0.29" }
netlink-packet-core = { version = "0.8" }
netlink-proto = { default-features = false, version = "0.12.0" }
nix = { version = "0.30.0", default-features = false, features = ["fs", "mount", "sched", "signal"] }
Expand Down
44 changes: 44 additions & 0 deletions examples/create_vxcan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT

use futures_util::stream::TryStreamExt;
use rtnetlink::{new_connection, Error, Handle, LinkUnspec, LinkVxcan};

#[tokio::main]
async fn main() -> Result<(), String> {
let (connection, handle, _) = new_connection().unwrap();
tokio::spawn(connection);

let link_name = "vxcan0";
let peer_name = "vxcan0-peer";

handle
.link()
.add(LinkVxcan::new(link_name, peer_name).build())
.execute()
.await
.map_err(|e| format!("{e}"))?;

set_link_up(&handle, link_name)
.await
.map_err(|e| format!("{e}"))?;

set_link_up(&handle, peer_name)
.await
.map_err(|e| format!("{e}"))?;

Ok(())
}

async fn set_link_up(handle: &Handle, name: &str) -> Result<(), Error> {
let mut links = handle.link().get().match_name(name.to_string()).execute();
if let Some(link) = links.try_next().await? {
handle
.link()
.set(LinkUnspec::new_with_index(link.header.index).up().build())
.execute()
.await?
} else {
println!("no link {name} found");
}
Ok(())
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pub use crate::{
LinkBridgeVlan, LinkDelPropRequest, LinkDelRequest, LinkDummy,
LinkGetRequest, LinkHandle, LinkMacSec, LinkMacVlan, LinkMacVtap,
LinkMessageBuilder, LinkNetkit, LinkSetRequest, LinkUnspec, LinkVeth,
LinkVlan, LinkVrf, LinkVxlan, LinkWireguard, LinkXfrm, QosMapping,
LinkVlan, LinkVrf, LinkVxcan, LinkVxlan, LinkWireguard, LinkXfrm,
QosMapping,
},
multicast::MulticastGroup,
neighbour::{
Expand Down
8 changes: 4 additions & 4 deletions src/link/bond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use std::net::{Ipv4Addr, Ipv6Addr};
use crate::{
link::LinkMessageBuilder,
packet_route::link::{
BondAllPortActive, BondArpAllTargets, BondArpValidate, BondFailOverMac,
BondLacpRate, BondMode, BondPrimaryReselect, BondXmitHashPolicy,
InfoBond, InfoData, InfoKind,
BondAdSelect, BondAllPortActive, BondArpAllTargets, BondArpValidate,
BondFailOverMac, BondLacpRate, BondMode, BondPrimaryReselect,
BondXmitHashPolicy, InfoBond, InfoData, InfoKind,
},
};

Expand Down Expand Up @@ -218,7 +218,7 @@ impl LinkMessageBuilder<LinkBond> {
/// Adds the `ad_select` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_select
/// AD_SELECT`.
pub fn ad_select(self, ad_select: u8) -> Self {
pub fn ad_select(self, ad_select: BondAdSelect) -> Self {
self.append_info_data(InfoBond::AdSelect(ad_select))
}

Expand Down
2 changes: 1 addition & 1 deletion src/link/bridge_port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl LinkMessageBuilder<LinkBridgePort> {
/// `ip link set name NAME type bridge_slave \
/// neigh_vlan_suppress { on | off }`.
pub fn neigh_vlan_suppress(self, v: bool) -> Self {
self.append_info_data(InfoBridgePort::NeighVlanSupress(v))
self.append_info_data(InfoBridgePort::NeighVlanSuppress(v))
}

/// This is equivalent to
Expand Down
2 changes: 2 additions & 0 deletions src/link/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod set;
mod veth;
mod vlan;
mod vrf;
mod vxcan;
mod vxlan;
mod wireguard;
mod xfrm;
Expand All @@ -47,6 +48,7 @@ pub use self::{
veth::LinkVeth,
vlan::{LinkVlan, QosMapping},
vrf::LinkVrf,
vxcan::LinkVxcan,
vxlan::LinkVxlan,
wireguard::LinkWireguard,
xfrm::LinkXfrm,
Expand Down
53 changes: 53 additions & 0 deletions src/link/vxcan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT

use crate::{
packet_route::link::{InfoData, InfoKind, InfoVxcan},
LinkMessageBuilder, LinkUnspec,
};

/// Represent virtual can interface.
/// Example code on creating a vxcan pair
/// ```no_run
/// use rtnetlink::{new_connection, LinkVxcan};
/// #[tokio::main]
/// async fn main() -> Result<(), String> {
/// let (connection, handle, _) = new_connection().unwrap();
/// tokio::spawn(connection);
///
/// handle
/// .link()
/// .add(LinkVxcan::new("vxcan0", "vxcan1").build())
/// .execute()
/// .await
/// .map_err(|e| format!("{e}"))
/// }
/// ```
///
/// Please check LinkMessageBuilder::<LinkVxcan> for more detail.
#[derive(Debug)]
pub struct LinkVxcan;

impl LinkVxcan {
/// Equal to `LinkMessageBuilder::<LinkVxcan>::new(name, peer)`
pub fn new(name: &str, peer: &str) -> LinkMessageBuilder<Self> {
LinkMessageBuilder::<LinkVxcan>::new(name, peer)
}
}

impl LinkMessageBuilder<LinkVxcan> {
/// Create [LinkMessageBuilder] for Vxcan
pub fn new(name: &str, peer: &str) -> Self {
LinkMessageBuilder::<LinkVxcan>::new_with_info_kind(InfoKind::Vxcan)
.name(name.to_string())
.peer(peer)
}

pub fn peer(mut self, peer: &str) -> Self {
let peer_msg = LinkMessageBuilder::<LinkUnspec>::new()
.name(peer.to_string())
.build();

self.info_data = Some(InfoData::Vxcan(InfoVxcan::Peer(peer_msg)));
self
}
}