Skip to content

[examples] Added few vrf examples following #PR59 #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
23 changes: 13 additions & 10 deletions examples/add_route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ use std::{env, net::Ipv4Addr};
use ipnetwork::Ipv4Network;
use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder};

const TEST_TABLE_ID: u32 = 299;

#[tokio::main]
async fn main() -> Result<(), ()> {
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
if args.len() != 4 {
usage();
return Ok(());
}
Expand All @@ -24,41 +22,46 @@ async fn main() -> Result<(), ()> {
std::process::exit(1);
});

let table_id = args[3].parse().unwrap_or_else(|_| {
eprintln!("invalid table_id");
std::process::exit(1);
});

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

if let Err(e) = add_route(&dest, &gateway, handle.clone()).await {
if let Err(e) = add_route(&dest, &gateway, table_id, handle.clone()).await {
eprintln!("{e}");
} else {
println!("Route has been added to table {TEST_TABLE_ID}");
println!("Route has been added to table {table_id}");
}
Ok(())
}

async fn add_route(
dest: &Ipv4Network,
gateway: &Ipv4Network,
table_id: u32,
handle: Handle,
) -> Result<(), Error> {
let route = RouteMessageBuilder::<Ipv4Addr>::new()
.destination_prefix(dest.ip(), dest.prefix())
.gateway(gateway.ip())
.table_id(TEST_TABLE_ID)
.table_id(table_id)
.build();
handle.route().add(route).execute().await?;
Ok(())
}

fn usage() {
eprintln!(
"\
usage:
cargo run --example add_route -- <destination>/<prefix_length> <gateway>
"usage:
cargo run --example add_route -- <destination>/<prefix_length> <gateway> <table_id>

Note that you need to run this program as root:

env CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER='sudo -E' \\
cargo run --example add_route -- <destination>/<prefix_length> \
<gateway>"
<gateway> <table_id>"
);
}
16 changes: 16 additions & 0 deletions examples/create_vrf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT

use rtnetlink::new_connection;

#[tokio::main]
async fn main() -> Result<(), String> {
let (connection, handle, _) = new_connection().unwrap();
tokio::spawn(connection);
handle
.link()
.add()
.vrf("my-vrf-1".into(), 666)
.execute()
.await
.map_err(|e| format!("{e}"))
}
67 changes: 67 additions & 0 deletions examples/get_vrf_table_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: MIT

use futures::stream::TryStreamExt;
use netlink_packet_route::link::{InfoData, InfoVrf, LinkAttribute, LinkInfo};
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 vrf_name = &args[1];

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

get_vrf_table_id(handle.clone(), vrf_name.to_string())
.await
.map_err(|e| format!("{e}"))
}

async fn get_vrf_table_id(handle: Handle, name: String) -> Result<(), Error> {
let mut links = handle.link().get().match_name(name.clone()).execute();
let msg = if let Some(msg) = links.try_next().await? {
msg
} else {
eprintln!("[get_vrf_table_id] : no link with name {name} found");
return Ok(());
};

// We should have received only one message
assert!(links.try_next().await?.is_none());

for nla in msg.attributes.into_iter() {
if let LinkAttribute::LinkInfo(lnkinfs) = nla {
for lnkinf in lnkinfs.into_iter() {
if let LinkInfo::Data(InfoData::Vrf(vrfinfs)) = lnkinf {
for vrfinf in vrfinfs.iter() {
if let InfoVrf::TableId(table_id) = vrfinf {
println!("VRF:{} TABLE_ID:{:?}", name, table_id);
}
}
}
}
}
}
Ok(())
}

fn usage() {
eprintln!(
"usage:
cargo run --example get_vrf_table_id -- <vrf_name>

Note that you need to run this program as root. Instead of running cargo as root,
build the example normally:

cd rtnetlink ; cargo build --example get_vrf_table_id

Then find the binary in the target directory:

cd ../target/debug/example ; sudo ./get_vrf_table_id <vrf_name>"
);
}
53 changes: 53 additions & 0 deletions examples/set_link_no_vrf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT

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);

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

async fn set_link_no_vrf(handle: Handle, name: String) -> Result<(), Error> {
let mut links = handle.link().get().match_name(name.clone()).execute();
if let Some(link) = links.try_next().await? {
handle
.link()
.set(link.header.index)
.nocontroller()
.execute()
.await?
} else {
println!("no link link {name} found");
}
Ok(())
}

fn usage() {
eprintln!(
"usage:
cargo run --example set_link_no_vrf -- <link_name>

Note that you need to run this program as root. Instead of running cargo as root,
build the example normally:

cd rtnetlink ; cargo build --example set_link_no_vrf

Then find the binary in the target directory:

cd ../target/debug/example ; sudo ./set_link_no_vrf <link_name>"
);
}
48 changes: 48 additions & 0 deletions examples/set_link_up.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT

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);

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

async fn set_link_up(handle: Handle, name: String) -> Result<(), Error> {
let mut links = handle.link().get().match_name(name.clone()).execute();
if let Some(link) = links.try_next().await? {
handle.link().set(link.header.index).up().execute().await?
} else {
println!("no link link {name} found");
}
Ok(())
}

fn usage() {
eprintln!(
"usage:
cargo run --example set_link_up -- <link_name>

Note that you need to run this program as root. Instead of running cargo as root,
build the example normally:

cd rtnetlink ; cargo build --example set_link_up

Then find the binary in the target directory:

cd ../target/debug/example ; sudo ./set_link_up <link_name>"
);
}
65 changes: 65 additions & 0 deletions examples/set_link_vrf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT

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() != 3 {
usage();
return Ok(());
}
let link_name = &args[1];
let ctrl_name = &args[2];

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

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

async fn set_link_vrf(
handle: Handle,
name: String,
controller: String,
) -> Result<(), Error> {
let mut ctrls =
handle.link().get().match_name(controller.clone()).execute();
let mut links = handle.link().get().match_name(name.clone()).execute();

if let Some(ctrl) = ctrls.try_next().await? {
if let Some(link) = links.try_next().await? {
handle
.link()
.set(link.header.index)
.controller(ctrl.header.index)
.execute()
.await?
} else {
println!("no link link {name} found");
}
} else {
println!("no vrf vrf {controller} found");
}
Ok(())
}

fn usage() {
eprintln!(
"usage:
cargo run --example set_link_vrf -- <link_name> <vrf_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 set_link_vrf

Then find the binary in the target directory:

cd ../target/debug/example ; sudo ./set_link_vrf <link_name> <vrf_name>"
);
}