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

Commit 8288e17

Browse files
flouthoccathay4t
authored andcommitted
LinkAddRequest: Allow adding macvlan on a link
Following adds support to create MACVLAN on a link. This is equivalent to `ip link add NAME name link LINK type macvlan mode MACVLAN_MODE`. But instead of specifying a link name (LINK), we specify a link index and a mode. Veth must be already up for this to work. Following behaviour is expected cause its same for `vxlan` and `vlan`. Signed-off-by: Aditya Rajan <[email protected]>
1 parent 2364a3b commit 8288e17

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use futures::stream::TryStreamExt;
2+
use rtnetlink::{new_connection, Error, Handle};
3+
use std::env;
4+
5+
#[tokio::main]
6+
async fn main() -> Result<(), String> {
7+
let args: Vec<String> = env::args().collect();
8+
if args.len() != 2 {
9+
usage();
10+
return Ok(());
11+
}
12+
let link_name = &args[1];
13+
14+
let (connection, handle, _) = new_connection().unwrap();
15+
tokio::spawn(connection);
16+
17+
create_macvlan(handle, link_name.to_string())
18+
.await
19+
.map_err(|e| format!("{}", e))
20+
}
21+
22+
async fn create_macvlan(handle: Handle, veth_name: String) -> Result<(), Error> {
23+
let mut links = handle
24+
.link()
25+
.get()
26+
.set_name_filter(veth_name.clone())
27+
.execute();
28+
if let Some(link) = links.try_next().await? {
29+
// hard code mode: 4u32 i.e bridge mode
30+
let request = handle
31+
.link()
32+
.add()
33+
.macvlan("test_macvlan".into(), link.header.index, 4u32);
34+
request.execute().await?
35+
} else {
36+
println!("no link link {} found", veth_name);
37+
}
38+
Ok(())
39+
}
40+
41+
fn usage() {
42+
eprintln!(
43+
"usage:
44+
cargo run --example create_macvlan -- <link name>
45+
46+
Note that you need to run this program as root. Instead of running cargo as root,
47+
build the example normally:
48+
49+
cd netlink-ip ; cargo build --example create_macvlan
50+
51+
Then find the binary in the target directory:
52+
53+
cd ../target/debug/example ; sudo ./create_macvlan <link_name>"
54+
);
55+
}

rtnetlink/src/link/add.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use futures::stream::StreamExt;
22

33
use crate::{
44
packet::{
5-
nlas::link::{Info, InfoData, InfoKind, InfoVlan, InfoVxlan, Nla, VethInfo},
5+
nlas::link::{Info, InfoData, InfoKind, InfoMacVlan, InfoVlan, InfoVxlan, Nla, VethInfo},
66
LinkMessage,
77
NetlinkMessage,
88
RtnlMessage,
@@ -334,6 +334,19 @@ impl LinkAddRequest {
334334
.up()
335335
}
336336

337+
/// Create macvlan on a link.
338+
/// This is equivalent to `ip link add NAME name link LINK type macvlan mode MACVLAN_MODE`,
339+
/// but instead of specifying a link name (`LINK`), we specify a link index.
340+
pub fn macvlan(self, name: String, index: u32, mode: u32) -> Self {
341+
self.name(name)
342+
.link_info(
343+
InfoKind::MacVlan,
344+
Some(InfoData::MacVlan(vec![InfoMacVlan::Mode(mode)])),
345+
)
346+
.append_nla(Nla::Link(index))
347+
.up()
348+
}
349+
337350
/// Create a VxLAN
338351
/// This is equivalent to `ip link add name NAME type vxlan id VNI`,
339352
/// it returns a VxlanAddRequest to further customize the vxlan

0 commit comments

Comments
 (0)