Skip to content

Commit fa2960e

Browse files
link: add vxcan support
Signed-off-by: Romain Reignier <romain.reignier@exail.com>
1 parent 1ab04a8 commit fa2960e

4 files changed

Lines changed: 101 additions & 1 deletion

File tree

examples/create_vxcan.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use futures_util::stream::TryStreamExt;
4+
use rtnetlink::{new_connection, Error, Handle, LinkUnspec, LinkVxcan};
5+
6+
#[tokio::main]
7+
async fn main() -> Result<(), String> {
8+
let (connection, handle, _) = new_connection().unwrap();
9+
tokio::spawn(connection);
10+
11+
let link_name = "vxcan0".to_string();
12+
let peer_name = "vxcan0-peer".to_string();
13+
14+
handle
15+
.link()
16+
.add(LinkVxcan::new(&link_name, &peer_name).build())
17+
.execute()
18+
.await
19+
.map_err(|e| format!("{e}"))?;
20+
21+
set_link_up(&handle, link_name.clone())
22+
.await
23+
.map_err(|e| format!("{e}"))?;
24+
25+
set_link_up(&handle, peer_name.clone())
26+
.await
27+
.map_err(|e| format!("{e}"))?;
28+
29+
Ok(())
30+
}
31+
32+
async fn set_link_up(handle: &Handle, name: String) -> Result<(), Error> {
33+
let mut links = handle.link().get().match_name(name.clone()).execute();
34+
if let Some(link) = links.try_next().await? {
35+
handle
36+
.link()
37+
.set(LinkUnspec::new_with_index(link.header.index).up().build())
38+
.execute()
39+
.await?
40+
} else {
41+
println!("no link link {name} found");
42+
}
43+
Ok(())
44+
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ pub use crate::{
5353
LinkBridgeVlan, LinkDelPropRequest, LinkDelRequest, LinkDummy,
5454
LinkGetRequest, LinkHandle, LinkMacSec, LinkMacVlan, LinkMacVtap,
5555
LinkMessageBuilder, LinkNetkit, LinkSetRequest, LinkUnspec, LinkVeth,
56-
LinkVlan, LinkVrf, LinkVxlan, LinkWireguard, LinkXfrm, QosMapping,
56+
LinkVlan, LinkVrf, LinkVxcan, LinkVxlan, LinkWireguard, LinkXfrm,
57+
QosMapping,
5758
},
5859
multicast::MulticastGroup,
5960
neighbour::{

src/link/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mod set;
2222
mod veth;
2323
mod vlan;
2424
mod vrf;
25+
mod vxcan;
2526
mod vxlan;
2627
mod wireguard;
2728
mod xfrm;
@@ -47,6 +48,7 @@ pub use self::{
4748
veth::LinkVeth,
4849
vlan::{LinkVlan, QosMapping},
4950
vrf::LinkVrf,
51+
vxcan::LinkVxcan,
5052
vxlan::LinkVxlan,
5153
wireguard::LinkWireguard,
5254
xfrm::LinkXfrm,

src/link/vxcan.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use crate::{
4+
packet_route::link::{InfoData, InfoKind, InfoVxcan},
5+
LinkMessageBuilder, LinkUnspec,
6+
};
7+
8+
/// Represent virtual can interface.
9+
/// Example code on creating a vxcan pair
10+
/// ```no_run
11+
/// use rtnetlink::{new_connection, LinkVxcan};
12+
/// #[tokio::main]
13+
/// async fn main() -> Result<(), String> {
14+
/// let (connection, handle, _) = new_connection().unwrap();
15+
/// tokio::spawn(connection);
16+
///
17+
/// handle
18+
/// .link()
19+
/// .add(LinkVxcan::new("vxcan0", "vxcan1").build())
20+
/// .execute()
21+
/// .await
22+
/// .map_err(|e| format!("{e}"))
23+
/// }
24+
/// ```
25+
///
26+
/// Please check LinkMessageBuilder::<LinkVxcan> for more detail.
27+
#[derive(Debug)]
28+
pub struct LinkVxcan;
29+
30+
impl LinkVxcan {
31+
/// Equal to `LinkMessageBuilder::<LinkVxcan>::new(name, peer)`
32+
pub fn new(name: &str, peer: &str) -> LinkMessageBuilder<Self> {
33+
LinkMessageBuilder::<LinkVxcan>::new(name, peer)
34+
}
35+
}
36+
37+
impl LinkMessageBuilder<LinkVxcan> {
38+
/// Create [LinkMessageBuilder] for Vxcan
39+
pub fn new(name: &str, peer: &str) -> Self {
40+
LinkMessageBuilder::<LinkVxcan>::new_with_info_kind(InfoKind::Vxcan)
41+
.name(name.to_string())
42+
.peer(peer)
43+
}
44+
45+
pub fn peer(mut self, peer: &str) -> Self {
46+
let peer_msg = LinkMessageBuilder::<LinkUnspec>::new()
47+
.name(peer.to_string())
48+
.build();
49+
50+
self.info_data = Some(InfoData::Vxcan(InfoVxcan::Peer(peer_msg)));
51+
self
52+
}
53+
}

0 commit comments

Comments
 (0)