### Create Dummy Network Interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Use `LinkDummy` to create a software loopback-like dummy network interface. This is equivalent to the `ip link add dummy0 type dummy` command. ```rust use rtnetlink::{new_connection, LinkDummy}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkDummy::new("dummy0").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` -------------------------------- ### Filter Address Listings by Interface, Prefix, and IP Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Demonstrates filtering IP addresses by interface index, prefix length, and the specific IP address. Useful for precise address lookups. ```rust use std::net::IpAddr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn find_address(handle: Handle) -> Result<(), Error> { // Filter by link index and specific address let target: IpAddr = "10.0.0.1".parse().unwrap(); let mut addrs = handle .address() .get() .set_link_index_filter(2) // only interface index 2 .set_prefix_length_filter(24) // only /24 prefixes .set_address_filter(target) // only 10.0.0.1 .execute(); while let Some(msg) = addrs.try_next().await? { println!("Match: {:?}", msg); } Ok(()) } ``` -------------------------------- ### Using a Custom Async Socket with rtnetlink Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Shows how to use `from_socket` to wrap a custom `AsyncSocket` implementation, bypassing the default socket creation. This is useful for custom socket configurations with non-standard options or socket types. The `connection` needs to be spawned to run in the background. ```rust use rtnetlink::{from_socket, Handle}; use netlink_sys::{protocols::NETLINK_ROUTE, TokioSocket}; #[tokio::main] async fn main() -> Result<(), Box> { // Create and configure socket manually let mut socket = TokioSocket::new(NETLINK_ROUTE)?; // ... apply custom socket options here ... let (connection, handle, _messages) = from_socket(socket); tokio::spawn(connection); // Use handle normally Ok(()) } ``` -------------------------------- ### LinkDummy — Create a dummy interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Creates a software loopback-like dummy network interface. Equivalent to `ip link add dummy0 type dummy`. ```APIDOC ## LinkDummy — Create a dummy interface ### Description Creates a software loopback-like dummy network interface. Equivalent to `ip link add dummy0 type dummy`. ### Method Signature `LinkDummy::new(name: &str) -> LinkDummyBuilder` ### Usage Example ```rust use rtnetlink::{new_connection, LinkDummy}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkDummy::new("dummy0").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` ``` -------------------------------- ### Handle::link Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Provides access to the `LinkHandle`, which is the entry point for all operations related to network interfaces (links), such as creating, modifying, deleting, and listing them. This is equivalent to `ip link` commands. ```APIDOC ## Handle::link ### Description Returns a `LinkHandle` for all `ip link` equivalent operations. Used as the entry point for creating, modifying, deleting, and listing network interfaces. ### Method ```rust handle.link() -> LinkHandle ``` ### Example ```rust use futures_util::stream::TryStreamExt; use netlink_packet_route::link::LinkAttribute; use rtnetlink::{new_connection, Error, Handle}; #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); // Dump all interfaces (equivalent to `ip link show`) let mut links = handle.link().get().execute(); while let Some(msg) = links.try_next().await.unwrap() { for attr in msg.attributes { if let LinkAttribute::IfName(name) = attr { println!("index={} name={}", msg.header.index, name); } } } Ok(()) } ``` ``` -------------------------------- ### Manage Traffic Control Qdiscs with Handle::qdisc Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Manages traffic control qdiscs (queuing disciplines). This is equivalent to `tc qdisc` commands. Only available on non-FreeBSD targets. ```rust use rtnetlink::new_connection; #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); let ifindex: i32 = 2; // interface index // Add an ingress qdisc (equivalent to: tc qdisc add dev eth0 ingress) handle .qdisc() .add(ifindex) .ingress() .execute() .await .unwrap_or_else(|e| eprintln!("Error: {e}")); // List all qdiscs (equivalent to: tc qdisc show) use futures_util::stream::TryStreamExt; let mut qdiscs = handle.qdisc().get().execute(); while let Some(qdisc) = qdiscs.try_next().await.unwrap() { println!("{qdisc:?}"); } Ok(()) } ``` -------------------------------- ### Create Linux Bridge Interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Use `LinkBridge` to create a Linux bridge device. This is equivalent to `ip link add my-bridge type bridge`. ```rust use rtnetlink::{new_connection, LinkBridge}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkBridge::new("my-bridge").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` -------------------------------- ### new_connection Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Opens a new netlink route socket using the Tokio backend. It returns a connection, a handle for dispatching requests, and a receiver for kernel notifications. The connection must be spawned as an async task. ```APIDOC ## new_connection ### Description Creates a new netlink `NETLINK_ROUTE` connection using the Tokio socket backend. Returns `(Connection, Handle, Receiver)`. The `Connection` future must be spawned; the `Handle` is used to make requests; the `Receiver` receives unsolicited kernel notifications. ### Method ```rust new_connection() -> Result<(Connection, Handle, Receiver), Error> ``` ### Example ```rust use rtnetlink::new_connection; #[tokio::main] async fn main() -> Result<(), Box> { let (connection, handle, _messages) = new_connection()?; // Drive the connection in the background tokio::spawn(connection); // `handle` is now ready to use println!("Connection established, handle ready."); Ok(()) } ``` ``` -------------------------------- ### Establish rtnetlink Connection with Tokio Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Opens a new NETLINK_ROUTE connection using the Tokio backend. The connection must be spawned as an async task. The returned handle is used for dispatching requests. ```rust use rtnetlink::new_connection; #[tokio::main] async fn main() -> Result<(), Box> { let (connection, handle, _messages) = new_connection()?; // Drive the connection in the background tokio::spawn(connection); // `handle` is now ready to use println!("Connection established, handle ready."); Ok(()) } ``` -------------------------------- ### from_socket Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Wraps any type implementing `AsyncSocket` into a `(Connection, Handle, Receiver)` tuple, allowing for custom socket configurations and bypassing the default socket creation. ```APIDOC ## from_socket — Bring your own async socket ### Description For custom socket configurations (non-standard options, custom socket types), `from_socket` wraps any type implementing `AsyncSocket` into a `(Connection, Handle, Receiver)` tuple, bypassing the default socket creation. ### Method `from_socket(socket: impl AsyncSocket) -> (Connection, Handle, Receiver)` ### Parameters #### Path Parameters - `socket` (impl AsyncSocket) - Required - An asynchronous socket implementation. ### Request Example ```rust use rtnetlink::{from_socket, Handle}; use netlink_sys::{protocols::NETLINK_ROUTE, TokioSocket}; #[tokio::main] async fn main() -> Result<(), Box> { // Create and configure socket manually let mut socket = TokioSocket::new(NETLINK_ROUTE)?; // ... apply custom socket options here ... let (connection, handle, _messages) = from_socket(socket); tokio::spawn(connection); // Use handle normally Ok(()) } ``` ``` -------------------------------- ### `Handle::qdisc` — Traffic control qdisc management Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Returns a `QDiscHandle` for adding, changing, replacing, and deleting qdiscs (queuing disciplines). Equivalent to `tc qdisc`. Only available on non-FreeBSD targets. ```APIDOC ## `Handle::qdisc` — Traffic control qdisc management (equivalent to `tc qdisc`) Returns a `QDiscHandle` for adding, changing, replacing, and deleting qdiscs (queuing disciplines). Only available on non-FreeBSD targets. ```rust use rtnetlink::new_connection; #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); let ifindex: i32 = 2; // interface index // Add an ingress qdisc (equivalent to: tc qdisc add dev eth0 ingress) handle .qdisc() .add(ifindex) .ingress() .execute() .await .unwrap_or_else(|e| eprintln!("Error: {e}")); // List all qdiscs (equivalent to: tc qdisc show) use futures_util::stream::TryStreamExt; let mut qdiscs = handle.qdisc().get().execute(); while let Some(qdisc) = qdiscs.try_next().await.unwrap() { println!("{qdisc:?}"); } Ok(()) } ``` ``` -------------------------------- ### Manage Routing Policy Rules with Handle::rule Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Returns a `RuleHandle` for managing routing policy database (RPDB) rules. This is equivalent to `ip rule` commands. ```rust use ipnetwork::Ipv4Network; use rtnetlink::{new_connection, Error, Handle, IpVersion}; async fn manage_rules(handle: Handle) -> Result<(), Error> { // List all IPv4 rules (equivalent to `ip rule show`) use futures_util::stream::TryStreamExt; let mut rules = handle.rule().get(IpVersion::V4).execute(); while let Some(rule) = rules.try_next().await? { println!("{rule:?}"); } // Add a rule: traffic to 192.168.50.0/24 looks up table 100 // Equivalent to: ip rule add to 192.168.50.0/24 lookup 100 let dst: Ipv4Network = "192.168.50.0/24".parse().unwrap(); handle .rule() .add() .v4() .destination_prefix(dst.ip(), dst.prefix()) .table_id(100) .execute() .await?; println!("Rule added."); Ok(()) } ``` -------------------------------- ### List Network Interfaces with rtnetlink Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Uses the `LinkHandle` to retrieve all network interfaces, equivalent to the `ip link show` command. It iterates through the attributes of each link message to find the interface name. ```rust use futures_util::stream::TryStreamExt; use netlink_packet_route::link::LinkAttribute; use rtnetlink::{new_connection, Error, Handle}; #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); // Dump all interfaces (equivalent to `ip link show`) let mut links = handle.link().get().execute(); while let Some(msg) = links.try_next().await.unwrap() { for attr in msg.attributes { if let LinkAttribute::IfName(name) = attr { println!("index={} name={}", msg.header.index, name); } } } Ok(()) } ``` -------------------------------- ### Create and Delete Network Namespace with rtnetlink Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Demonstrates creating and deleting a network namespace using `NetworkNamespace::add` and `NetworkNamespace::del`. This function forks a child process to avoid moving the caller into the new namespace and requires root privileges. It is only available on non-FreeBSD targets. ```rust use rtnetlink::NetworkNamespace; #[tokio::main] async fn main() -> Result<(), String> { // Create a new network namespace (equivalent to: ip netns add my-ns) NetworkNamespace::add("my-ns".to_string()) .await .map_err(|e| format!("add failed: {e}"))?; println!("Namespace 'my-ns' created at /run/netns/my-ns"); // Delete the namespace (equivalent to: ip netns del my-ns) NetworkNamespace::del("my-ns".to_string()) .await .map_err(|e| format!("del failed: {e}"))?; println!("Namespace 'my-ns' deleted."); Ok(()) } ``` -------------------------------- ### Add MPLS Route via RouteMessageBuilder Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Creates MPLS label-switched routes. This is equivalent to the `ip route add via encap mpls ` command. ```rust use netlink_packet_route::route::MplsLabel; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn add_mpls_route(handle: Handle) -> Result<(), Error> { let input = MplsLabel { label: 100, traffic_class: 0, bottom_of_stack: true, ttl: 0 }; let output = MplsLabel { label: 200, traffic_class: 0, bottom_of_stack: true, ttl: 0 }; let route = RouteMessageBuilder::::new() .label(input) .via("10.0.0.1".parse().unwrap()) .output_mpls(vec![output]) .build(); handle.route().add(route).execute().await?; Ok(()) } ``` -------------------------------- ### Build ECMP (Multipath) Route Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Constructs and adds an Equal-Cost Multi-Path (ECMP) route with multiple nexthops. Each nexthop can have a different gateway and weight. ```rust use std::net::Ipv4Addr; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder, RouteNextHopBuilder}; async fn add_ecmp_route(handle: Handle, iface_index: u32) -> Result<(), Error> { // Equivalent to: ip route add 0.0.0.0/0 nexthop via 10.0.0.1 weight 1 \ // nexthop via 10.0.0.2 weight 2 let route = RouteMessageBuilder::::new() .destination_prefix("0.0.0.0".parse().unwrap(), 0) .multipath(vec![ RouteNextHopBuilder::new_ipv4() .interface(iface_index) .via("10.0.0.1".parse::().unwrap().into()) .unwrap() .weight(0) // kernel weight 0 = `weight 1` in ip route output .build(), RouteNextHopBuilder::new_ipv4() .interface(iface_index) .via("10.0.0.2".parse::().unwrap().into()) .unwrap() .weight(1) // kernel weight 1 = `weight 2` in ip route output .build(), ]) .build(); handle.route().add(route).execute().await?; Ok(()) } ``` -------------------------------- ### AddressHandle::add Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Assigns an IP address (IPv4 or IPv6) with a prefix length to a network interface identified by its kernel index. This is equivalent to the `ip addr add
/ dev ` command. ```APIDOC ## AddressHandle::add ### Description Assigns an IP address (IPv4 or IPv6) with a prefix length to a network interface identified by its kernel index. Equivalent to `ip addr add
/ dev `. ### Method ```rust handle.address().add(link.header.index, ip, prefix).execute().await? ``` ### Parameters - **link.header.index** (u32) - The kernel index of the network interface. - **ip** (IpAddr) - The IP address to assign. - **prefix** (u8) - The prefix length of the IP address. ### Request Example ```rust use std::net::IpAddr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn add_address(handle: Handle, iface: &str, addr: &str, prefix: u8) -> Result<(), Error> { let ip: IpAddr = addr.parse().expect("valid IP"); // Resolve interface index by name let mut links = handle.link().get().match_name(iface.to_string()).execute(); if let Some(link) = links.try_next().await? { handle .address() .add(link.header.index, ip, prefix) .execute() .await?; println!("Added {ip}/{prefix} to '{iface}'"); } Ok(()) } ``` ### Response - **Success Response**: Returns `Ok(())` on successful addition. - **Error Response**: Returns `Err(Error)` if the operation fails. ``` -------------------------------- ### RouteNextHopBuilder Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Constructs individual nexthop entries for Equal-Cost Multi-Path (ECMP) routing. Multiple nexthops can be combined using `RouteMessageBuilder::multipath()`. ```APIDOC ## RouteNextHopBuilder ### Description Constructs individual nexthop entries for Equal-Cost Multi-Path routing. Multiple nexthops are combined using `RouteMessageBuilder::multipath()`. ### Method ```rust RouteNextHopBuilder::new_ipv4() // or new_ipv6() ``` ### Parameters - **interface(iface_index)**: Sets the interface index for the nexthop. - **via(gateway_ip)**: Sets the gateway IP address for the nexthop. - **weight(weight)**: Sets the weight for the nexthop (used for ECMP balancing). ### Request Example ```rust use std::net::Ipv4Addr; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder, RouteNextHopBuilder}; async fn add_ecmp_route(handle: Handle, iface_index: u32) -> Result<(), Error> { // Equivalent to: ip route add 0.0.0.0/0 nexthop via 10.0.0.1 weight 1 \ // nexthop via 10.0.0.2 weight 2 let route = RouteMessageBuilder::::new() .destination_prefix("0.0.0.0".parse().unwrap(), 0) .multipath(vec![ RouteNextHopBuilder::new_ipv4() .interface(iface_index) .via("10.0.0.1".parse::().unwrap().into()) .unwrap() .weight(0) // kernel weight 0 = `weight 1` in ip route output .build(), RouteNextHopBuilder::new_ipv4() .interface(iface_index) .via("10.0.0.2".parse::().unwrap().into()) .unwrap() .weight(1) // kernel weight 1 = `weight 2` in ip route output .build(), ]) .build(); handle.route().add(route).execute().await?; Ok(()) } ``` ### Response - **Success Response**: Returns a `RouteMessage` object configured for ECMP routing. - **Error Response**: Not applicable for the builder itself, errors occur during message execution. ``` -------------------------------- ### LinkBridge — Create a bridge interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Creates a Linux bridge device. Equivalent to `ip link add my-bridge type bridge`. ```APIDOC ## LinkBridge — Create a bridge interface ### Description Creates a Linux bridge device. Equivalent to `ip link add my-bridge type bridge`. ### Method Signature `LinkBridge::new(name: &str) -> LinkBridgeBuilder` ### Usage Example ```rust use rtnetlink::{new_connection, LinkBridge}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkBridge::new("my-bridge").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` ``` -------------------------------- ### List IPv4 Routing Table Entries Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Retrieves and prints all IPv4 routing table entries. Requires a Handle to the rtnetlink connection. ```rust use std::net::Ipv4Addr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn list_ipv4_routes(handle: Handle) -> Result<(), Error> { let route_msg = RouteMessageBuilder::::new().build(); let mut routes = handle.route().get(route_msg).execute(); while let Some(route) = routes.try_next().await? { println!("{route:?}"); } Ok(()) } ``` -------------------------------- ### Create Virtual Ethernet (veth) Pair Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Use `LinkVeth` to create a virtual Ethernet pair. This is equivalent to `ip link add veth0 type veth peer name veth0-peer`. ```rust use rtnetlink::{new_connection, LinkVeth}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkVeth::new("veth0", "veth0-peer").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` -------------------------------- ### NetworkNamespace::add / del Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Manages Linux network namespaces, equivalent to the `ip netns` command. The `add` function forks a child process to avoid moving the caller into the new namespace. Requires root privileges and is only available on non-FreeBSD targets. ```APIDOC ## NetworkNamespace::add / del — Network namespace management ### Description Creates or deletes Linux network namespaces. The `add` function forks a child process internally to avoid moving the caller into the new namespace. Requires root privileges. Only available on non-FreeBSD targets. ### Method `NetworkNamespace::add(name: String)` `NetworkNamespace::del(name: String)` ### Parameters #### Path Parameters - `name` (String) - Required - The name of the network namespace. ### Request Example ```rust use rtnetlink::NetworkNamespace; #[tokio::main] async fn main() -> Result<(), String> { // Create a new network namespace (equivalent to: ip netns add my-ns) NetworkNamespace::add("my-ns".to_string()) .await .map_err(|e| format!("add failed: {e}"))?; println!("Namespace 'my-ns' created at /run/netns/my-ns"); // Delete the namespace (equivalent to: ip netns del my-ns) NetworkNamespace::del("my-ns".to_string()) .await .map_err(|e| format!("del failed: {e}"))?; println!("Namespace 'my-ns' deleted."); Ok(()) } ``` ``` -------------------------------- ### LinkVeth — Create a veth pair Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Creates a virtual Ethernet pair. Equivalent to `ip link add veth0 type veth peer name veth0-peer`. ```APIDOC ## LinkVeth — Create a veth pair ### Description Creates a virtual Ethernet pair. Equivalent to `ip link add veth0 type veth peer name veth0-peer`. ### Method Signature `LinkVeth::new(name: &str, peer_name: &str) -> LinkVethBuilder` ### Usage Example ```rust use rtnetlink::{new_connection, LinkVeth}; #[tokio::main] async fn main() -> Result<(), String> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .link() .add(LinkVeth::new("veth0", "veth0-peer").build()) .execute() .await .map_err(|e| format!("{e}")) } ``` ``` -------------------------------- ### Add IP Address to Interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Adds an IPv4 or IPv6 address with a specified prefix length to a network interface. Requires the interface name and IP address details. ```rust use std::net::IpAddr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn add_address(handle: Handle, iface: &str, addr: &str, prefix: u8) -> Result<(), Error> { let ip: IpAddr = addr.parse().expect("valid IP"); // Resolve interface index by name let mut links = handle.link().get().match_name(iface.to_string()).execute(); if let Some(link) = links.try_next().await? { handle .address() .add(link.header.index, ip, prefix) .execute() .await?; println!("Added {ip}/{prefix} to '{iface}'"); } Ok(()) } #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); add_address(handle, "eth0", "192.168.100.1", 24).await.unwrap(); Ok(()) } ``` -------------------------------- ### List IP Addresses on an Interface Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Access the `AddressHandle` via `Handle::address` to list IP addresses associated with a specific interface, such as 'lo'. ```rust use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn list_addresses_on_lo(handle: Handle) -> Result<(), Error> { let mut links = handle.link().get().match_name("lo".to_string()).execute(); if let Some(link) = links.try_next().await? { let mut addrs = handle .address() .get() .set_link_index_filter(link.header.index) .execute(); while let Some(msg) = addrs.try_next().await? { println!("{msg:?}"); } } Ok(()) } ``` -------------------------------- ### Add IPv4 Route with Gateway and Table ID Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Adds a specific IPv4 route to the routing table, including destination prefix, gateway, table ID, and priority. Equivalent to `ip route add` command. ```rust use std::net::Ipv4Addr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn add_ipv4_route(handle: Handle) -> Result<(), Error> { // Equivalent to: ip route add 10.10.0.0/16 via 192.168.1.1 table 299 let route = RouteMessageBuilder::::new() .destination_prefix("10.10.0.0".parse().unwrap(), 16) .gateway("192.168.1.1".parse().unwrap()) .table_id(299) .priority(100) // metric .build(); handle.route().add(route).execute().await?; println!("Route added."); Ok(()) } ``` -------------------------------- ### MPLS route via RouteMessageBuilder:: Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Creates MPLS label-switched routes. Equivalent to `ip route add via encap mpls `. ```APIDOC ## MPLS route via `RouteMessageBuilder::` Creates MPLS label-switched routes. Equivalent to `ip route add via encap mpls `. ```rust use netlink_packet_route::route::MplsLabel; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn add_mpls_route(handle: Handle) -> Result<(), Error> { let input = MplsLabel { label: 100, traffic_class: 0, bottom_of_stack: true, ttl: 0 }; let output = MplsLabel { label: 200, traffic_class: 0, bottom_of_stack: true, ttl: 0 }; let route = RouteMessageBuilder::::new() .label(input) .via("10.0.0.1".parse().unwrap()) .output_mpls(vec![output]) .build(); handle.route().add(route).execute().await?; Ok(()) } ``` ``` -------------------------------- ### Look Up Network Interface by Index or Name Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Retrieves a single network interface by its kernel index or name using `match_index` or `match_name`. Name-based lookup requires Linux kernel version 2.6.33 or later. ```rust use futures_util::stream::TryStreamExt; use netlink_packet_route::link::LinkAttribute; use rtnetlink::{new_connection, Error, Handle}; async fn find_link(handle: Handle) -> Result<(), Error> { // By index let mut by_index = handle.link().get().match_index(1).execute(); if let Some(msg) = by_index.try_next().await? { println!("Found interface with index 1: {:?}", msg.header); } // By name let mut by_name = handle.link().get().match_name("eth0".to_string()).execute(); if let Some(msg) = by_name.try_next().await? { for attr in msg.attributes { if let LinkAttribute::IfName(n) = attr { println!("Found interface: {n}"); } } } Ok(()) } ``` -------------------------------- ### `Handle::rule` — Manage routing policy rules Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Returns a `RuleHandle` for listing, adding, and deleting routing policy database (RPDB) rules. Equivalent to `ip rule`. ```APIDOC ## `Handle::rule` — Manage routing policy rules (equivalent to `ip rule`) Returns a `RuleHandle` for listing, adding, and deleting routing policy database (RPDB) rules. ```rust use ipnetwork::Ipv4Network; use rtnetlink::{new_connection, Error, Handle, IpVersion}; async fn manage_rules(handle: Handle) -> Result<(), Error> { // List all IPv4 rules (equivalent to `ip rule show`) use futures_util::stream::TryStreamExt; let mut rules = handle.rule().get(IpVersion::V4).execute(); while let Some(rule) = rules.try_next().await? { println!("{rule:?}"); } // Add a rule: traffic to 192.168.50.0/24 looks up table 100 // Equivalent to: ip rule add to 192.168.50.0/24 lookup 100 let dst: Ipv4Network = "192.168.50.0/24".parse().unwrap(); handle .rule() .add() .v4() .destination_prefix(dst.ip(), dst.prefix()) .table_id(100) .execute() .await?; println!("Rule added."); Ok(()) } ``` ``` -------------------------------- ### Handle::address — Access the address sub-handle Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Returns an `AddressHandle` for `ip addr` equivalent operations: listing, adding, and deleting IP addresses on interfaces. ```APIDOC ## Handle::address — Access the address sub-handle ### Description Returns an `AddressHandle` for `ip addr` equivalent operations: listing, adding, and deleting IP addresses on interfaces. ### Method Signature `Handle::address()` ### Usage Example (List addresses on 'lo') ```rust use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn list_addresses_on_lo(handle: Handle) -> Result<(), Error> { let mut links = handle.link().get().match_name("lo".to_string()).execute(); if let Some(link) = links.try_next().await? { let mut addrs = handle .address() .get() .set_link_index_filter(link.header.index) .execute(); while let Some(msg) = addrs.try_next().await? { println!("{msg:?}"); } } Ok(()) } ``` ``` -------------------------------- ### LinkGetRequest::match_index / LinkGetRequest::match_name Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Allows retrieving a specific network interface by its kernel index or name, offering a more targeted lookup than dumping all interfaces. Name-based lookup requires a kernel version of 2.6.33 or newer. ```APIDOC ## LinkGetRequest::match_index / LinkGetRequest::match_name ### Description Retrieves exactly one interface by its kernel index or its name, without dumping the full interface list. Requires Linux kernel >= 2.6.33 for name-based lookup. ### Method ```rust // For index lookup handle.link().get().match_index(index: u32).execute() // For name lookup handle.link().get().match_name(name: String).execute() ``` ### Parameters #### Path Parameters - **index** (*u32*) - Required - The kernel index of the network interface. - **name** (*String*) - Required - The name of the network interface. ### Example ```rust use futures_util::stream::TryStreamExt; use netlink_packet_route::link::LinkAttribute; use rtnetlink::{new_connection, Error, Handle}; async fn find_link(handle: Handle) -> Result<(), Error> { // By index let mut by_index = handle.link().get().match_index(1).execute(); if let Some(msg) = by_index.try_next().await? { println!("Found interface with index 1: {:?}", msg.header); } // By name let mut by_name = handle.link().get().match_name("eth0".to_string()).execute(); if let Some(msg) = by_name.try_next().await? { for attr in msg.attributes { if let LinkAttribute::IfName(n) = attr { println!("Found interface: {n}"); } } } Ok(()) } ``` ``` -------------------------------- ### Handling rtnetlink Errors Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Illustrates how to handle potential errors returned by `rtnetlink` operations, specifically from the `handle.link().del().execute().await` call. It demonstrates matching against different `rtnetlink::Error` variants like `NetlinkError`, `RequestFailed`, and other general errors. ```rust use rtnetlink::{new_connection, Error}; #[tokio::main] async fn main() { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); match handle.link().del(9999).execute().await { Ok(()) => println!("Deleted."), Err(Error::NetlinkError(msg)) => eprintln!("Kernel error: {msg}"), Err(Error::RequestFailed) => eprintln!("Request could not be sent"), Err(e) => eprintln!("Other error: {e}"), } } ``` -------------------------------- ### RouteMessageBuilder Source: https://context7.com/rust-netlink/rtnetlink/llms.txt A typed builder for constructing `RouteMessage` values for IPv4 or IPv6 routes. It allows setting various route attributes like destination, gateway, and table ID. ```APIDOC ## RouteMessageBuilder ### Description A typed builder for constructing `RouteMessage` values. Generic over `Ipv4Addr`, `Ipv6Addr`, `IpAddr`, or `MplsLabel` depending on the route family. Defaults to main table, static protocol, universe scope, and unicast kind. ### Method ```rust RouteMessageBuilder::::new() ``` ### Parameters - **destination_prefix(destination, prefix_len)**: Sets the destination network prefix. - **gateway(gateway)**: Sets the gateway for the route. - **table_id(table_id)**: Sets the routing table identifier. - **priority(priority)**: Sets the priority (metric) of the route. ### Request Example ```rust use std::net::Ipv4Addr; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn add_ipv4_route(handle: Handle) -> Result<(), Error> { // Equivalent to: ip route add 10.10.0.0/16 via 192.168.1.1 table 299 let route = RouteMessageBuilder::::new() .destination_prefix("10.10.0.0".parse().unwrap(), 16) .gateway("192.168.1.1".parse().unwrap()) .table_id(299) .priority(100) // metric .build(); handle.route().add(route).execute().await?; println!("Route added."); Ok(()) } ``` ### Response - **Success Response**: Returns a `RouteMessage` object that can be used with `handle.route().add()`. - **Error Response**: Not applicable for the builder itself, errors occur during message execution. ``` -------------------------------- ### Add ARP Entry with Handle::neighbours Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Manages ARP/NDP entries in the neighbour table. This is equivalent to `ip neighbour` commands. Requires resolving the interface index first. ```rust use std::{convert::TryFrom, net::IpAddr}; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn add_arp_entry(handle: Handle) -> Result<(), Error> { // Resolve the interface index let mut links = handle.link().get().match_name("eth0".to_string()).execute(); if let Some(link) = links.try_next().await? { let ip: IpAddr = "192.168.1.50".parse().unwrap(); let mac: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; // Equivalent to: ip neighbour add 192.168.1.50 lladdr aa:bb:cc:dd:ee:ff dev eth0 handle .neighbours() .add(link.header.index, ip) .link_layer_address(&mac) .execute() .await?; println!("ARP entry added."); } Ok(()) } ``` -------------------------------- ### AddressGetRequest filters Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Filters for retrieving IP addresses associated with network interfaces. Supports filtering by interface index, prefix length, and specific IP address. ```APIDOC ## AddressGetRequest filters ### Description `AddressGetRequest` supports three client-side filters to narrow results: by interface index, prefix length, and specific IP address. ### Method ```rust handle.address().get().set_link_index_filter(index).set_prefix_length_filter(prefix).set_address_filter(addr).execute() ``` ### Parameters #### Query Parameters - **link_index** (u32) - Filter by interface index. - **prefix_length** (u8) - Filter by prefix length. - **address** (IpAddr) - Filter by specific IP address. ### Request Example ```rust use std::net::IpAddr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn find_address(handle: Handle) -> Result<(), Error> { // Filter by link index and specific address let target: IpAddr = "10.0.0.1".parse().unwrap(); let mut addrs = handle .address() .get() .set_link_index_filter(2) // only interface index 2 .set_prefix_length_filter(24) // only /24 prefixes .set_address_filter(target) // only 10.0.0.1 .execute(); while let Some(msg) = addrs.try_next().await? { println!("Match: {:?}", msg); } Ok(()) } ``` ### Response - **Success Response**: Returns a stream of `AddressMessage` objects matching the filters. - **Error Response**: Returns `Err(Error)` if the operation fails. ``` -------------------------------- ### Manage Traffic Filters with Handle::traffic_filter Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Manages traffic control filters scoped to a specific interface. This is equivalent to `tc filter` commands. ```rust use rtnetlink::new_connection; #[tokio::main] async fn main() -> Result<(), ()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); let ifindex: i32 = 2; // List filters on interface (equivalent to: tc filter show dev eth0) use futures_util::stream::TryStreamExt; let mut filters = handle.traffic_filter(ifindex).get().execute(); while let Some(f) = filters.try_next().await.unwrap() { println!("{f:?}"); } Ok(()) } ``` -------------------------------- ### new_multicast_connection Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Opens a multicast netlink socket subscribed to specified multicast groups. This is useful for monitoring network events like link status changes, address updates, and route modifications in real-time. ```APIDOC ## new_multicast_connection ### Description Opens a multicast netlink socket subscribed to one or more `MulticastGroup` channels. The returned `Receiver` channel delivers unsolicited kernel event messages (link up/down, address added/removed, route changes, etc.) in real time. This is equivalent to `ip monitor`. ### Method ```rust new_multicast_connection(groups: &[MulticastGroup]) -> Result<(Connection, Handle, Receiver), Error> ``` ### Parameters #### Path Parameters - **groups** (*&[MulticastGroup]*) - Required - A slice of `MulticastGroup` enums specifying which events to monitor. ### Example ```rust use futures_util::stream::StreamExt; use rtnetlink::{new_multicast_connection, MulticastGroup}; #[tokio::main] async fn main() -> Result<(), String> { let (conn, _handle, mut messages) = new_multicast_connection(&[ MulticastGroup::Link, MulticastGroup::Ipv4Ifaddr, MulticastGroup::Ipv6Ifaddr, MulticastGroup::Ipv4Route, MulticastGroup::Ipv6Route, MulticastGroup::Neigh, ]) .map_err(|e| format!("{e}"))?; tokio::spawn(conn); // Print every kernel network event as it arrives while let Some((message, _addr)) = messages.next().await { println!("{:?}", message.payload); } Ok(()) } ``` ``` -------------------------------- ### Handle::route Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Accesses the routing table sub-handle, providing methods for `ip route` equivalent operations like listing, adding, and deleting routes. ```APIDOC ## Handle::route ### Description Returns a `RouteHandle` for `ip route` equivalent operations: listing, adding, and deleting routing table entries. ### Method ```rust handle.route() ``` ### Usage This method returns a `RouteHandle` which can then be used to perform various routing operations. ### Request Example ```rust use std::net::Ipv4Addr; use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle, RouteMessageBuilder}; async fn list_ipv4_routes(handle: Handle) -> Result<(), Error> { let route_msg = RouteMessageBuilder::::new().build(); let mut routes = handle.route().get(route_msg).execute(); while let Some(route) = routes.try_next().await? { println!("{route:?}"); } Ok(()) } ``` ### Response - **Success Response**: Returns a `RouteHandle` object. - **Error Response**: Not applicable for this method as it only returns a handle. ``` -------------------------------- ### Delete Network Interface by Index Source: https://context7.com/rust-netlink/rtnetlink/llms.txt Use `LinkHandle::del` to remove a network interface by its kernel index. This is equivalent to `ip link del `. ```rust use futures_util::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; async fn delete_link(handle: Handle, name: &str) -> Result<(), Error> { let mut links = handle.link().get().match_name(name.to_string()).execute(); if let Some(link) = links.try_next().await? { handle.link().del(link.header.index).execute().await?; println!("Deleted interface '{}' (index={})", name, link.header.index); } Ok(()) } ```