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

Commit

Permalink
LinkAddRequest: Allow adding macvlan on a link
Browse files Browse the repository at this point in the history
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 <arajan@redhat.com>
  • Loading branch information
flouthoc committed Nov 10, 2021
1 parent aca87d2 commit dc55251
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 11 deletions.
55 changes: 55 additions & 0 deletions rtnetlink/examples/create_macvlan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use futures::stream::TryStreamExt;
use rtnetlink::{new_connection, Error, Handle};
use std::env;

#[tokio::main]
async fn main() -> Result<(), String> {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
usage();
return Ok(());
}
let link_name = &args[1];

let (connection, handle, _) = new_connection().unwrap();
tokio::spawn(connection);

create_macvlan(handle, link_name.to_string())
.await
.map_err(|e| format!("{}", e))
}

async fn create_macvlan(handle: Handle, veth_name: String) -> Result<(), Error> {
let mut links = handle
.link()
.get()
.set_name_filter(veth_name.clone())
.execute();
if let Some(link) = links.try_next().await? {
// hard code mode: 4u32 i.e bridge mode
let request = handle
.link()
.add()
.macvlan("test_macvlan".into(), link.header.index, 4u32);
request.execute().await?
} else {
println!("no link link {} found", veth_name);
}
Ok(())
}

fn usage() {
eprintln!(
"usage:
cargo run --example create_macvlan -- <link name>
Note that you need to run this program as root. Instead of running cargo as root,
build the example normally:
cd netlink-ip ; cargo build --example create_macvlan
Then find the binary in the target directory:
cd ../target/debug/example ; sudo ./create_macvlan <link_name>"
);
}
27 changes: 16 additions & 11 deletions rtnetlink/src/link/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@ use futures::stream::StreamExt;

use crate::{
packet::{
nlas::link::{Info, InfoData, InfoKind, InfoVlan, InfoVxlan, Nla, VethInfo},
LinkMessage,
NetlinkMessage,
RtnlMessage,
IFF_UP,
NLM_F_ACK,
NLM_F_CREATE,
NLM_F_EXCL,
nlas::link::{Info, InfoData, InfoKind, InfoMacVlan, InfoVlan, InfoVxlan, Nla, VethInfo},
LinkMessage, NetlinkMessage, RtnlMessage, IFF_UP, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL,
NLM_F_REQUEST,
},
try_nl,
Error,
Handle,
try_nl, Error, Handle,
};

/// A request to create a new vxlan link.
Expand Down Expand Up @@ -334,6 +326,19 @@ impl LinkAddRequest {
.up()
}

/// 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.
pub fn macvlan(self, name: String, index: u32, mode: u32) -> Self {
self.name(name)
.link_info(
InfoKind::MacVlan,
Some(InfoData::MacVlan(vec![InfoMacVlan::Mode(mode)])),
)
.append_nla(Nla::Link(index))
.up()
}

/// Create a VxLAN
/// This is equivalent to `ip link add name NAME type vxlan id VNI`,
/// it returns a VxlanAddRequest to further customize the vxlan
Expand Down

0 comments on commit dc55251

Please sign in to comment.