diff --git a/examples/add_route.rs b/examples/add_route.rs index ab7ff81..ea00b65 100644 --- a/examples/add_route.rs +++ b/examples/add_route.rs @@ -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 = env::args().collect(); - if args.len() != 3 { + if args.len() != 4 { usage(); return Ok(()); } @@ -24,13 +22,18 @@ 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(()) } @@ -38,12 +41,13 @@ async fn main() -> Result<(), ()> { async fn add_route( dest: &Ipv4Network, gateway: &Ipv4Network, + table_id: u32, handle: Handle, ) -> Result<(), Error> { let route = RouteMessageBuilder::::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(()) @@ -51,14 +55,13 @@ async fn add_route( fn usage() { eprintln!( - "\ -usage: - cargo run --example add_route -- / + "usage: + cargo run --example add_route -- / 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 -- / \ - " + " ); } diff --git a/examples/create_vrf.rs b/examples/create_vrf.rs new file mode 100644 index 0000000..95190b8 --- /dev/null +++ b/examples/create_vrf.rs @@ -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}")) +} diff --git a/examples/get_vrf_table_id.rs b/examples/get_vrf_table_id.rs new file mode 100644 index 0000000..65c9866 --- /dev/null +++ b/examples/get_vrf_table_id.rs @@ -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 = 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 -- + +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 " + ); +} diff --git a/examples/set_link_no_vrf.rs b/examples/set_link_no_vrf.rs new file mode 100644 index 0000000..a6d850d --- /dev/null +++ b/examples/set_link_no_vrf.rs @@ -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 = 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 -- + +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 " + ); +} diff --git a/examples/set_link_up.rs b/examples/set_link_up.rs new file mode 100644 index 0000000..e2fe8e6 --- /dev/null +++ b/examples/set_link_up.rs @@ -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 = 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 -- + +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 " + ); +} diff --git a/examples/set_link_vrf.rs b/examples/set_link_vrf.rs new file mode 100644 index 0000000..f9eee4e --- /dev/null +++ b/examples/set_link_vrf.rs @@ -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 = 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 -- + +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 " + ); +}