pub struct Connection<P: ProtocolState> { /* private fields */ }Expand description
High-level netlink connection parameterized by protocol state.
The type parameter P determines which protocol this connection uses
and which methods are available:
Connection<Route>: RTNetlink for interfaces, addresses, routes, TCConnection<Generic>: Generic netlink for WireGuard, MACsec, etc.
§Example
use nlink::netlink::{Connection, Route, Generic};
// Route protocol connection
let route = Connection::<Route>::new()?;
route.get_links().await?;
// Generic netlink connection
let genl = Connection::<Generic>::new()?;
genl.get_family("wireguard").await?;Implementations§
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_address<A: AddressConfig>(&self, config: A) -> Result<()>
pub async fn add_address<A: AddressConfig>(&self, config: A) -> Result<()>
Add an IP address to an interface.
This method is namespace-safe: interface names are resolved via netlink, which queries the namespace that this connection is bound to.
§Example
use nlink::netlink::addr::{Ipv4Address, Ipv6Address};
use std::net::{Ipv4Addr, Ipv6Addr};
// Add IPv4 address
conn.add_address(
Ipv4Address::new("eth0", Ipv4Addr::new(192, 168, 1, 100), 24)
).await?;
// Add IPv6 address
conn.add_address(
Ipv6Address::new("eth0", "2001:db8::1".parse()?, 64)
).await?;Sourcepub async fn del_address(
&self,
ifname: impl Into<InterfaceRef>,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn del_address( &self, ifname: impl Into<InterfaceRef>, address: IpAddr, prefix_len: u8, ) -> Result<()>
Sourcepub async fn del_address_by_index(
&self,
ifindex: u32,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn del_address_by_index( &self, ifindex: u32, address: IpAddr, prefix_len: u8, ) -> Result<()>
Delete an IP address from an interface by index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn add_address_by_index(
&self,
ifindex: u32,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn add_address_by_index( &self, ifindex: u32, address: IpAddr, prefix_len: u8, ) -> Result<()>
Add an IP address to an interface by index.
This is namespace-safe as it doesn’t require interface name resolution.
§Example
// Get interface index via netlink
let link = conn.get_link_by_name("eth0").await?.unwrap();
// Add address by index
conn.add_address_by_index(link.ifindex(), "192.168.1.100".parse()?, 24).await?;Sourcepub async fn replace_address_by_index(
&self,
ifindex: u32,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn replace_address_by_index( &self, ifindex: u32, address: IpAddr, prefix_len: u8, ) -> Result<()>
Replace an IP address on an interface by index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn add_address_by_name(
&self,
ifname: impl Into<InterfaceRef>,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn add_address_by_name( &self, ifname: impl Into<InterfaceRef>, address: IpAddr, prefix_len: u8, ) -> Result<()>
Sourcepub async fn replace_address_by_name(
&self,
ifname: impl Into<InterfaceRef>,
address: IpAddr,
prefix_len: u8,
) -> Result<()>
pub async fn replace_address_by_name( &self, ifname: impl Into<InterfaceRef>, address: IpAddr, prefix_len: u8, ) -> Result<()>
Sourcepub async fn del_address_v4(
&self,
ifname: impl Into<InterfaceRef>,
address: Ipv4Addr,
prefix_len: u8,
) -> Result<()>
pub async fn del_address_v4( &self, ifname: impl Into<InterfaceRef>, address: Ipv4Addr, prefix_len: u8, ) -> Result<()>
Delete an IPv4 address from an interface.
Sourcepub async fn del_address_v6(
&self,
ifname: impl Into<InterfaceRef>,
address: Ipv6Addr,
prefix_len: u8,
) -> Result<()>
pub async fn del_address_v6( &self, ifname: impl Into<InterfaceRef>, address: Ipv6Addr, prefix_len: u8, ) -> Result<()>
Delete an IPv6 address from an interface.
Sourcepub async fn del_address_config<A: AddressConfig>(
&self,
config: A,
) -> Result<()>
pub async fn del_address_config<A: AddressConfig>( &self, config: A, ) -> Result<()>
Delete an IP address using a typed config.
Sourcepub async fn replace_address<A: AddressConfig>(&self, config: A) -> Result<()>
pub async fn replace_address<A: AddressConfig>(&self, config: A) -> Result<()>
Replace an IP address (add or update).
This is like add_address but will update if the address exists.
§Example
// Update address properties (lifetimes, etc.)
conn.replace_address(
Ipv4Address::new("eth0", Ipv4Addr::new(192, 168, 1, 100), 24)
.preferred_lifetime(3600)
.valid_lifetime(7200)
).await?;Sourcepub async fn flush_addresses(
&self,
ifname: impl Into<InterfaceRef>,
) -> Result<()>
pub async fn flush_addresses( &self, ifname: impl Into<InterfaceRef>, ) -> Result<()>
Sourcepub async fn flush_addresses_by_index(&self, ifindex: u32) -> Result<()>
pub async fn flush_addresses_by_index(&self, ifindex: u32) -> Result<()>
Flush all addresses from an interface by index.
This is namespace-safe as it doesn’t require interface name resolution.
Source§impl Connection<Audit>
impl Connection<Audit>
Sourcepub async fn get_status(&self) -> Result<AuditStatus>
pub async fn get_status(&self) -> Result<AuditStatus>
Get the current audit status.
§Example
use nlink::netlink::{Connection, Audit};
let conn = Connection::<Audit>::new()?;
let status = conn.get_status().await?;
println!("Audit enabled: {}", status.is_enabled());
println!("Audit locked: {}", status.is_locked());
println!("Failure mode: {:?}", status.failure_mode());
println!("Audit daemon PID: {}", status.pid);
println!("Rate limit: {} msgs/sec", status.rate_limit);
println!("Backlog: {}/{}", status.backlog, status.backlog_limit);
println!("Lost messages: {}", status.lost);Sourcepub async fn get_tty_status(&self) -> Result<AuditTtyStatus>
pub async fn get_tty_status(&self) -> Result<AuditTtyStatus>
Sourcepub async fn get_features(&self) -> Result<AuditFeatures>
pub async fn get_features(&self) -> Result<AuditFeatures>
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_bridge_vlans(
&self,
dev: impl Into<InterfaceRef>,
) -> Result<Vec<BridgeVlanEntry>>
pub async fn get_bridge_vlans( &self, dev: impl Into<InterfaceRef>, ) -> Result<Vec<BridgeVlanEntry>>
Sourcepub async fn get_bridge_vlans_by_index(
&self,
ifindex: u32,
) -> Result<Vec<BridgeVlanEntry>>
pub async fn get_bridge_vlans_by_index( &self, ifindex: u32, ) -> Result<Vec<BridgeVlanEntry>>
Get VLAN configuration for a bridge port by interface index.
Use this method when operating in a network namespace.
Sourcepub async fn get_bridge_vlans_all(
&self,
bridge: impl Into<InterfaceRef>,
) -> Result<Vec<BridgeVlanEntry>>
pub async fn get_bridge_vlans_all( &self, bridge: impl Into<InterfaceRef>, ) -> Result<Vec<BridgeVlanEntry>>
Sourcepub async fn get_bridge_vlans_all_by_index(
&self,
bridge_idx: u32,
) -> Result<Vec<BridgeVlanEntry>>
pub async fn get_bridge_vlans_all_by_index( &self, bridge_idx: u32, ) -> Result<Vec<BridgeVlanEntry>>
Get VLAN configuration for all ports of a bridge by interface index.
Sourcepub async fn add_bridge_vlan(&self, config: BridgeVlanBuilder) -> Result<()>
pub async fn add_bridge_vlan(&self, config: BridgeVlanBuilder) -> Result<()>
Add VLAN to a bridge port.
§Example
use nlink::netlink::bridge_vlan::BridgeVlanBuilder;
// Add VLAN 100 as PVID and untagged (native VLAN)
conn.add_bridge_vlan(
BridgeVlanBuilder::new(100)
.dev("eth0")
.pvid()
.untagged()
).await?;
// Add VLAN range 200-210 as tagged
conn.add_bridge_vlan(
BridgeVlanBuilder::new(200)
.dev("eth0")
.range(210)
).await?;Sourcepub async fn del_bridge_vlan(
&self,
dev: impl Into<InterfaceRef>,
vid: u16,
) -> Result<()>
pub async fn del_bridge_vlan( &self, dev: impl Into<InterfaceRef>, vid: u16, ) -> Result<()>
Sourcepub async fn del_bridge_vlan_by_index(
&self,
ifindex: u32,
vid: u16,
) -> Result<()>
pub async fn del_bridge_vlan_by_index( &self, ifindex: u32, vid: u16, ) -> Result<()>
Delete VLAN from a bridge port by interface index.
Sourcepub async fn del_bridge_vlan_range(
&self,
dev: impl Into<InterfaceRef>,
vid_start: u16,
vid_end: u16,
) -> Result<()>
pub async fn del_bridge_vlan_range( &self, dev: impl Into<InterfaceRef>, vid_start: u16, vid_end: u16, ) -> Result<()>
Sourcepub async fn set_bridge_pvid(
&self,
dev: impl Into<InterfaceRef>,
vid: u16,
) -> Result<()>
pub async fn set_bridge_pvid( &self, dev: impl Into<InterfaceRef>, vid: u16, ) -> Result<()>
Sourcepub async fn set_bridge_pvid_by_index(
&self,
ifindex: u32,
vid: u16,
) -> Result<()>
pub async fn set_bridge_pvid_by_index( &self, ifindex: u32, vid: u16, ) -> Result<()>
Set PVID for a bridge port by interface index.
Sourcepub async fn add_bridge_vlan_tagged(
&self,
dev: impl Into<InterfaceRef>,
vid: u16,
) -> Result<()>
pub async fn add_bridge_vlan_tagged( &self, dev: impl Into<InterfaceRef>, vid: u16, ) -> Result<()>
Sourcepub async fn add_bridge_vlan_range(
&self,
dev: impl Into<InterfaceRef>,
vid_start: u16,
vid_end: u16,
) -> Result<()>
pub async fn add_bridge_vlan_range( &self, dev: impl Into<InterfaceRef>, vid_start: u16, vid_end: u16, ) -> Result<()>
Sourcepub async fn get_vlan_tunnels(
&self,
dev: impl Into<InterfaceRef>,
) -> Result<Vec<BridgeVlanTunnelEntry>>
pub async fn get_vlan_tunnels( &self, dev: impl Into<InterfaceRef>, ) -> Result<Vec<BridgeVlanTunnelEntry>>
Get VLAN-to-tunnel ID mappings for a bridge port.
Returns all VLAN-to-VNI mappings configured on the specified interface. This is typically used on VXLAN bridge ports.
§Example
let tunnels = conn.get_vlan_tunnels("vxlan0").await?;
for t in &tunnels {
println!("VLAN {} -> VNI {}", t.vid, t.tunnel_id);
}Sourcepub async fn get_vlan_tunnels_by_index(
&self,
ifindex: u32,
) -> Result<Vec<BridgeVlanTunnelEntry>>
pub async fn get_vlan_tunnels_by_index( &self, ifindex: u32, ) -> Result<Vec<BridgeVlanTunnelEntry>>
Get VLAN-to-tunnel ID mappings by interface index.
Use this method when operating in a network namespace.
Sourcepub async fn add_vlan_tunnel(
&self,
config: BridgeVlanTunnelBuilder,
) -> Result<()>
pub async fn add_vlan_tunnel( &self, config: BridgeVlanTunnelBuilder, ) -> Result<()>
Add VLAN-to-tunnel ID mapping.
Creates a mapping between a VLAN ID and a tunnel ID (VNI) on a VXLAN bridge port.
§Example
use nlink::netlink::bridge_vlan::BridgeVlanTunnelBuilder;
// Map VLAN 100 to VNI 10000
conn.add_vlan_tunnel(
BridgeVlanTunnelBuilder::new(100, 10000)
.dev("vxlan0")
).await?;
// Map VLAN range 200-210 to VNI range 20000-20010
conn.add_vlan_tunnel(
BridgeVlanTunnelBuilder::new(200, 20000)
.dev("vxlan0")
.range(210)
).await?;Sourcepub async fn del_vlan_tunnel(
&self,
dev: impl Into<InterfaceRef>,
vid: u16,
) -> Result<()>
pub async fn del_vlan_tunnel( &self, dev: impl Into<InterfaceRef>, vid: u16, ) -> Result<()>
Sourcepub async fn del_vlan_tunnel_by_index(
&self,
ifindex: u32,
vid: u16,
) -> Result<()>
pub async fn del_vlan_tunnel_by_index( &self, ifindex: u32, vid: u16, ) -> Result<()>
Delete VLAN-to-tunnel ID mapping by interface index.
Sourcepub async fn del_vlan_tunnel_range(
&self,
dev: impl Into<InterfaceRef>,
vid_start: u16,
vid_end: u16,
) -> Result<()>
pub async fn del_vlan_tunnel_range( &self, dev: impl Into<InterfaceRef>, vid_start: u16, vid_end: u16, ) -> Result<()>
Source§impl<P: ProtocolState + Default> Connection<P>
impl<P: ProtocolState + Default> Connection<P>
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Create a new connection for this protocol type.
This is available for protocols that implement Default.
For protocols that require special initialization (like Connector,
KobjectUevent, or Wireguard), use their specific constructors.
§Example
use nlink::netlink::{Connection, Route, Generic};
let route = Connection::<Route>::new()?;
let genl = Connection::<Generic>::new()?;Sourcepub fn new_in_namespace(ns_fd: RawFd) -> Result<Self>
pub fn new_in_namespace(ns_fd: RawFd) -> Result<Self>
Create a connection that operates in a specific network namespace.
The namespace is specified by an open file descriptor to a namespace file
(e.g., /proc/<pid>/ns/net or /var/run/netns/<name>).
§Example
use std::fs::File;
use std::os::unix::io::AsRawFd;
use nlink::netlink::{Connection, Route};
let ns_file = File::open("/var/run/netns/myns")?;
let conn = Connection::<Route>::new_in_namespace(ns_file.as_raw_fd())?;
// All operations now occur in the "myns" namespace
let links = conn.get_links().await?;Sourcepub fn new_in_namespace_path<T: AsRef<Path>>(ns_path: T) -> Result<Self>
pub fn new_in_namespace_path<T: AsRef<Path>>(ns_path: T) -> Result<Self>
Create a connection that operates in a network namespace specified by path.
§Example
use nlink::netlink::{Connection, Route};
// For a named namespace (created via `ip netns add myns`)
let conn = Connection::<Route>::new_in_namespace_path("/var/run/netns/myns")?;
// For a container's namespace
let conn = Connection::<Route>::new_in_namespace_path("/proc/1234/ns/net")?;
// Query interfaces in that namespace
let links = conn.get_links().await?;Source§impl<P: ProtocolState> Connection<P>
impl<P: ProtocolState> Connection<P>
Sourcepub fn socket(&self) -> &NetlinkSocket
pub fn socket(&self) -> &NetlinkSocket
Get the underlying socket.
Sourcepub fn timeout(self, timeout: Duration) -> Self
pub fn timeout(self, timeout: Duration) -> Self
Set a default timeout for all netlink operations.
Operations that exceed the timeout return Error::Timeout.
By default, no timeout is set and operations wait indefinitely.
§Example
use nlink::{Connection, Route};
use std::time::Duration;
let conn = Connection::<Route>::new()?
.timeout(Duration::from_secs(5));Sourcepub fn no_timeout(self) -> Self
pub fn no_timeout(self) -> Self
Clear the timeout (operations will wait indefinitely).
Sourcepub fn get_timeout(&self) -> Option<Duration>
pub fn get_timeout(&self) -> Option<Duration>
Get the configured timeout.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub fn for_namespace(spec: NamespaceSpec<'_>) -> Result<Self>
pub fn for_namespace(spec: NamespaceSpec<'_>) -> Result<Self>
Create a connection for the specified namespace.
This is a convenience method that creates a Route protocol connection for any namespace specification.
§Example
use nlink::netlink::{Connection, Route};
use nlink::netlink::namespace::NamespaceSpec;
// For a named namespace
let conn = Connection::<Route>::for_namespace(NamespaceSpec::Named("myns"))?;
// For a container by PID
let conn = Connection::<Route>::for_namespace(NamespaceSpec::Pid(1234))?;
// For the default namespace
let conn = Connection::<Route>::for_namespace(NamespaceSpec::Default)?;Sourcepub fn subscribe(&mut self, groups: &[RtnetlinkGroup]) -> Result<()>
pub fn subscribe(&mut self, groups: &[RtnetlinkGroup]) -> Result<()>
Sourcepub fn subscribe_all(&mut self) -> Result<()>
pub fn subscribe_all(&mut self) -> Result<()>
Sourcepub async fn dump_typed<T: FromNetlink>(&self, msg_type: u16) -> Result<Vec<T>>
pub async fn dump_typed<T: FromNetlink>(&self, msg_type: u16) -> Result<Vec<T>>
Send a dump request and parse all responses into typed messages.
This is a convenience method that combines dump() with parsing.
The type T must implement FromNetlink::write_dump_header to provide
the required message header (e.g., IfInfoMsg for links, IfAddrMsg for addresses).
§Example
use nlink::netlink::messages::AddressMessage;
use nlink::netlink::message::NlMsgType;
let addresses: Vec<AddressMessage> = conn.dump_typed(NlMsgType::RTM_GETADDR).await?;
for addr in addresses {
println!("{}: {:?}", addr.ifindex(), addr.address);
}Sourcepub fn parse_response<T: FromNetlink>(&self, response: &[u8]) -> Result<T>
pub fn parse_response<T: FromNetlink>(&self, response: &[u8]) -> Result<T>
Parse a single response into a typed message.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub fn batch(&self) -> Batch<'_>
pub fn batch(&self) -> Batch<'_>
Create a batch for executing multiple operations in minimal syscalls.
Operations are buffered and sent as concatenated messages in a single
sendmsg(). The kernel processes them sequentially and returns one
ACK per message.
§Example
use nlink::netlink::{Connection, Route};
use nlink::netlink::route::Ipv4Route;
let conn = Connection::<Route>::new()?;
let results = conn.batch()
.add_route(Ipv4Route::new("10.0.0.0", 8).dev_index(5))
.add_route(Ipv4Route::new("10.1.0.0", 16).dev_index(5))
.execute()
.await?;Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_links(&self) -> Result<Vec<LinkMessage>>
pub async fn get_links(&self) -> Result<Vec<LinkMessage>>
Sourcepub async fn get_link_by_name(
&self,
name: impl Into<InterfaceRef>,
) -> Result<Option<LinkMessage>>
pub async fn get_link_by_name( &self, name: impl Into<InterfaceRef>, ) -> Result<Option<LinkMessage>>
Get a network interface by name.
Returns None if the interface doesn’t exist.
Sourcepub async fn get_link_by_index(&self, index: u32) -> Result<Option<LinkMessage>>
pub async fn get_link_by_index(&self, index: u32) -> Result<Option<LinkMessage>>
Get a network interface by index.
Returns None if the interface doesn’t exist.
Sourcepub async fn resolve_interface(&self, iface: &InterfaceRef) -> Result<u32>
pub async fn resolve_interface(&self, iface: &InterfaceRef) -> Result<u32>
Resolve an interface reference to an index.
This method is namespace-safe: it uses netlink to resolve interface names, which queries the namespace that this connection is bound to.
- If the reference is already an index, returns it directly.
- If the reference is a name, queries the kernel via netlink.
§Errors
Returns Error::InterfaceNotFound if the interface name doesn’t exist.
§Example
use nlink::netlink::{Connection, Route, InterfaceRef};
let conn = Connection::<Route>::new()?;
// Resolve a name
let ifindex = conn.resolve_interface(&InterfaceRef::name("eth0")).await?;
// Pass-through an index
let ifindex = conn.resolve_interface(&InterfaceRef::index(2)).await?;
assert_eq!(ifindex, 2);Sourcepub async fn resolve_interface_opt(
&self,
iface: Option<&InterfaceRef>,
) -> Result<Option<u32>>
pub async fn resolve_interface_opt( &self, iface: Option<&InterfaceRef>, ) -> Result<Option<u32>>
Resolve an optional interface reference.
Returns None if the input is None, otherwise resolves the reference.
Sourcepub async fn get_interface_names(&self) -> Result<HashMap<u32, String>>
pub async fn get_interface_names(&self) -> Result<HashMap<u32, String>>
Build a map of interface index to name.
This is a convenience method for code that needs to look up interface names by index (e.g., when displaying addresses, routes, or TC objects).
§Example
let names = conn.get_interface_names().await?;
let addresses = conn.get_addresses().await?;
for addr in addresses {
let name = names.get(&addr.ifindex()).map(|s| s.as_str()).unwrap_or("?");
println!("{}: {:?}", name, addr.address);
}Sourcepub async fn interface_name(&self, ifindex: u32) -> Result<Option<String>>
pub async fn interface_name(&self, ifindex: u32) -> Result<Option<String>>
Get interface name by index.
This is a convenience method for getting a single interface name.
For looking up multiple names, prefer [get_interface_names()]
to build a lookup map.
Returns None if no interface with that index exists.
§Example
if let Some(name) = conn.interface_name(route.oif.unwrap()).await? {
println!("Route via {}", name);
}Sourcepub async fn get_bond_info(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<BondInfo>
pub async fn get_bond_info( &self, iface: impl Into<InterfaceRef>, ) -> Result<BondInfo>
Get bond information for a bond interface.
Returns the bond configuration as reported by the kernel.
§Errors
Returns an error if the interface doesn’t exist or is not a bond.
§Example
let info = conn.get_bond_info("bond0").await?;
println!("Mode: {:?}, miimon: {}ms", info.bond_mode(), info.miimon);Sourcepub async fn get_bond_slaves(
&self,
bond: impl Into<InterfaceRef>,
) -> Result<Vec<(LinkMessage, BondSlaveInfo)>>
pub async fn get_bond_slaves( &self, bond: impl Into<InterfaceRef>, ) -> Result<Vec<(LinkMessage, BondSlaveInfo)>>
List all slaves of a bond interface with their status.
Returns a list of (LinkMessage, BondSlaveInfo) pairs for each slave.
§Example
let slaves = conn.get_bond_slaves("bond0").await?;
for (link, info) in &slaves {
println!("{}: state={:?}, mii={:?}",
link.name_or("?"), info.state, info.mii_status);
}Sourcepub async fn get_addresses(&self) -> Result<Vec<AddressMessage>>
pub async fn get_addresses(&self) -> Result<Vec<AddressMessage>>
Sourcepub async fn get_addresses_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Vec<AddressMessage>>
pub async fn get_addresses_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Vec<AddressMessage>>
Get IP addresses for a specific interface.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn get_addresses_by_index(
&self,
ifindex: u32,
) -> Result<Vec<AddressMessage>>
pub async fn get_addresses_by_index( &self, ifindex: u32, ) -> Result<Vec<AddressMessage>>
Get IP addresses for a specific interface by index.
Sourcepub async fn get_address_by_ip(
&self,
addr: IpAddr,
) -> Result<Option<AddressMessage>>
pub async fn get_address_by_ip( &self, addr: IpAddr, ) -> Result<Option<AddressMessage>>
Sourcepub async fn get_routes(&self) -> Result<Vec<RouteMessage>>
pub async fn get_routes(&self) -> Result<Vec<RouteMessage>>
Sourcepub async fn get_routes_for_table(
&self,
table_id: u32,
) -> Result<Vec<RouteMessage>>
pub async fn get_routes_for_table( &self, table_id: u32, ) -> Result<Vec<RouteMessage>>
Get routes for a specific table.
Sourcepub async fn get_route_v4(
&self,
destination: Ipv4Addr,
prefix_len: u8,
) -> Result<Option<RouteMessage>>
pub async fn get_route_v4( &self, destination: Ipv4Addr, prefix_len: u8, ) -> Result<Option<RouteMessage>>
Get a specific IPv4 route by destination and prefix length.
Uses RTM_GETROUTE without NLM_F_DUMP to query the kernel directly, which is more efficient than dumping all routes for large routing tables.
Returns None if no matching route is found.
§Example
use std::net::Ipv4Addr;
// Look up route to 10.0.0.0/8
if let Some(route) = conn.get_route_v4(Ipv4Addr::new(10, 0, 0, 0), 8).await? {
println!("Gateway: {:?}", route.gateway);
}Sourcepub async fn get_route_v6(
&self,
destination: Ipv6Addr,
prefix_len: u8,
) -> Result<Option<RouteMessage>>
pub async fn get_route_v6( &self, destination: Ipv6Addr, prefix_len: u8, ) -> Result<Option<RouteMessage>>
Get a specific IPv6 route by destination and prefix length.
Uses RTM_GETROUTE without NLM_F_DUMP to query the kernel directly, which is more efficient than dumping all routes for large routing tables.
Returns None if no matching route is found.
§Example
use std::net::Ipv6Addr;
// Look up route to 2001:db8::/32
let dest: Ipv6Addr = "2001:db8::".parse()?;
if let Some(route) = conn.get_route_v6(dest, 32).await? {
println!("Gateway: {:?}", route.gateway);
}Sourcepub async fn get_neighbors(&self) -> Result<Vec<NeighborMessage>>
pub async fn get_neighbors(&self) -> Result<Vec<NeighborMessage>>
Sourcepub async fn get_neighbors_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Vec<NeighborMessage>>
pub async fn get_neighbors_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Vec<NeighborMessage>>
Get neighbor entries for a specific interface.
Accepts either an interface name or index via InterfaceRef.
See also get_neighbors_by_index in the neighbor module.
Sourcepub async fn get_rules(&self) -> Result<Vec<RuleMessage>>
pub async fn get_rules(&self) -> Result<Vec<RuleMessage>>
Sourcepub async fn get_rules_for_family(&self, family: u8) -> Result<Vec<RuleMessage>>
pub async fn get_rules_for_family(&self, family: u8) -> Result<Vec<RuleMessage>>
Get routing rules for a specific address family.
§Arguments
family- Address family:libc::AF_INETfor IPv4,libc::AF_INET6for IPv6
Sourcepub async fn get_rules_v4(&self) -> Result<Vec<RuleMessage>>
pub async fn get_rules_v4(&self) -> Result<Vec<RuleMessage>>
Get IPv4 routing rules.
Sourcepub async fn get_rules_v6(&self) -> Result<Vec<RuleMessage>>
pub async fn get_rules_v6(&self) -> Result<Vec<RuleMessage>>
Get IPv6 routing rules.
Sourcepub async fn add_rule(&self, rule: RuleBuilder) -> Result<()>
pub async fn add_rule(&self, rule: RuleBuilder) -> Result<()>
Add a routing rule.
Use the super::rule::RuleBuilder to construct the rule.
§Example
use nlink::netlink::rule::RuleBuilder;
// Add a rule to lookup table 100 for traffic from 10.0.0.0/8
conn.add_rule(
RuleBuilder::v4()
.priority(100)
.from("10.0.0.0", 8)
.table(100)
).await?;Sourcepub async fn del_rule(&self, rule: RuleBuilder) -> Result<()>
pub async fn del_rule(&self, rule: RuleBuilder) -> Result<()>
Sourcepub async fn del_rule_by_priority(
&self,
family: u8,
priority: u32,
) -> Result<()>
pub async fn del_rule_by_priority( &self, family: u8, priority: u32, ) -> Result<()>
Delete a rule by priority.
Sourcepub async fn flush_rules(&self, family: u8) -> Result<()>
pub async fn flush_rules(&self, family: u8) -> Result<()>
Flush all non-default routing rules for a family.
This deletes all rules except the default ones (priority 0, 32766, 32767).
Sourcepub async fn get_qdiscs(&self) -> Result<Vec<TcMessage>>
pub async fn get_qdiscs(&self) -> Result<Vec<TcMessage>>
Sourcepub async fn get_qdiscs_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Vec<TcMessage>>
pub async fn get_qdiscs_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Vec<TcMessage>>
Get qdiscs for a specific interface.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn get_qdiscs_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
pub async fn get_qdiscs_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
Get qdiscs for a specific interface by index.
Sourcepub async fn get_classes(&self) -> Result<Vec<TcMessage>>
pub async fn get_classes(&self) -> Result<Vec<TcMessage>>
Get all TC classes.
Sourcepub async fn get_classes_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Vec<TcMessage>>
pub async fn get_classes_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Vec<TcMessage>>
Get TC classes for a specific interface.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn get_classes_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
pub async fn get_classes_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
Get TC classes for a specific interface by index.
Sourcepub async fn get_filters(&self) -> Result<Vec<TcMessage>>
pub async fn get_filters(&self) -> Result<Vec<TcMessage>>
Get all TC filters.
Sourcepub async fn get_filters_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Vec<TcMessage>>
pub async fn get_filters_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Vec<TcMessage>>
Get TC filters for a specific interface.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn get_filters_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
pub async fn get_filters_by_index(&self, ifindex: u32) -> Result<Vec<TcMessage>>
Get TC filters for a specific interface by index.
Sourcepub async fn get_tc_chains(
&self,
ifname: impl Into<InterfaceRef>,
parent: &str,
) -> Result<Vec<u32>>
pub async fn get_tc_chains( &self, ifname: impl Into<InterfaceRef>, parent: &str, ) -> Result<Vec<u32>>
Sourcepub async fn get_tc_chains_by_index(
&self,
ifindex: u32,
parent: &str,
) -> Result<Vec<u32>>
pub async fn get_tc_chains_by_index( &self, ifindex: u32, parent: &str, ) -> Result<Vec<u32>>
Get all TC filter chains for an interface by index.
Sourcepub async fn add_tc_chain(
&self,
ifname: impl Into<InterfaceRef>,
parent: &str,
chain: u32,
) -> Result<()>
pub async fn add_tc_chain( &self, ifname: impl Into<InterfaceRef>, parent: &str, chain: u32, ) -> Result<()>
Sourcepub async fn add_tc_chain_by_index(
&self,
ifindex: u32,
parent: &str,
chain: u32,
) -> Result<()>
pub async fn add_tc_chain_by_index( &self, ifindex: u32, parent: &str, chain: u32, ) -> Result<()>
Add a TC filter chain by interface index.
Sourcepub async fn del_tc_chain(
&self,
ifname: impl Into<InterfaceRef>,
parent: &str,
chain: u32,
) -> Result<()>
pub async fn del_tc_chain( &self, ifname: impl Into<InterfaceRef>, parent: &str, chain: u32, ) -> Result<()>
Sourcepub async fn del_tc_chain_by_index(
&self,
ifindex: u32,
parent: &str,
chain: u32,
) -> Result<()>
pub async fn del_tc_chain_by_index( &self, ifindex: u32, parent: &str, chain: u32, ) -> Result<()>
Delete a TC filter chain by interface index.
Sourcepub async fn get_root_qdisc_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Option<TcMessage>>
pub async fn get_root_qdisc_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Option<TcMessage>>
Get the root qdisc for an interface (parent == ROOT).
Returns None if no root qdisc is configured.
Accepts either an interface name or index via InterfaceRef.
§Example
if let Some(root) = conn.get_root_qdisc_by_name("eth0").await? {
println!("Root qdisc: {}", root.kind().unwrap_or("?"));
}Sourcepub async fn get_root_qdisc_by_index(
&self,
ifindex: u32,
) -> Result<Option<TcMessage>>
pub async fn get_root_qdisc_by_index( &self, ifindex: u32, ) -> Result<Option<TcMessage>>
Get the root qdisc for an interface by index.
Returns None if no root qdisc is configured.
Sourcepub async fn get_qdisc_by_handle(
&self,
ifname: &str,
handle: &str,
) -> Result<Option<TcMessage>>
pub async fn get_qdisc_by_handle( &self, ifname: &str, handle: &str, ) -> Result<Option<TcMessage>>
Sourcepub async fn get_qdisc_by_handle_index(
&self,
ifindex: u32,
handle: &str,
) -> Result<Option<TcMessage>>
pub async fn get_qdisc_by_handle_index( &self, ifindex: u32, handle: &str, ) -> Result<Option<TcMessage>>
Sourcepub async fn get_netem_by_name(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Option<NetemOptions>>
pub async fn get_netem_by_name( &self, iface: impl Into<InterfaceRef>, ) -> Result<Option<NetemOptions>>
Get netem options for an interface, if a netem qdisc is configured at root.
This is a convenience method that returns Some only if a netem qdisc
is the root qdisc and its options can be parsed.
Accepts either an interface name or index via InterfaceRef.
§Example
if let Some(netem) = conn.get_netem_by_name("eth0").await? {
if let Some(delay) = netem.delay() {
println!("Delay: {:?}", delay);
}
if let Some(loss) = netem.loss() {
println!("Loss: {:.2}%", loss);
}
if let Some(rate) = netem.rate_bps() {
println!("Rate limit: {} bytes/sec", rate);
}
}Sourcepub async fn get_netem_by_index(
&self,
ifindex: u32,
) -> Result<Option<NetemOptions>>
pub async fn get_netem_by_index( &self, ifindex: u32, ) -> Result<Option<NetemOptions>>
Get netem options for an interface by index.
Returns None if no netem qdisc is configured at root.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn set_link_up(&self, iface: impl Into<InterfaceRef>) -> Result<()>
pub async fn set_link_up(&self, iface: impl Into<InterfaceRef>) -> Result<()>
Bring a network interface up.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_link_up("eth0").await?;
conn.set_link_up(5u32).await?; // by indexSourcepub async fn set_link_up_by_index(&self, ifindex: u32) -> Result<()>
pub async fn set_link_up_by_index(&self, ifindex: u32) -> Result<()>
Bring a network interface up by index.
Sourcepub async fn set_link_down(&self, iface: impl Into<InterfaceRef>) -> Result<()>
pub async fn set_link_down(&self, iface: impl Into<InterfaceRef>) -> Result<()>
Bring a network interface down.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_link_down("eth0").await?;
conn.set_link_down(5u32).await?; // by indexSourcepub async fn set_link_down_by_index(&self, ifindex: u32) -> Result<()>
pub async fn set_link_down_by_index(&self, ifindex: u32) -> Result<()>
Bring a network interface down by index.
Sourcepub async fn set_link_state(
&self,
iface: impl Into<InterfaceRef>,
up: bool,
) -> Result<()>
pub async fn set_link_state( &self, iface: impl Into<InterfaceRef>, up: bool, ) -> Result<()>
Set the state of a network interface (up or down).
Accepts either an interface name or index via InterfaceRef.
§Arguments
iface- The interface name or indexup-trueto bring the interface up,falseto bring it down
§Example
// Bring interface up
conn.set_link_state("eth0", true).await?;
// Bring interface down by index
conn.set_link_state(5u32, false).await?;Sourcepub async fn set_link_state_by_index(
&self,
ifindex: u32,
up: bool,
) -> Result<()>
pub async fn set_link_state_by_index( &self, ifindex: u32, up: bool, ) -> Result<()>
Set the state of a network interface by index.
Sourcepub async fn set_link_mtu(
&self,
iface: impl Into<InterfaceRef>,
mtu: u32,
) -> Result<()>
pub async fn set_link_mtu( &self, iface: impl Into<InterfaceRef>, mtu: u32, ) -> Result<()>
Set the MTU of a network interface.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_link_mtu("eth0", 9000).await?;
conn.set_link_mtu(5u32, 9000).await?; // by indexSourcepub async fn set_link_mtu_by_index(&self, ifindex: u32, mtu: u32) -> Result<()>
pub async fn set_link_mtu_by_index(&self, ifindex: u32, mtu: u32) -> Result<()>
Set the MTU of a network interface by index.
Sourcepub async fn del_link(&self, iface: impl Into<InterfaceRef>) -> Result<()>
pub async fn del_link(&self, iface: impl Into<InterfaceRef>) -> Result<()>
Delete a network interface.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.del_link("veth0").await?;
conn.del_link(5u32).await?; // by indexSourcepub async fn del_link_by_index(&self, ifindex: u32) -> Result<()>
pub async fn del_link_by_index(&self, ifindex: u32) -> Result<()>
Delete a network interface by index.
Sourcepub async fn set_link_txqlen(
&self,
iface: impl Into<InterfaceRef>,
txqlen: u32,
) -> Result<()>
pub async fn set_link_txqlen( &self, iface: impl Into<InterfaceRef>, txqlen: u32, ) -> Result<()>
Set the TX queue length of a network interface.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_link_txqlen("eth0", 1000).await?;
conn.set_link_txqlen(5u32, 1000).await?; // by indexSource§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_nsid(&self, ns_fd: RawFd) -> Result<u32>
pub async fn get_nsid(&self, ns_fd: RawFd) -> Result<u32>
Get the namespace ID for a given file descriptor.
The file descriptor should be an open reference to a network namespace
(e.g., from opening /proc/<pid>/ns/net).
§Errors
Returns an error if the namespace ID cannot be determined.
§Example
use std::fs::File;
use std::os::unix::io::AsRawFd;
let ns_file = File::open("/var/run/netns/myns")?;
let nsid = conn.get_nsid(ns_file.as_raw_fd()).await?;
println!("Namespace ID: {}", nsid);Sourcepub async fn get_nsid_for_pid(&self, pid: u32) -> Result<u32>
pub async fn get_nsid_for_pid(&self, pid: u32) -> Result<u32>
Source§impl Connection<Generic>
impl Connection<Generic>
Sourcepub async fn get_family(&self, name: &str) -> Result<FamilyInfo>
pub async fn get_family(&self, name: &str) -> Result<FamilyInfo>
Get information about a Generic Netlink family.
The result is cached, so subsequent calls for the same family do not require kernel communication.
§Example
use nlink::netlink::{Connection, Generic};
let conn = Connection::<Generic>::new()?;
let wg = conn.get_family("wireguard").await?;
println!("WireGuard family ID: {}", wg.id);Sourcepub async fn get_family_id(&self, name: &str) -> Result<u16>
pub async fn get_family_id(&self, name: &str) -> Result<u16>
Get the family ID for a given family name.
This is a convenience method that returns just the ID.
Sourcepub fn clear_cache(&self)
pub fn clear_cache(&self)
Clear the family cache.
This is rarely needed, but may be useful if families are dynamically loaded/unloaded.
Sourcepub async fn command(
&self,
family_id: u16,
cmd: u8,
version: u8,
build_attrs: impl FnOnce(&mut MessageBuilder),
) -> Result<Vec<u8>>
pub async fn command( &self, family_id: u16, cmd: u8, version: u8, build_attrs: impl FnOnce(&mut MessageBuilder), ) -> Result<Vec<u8>>
Send a GENL command and wait for a response.
This is a low-level method for sending arbitrary GENL commands.
Family-specific wrappers (like Connection<Wireguard>) should use this.
Source§impl Connection<Connector>
impl Connection<Connector>
Sourcepub async fn unregister(&self) -> Result<()>
pub async fn unregister(&self) -> Result<()>
Unregister from process events.
After calling this, no more events will be received.
Sourcepub async fn recv(&self) -> Result<ProcEvent>
pub async fn recv(&self) -> Result<ProcEvent>
Receive the next process event.
This method blocks until an event is available.
§Example
use nlink::netlink::{Connection, Connector};
use nlink::netlink::connector::ProcEvent;
let conn = Connection::<Connector>::new_proc_events().await?;
loop {
let event = conn.recv().await?;
if let Some(pid) = event.pid() {
println!("Event for PID {}: {:?}", pid, event);
}
}Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_fdb(
&self,
bridge: impl Into<InterfaceRef>,
) -> Result<Vec<FdbEntry>>
pub async fn get_fdb( &self, bridge: impl Into<InterfaceRef>, ) -> Result<Vec<FdbEntry>>
Get all FDB entries for a bridge.
Returns entries where the master device matches the specified bridge, or entries directly on the bridge interface itself.
§Example
let entries = conn.get_fdb("br0").await?;
for entry in &entries {
println!("{} on ifindex {} vlan={:?}",
entry.mac_str(), entry.ifindex, entry.vlan);
}Sourcepub async fn get_fdb_by_index(&self, bridge_idx: u32) -> Result<Vec<FdbEntry>>
pub async fn get_fdb_by_index(&self, bridge_idx: u32) -> Result<Vec<FdbEntry>>
Get all FDB entries for a bridge by interface index.
Use this method when operating in a network namespace to avoid
reading /sys/class/net/ from the wrong namespace.
Sourcepub async fn get_fdb_for_port(
&self,
bridge: impl Into<InterfaceRef>,
port: impl Into<InterfaceRef>,
) -> Result<Vec<FdbEntry>>
pub async fn get_fdb_for_port( &self, bridge: impl Into<InterfaceRef>, port: impl Into<InterfaceRef>, ) -> Result<Vec<FdbEntry>>
Sourcepub async fn add_fdb(&self, entry: FdbEntryBuilder) -> Result<()>
pub async fn add_fdb(&self, entry: FdbEntryBuilder) -> Result<()>
Add an FDB entry.
§Example
use nlink::netlink::fdb::FdbEntryBuilder;
let mac = FdbEntryBuilder::parse_mac("aa:bb:cc:dd:ee:ff")?;
conn.add_fdb(
FdbEntryBuilder::new(mac)
.dev("veth0")
.master("br0")
.vlan(100)
).await?;
// Namespace-safe version using interface index
conn.add_fdb(
FdbEntryBuilder::new(mac)
.ifindex(5)
.master_ifindex(3)
).await?;Sourcepub async fn replace_fdb(&self, entry: FdbEntryBuilder) -> Result<()>
pub async fn replace_fdb(&self, entry: FdbEntryBuilder) -> Result<()>
Replace an FDB entry (add or update).
If the entry exists, it will be updated. Otherwise, it will be created.
Sourcepub async fn del_fdb(
&self,
dev: impl Into<InterfaceRef>,
mac: [u8; 6],
vlan: Option<u16>,
) -> Result<()>
pub async fn del_fdb( &self, dev: impl Into<InterfaceRef>, mac: [u8; 6], vlan: Option<u16>, ) -> Result<()>
Source§impl Connection<FibLookup>
impl Connection<FibLookup>
Sourcepub async fn lookup(&self, addr: Ipv4Addr) -> Result<FibLookupResult>
pub async fn lookup(&self, addr: Ipv4Addr) -> Result<FibLookupResult>
Look up a route for an IPv4 address.
§Example
use nlink::netlink::{Connection, FibLookup};
use std::net::Ipv4Addr;
let conn = Connection::<FibLookup>::new()?;
let result = conn.lookup(Ipv4Addr::new(8, 8, 8, 8)).await?;
if result.is_success() {
println!("Route found: type={:?}, table={}, prefix=/{}",
result.route_type, result.table_id, result.prefix_len);
}Sourcepub async fn lookup_in_table(
&self,
addr: Ipv4Addr,
table: u8,
) -> Result<FibLookupResult>
pub async fn lookup_in_table( &self, addr: Ipv4Addr, table: u8, ) -> Result<FibLookupResult>
Sourcepub async fn lookup_with_mark(
&self,
addr: Ipv4Addr,
mark: u32,
) -> Result<FibLookupResult>
pub async fn lookup_with_mark( &self, addr: Ipv4Addr, mark: u32, ) -> Result<FibLookupResult>
Look up a route for an IPv4 address with a specific firewall mark.
Firewall marks can be used for policy routing decisions.
§Example
use nlink::netlink::{Connection, FibLookup};
use std::net::Ipv4Addr;
let conn = Connection::<FibLookup>::new()?;
let result = conn.lookup_with_mark(Ipv4Addr::new(8, 8, 8, 8), 0x100).await?;Sourcepub async fn lookup_with_options(
&self,
request: FibResultNl,
) -> Result<FibLookupResult>
pub async fn lookup_with_options( &self, request: FibResultNl, ) -> Result<FibLookupResult>
Look up a route with custom options.
This method allows full control over the lookup parameters.
§Example
use nlink::netlink::{Connection, FibLookup};
use nlink::netlink::fib_lookup::FibResultNl;
use std::net::Ipv4Addr;
let conn = Connection::<FibLookup>::new()?;
let request = FibResultNl {
fl_addr: u32::from_be_bytes(Ipv4Addr::new(8, 8, 8, 8).octets()),
fl_tos: 0x10, // Specific TOS value
..Default::default()
};
let result = conn.lookup_with_options(request).await?;Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_filter(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
config: impl FilterConfig,
) -> Result<()>
pub async fn add_filter( &self, dev: impl Into<InterfaceRef>, parent: &str, config: impl FilterConfig, ) -> Result<()>
Sourcepub async fn add_filter_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn add_filter_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Add a filter with explicit parameters.
§Arguments
dev- Interface nameparent- Parent qdisc handle (e.g., “1:”)handle- Filter handle (optional)protocol- Ethernet protocol (e.g., 0x0800 for IPv4)priority- Filter priority (lower = higher priority)config- Filter configuration
Sourcepub async fn add_filter_by_index(
&self,
ifindex: u32,
parent: &str,
config: impl FilterConfig,
) -> Result<()>
pub async fn add_filter_by_index( &self, ifindex: u32, parent: &str, config: impl FilterConfig, ) -> Result<()>
Add a filter by interface index.
Sourcepub async fn add_filter_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn add_filter_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Add a filter by interface index with explicit parameters.
Sourcepub async fn replace_filter(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
config: impl FilterConfig,
) -> Result<()>
pub async fn replace_filter( &self, dev: impl Into<InterfaceRef>, parent: &str, config: impl FilterConfig, ) -> Result<()>
Replace a filter on an interface (create if not exists).
This uses NLM_F_CREATE | NLM_F_REPLACE flags to atomically replace an existing filter or create a new one.
§Example
let filter = U32Filter::new()
.classid("1:10")
.match_dst_port(80)
.build();
conn.replace_filter("eth0", "1:", filter).await?;Sourcepub async fn replace_filter_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn replace_filter_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Replace a filter with explicit parameters.
Sourcepub async fn replace_filter_by_index(
&self,
ifindex: u32,
parent: &str,
config: impl FilterConfig,
) -> Result<()>
pub async fn replace_filter_by_index( &self, ifindex: u32, parent: &str, config: impl FilterConfig, ) -> Result<()>
Replace a filter by interface index.
Sourcepub async fn replace_filter_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn replace_filter_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Replace a filter by interface index with explicit parameters.
Sourcepub async fn change_filter(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn change_filter( &self, dev: impl Into<InterfaceRef>, parent: &str, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Sourcepub async fn change_filter_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn change_filter_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Change a filter with explicit handle.
Sourcepub async fn change_filter_by_index(
&self,
ifindex: u32,
parent: &str,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn change_filter_by_index( &self, ifindex: u32, parent: &str, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Change a filter by interface index.
Sourcepub async fn change_filter_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
protocol: u16,
priority: u16,
config: impl FilterConfig,
) -> Result<()>
pub async fn change_filter_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, protocol: u16, priority: u16, config: impl FilterConfig, ) -> Result<()>
Change a filter by interface index with explicit handle.
Sourcepub async fn del_filter(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
protocol: u16,
priority: u16,
) -> Result<()>
pub async fn del_filter( &self, dev: impl Into<InterfaceRef>, parent: &str, protocol: u16, priority: u16, ) -> Result<()>
Sourcepub async fn del_filter_by_index(
&self,
ifindex: u32,
parent: &str,
protocol: u16,
priority: u16,
) -> Result<()>
pub async fn del_filter_by_index( &self, ifindex: u32, parent: &str, protocol: u16, priority: u16, ) -> Result<()>
Delete a filter by interface index.
Sourcepub async fn flush_filters(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
) -> Result<()>
pub async fn flush_filters( &self, dev: impl Into<InterfaceRef>, parent: &str, ) -> Result<()>
Delete all filters from a parent qdisc.
Sourcepub async fn flush_filters_by_index(
&self,
ifindex: u32,
parent: &str,
) -> Result<()>
pub async fn flush_filters_by_index( &self, ifindex: u32, parent: &str, ) -> Result<()>
Delete all filters from a parent qdisc by interface index.
Sourcepub async fn attach_bpf(
&self,
dev: impl Into<InterfaceRef>,
direction: BpfDirection,
filter: BpfFilter,
) -> Result<()>
pub async fn attach_bpf( &self, dev: impl Into<InterfaceRef>, direction: BpfDirection, filter: BpfFilter, ) -> Result<()>
Attach a BPF program to ingress or egress using clsact.
Creates the clsact qdisc if it doesn’t exist, then attaches the BPF filter. This is the standard pattern for BPF TC programs.
§Example
use nlink::netlink::filter::{BpfFilter, BpfDirection};
let filter = BpfFilter::from_pinned("/sys/fs/bpf/my_prog")?
.direct_action();
conn.attach_bpf("eth0", BpfDirection::Ingress, filter).await?;Sourcepub async fn attach_bpf_by_index(
&self,
ifindex: u32,
direction: BpfDirection,
filter: BpfFilter,
) -> Result<()>
pub async fn attach_bpf_by_index( &self, ifindex: u32, direction: BpfDirection, filter: BpfFilter, ) -> Result<()>
Attach a BPF program by interface index (namespace-safe).
Sourcepub async fn detach_bpf(
&self,
dev: impl Into<InterfaceRef>,
direction: BpfDirection,
) -> Result<()>
pub async fn detach_bpf( &self, dev: impl Into<InterfaceRef>, direction: BpfDirection, ) -> Result<()>
Sourcepub async fn detach_bpf_by_index(
&self,
ifindex: u32,
direction: BpfDirection,
) -> Result<()>
pub async fn detach_bpf_by_index( &self, ifindex: u32, direction: BpfDirection, ) -> Result<()>
Detach all BPF filters from an interface direction by index.
Sourcepub async fn list_bpf_programs(
&self,
dev: impl Into<InterfaceRef>,
) -> Result<Vec<BpfInfo>>
pub async fn list_bpf_programs( &self, dev: impl Into<InterfaceRef>, ) -> Result<Vec<BpfInfo>>
List attached BPF programs on an interface (both directions).
Returns [BpfInfo] for each BPF filter found on the interface’s
clsact qdisc. Returns an empty vec if no clsact qdisc exists.
§Example
let programs = conn.list_bpf_programs("eth0").await?;
for prog in &programs {
println!("BPF: id={:?} name={:?} da={}", prog.id, prog.name, prog.direct_action);
}Source§impl Connection<Devlink>
impl Connection<Devlink>
Sourcepub fn subscribe(&mut self) -> Result<()>
pub fn subscribe(&mut self) -> Result<()>
Subscribe to devlink multicast events.
After subscribing, use events() or into_events() to receive events.
Sourcepub async fn get_devices(&self) -> Result<Vec<DevlinkDevice>>
pub async fn get_devices(&self) -> Result<Vec<DevlinkDevice>>
Sourcepub async fn get_device_info(
&self,
bus: &str,
device: &str,
) -> Result<DevlinkInfo>
pub async fn get_device_info( &self, bus: &str, device: &str, ) -> Result<DevlinkInfo>
Sourcepub async fn get_ports(&self) -> Result<Vec<DevlinkPort>>
pub async fn get_ports(&self) -> Result<Vec<DevlinkPort>>
List all ports across all devices.
Sourcepub async fn get_device_ports(
&self,
bus: &str,
device: &str,
) -> Result<Vec<DevlinkPort>>
pub async fn get_device_ports( &self, bus: &str, device: &str, ) -> Result<Vec<DevlinkPort>>
List ports for a specific device.
Sourcepub async fn get_port(
&self,
bus: &str,
device: &str,
index: u32,
) -> Result<Option<DevlinkPort>>
pub async fn get_port( &self, bus: &str, device: &str, index: u32, ) -> Result<Option<DevlinkPort>>
Get a specific port by device and index.
Sourcepub async fn get_port_by_netdev(
&self,
netdev: &str,
) -> Result<Option<DevlinkPort>>
pub async fn get_port_by_netdev( &self, netdev: &str, ) -> Result<Option<DevlinkPort>>
Find the port associated with a network interface name.
Sourcepub async fn get_health_reporters(
&self,
bus: &str,
device: &str,
) -> Result<Vec<HealthReporter>>
pub async fn get_health_reporters( &self, bus: &str, device: &str, ) -> Result<Vec<HealthReporter>>
List all health reporters for a device.
Sourcepub async fn get_health_reporter(
&self,
bus: &str,
device: &str,
name: &str,
) -> Result<Option<HealthReporter>>
pub async fn get_health_reporter( &self, bus: &str, device: &str, name: &str, ) -> Result<Option<HealthReporter>>
Get a specific health reporter by name.
Sourcepub async fn get_health_errors(
&self,
bus: &str,
device: &str,
) -> Result<Vec<HealthReporter>>
pub async fn get_health_errors( &self, bus: &str, device: &str, ) -> Result<Vec<HealthReporter>>
List health reporters that are in error state.
Sourcepub async fn get_params(
&self,
bus: &str,
device: &str,
) -> Result<Vec<DevlinkParam>>
pub async fn get_params( &self, bus: &str, device: &str, ) -> Result<Vec<DevlinkParam>>
List all parameters for a device.
Sourcepub async fn get_param(
&self,
bus: &str,
device: &str,
name: &str,
) -> Result<Option<DevlinkParam>>
pub async fn get_param( &self, bus: &str, device: &str, name: &str, ) -> Result<Option<DevlinkParam>>
Get a specific parameter by name.
Sourcepub async fn health_reporter_recover(
&self,
bus: &str,
device: &str,
reporter: &str,
) -> Result<()>
pub async fn health_reporter_recover( &self, bus: &str, device: &str, reporter: &str, ) -> Result<()>
Trigger recovery on a health reporter.
Sourcepub async fn set_health_reporter(
&self,
bus: &str,
device: &str,
reporter: &str,
auto_recover: Option<bool>,
auto_dump: Option<bool>,
graceful_period_ms: Option<u64>,
) -> Result<()>
pub async fn set_health_reporter( &self, bus: &str, device: &str, reporter: &str, auto_recover: Option<bool>, auto_dump: Option<bool>, graceful_period_ms: Option<u64>, ) -> Result<()>
Configure a health reporter’s settings.
Sourcepub async fn flash_update(
&self,
bus: &str,
device: &str,
request: FlashRequest,
) -> Result<()>
pub async fn flash_update( &self, bus: &str, device: &str, request: FlashRequest, ) -> Result<()>
Flash firmware to a device.
This is a long-running operation. The kernel will send progress notifications asynchronously.
Sourcepub async fn reload(
&self,
bus: &str,
device: &str,
action: ReloadAction,
) -> Result<()>
pub async fn reload( &self, bus: &str, device: &str, action: ReloadAction, ) -> Result<()>
Reload the device with the specified action.
Sourcepub async fn port_split(
&self,
bus: &str,
device: &str,
port_index: u32,
count: u32,
) -> Result<()>
pub async fn port_split( &self, bus: &str, device: &str, port_index: u32, count: u32, ) -> Result<()>
Split a port into sub-ports.
Source§impl Connection<Ethtool>
impl Connection<Ethtool>
Sourcepub async fn new_async() -> Result<Self>
pub async fn new_async() -> Result<Self>
Create a new ethtool connection.
This resolves the ethtool GENL family ID during initialization.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
let state = conn.get_link_state("eth0").await?;
println!("Link: {}", if state.link { "up" } else { "down" });Sourcepub fn monitor_group_id(&self) -> Option<u32>
pub fn monitor_group_id(&self) -> Option<u32>
Get the monitor multicast group ID (if available).
Sourcepub async fn get_link_state(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<LinkState>
pub async fn get_link_state( &self, iface: impl Into<InterfaceRef>, ) -> Result<LinkState>
Get link state (carrier detection, signal quality).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let state = conn.get_link_state("eth0").await?;
// By index
let state = conn.get_link_state(5u32).await?;
println!("Link detected: {}", state.link);Sourcepub async fn get_link_state_by_name(&self, ifname: &str) -> Result<LinkState>
pub async fn get_link_state_by_name(&self, ifname: &str) -> Result<LinkState>
Get link state by interface name.
Sourcepub async fn get_link_info(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<LinkInfo>
pub async fn get_link_info( &self, iface: impl Into<InterfaceRef>, ) -> Result<LinkInfo>
Get link info (port type, transceiver, MDI-X).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let info = conn.get_link_info("eth0").await?;
// By index
let info = conn.get_link_info(5u32).await?;
println!("Port: {:?}", info.port);
println!("Transceiver: {:?}", info.transceiver);Sourcepub async fn get_link_info_by_name(&self, ifname: &str) -> Result<LinkInfo>
pub async fn get_link_info_by_name(&self, ifname: &str) -> Result<LinkInfo>
Get link info by interface name.
Sourcepub async fn get_link_modes(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<LinkModes>
pub async fn get_link_modes( &self, iface: impl Into<InterfaceRef>, ) -> Result<LinkModes>
Get link modes (speed, duplex, autonegotiation).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let modes = conn.get_link_modes("eth0").await?;
// By index
let modes = conn.get_link_modes(5u32).await?;
println!("Speed: {:?} Mb/s", modes.speed);
println!("Duplex: {:?}", modes.duplex);
println!("Autoneg: {}", modes.autoneg);
println!("Supported modes: {:?}", modes.supported_modes());Sourcepub async fn get_link_modes_by_name(&self, ifname: &str) -> Result<LinkModes>
pub async fn get_link_modes_by_name(&self, ifname: &str) -> Result<LinkModes>
Get link modes by interface name.
Sourcepub async fn set_link_modes(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(LinkModesBuilder) -> LinkModesBuilder,
) -> Result<()>
pub async fn set_link_modes( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(LinkModesBuilder) -> LinkModesBuilder, ) -> Result<()>
Set link modes (speed, duplex, autonegotiation).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
use nlink::netlink::genl::ethtool::Duplex;
let conn = Connection::<Ethtool>::new_async().await?;
// Force 1000Mbps full duplex (by name)
conn.set_link_modes("eth0", |m| {
m.autoneg(false)
.speed(1000)
.duplex(Duplex::Full)
}).await?;
// By index
conn.set_link_modes(5u32, |m| {
m.autoneg(true)
.advertise("1000baseT/Full")
.advertise("100baseT/Full")
}).await?;Sourcepub async fn set_link_modes_by_name(
&self,
ifname: &str,
configure: impl FnOnce(LinkModesBuilder) -> LinkModesBuilder,
) -> Result<()>
pub async fn set_link_modes_by_name( &self, ifname: &str, configure: impl FnOnce(LinkModesBuilder) -> LinkModesBuilder, ) -> Result<()>
Set link modes by interface name.
Sourcepub async fn get_features(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Features>
pub async fn get_features( &self, iface: impl Into<InterfaceRef>, ) -> Result<Features>
Get device features (offloads).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let features = conn.get_features("eth0").await?;
// By index
let features = conn.get_features(5u32).await?;
println!("TSO: {}", features.is_active("tx-tcp-segmentation"));
println!("GRO: {}", features.is_active("rx-gro"));
for (name, enabled) in features.iter() {
println!("{}: {}", name, if enabled { "on" } else { "off" });
}Sourcepub async fn get_features_by_name(&self, ifname: &str) -> Result<Features>
pub async fn get_features_by_name(&self, ifname: &str) -> Result<Features>
Get device features by interface name.
Sourcepub async fn set_features(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(FeaturesBuilder) -> FeaturesBuilder,
) -> Result<()>
pub async fn set_features( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(FeaturesBuilder) -> FeaturesBuilder, ) -> Result<()>
Set device features (offloads).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
conn.set_features("eth0", |f| {
f.enable("tx-checksumming")
.disable("rx-gro")
}).await?;
// By index
conn.set_features(5u32, |f| {
f.enable("tx-checksumming")
}).await?;Sourcepub async fn set_features_by_name(
&self,
ifname: &str,
configure: impl FnOnce(FeaturesBuilder) -> FeaturesBuilder,
) -> Result<()>
pub async fn set_features_by_name( &self, ifname: &str, configure: impl FnOnce(FeaturesBuilder) -> FeaturesBuilder, ) -> Result<()>
Set device features by interface name.
Sourcepub async fn get_rings(&self, iface: impl Into<InterfaceRef>) -> Result<Rings>
pub async fn get_rings(&self, iface: impl Into<InterfaceRef>) -> Result<Rings>
Get ring buffer sizes.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let rings = conn.get_rings("eth0").await?;
// By index
let rings = conn.get_rings(5u32).await?;
println!("RX: {:?} (max {:?})", rings.rx, rings.rx_max);
println!("TX: {:?} (max {:?})", rings.tx, rings.tx_max);Sourcepub async fn get_rings_by_name(&self, ifname: &str) -> Result<Rings>
pub async fn get_rings_by_name(&self, ifname: &str) -> Result<Rings>
Get ring buffer sizes by interface name.
Sourcepub async fn set_rings(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(RingsBuilder) -> RingsBuilder,
) -> Result<()>
pub async fn set_rings( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(RingsBuilder) -> RingsBuilder, ) -> Result<()>
Set ring buffer sizes.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
conn.set_rings("eth0", |r| {
r.rx(4096).tx(4096)
}).await?;
// By index
conn.set_rings(5u32, |r| {
r.rx(4096).tx(4096)
}).await?;Sourcepub async fn set_rings_by_name(
&self,
ifname: &str,
configure: impl FnOnce(RingsBuilder) -> RingsBuilder,
) -> Result<()>
pub async fn set_rings_by_name( &self, ifname: &str, configure: impl FnOnce(RingsBuilder) -> RingsBuilder, ) -> Result<()>
Set ring buffer sizes by interface name.
Sourcepub async fn get_channels(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Channels>
pub async fn get_channels( &self, iface: impl Into<InterfaceRef>, ) -> Result<Channels>
Get channel counts (RX/TX queues).
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let channels = conn.get_channels("eth0").await?;
// By index
let channels = conn.get_channels(5u32).await?;
println!("RX: {:?} (max {:?})", channels.rx_count, channels.rx_max);
println!("TX: {:?} (max {:?})", channels.tx_count, channels.tx_max);
println!("Combined: {:?} (max {:?})", channels.combined_count, channels.combined_max);Sourcepub async fn get_channels_by_name(&self, ifname: &str) -> Result<Channels>
pub async fn get_channels_by_name(&self, ifname: &str) -> Result<Channels>
Get channel counts by interface name.
Sourcepub async fn set_channels(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(ChannelsBuilder) -> ChannelsBuilder,
) -> Result<()>
pub async fn set_channels( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(ChannelsBuilder) -> ChannelsBuilder, ) -> Result<()>
Set channel counts.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
conn.set_channels("eth0", |c| {
c.combined(4)
}).await?;
// By index
conn.set_channels(5u32, |c| {
c.combined(4)
}).await?;Sourcepub async fn set_channels_by_name(
&self,
ifname: &str,
configure: impl FnOnce(ChannelsBuilder) -> ChannelsBuilder,
) -> Result<()>
pub async fn set_channels_by_name( &self, ifname: &str, configure: impl FnOnce(ChannelsBuilder) -> ChannelsBuilder, ) -> Result<()>
Set channel counts by interface name.
Sourcepub async fn get_coalesce(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<Coalesce>
pub async fn get_coalesce( &self, iface: impl Into<InterfaceRef>, ) -> Result<Coalesce>
Get interrupt coalescing parameters.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let coalesce = conn.get_coalesce("eth0").await?;
// By index
let coalesce = conn.get_coalesce(5u32).await?;
println!("RX usecs: {:?}", coalesce.rx_usecs);
println!("TX usecs: {:?}", coalesce.tx_usecs);
println!("Adaptive RX: {:?}", coalesce.use_adaptive_rx);Sourcepub async fn get_coalesce_by_name(&self, ifname: &str) -> Result<Coalesce>
pub async fn get_coalesce_by_name(&self, ifname: &str) -> Result<Coalesce>
Get interrupt coalescing parameters by interface name.
Sourcepub async fn set_coalesce(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(CoalesceBuilder) -> CoalesceBuilder,
) -> Result<()>
pub async fn set_coalesce( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(CoalesceBuilder) -> CoalesceBuilder, ) -> Result<()>
Set interrupt coalescing parameters.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
conn.set_coalesce("eth0", |c| {
c.rx_usecs(100)
.tx_usecs(100)
.use_adaptive_rx(true)
}).await?;
// By index
conn.set_coalesce(5u32, |c| {
c.rx_usecs(100)
}).await?;Sourcepub async fn set_coalesce_by_name(
&self,
ifname: &str,
configure: impl FnOnce(CoalesceBuilder) -> CoalesceBuilder,
) -> Result<()>
pub async fn set_coalesce_by_name( &self, ifname: &str, configure: impl FnOnce(CoalesceBuilder) -> CoalesceBuilder, ) -> Result<()>
Set interrupt coalescing parameters by interface name.
Sourcepub async fn get_pause(&self, iface: impl Into<InterfaceRef>) -> Result<Pause>
pub async fn get_pause(&self, iface: impl Into<InterfaceRef>) -> Result<Pause>
Get pause/flow control settings.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
let pause = conn.get_pause("eth0").await?;
// By index
let pause = conn.get_pause(5u32).await?;
println!("Autoneg: {:?}", pause.autoneg);
println!("RX pause: {:?}", pause.rx);
println!("TX pause: {:?}", pause.tx);Sourcepub async fn get_pause_by_name(&self, ifname: &str) -> Result<Pause>
pub async fn get_pause_by_name(&self, ifname: &str) -> Result<Pause>
Get pause/flow control settings by interface name.
Sourcepub async fn set_pause(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(PauseBuilder) -> PauseBuilder,
) -> Result<()>
pub async fn set_pause( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(PauseBuilder) -> PauseBuilder, ) -> Result<()>
Set pause/flow control settings.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Ethtool};
let conn = Connection::<Ethtool>::new_async().await?;
// By name
conn.set_pause("eth0", |p| {
p.autoneg(true)
.rx(true)
.tx(true)
}).await?;
// By index
conn.set_pause(5u32, |p| {
p.autoneg(true)
}).await?;Sourcepub async fn set_pause_by_name(
&self,
ifname: &str,
configure: impl FnOnce(PauseBuilder) -> PauseBuilder,
) -> Result<()>
pub async fn set_pause_by_name( &self, ifname: &str, configure: impl FnOnce(PauseBuilder) -> PauseBuilder, ) -> Result<()>
Set pause/flow control settings by interface name.
Sourcepub fn subscribe(&mut self) -> Result<()>
pub fn subscribe(&mut self) -> Result<()>
Subscribe to ethtool events.
After subscribing, use events() or into_events() to receive
notifications about ethtool configuration changes.
§Example
use nlink::netlink::{Connection, Ethtool};
use tokio_stream::StreamExt;
let mut conn = Connection::<Ethtool>::new_async().await?;
conn.subscribe()?;
let mut events = conn.events();
while let Some(event) = events.next().await {
println!("{:?}", event?);
}Source§impl Connection<Macsec>
impl Connection<Macsec>
Sourcepub async fn get_device(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<MacsecDevice>
pub async fn get_device( &self, iface: impl Into<InterfaceRef>, ) -> Result<MacsecDevice>
Get device information.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Macsec};
let conn = Connection::<Macsec>::new_async().await?;
// By name (convenient)
let device = conn.get_device("macsec0").await?;
// By index (efficient for repeated operations)
let device = conn.get_device(5u32).await?;Sourcepub async fn get_device_by_index(&self, ifindex: u32) -> Result<MacsecDevice>
pub async fn get_device_by_index(&self, ifindex: u32) -> Result<MacsecDevice>
Get device information by interface index.
Returns the current configuration and status of the MACsec interface. This is the preferred method for namespace operations.
§Example
// Get ifindex via Route connection first
let route_conn = Connection::<Route>::new()?;
let link = route_conn.get_link_by_name("macsec0").await?.unwrap();
let macsec_conn = Connection::<Macsec>::new_async().await?;
let device = macsec_conn.get_device_by_index(link.ifindex()).await?;
println!("SCI: {:016x}", device.sci);Sourcepub async fn add_tx_sa_by_index(
&self,
ifindex: u32,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn add_tx_sa_by_index( &self, ifindex: u32, sa: MacsecSaBuilder, ) -> Result<()>
Sourcepub async fn del_tx_sa_by_index(&self, ifindex: u32, an: u8) -> Result<()>
pub async fn del_tx_sa_by_index(&self, ifindex: u32, an: u8) -> Result<()>
Delete a TX Security Association by interface index.
§Arguments
ifindex- Interface indexan- Association Number (0-3)
Sourcepub async fn update_tx_sa_by_index(
&self,
ifindex: u32,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn update_tx_sa_by_index( &self, ifindex: u32, sa: MacsecSaBuilder, ) -> Result<()>
Update a TX Security Association by interface index.
This can be used to activate/deactivate an SA or update the packet number.
Sourcepub async fn add_rx_sc_by_index(&self, ifindex: u32, sci: u64) -> Result<()>
pub async fn add_rx_sc_by_index(&self, ifindex: u32, sci: u64) -> Result<()>
Add an RX Secure Channel by interface index.
§Arguments
ifindex- Interface indexsci- Secure Channel Identifier (typically peer’s MAC + port)
Sourcepub async fn del_rx_sc_by_index(&self, ifindex: u32, sci: u64) -> Result<()>
pub async fn del_rx_sc_by_index(&self, ifindex: u32, sci: u64) -> Result<()>
Delete an RX Secure Channel by interface index.
This also deletes all associated RX SAs.
Sourcepub async fn add_rx_sa_by_index(
&self,
ifindex: u32,
sci: u64,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn add_rx_sa_by_index( &self, ifindex: u32, sci: u64, sa: MacsecSaBuilder, ) -> Result<()>
Add an RX Security Association by interface index.
§Arguments
ifindex- Interface indexsci- Secure Channel Identifiersa- SA configuration
Sourcepub async fn del_rx_sa_by_index(
&self,
ifindex: u32,
sci: u64,
an: u8,
) -> Result<()>
pub async fn del_rx_sa_by_index( &self, ifindex: u32, sci: u64, an: u8, ) -> Result<()>
Delete an RX Security Association by interface index.
Sourcepub async fn update_rx_sa_by_index(
&self,
ifindex: u32,
sci: u64,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn update_rx_sa_by_index( &self, ifindex: u32, sci: u64, sa: MacsecSaBuilder, ) -> Result<()>
Update an RX Security Association by interface index.
Sourcepub async fn add_tx_sa(
&self,
iface: impl Into<InterfaceRef>,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn add_tx_sa( &self, iface: impl Into<InterfaceRef>, sa: MacsecSaBuilder, ) -> Result<()>
Add a TX Security Association.
Accepts either an interface name or index via InterfaceRef.
§Example
let key = [0u8; 16];
conn.add_tx_sa("macsec0", MacsecSaBuilder::new(0).key(&key).active(true)).await?;Sourcepub async fn del_tx_sa(
&self,
iface: impl Into<InterfaceRef>,
an: u8,
) -> Result<()>
pub async fn del_tx_sa( &self, iface: impl Into<InterfaceRef>, an: u8, ) -> Result<()>
Delete a TX Security Association.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn update_tx_sa(
&self,
iface: impl Into<InterfaceRef>,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn update_tx_sa( &self, iface: impl Into<InterfaceRef>, sa: MacsecSaBuilder, ) -> Result<()>
Update a TX Security Association.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn add_rx_sc(
&self,
iface: impl Into<InterfaceRef>,
sci: u64,
) -> Result<()>
pub async fn add_rx_sc( &self, iface: impl Into<InterfaceRef>, sci: u64, ) -> Result<()>
Add an RX Secure Channel.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn del_rx_sc(
&self,
iface: impl Into<InterfaceRef>,
sci: u64,
) -> Result<()>
pub async fn del_rx_sc( &self, iface: impl Into<InterfaceRef>, sci: u64, ) -> Result<()>
Delete an RX Secure Channel.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn add_rx_sa(
&self,
iface: impl Into<InterfaceRef>,
sci: u64,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn add_rx_sa( &self, iface: impl Into<InterfaceRef>, sci: u64, sa: MacsecSaBuilder, ) -> Result<()>
Add an RX Security Association.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn del_rx_sa(
&self,
iface: impl Into<InterfaceRef>,
sci: u64,
an: u8,
) -> Result<()>
pub async fn del_rx_sa( &self, iface: impl Into<InterfaceRef>, sci: u64, an: u8, ) -> Result<()>
Delete an RX Security Association.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn update_rx_sa(
&self,
iface: impl Into<InterfaceRef>,
sci: u64,
sa: MacsecSaBuilder,
) -> Result<()>
pub async fn update_rx_sa( &self, iface: impl Into<InterfaceRef>, sci: u64, sa: MacsecSaBuilder, ) -> Result<()>
Update an RX Security Association.
Accepts either an interface name or index via InterfaceRef.
Source§impl Connection<Mptcp>
impl Connection<Mptcp>
Sourcepub async fn get_endpoints(&self) -> Result<Vec<MptcpEndpoint>>
pub async fn get_endpoints(&self) -> Result<Vec<MptcpEndpoint>>
Sourcepub async fn add_endpoint(&self, endpoint: MptcpEndpointBuilder) -> Result<()>
pub async fn add_endpoint(&self, endpoint: MptcpEndpointBuilder) -> Result<()>
Sourcepub async fn del_endpoint(&self, id: u8) -> Result<()>
pub async fn del_endpoint(&self, id: u8) -> Result<()>
Sourcepub async fn flush_endpoints(&self) -> Result<()>
pub async fn flush_endpoints(&self) -> Result<()>
Sourcepub async fn get_limits(&self) -> Result<MptcpLimits>
pub async fn get_limits(&self) -> Result<MptcpLimits>
Sourcepub async fn set_limits(&self, limits: MptcpLimits) -> Result<()>
pub async fn set_limits(&self, limits: MptcpLimits) -> Result<()>
Sourcepub async fn set_endpoint_flags(&self, id: u8, flags: MptcpFlags) -> Result<()>
pub async fn set_endpoint_flags(&self, id: u8, flags: MptcpFlags) -> Result<()>
Sourcepub async fn create_subflow(&self, subflow: MptcpSubflowBuilder) -> Result<()>
pub async fn create_subflow(&self, subflow: MptcpSubflowBuilder) -> Result<()>
Create a new subflow on an existing MPTCP connection.
This allows programmatic creation of subflows between specific local and remote addresses on an active MPTCP connection.
§Example
use nlink::netlink::genl::mptcp::MptcpSubflowBuilder;
use std::net::Ipv4Addr;
// Create a subflow using local address ID 1 to the remote
conn.create_subflow(
MptcpSubflowBuilder::new(connection_token)
.local_id(1)
.remote_addr(Ipv4Addr::new(10, 0, 0, 1).into())
.remote_port(80)
).await?;Sourcepub async fn destroy_subflow(&self, subflow: MptcpSubflowBuilder) -> Result<()>
pub async fn destroy_subflow(&self, subflow: MptcpSubflowBuilder) -> Result<()>
Destroy a subflow on an existing MPTCP connection.
This closes a specific subflow identified by its local and remote addresses.
§Example
use nlink::netlink::genl::mptcp::MptcpSubflowBuilder;
use std::net::Ipv4Addr;
// Destroy the subflow between specific addresses
conn.destroy_subflow(
MptcpSubflowBuilder::new(connection_token)
.local_addr(Ipv4Addr::new(192, 168, 1, 1).into())
.local_port(12345)
.remote_addr(Ipv4Addr::new(10, 0, 0, 1).into())
.remote_port(80)
).await?;Sourcepub async fn announce_addr(&self, announce: MptcpAnnounceBuilder) -> Result<()>
pub async fn announce_addr(&self, announce: MptcpAnnounceBuilder) -> Result<()>
Announce an address to a peer on a specific connection.
This sends an ADD_ADDR message to the peer on the specified connection.
§Example
use nlink::netlink::genl::mptcp::MptcpAnnounceBuilder;
use std::net::Ipv4Addr;
// Announce address ID 1 to the peer
conn.announce_addr(
MptcpAnnounceBuilder::new(connection_token)
.addr_id(1)
.address(Ipv4Addr::new(192, 168, 2, 1).into())
).await?;Source§impl Connection<Nl80211>
impl Connection<Nl80211>
Sourcepub fn subscribe(&mut self) -> Result<()>
pub fn subscribe(&mut self) -> Result<()>
Subscribe to nl80211 multicast events (scan, mlme, regulatory, config).
After subscribing, use events() or into_events() to receive events.
§Example
use nlink::netlink::{Connection, Nl80211};
use tokio_stream::StreamExt;
let mut conn = Connection::<Nl80211>::new_async().await?;
conn.subscribe()?;
let mut events = conn.events();
while let Some(event) = events.next().await {
println!("{:?}", event?);
}Sourcepub async fn get_interfaces(&self) -> Result<Vec<WirelessInterface>>
pub async fn get_interfaces(&self) -> Result<Vec<WirelessInterface>>
Sourcepub async fn get_interface(
&self,
name: &str,
) -> Result<Option<WirelessInterface>>
pub async fn get_interface( &self, name: &str, ) -> Result<Option<WirelessInterface>>
Get a specific wireless interface by name.
Sourcepub async fn get_interface_by_index(
&self,
ifindex: u32,
) -> Result<Option<WirelessInterface>>
pub async fn get_interface_by_index( &self, ifindex: u32, ) -> Result<Option<WirelessInterface>>
Get a specific wireless interface by index.
Sourcepub async fn trigger_scan(
&self,
iface: &str,
request: &ScanRequest,
) -> Result<()>
pub async fn trigger_scan( &self, iface: &str, request: &ScanRequest, ) -> Result<()>
Trigger a scan on an interface.
This is asynchronous: the kernel starts the scan and returns
immediately. Poll get_scan_results() to get results.
§Errors
Returns Error::Kernel with EBUSY if a scan is already in progress.
Sourcepub async fn trigger_scan_by_index(
&self,
ifindex: u32,
request: &ScanRequest,
) -> Result<()>
pub async fn trigger_scan_by_index( &self, ifindex: u32, request: &ScanRequest, ) -> Result<()>
Trigger a scan by interface index (namespace-safe).
Sourcepub async fn get_scan_results(&self, iface: &str) -> Result<Vec<ScanResult>>
pub async fn get_scan_results(&self, iface: &str) -> Result<Vec<ScanResult>>
Get cached scan results for an interface.
Returns the most recent scan results. Call trigger_scan() first
to ensure fresh results.
Sourcepub async fn get_scan_results_by_index(
&self,
ifindex: u32,
) -> Result<Vec<ScanResult>>
pub async fn get_scan_results_by_index( &self, ifindex: u32, ) -> Result<Vec<ScanResult>>
Get scan results by interface index (namespace-safe).
Sourcepub async fn get_station(&self, iface: &str) -> Result<Option<StationInfo>>
pub async fn get_station(&self, iface: &str) -> Result<Option<StationInfo>>
Get station info for the currently associated AP.
Sourcepub async fn get_station_by_index(
&self,
ifindex: u32,
) -> Result<Option<StationInfo>>
pub async fn get_station_by_index( &self, ifindex: u32, ) -> Result<Option<StationInfo>>
Get station info by interface index (namespace-safe).
Sourcepub async fn get_stations(&self, iface: &str) -> Result<Vec<StationInfo>>
pub async fn get_stations(&self, iface: &str) -> Result<Vec<StationInfo>>
List all stations (useful in AP mode).
Sourcepub async fn get_stations_by_index(
&self,
ifindex: u32,
) -> Result<Vec<StationInfo>>
pub async fn get_stations_by_index( &self, ifindex: u32, ) -> Result<Vec<StationInfo>>
List all stations by interface index.
Sourcepub async fn get_phy(&self, wiphy: u32) -> Result<Option<PhyInfo>>
pub async fn get_phy(&self, wiphy: u32) -> Result<Option<PhyInfo>>
Get capabilities of a specific physical device.
Sourcepub async fn get_regulatory(&self) -> Result<RegulatoryDomain>
pub async fn get_regulatory(&self) -> Result<RegulatoryDomain>
Get the current regulatory domain.
Sourcepub async fn connect_by_index(
&self,
ifindex: u32,
request: ConnectRequest,
) -> Result<()>
pub async fn connect_by_index( &self, ifindex: u32, request: ConnectRequest, ) -> Result<()>
Connect by interface index (namespace-safe).
Sourcepub async fn disconnect(&self, iface: &str) -> Result<()>
pub async fn disconnect(&self, iface: &str) -> Result<()>
Disconnect from the current network.
Sourcepub async fn disconnect_by_index(&self, ifindex: u32) -> Result<()>
pub async fn disconnect_by_index(&self, ifindex: u32) -> Result<()>
Disconnect by interface index (namespace-safe).
Sourcepub async fn set_power_save(&self, iface: &str, enabled: bool) -> Result<()>
pub async fn set_power_save(&self, iface: &str, enabled: bool) -> Result<()>
Set power save mode.
Sourcepub async fn get_power_save(&self, iface: &str) -> Result<PowerSaveState>
pub async fn get_power_save(&self, iface: &str) -> Result<PowerSaveState>
Get power save mode.
Source§impl Connection<Wireguard>
impl Connection<Wireguard>
Sourcepub async fn get_device(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<WgDevice>
pub async fn get_device( &self, iface: impl Into<InterfaceRef>, ) -> Result<WgDevice>
Get device information.
Accepts either an interface name or index via InterfaceRef.
§Example
use nlink::netlink::{Connection, Wireguard};
let conn = Connection::<Wireguard>::new_async().await?;
// By name
let device = conn.get_device("wg0").await?;
// By index
let device = conn.get_device(5u32).await?;Sourcepub async fn set_device(
&self,
iface: impl Into<InterfaceRef>,
configure: impl FnOnce(WgDeviceBuilder) -> WgDeviceBuilder,
) -> Result<()>
pub async fn set_device( &self, iface: impl Into<InterfaceRef>, configure: impl FnOnce(WgDeviceBuilder) -> WgDeviceBuilder, ) -> Result<()>
Set device configuration.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_device("wg0", |dev| {
dev.private_key(my_key)
.listen_port(51820)
}).await?;Sourcepub async fn set_peer(
&self,
iface: impl Into<InterfaceRef>,
public_key: [u8; 32],
configure: impl FnOnce(WgPeerBuilder) -> WgPeerBuilder,
) -> Result<()>
pub async fn set_peer( &self, iface: impl Into<InterfaceRef>, public_key: [u8; 32], configure: impl FnOnce(WgPeerBuilder) -> WgPeerBuilder, ) -> Result<()>
Add or update a peer.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn del_peer(
&self,
iface: impl Into<InterfaceRef>,
public_key: [u8; 32],
) -> Result<()>
pub async fn del_peer( &self, iface: impl Into<InterfaceRef>, public_key: [u8; 32], ) -> Result<()>
Remove a peer by public key.
Accepts either an interface name or index via InterfaceRef.
Sourcepub async fn get_device_by_name(&self, ifname: &str) -> Result<WgDevice>
pub async fn get_device_by_name(&self, ifname: &str) -> Result<WgDevice>
Get device information by interface name.
Returns the current configuration and status of the WireGuard interface.
Sourcepub async fn set_device_by_name(
&self,
ifname: &str,
configure: impl FnOnce(WgDeviceBuilder) -> WgDeviceBuilder,
) -> Result<()>
pub async fn set_device_by_name( &self, ifname: &str, configure: impl FnOnce(WgDeviceBuilder) -> WgDeviceBuilder, ) -> Result<()>
Set device configuration by interface name.
Sourcepub async fn set_peer_by_name(
&self,
ifname: &str,
public_key: [u8; 32],
configure: impl FnOnce(WgPeerBuilder) -> WgPeerBuilder,
) -> Result<()>
pub async fn set_peer_by_name( &self, ifname: &str, public_key: [u8; 32], configure: impl FnOnce(WgPeerBuilder) -> WgPeerBuilder, ) -> Result<()>
Add or update a peer by interface name.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_link<L: LinkConfig>(&self, config: L) -> Result<()>
pub async fn add_link<L: LinkConfig>(&self, config: L) -> Result<()>
Add a new network interface.
§Example
use nlink::netlink::link::{DummyLink, VethLink, BridgeLink};
// Create a dummy interface
conn.add_link(DummyLink::new("dummy0")).await?;
// Create a veth pair
conn.add_link(VethLink::new("veth0", "veth1")).await?;
// Create a bridge
conn.add_link(BridgeLink::new("br0").stp(true)).await?;
// Create a VLAN with parent by index (namespace-safe)
conn.add_link(VlanLink::with_parent_index("vlan100", 5, 100)).await?;Sourcepub async fn set_link_master(
&self,
iface: impl Into<InterfaceRef>,
master: impl Into<InterfaceRef>,
) -> Result<()>
pub async fn set_link_master( &self, iface: impl Into<InterfaceRef>, master: impl Into<InterfaceRef>, ) -> Result<()>
Sourcepub async fn set_link_master_by_index(
&self,
ifindex: u32,
master_index: u32,
) -> Result<()>
pub async fn set_link_master_by_index( &self, ifindex: u32, master_index: u32, ) -> Result<()>
Set the master device by interface indices.
Sourcepub async fn enslave(
&self,
member: impl Into<InterfaceRef>,
master: impl Into<InterfaceRef>,
) -> Result<()>
pub async fn enslave( &self, member: impl Into<InterfaceRef>, master: impl Into<InterfaceRef>, ) -> Result<()>
Enslave an interface to a bond or bridge.
This convenience method handles the required down/master/up sequence: the member interface must be brought down before enslaving, then brought back up afterward.
§Example
// Enslave eth0 to bond0 (handles down/master/up automatically)
conn.enslave("eth0", "bond0").await?;Sourcepub async fn enslave_by_index(
&self,
member_index: u32,
master_index: u32,
) -> Result<()>
pub async fn enslave_by_index( &self, member_index: u32, master_index: u32, ) -> Result<()>
Enslave an interface to a bond or bridge by index.
Sourcepub async fn set_link_nomaster(
&self,
iface: impl Into<InterfaceRef>,
) -> Result<()>
pub async fn set_link_nomaster( &self, iface: impl Into<InterfaceRef>, ) -> Result<()>
Remove an interface from its master device.
Accepts either an interface name or index via InterfaceRef.
§Example
// Remove eth0 from its bridge/bond
conn.set_link_nomaster("eth0").await?;Sourcepub async fn set_link_nomaster_by_index(&self, ifindex: u32) -> Result<()>
pub async fn set_link_nomaster_by_index(&self, ifindex: u32) -> Result<()>
Remove an interface from its master by index.
Sourcepub async fn set_link_name(
&self,
iface: impl Into<InterfaceRef>,
new_name: &str,
) -> Result<()>
pub async fn set_link_name( &self, iface: impl Into<InterfaceRef>, new_name: &str, ) -> Result<()>
Rename a network interface.
Accepts either an interface name or index via InterfaceRef.
Note: The interface must be down to be renamed.
§Example
conn.set_link_name("eth0", "lan0").await?;Sourcepub async fn set_link_name_by_index(
&self,
ifindex: u32,
new_name: &str,
) -> Result<()>
pub async fn set_link_name_by_index( &self, ifindex: u32, new_name: &str, ) -> Result<()>
Rename a network interface by index.
Sourcepub async fn set_link_address(
&self,
iface: impl Into<InterfaceRef>,
address: [u8; 6],
) -> Result<()>
pub async fn set_link_address( &self, iface: impl Into<InterfaceRef>, address: [u8; 6], ) -> Result<()>
Set the MAC address of a network interface.
Accepts either an interface name or index via InterfaceRef.
§Example
conn.set_link_address("eth0", [0x00, 0x11, 0x22, 0x33, 0x44, 0x55]).await?;Sourcepub async fn set_link_address_by_index(
&self,
ifindex: u32,
address: [u8; 6],
) -> Result<()>
pub async fn set_link_address_by_index( &self, ifindex: u32, address: [u8; 6], ) -> Result<()>
Set the MAC address by interface index.
Sourcepub async fn set_link_netns_pid(
&self,
iface: impl Into<InterfaceRef>,
pid: u32,
) -> Result<()>
pub async fn set_link_netns_pid( &self, iface: impl Into<InterfaceRef>, pid: u32, ) -> Result<()>
Move a network interface to a different network namespace.
Accepts either an interface name or index via InterfaceRef.
§Example
// Move veth1 to namespace by PID
conn.set_link_netns_pid("veth1", container_pid).await?;Sourcepub async fn set_link_netns_pid_by_index(
&self,
ifindex: u32,
pid: u32,
) -> Result<()>
pub async fn set_link_netns_pid_by_index( &self, ifindex: u32, pid: u32, ) -> Result<()>
Move a network interface to a namespace by PID (by index).
Sourcepub async fn set_link_netns_fd(
&self,
iface: impl Into<InterfaceRef>,
fd: i32,
) -> Result<()>
pub async fn set_link_netns_fd( &self, iface: impl Into<InterfaceRef>, fd: i32, ) -> Result<()>
Move a network interface to a namespace by file descriptor.
Accepts either an interface name or index via InterfaceRef.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_mpls_routes(&self) -> Result<Vec<MplsRoute>>
pub async fn get_mpls_routes(&self) -> Result<Vec<MplsRoute>>
Sourcepub async fn add_mpls_route(
&self,
route_builder: MplsRouteBuilder,
) -> Result<()>
pub async fn add_mpls_route( &self, route_builder: MplsRouteBuilder, ) -> Result<()>
Sourcepub async fn replace_mpls_route(
&self,
route_builder: MplsRouteBuilder,
) -> Result<()>
pub async fn replace_mpls_route( &self, route_builder: MplsRouteBuilder, ) -> Result<()>
Replace an MPLS route (add or update).
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
pub async fn add_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
Add a neighbor entry.
This method is namespace-safe: interface names are resolved via netlink.
§Example
use nlink::netlink::neigh::{Neighbor, NeighborState};
use std::net::Ipv4Addr;
// Add a permanent ARP entry
conn.add_neighbor(
Neighbor::new_v4("eth0", Ipv4Addr::new(192, 168, 1, 100))
.lladdr([0x00, 0x11, 0x22, 0x33, 0x44, 0x55])
.state(NeighborState::Permanent)
).await?;Sourcepub async fn del_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
pub async fn del_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
Delete a neighbor entry using a config.
Sourcepub async fn add_neighbor_v4_by_index(
&self,
ifindex: u32,
destination: Ipv4Addr,
lladdr: [u8; 6],
) -> Result<()>
pub async fn add_neighbor_v4_by_index( &self, ifindex: u32, destination: Ipv4Addr, lladdr: [u8; 6], ) -> Result<()>
Add an IPv4 neighbor entry by interface index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn add_neighbor_v6_by_index(
&self,
ifindex: u32,
destination: Ipv6Addr,
lladdr: [u8; 6],
) -> Result<()>
pub async fn add_neighbor_v6_by_index( &self, ifindex: u32, destination: Ipv6Addr, lladdr: [u8; 6], ) -> Result<()>
Add an IPv6 neighbor entry by interface index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn del_neighbor_v4(
&self,
ifname: impl Into<InterfaceRef>,
destination: Ipv4Addr,
) -> Result<()>
pub async fn del_neighbor_v4( &self, ifname: impl Into<InterfaceRef>, destination: Ipv4Addr, ) -> Result<()>
Sourcepub async fn del_neighbor_v4_by_index(
&self,
ifindex: u32,
destination: Ipv4Addr,
) -> Result<()>
pub async fn del_neighbor_v4_by_index( &self, ifindex: u32, destination: Ipv4Addr, ) -> Result<()>
Delete an IPv4 neighbor entry by interface index.
Sourcepub async fn del_neighbor_v6(
&self,
ifname: impl Into<InterfaceRef>,
destination: Ipv6Addr,
) -> Result<()>
pub async fn del_neighbor_v6( &self, ifname: impl Into<InterfaceRef>, destination: Ipv6Addr, ) -> Result<()>
Delete an IPv6 neighbor entry.
Sourcepub async fn del_neighbor_v6_by_index(
&self,
ifindex: u32,
destination: Ipv6Addr,
) -> Result<()>
pub async fn del_neighbor_v6_by_index( &self, ifindex: u32, destination: Ipv6Addr, ) -> Result<()>
Delete an IPv6 neighbor entry by interface index.
Sourcepub async fn replace_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
pub async fn replace_neighbor<N: NeighborConfig>(&self, config: N) -> Result<()>
Replace a neighbor entry (add or update).
If the entry exists, it will be updated. Otherwise, it will be created.
Sourcepub async fn replace_neighbor_v4_by_index(
&self,
ifindex: u32,
destination: Ipv4Addr,
lladdr: [u8; 6],
) -> Result<()>
pub async fn replace_neighbor_v4_by_index( &self, ifindex: u32, destination: Ipv4Addr, lladdr: [u8; 6], ) -> Result<()>
Replace an IPv4 neighbor entry by interface index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn replace_neighbor_v6_by_index(
&self,
ifindex: u32,
destination: Ipv6Addr,
lladdr: [u8; 6],
) -> Result<()>
pub async fn replace_neighbor_v6_by_index( &self, ifindex: u32, destination: Ipv6Addr, lladdr: [u8; 6], ) -> Result<()>
Replace an IPv6 neighbor entry by interface index.
This is namespace-safe as it doesn’t require interface name resolution.
Sourcepub async fn flush_neighbors(
&self,
ifname: impl Into<InterfaceRef>,
) -> Result<()>
pub async fn flush_neighbors( &self, ifname: impl Into<InterfaceRef>, ) -> Result<()>
Sourcepub async fn flush_neighbors_by_index(&self, ifindex: u32) -> Result<()>
pub async fn flush_neighbors_by_index(&self, ifindex: u32) -> Result<()>
Flush all neighbor entries for an interface by index.
Sourcepub async fn add_proxy_arp(
&self,
ifname: impl Into<InterfaceRef>,
destination: Ipv4Addr,
) -> Result<()>
pub async fn add_proxy_arp( &self, ifname: impl Into<InterfaceRef>, destination: Ipv4Addr, ) -> Result<()>
Sourcepub async fn add_proxy_arp_by_index(
&self,
ifindex: u32,
destination: Ipv4Addr,
) -> Result<()>
pub async fn add_proxy_arp_by_index( &self, ifindex: u32, destination: Ipv4Addr, ) -> Result<()>
Add a proxy ARP entry by interface index.
Sourcepub async fn del_proxy_arp(
&self,
ifname: impl Into<InterfaceRef>,
destination: Ipv4Addr,
) -> Result<()>
pub async fn del_proxy_arp( &self, ifname: impl Into<InterfaceRef>, destination: Ipv4Addr, ) -> Result<()>
Delete a proxy ARP entry.
Sourcepub async fn del_proxy_arp_by_index(
&self,
ifindex: u32,
destination: Ipv4Addr,
) -> Result<()>
pub async fn del_proxy_arp_by_index( &self, ifindex: u32, destination: Ipv4Addr, ) -> Result<()>
Delete a proxy ARP entry by interface index.
Sourcepub async fn get_neighbors_by_index(
&self,
ifindex: u32,
) -> Result<Vec<NeighborMessage>>
pub async fn get_neighbors_by_index( &self, ifindex: u32, ) -> Result<Vec<NeighborMessage>>
Get neighbor entries for an interface by index.
Source§impl Connection<Netfilter>
impl Connection<Netfilter>
Sourcepub async fn get_conntrack(&self) -> Result<Vec<ConntrackEntry>>
pub async fn get_conntrack(&self) -> Result<Vec<ConntrackEntry>>
Sourcepub async fn get_conntrack_v6(&self) -> Result<Vec<ConntrackEntry>>
pub async fn get_conntrack_v6(&self) -> Result<Vec<ConntrackEntry>>
Get connection tracking entries for IPv6.
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_nexthops(&self) -> Result<Vec<Nexthop>>
pub async fn get_nexthops(&self) -> Result<Vec<Nexthop>>
Sourcepub async fn get_nexthop(&self, id: u32) -> Result<Option<Nexthop>>
pub async fn get_nexthop(&self, id: u32) -> Result<Option<Nexthop>>
Get a specific nexthop by ID.
Returns None if the nexthop doesn’t exist.
Sourcepub async fn add_nexthop(&self, nh_builder: NexthopBuilder) -> Result<()>
pub async fn add_nexthop(&self, nh_builder: NexthopBuilder) -> Result<()>
Sourcepub async fn replace_nexthop(&self, nh_builder: NexthopBuilder) -> Result<()>
pub async fn replace_nexthop(&self, nh_builder: NexthopBuilder) -> Result<()>
Replace a nexthop (add or update).
If the nexthop exists, it’s updated. If it doesn’t exist, it’s created.
Sourcepub async fn del_nexthop(&self, id: u32) -> Result<()>
pub async fn del_nexthop(&self, id: u32) -> Result<()>
Delete a nexthop by ID.
Note: Deleting a nexthop that is in use by routes or groups will fail.
Sourcepub async fn add_nexthop_group(
&self,
builder: NexthopGroupBuilder,
) -> Result<()>
pub async fn add_nexthop_group( &self, builder: NexthopGroupBuilder, ) -> Result<()>
Add a nexthop group.
§Example
use nlink::netlink::nexthop::NexthopGroupBuilder;
// ECMP group with equal weights
conn.add_nexthop_group(
NexthopGroupBuilder::new(100)
.member(1, 1)
.member(2, 1)
).await?;
// Weighted multipath (2:1 ratio)
conn.add_nexthop_group(
NexthopGroupBuilder::new(101)
.member(1, 2)
.member(2, 1)
).await?;
// Resilient group with custom parameters
conn.add_nexthop_group(
NexthopGroupBuilder::new(102)
.resilient()
.member(1, 1)
.member(2, 1)
.buckets(128)
.idle_timer(120)
).await?;Sourcepub async fn replace_nexthop_group(
&self,
builder: NexthopGroupBuilder,
) -> Result<()>
pub async fn replace_nexthop_group( &self, builder: NexthopGroupBuilder, ) -> Result<()>
Replace a nexthop group (add or update).
Sourcepub async fn del_nexthop_group(&self, id: u32) -> Result<()>
pub async fn del_nexthop_group(&self, id: u32) -> Result<()>
Delete a nexthop group by ID.
Note: Deleting a group that is in use by routes will fail.
Sourcepub async fn get_nexthop_groups(&self) -> Result<Vec<Nexthop>>
pub async fn get_nexthop_groups(&self) -> Result<Vec<Nexthop>>
Get only nexthop groups (not individual nexthops).
Source§impl Connection<Nftables>
impl Connection<Nftables>
Sourcepub async fn list_tables(&self) -> Result<Vec<Table>>
pub async fn list_tables(&self) -> Result<Vec<Table>>
List all nftables tables.
Sourcepub async fn del_table(&self, name: &str, family: Family) -> Result<()>
pub async fn del_table(&self, name: &str, family: Family) -> Result<()>
Delete an nftables table.
Sourcepub async fn flush_table(&self, name: &str, family: Family) -> Result<()>
pub async fn flush_table(&self, name: &str, family: Family) -> Result<()>
Flush all rules from a table (keeps chains).
Sourcepub async fn list_chains(&self) -> Result<Vec<ChainInfo>>
pub async fn list_chains(&self) -> Result<Vec<ChainInfo>>
List all chains.
Sourcepub async fn del_chain(
&self,
table: &str,
name: &str,
family: Family,
) -> Result<()>
pub async fn del_chain( &self, table: &str, name: &str, family: Family, ) -> Result<()>
Delete a chain.
Sourcepub async fn list_rules(
&self,
table: &str,
family: Family,
) -> Result<Vec<RuleInfo>>
pub async fn list_rules( &self, table: &str, family: Family, ) -> Result<Vec<RuleInfo>>
List all rules in a table.
Sourcepub async fn del_rule(
&self,
table: &str,
chain: &str,
family: Family,
handle: u64,
) -> Result<()>
pub async fn del_rule( &self, table: &str, chain: &str, family: Family, handle: u64, ) -> Result<()>
Delete a rule by handle.
Sourcepub async fn del_set(
&self,
table: &str,
name: &str,
family: Family,
) -> Result<()>
pub async fn del_set( &self, table: &str, name: &str, family: Family, ) -> Result<()>
Delete a set.
Sourcepub async fn add_set_elements(
&self,
table: &str,
set: &str,
family: Family,
elements: &[SetElement],
) -> Result<()>
pub async fn add_set_elements( &self, table: &str, set: &str, family: Family, elements: &[SetElement], ) -> Result<()>
Add elements to a set.
Sourcepub async fn del_set_elements(
&self,
table: &str,
set: &str,
family: Family,
elements: &[SetElement],
) -> Result<()>
pub async fn del_set_elements( &self, table: &str, set: &str, family: Family, elements: &[SetElement], ) -> Result<()>
Delete elements from a set.
Sourcepub fn transaction(&self) -> Transaction
pub fn transaction(&self) -> Transaction
Sourcepub async fn flush_ruleset(&self) -> Result<()>
pub async fn flush_ruleset(&self) -> Result<()>
Flush the entire ruleset (all tables, chains, rules, sets).
Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_route<R: RouteConfig>(&self, config: R) -> Result<()>
pub async fn add_route<R: RouteConfig>(&self, config: R) -> Result<()>
Add a route.
§Example
use nlink::netlink::route::{Ipv4Route, Ipv6Route};
use std::net::{Ipv4Addr, Ipv6Addr};
// Add IPv4 route
conn.add_route(
Ipv4Route::new("192.168.2.0", 24)
.gateway(Ipv4Addr::new(192, 168, 1, 1))
).await?;
// Add IPv6 route
conn.add_route(
Ipv6Route::new("2001:db8:2::", 48)
.gateway("2001:db8::1".parse()?)
).await?;
// Add route with interface by index (namespace-safe)
conn.add_route(
Ipv4Route::new("10.0.0.0", 8)
.dev_index(5)
).await?;Sourcepub async fn del_route<R: RouteConfig>(&self, config: R) -> Result<()>
pub async fn del_route<R: RouteConfig>(&self, config: R) -> Result<()>
Delete a route using a config.
Sourcepub async fn del_route_v6(
&self,
destination: &str,
prefix_len: u8,
) -> Result<()>
pub async fn del_route_v6( &self, destination: &str, prefix_len: u8, ) -> Result<()>
Delete an IPv6 route by destination.
Sourcepub async fn replace_route<R: RouteConfig>(&self, config: R) -> Result<()>
pub async fn replace_route<R: RouteConfig>(&self, config: R) -> Result<()>
Replace a route (add or update).
If the route exists, it will be updated. Otherwise, it will be created.
Source§impl Connection<SELinux>
impl Connection<SELinux>
Sourcepub async fn recv(&self) -> Result<SELinuxEvent>
pub async fn recv(&self) -> Result<SELinuxEvent>
Receive the next SELinux event.
This method blocks until an event is received from the kernel.
§Example
use nlink::netlink::{Connection, SELinux};
use nlink::netlink::selinux::SELinuxEvent;
let conn = Connection::<SELinux>::new()?;
loop {
match conn.recv().await? {
SELinuxEvent::SetEnforce { enforcing } => {
if enforcing {
println!("SELinux now enforcing");
} else {
println!("SELinux now permissive");
}
}
SELinuxEvent::PolicyLoad { seqno } => {
println!("New policy loaded (seqno: {})", seqno);
}
}
}Sourcepub fn is_available() -> bool
pub fn is_available() -> bool
Check if SELinux is available on this system.
This checks if the SELinux filesystem is mounted.
Sourcepub fn get_enforce() -> Result<bool>
pub fn get_enforce() -> Result<bool>
Get the current SELinux enforcement mode.
Returns true if enforcing, false if permissive,
or an error if SELinux is not available.
Source§impl Connection<SockDiag>
impl Connection<SockDiag>
Sourcepub async fn query(&self, filter: &SocketFilter) -> Result<Vec<SocketInfo>>
pub async fn query(&self, filter: &SocketFilter) -> Result<Vec<SocketInfo>>
Sourcepub async fn query_tcp(&self) -> Result<Vec<InetSocket>>
pub async fn query_tcp(&self) -> Result<Vec<InetSocket>>
Sourcepub async fn query_udp(&self) -> Result<Vec<InetSocket>>
pub async fn query_udp(&self) -> Result<Vec<InetSocket>>
Query UDP sockets with default filter.
Sourcepub async fn query_unix_sockets(&self) -> Result<Vec<UnixSocket>>
pub async fn query_unix_sockets(&self) -> Result<Vec<UnixSocket>>
Query Unix sockets with default filter.
Sourcepub async fn query_netlink_sockets(&self) -> Result<Vec<NetlinkSocket>>
pub async fn query_netlink_sockets(&self) -> Result<Vec<NetlinkSocket>>
Query Netlink sockets with default filter.
Sourcepub async fn socket_summary(&self) -> Result<SocketSummary>
pub async fn socket_summary(&self) -> Result<SocketSummary>
Get aggregated socket statistics across all families.
Queries TCP, UDP, raw, and Unix sockets and aggregates the counts
by state. This is equivalent to ss -s.
§Example
use nlink::netlink::{Connection, SockDiag};
let conn = Connection::<SockDiag>::new()?;
let summary = conn.socket_summary().await?;
println!("{}", summary);
// Total: 234
// TCP: 45 (estab 23, closed 12, orphaned 0, timewait 8)
// UDP: 12
// RAW: 2
// UNIX: 175Sourcepub async fn destroy_tcp_socket(&self, socket: &InetSocket) -> Result<()>
pub async fn destroy_tcp_socket(&self, socket: &InetSocket) -> Result<()>
Force-close a TCP socket by sending SOCK_DESTROY.
The kernel sends a RST to the remote peer. Requires CAP_NET_ADMIN
and Linux 4.9+. Only TCP sockets can be destroyed.
§Errors
Returns Error::Kernel with EPERM if insufficient privileges.
Returns Error::Kernel with EOPNOTSUPP if the socket type doesn’t
support destruction.
§Example
let sockets = conn.query_tcp().await?;
for sock in &sockets {
if sock.remote.port() == 8080 {
conn.destroy_tcp_socket(sock).await?;
}
}Sourcepub async fn destroy_matching(
&self,
filter: &InetFilter,
) -> Result<DestroyResult>
pub async fn destroy_matching( &self, filter: &InetFilter, ) -> Result<DestroyResult>
Destroy all TCP sockets matching the given filter.
Queries sockets matching the filter, then destroys each one.
Returns a DestroyResult with the count of destroyed sockets and any errors.
Requires CAP_NET_ADMIN.
§Example
use nlink::sockdiag::{InetFilter, Protocol, TcpState};
let conn = Connection::<SockDiag>::new()?;
let filter = InetFilter {
protocol: Protocol::Tcp,
states: TcpState::TimeWait.mask(),
..Default::default()
};
let result = conn.destroy_matching(&filter).await?;
println!("Destroyed {} sockets", result.destroyed);Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn get_srv6_local_routes(&self) -> Result<Vec<Srv6LocalRoute>>
pub async fn get_srv6_local_routes(&self) -> Result<Vec<Srv6LocalRoute>>
Sourcepub async fn add_srv6_local(&self, builder: Srv6LocalBuilder) -> Result<()>
pub async fn add_srv6_local(&self, builder: Srv6LocalBuilder) -> Result<()>
Sourcepub async fn replace_srv6_local(&self, builder: Srv6LocalBuilder) -> Result<()>
pub async fn replace_srv6_local(&self, builder: Srv6LocalBuilder) -> Result<()>
Replace an SRv6 local route (add or update).
Source§impl<P: EventSource> Connection<P>
impl<P: EventSource> Connection<P>
Sourcepub fn events(&self) -> EventSubscription<'_, P>
pub fn events(&self) -> EventSubscription<'_, P>
Create an event stream that borrows this connection.
Returns a Stream that borrows the connection. The connection
remains usable for queries while the stream is active.
§Example
use nlink::netlink::{Connection, KobjectUevent};
use tokio_stream::StreamExt;
let conn = Connection::<KobjectUevent>::new()?;
// Borrow connection for streaming
let mut events = conn.events();
while let Some(event) = events.try_next().await? {
if event.is_add() {
println!("Device added: {}", event.devpath);
}
}
// Connection still usable
drop(events);Sourcepub fn into_events(self) -> OwnedEventStream<P>
pub fn into_events(self) -> OwnedEventStream<P>
Convert this connection into an owned event stream.
This consumes the connection. Use events()
if you need to keep using the connection for queries.
§Example
use nlink::netlink::{Connection, SELinux};
use tokio_stream::StreamExt;
let conn = Connection::<SELinux>::new()?;
let mut stream = conn.into_events();
while let Some(event) = stream.try_next().await? {
println!("{:?}", event);
}
// Recover connection if needed
let conn = stream.into_connection();Source§impl Connection<Route>
impl Connection<Route>
Sourcepub async fn add_qdisc(
&self,
dev: impl Into<InterfaceRef>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn add_qdisc( &self, dev: impl Into<InterfaceRef>, config: impl QdiscConfig, ) -> Result<()>
Sourcepub async fn add_qdisc_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn add_qdisc_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Add a qdisc with explicit parent and handle.
Sourcepub async fn add_qdisc_by_index(
&self,
ifindex: u32,
config: impl QdiscConfig,
) -> Result<()>
pub async fn add_qdisc_by_index( &self, ifindex: u32, config: impl QdiscConfig, ) -> Result<()>
Add a qdisc by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
§Example
use nlink::netlink::{Connection, Route, namespace, tc::NetemConfig};
use std::time::Duration;
let conn: Connection<Route> = namespace::connection_for("myns")?;
let link = conn.get_link_by_name("eth0").await?;
let netem = NetemConfig::new()
.delay(Duration::from_millis(100))
.build();
conn.add_qdisc_by_index(link.ifindex(), netem).await?;Sourcepub async fn add_qdisc_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn add_qdisc_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Add a qdisc by interface index with explicit parent and handle.
Sourcepub async fn del_qdisc_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
) -> Result<()>
pub async fn del_qdisc_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, ) -> Result<()>
Delete a qdisc with explicit handle.
Sourcepub async fn del_qdisc_by_index(&self, ifindex: u32, parent: &str) -> Result<()>
pub async fn del_qdisc_by_index(&self, ifindex: u32, parent: &str) -> Result<()>
Delete a qdisc by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
Sourcepub async fn del_qdisc_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
) -> Result<()>
pub async fn del_qdisc_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, ) -> Result<()>
Delete a qdisc by interface index with explicit handle.
Sourcepub async fn replace_qdisc(
&self,
dev: impl Into<InterfaceRef>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn replace_qdisc( &self, dev: impl Into<InterfaceRef>, config: impl QdiscConfig, ) -> Result<()>
Sourcepub async fn replace_qdisc_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn replace_qdisc_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Replace a qdisc with explicit parent and handle.
Sourcepub async fn replace_qdisc_by_index(
&self,
ifindex: u32,
config: impl QdiscConfig,
) -> Result<()>
pub async fn replace_qdisc_by_index( &self, ifindex: u32, config: impl QdiscConfig, ) -> Result<()>
Replace a qdisc by interface index (add or update).
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
Sourcepub async fn replace_qdisc_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn replace_qdisc_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Replace a qdisc by interface index with explicit parent and handle.
Sourcepub async fn change_qdisc(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
config: impl QdiscConfig,
) -> Result<()>
pub async fn change_qdisc( &self, dev: impl Into<InterfaceRef>, parent: &str, config: impl QdiscConfig, ) -> Result<()>
Sourcepub async fn change_qdisc_full(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn change_qdisc_full( &self, dev: impl Into<InterfaceRef>, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Change a qdisc with explicit handle.
Sourcepub async fn change_qdisc_by_index(
&self,
ifindex: u32,
parent: &str,
config: impl QdiscConfig,
) -> Result<()>
pub async fn change_qdisc_by_index( &self, ifindex: u32, parent: &str, config: impl QdiscConfig, ) -> Result<()>
Change a qdisc’s parameters by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
Sourcepub async fn change_qdisc_by_index_full(
&self,
ifindex: u32,
parent: &str,
handle: Option<&str>,
config: impl QdiscConfig,
) -> Result<()>
pub async fn change_qdisc_by_index_full( &self, ifindex: u32, parent: &str, handle: Option<&str>, config: impl QdiscConfig, ) -> Result<()>
Change a qdisc by interface index with explicit handle.
Sourcepub async fn apply_netem(
&self,
dev: impl Into<InterfaceRef>,
config: NetemConfig,
) -> Result<()>
pub async fn apply_netem( &self, dev: impl Into<InterfaceRef>, config: NetemConfig, ) -> Result<()>
Apply a netem configuration to an interface.
This is a convenience method that replaces any existing root qdisc with a netem qdisc. If no root qdisc exists, it creates one.
§Example
use nlink::netlink::tc::NetemConfig;
use std::time::Duration;
let netem = NetemConfig::new()
.delay(Duration::from_millis(100))
.jitter(Duration::from_millis(10))
.loss(1.0)
.build();
conn.apply_netem("eth0", netem).await?;Sourcepub async fn apply_netem_by_index(
&self,
ifindex: u32,
config: NetemConfig,
) -> Result<()>
pub async fn apply_netem_by_index( &self, ifindex: u32, config: NetemConfig, ) -> Result<()>
Apply a netem configuration by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
If no root qdisc exists, it creates one.
Sourcepub async fn del_netem_by_index(&self, ifindex: u32) -> Result<()>
pub async fn del_netem_by_index(&self, ifindex: u32) -> Result<()>
Remove netem configuration by interface index.
Sourcepub async fn add_class(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn add_class( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Add a TC class.
§Example
use nlink::netlink::{Connection, Route};
use nlink::netlink::tc::HtbQdiscConfig;
let conn = Connection::<Route>::new()?;
// First add an HTB qdisc
let htb = HtbQdiscConfig::new().default_class(0x10).build();
conn.add_qdisc_full("eth0", "root", Some("1:"), htb).await?;
// Then add a class with rate 10mbit, ceil 100mbit
conn.add_class("eth0", "1:0", "1:10", "htb",
&["rate", "10mbit", "ceil", "100mbit"]).await?;Sourcepub async fn add_class_by_index(
&self,
ifindex: u32,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn add_class_by_index( &self, ifindex: u32, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Add a TC class by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
Sourcepub async fn del_class(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
) -> Result<()>
pub async fn del_class( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, ) -> Result<()>
Sourcepub async fn del_class_by_index(
&self,
ifindex: u32,
parent: &str,
classid: &str,
) -> Result<()>
pub async fn del_class_by_index( &self, ifindex: u32, parent: &str, classid: &str, ) -> Result<()>
Delete a TC class by interface index.
Sourcepub async fn change_class(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn change_class( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Sourcepub async fn change_class_by_index(
&self,
ifindex: u32,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn change_class_by_index( &self, ifindex: u32, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Change a TC class by interface index.
Sourcepub async fn replace_class(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn replace_class( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Sourcepub async fn replace_class_by_index(
&self,
ifindex: u32,
parent: &str,
classid: &str,
kind: &str,
params: &[&str],
) -> Result<()>
pub async fn replace_class_by_index( &self, ifindex: u32, parent: &str, classid: &str, kind: &str, params: &[&str], ) -> Result<()>
Replace a TC class by interface index.
Sourcepub async fn add_class_config<C: ClassConfig>(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn add_class_config<C: ClassConfig>( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, config: C, ) -> Result<()>
Add a TC class with typed configuration.
This method provides a type-safe way to add classes, as an alternative
to the string-based add_class method.
§Example
use nlink::netlink::{Connection, Route};
use nlink::netlink::tc::{HtbQdiscConfig, HtbClassConfig};
let conn = Connection::<Route>::new()?;
// First add HTB qdisc
let htb = HtbQdiscConfig::new().default_class(0x30).build();
conn.add_qdisc_full("eth0", "root", Some("1:"), htb).await?;
// Add a class with guaranteed 100mbit, ceiling 500mbit
conn.add_class_config("eth0", "1:0", "1:10",
HtbClassConfig::new("100mbit")?
.ceil("500mbit")?
.prio(1)
.build()
).await?;Sourcepub async fn add_class_config_by_index<C: ClassConfig>(
&self,
ifindex: u32,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn add_class_config_by_index<C: ClassConfig>( &self, ifindex: u32, parent: &str, classid: &str, config: C, ) -> Result<()>
Add a TC class with typed configuration by interface index.
This is useful for namespace-aware operations where you’ve already
resolved the interface index via conn.get_link_by_name().
Sourcepub async fn change_class_config<C: ClassConfig>(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn change_class_config<C: ClassConfig>( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, config: C, ) -> Result<()>
Sourcepub async fn change_class_config_by_index<C: ClassConfig>(
&self,
ifindex: u32,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn change_class_config_by_index<C: ClassConfig>( &self, ifindex: u32, parent: &str, classid: &str, config: C, ) -> Result<()>
Change a TC class with typed configuration by interface index.
Sourcepub async fn replace_class_config<C: ClassConfig>(
&self,
dev: impl Into<InterfaceRef>,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn replace_class_config<C: ClassConfig>( &self, dev: impl Into<InterfaceRef>, parent: &str, classid: &str, config: C, ) -> Result<()>
Sourcepub async fn replace_class_config_by_index<C: ClassConfig>(
&self,
ifindex: u32,
parent: &str,
classid: &str,
config: C,
) -> Result<()>
pub async fn replace_class_config_by_index<C: ClassConfig>( &self, ifindex: u32, parent: &str, classid: &str, config: C, ) -> Result<()>
Replace a TC class with typed configuration by interface index.
Source§impl Connection<KobjectUevent>
impl Connection<KobjectUevent>
Sourcepub async fn recv(&self) -> Result<Uevent>
pub async fn recv(&self) -> Result<Uevent>
Receive the next uevent from the kernel.
This method blocks until a uevent is available.
§Example
use nlink::netlink::{Connection, KobjectUevent};
let conn = Connection::<KobjectUevent>::new()?;
loop {
let event = conn.recv().await?;
if event.is_add() && event.subsystem == "usb" {
println!("USB device added: {:?}", event.devname());
}
}