### Creating a Namespace Header Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example showing how to create an `NsidHeader` with a specified address family. ```APIDOC ## Creating a Namespace Header ```rust use netlink_packet_route::nsid::NsidHeader; use netlink_packet_route::AddressFamily; let header = NsidHeader { family: AddressFamily::Unspec, }; ``` ``` -------------------------------- ### Example Buffer Sizing Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/configuration.md Demonstrates setting buffer sizes for netlink messages, with examples for conservative, bulk, and small message scenarios. ```rust // Conservative size for most messages let mut buffer = vec![0u8; 4096]; // For bulk operations let mut buffer = vec![0u8; 16384]; // For single small message let mut buffer = vec![0u8; 1024]; ``` -------------------------------- ### Create Namespace Header Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Shows how to create an NsidHeader, initializing it with the AddressFamily::Unspec. ```rust use netlink_packet_route::nsid::NsidHeader; use netlink_packet_route::AddressFamily; let header = NsidHeader { family: AddressFamily::Unspec, }; ``` -------------------------------- ### Get Target Namespace ID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example illustrating how to query for a target namespace ID. ```APIDOC ## Get Target Namespace ID ```rust // Query which namespace ID corresponds to target let attributes = vec![ NsidAttribute::TargetNsid(1), // Query for namespace 1 ]; ``` ``` -------------------------------- ### Query Namespace by PID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example demonstrating how to construct attributes to query a namespace ID using a Process ID (PID). ```APIDOC ## Query Namespace by PID ```rust // Query namespace ID for a process let attributes = vec![ NsidAttribute::Pid(1234), // Query PID 1234 ]; ``` ``` -------------------------------- ### Query Namespace by File Descriptor Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example showing how to construct attributes to query a namespace ID using a file descriptor. ```APIDOC ## Query Namespace by File Descriptor ```rust // Query namespace by its file descriptor let attributes = vec![ NsidAttribute::Fd(5), // File descriptor 5 ]; ``` ``` -------------------------------- ### Creating an Ingress Qdisc Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Shows how to construct the header and attributes for a simple ingress qdisc, typically used for incoming traffic shaping. ```rust // Simple ingress qdisc for incoming traffic shaping let header = TcHeader { ifindex: 2, // eth0 parent: TcHandle { major: 0xffff, minor: 0xfff1 }, // Ingress parent handle: TcHandle { major: 0, minor: 0 }, info: 0, }; let attributes = vec![ TcAttribute::Kind("ingress".to_string()), ]; ``` -------------------------------- ### Autonomous Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Shows how to create attributes for an autonomous IPv6 prefix, which can be used for autoconfiguration, including the address. ```APIDOC ## Autonomous Prefix ### Description Represents an autonomous IPv6 prefix from an RA, which can be used for autoconfiguration. Includes the address. ### Usage ```rust // Autonomous prefix from RA (can be used for autoconfiguration) let flags = PrefixFlags::AUTONOMOUS; let attributes = vec![ PrefixAttribute::Address("2001:db8:2::/64".parse()?), ]; ``` ``` -------------------------------- ### Get Current Namespace ID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example for obtaining the namespace ID of the current process. ```APIDOC ## Get Current Namespace ID Query for the current namespace: ```rust // Get the NSID of the current process let attributes = vec![ NsidAttribute::Pid(std::process::id()), ]; ``` ``` -------------------------------- ### Parsing a Namespace ID Message Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Example demonstrating how to parse raw bytes into an `NsidMessage` and iterate through its attributes. ```APIDOC ## Parsing a Namespace ID Message ```rust use netlink_packet_route::nsid::{NsidMessage, NsidMessageBuffer}; use netlink_packet_core::Parseable; let buffer = NsidMessageBuffer::new(&raw_bytes); let msg = NsidMessage::parse(&buffer)?; println!("Family: {:?}", msg.header.family); for attr in &msg.attributes { match attr { NsidAttribute::Nsid(id) => { println!("Namespace ID: {}", id); } NsidAttribute::Pid(pid) => { println!("Process ID: {}", pid); } NsidAttribute::Fd(fd) => { println!("File descriptor: {}", fd); } NsidAttribute::TargetNsid(id) => { println!("Target namespace ID: {}", id); } _ => {} } } ``` ``` -------------------------------- ### Autonomous Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Shows how to define an autonomous prefix, which can be used for autoconfiguration, by setting the AUTONOMOUS flag. ```rust // Autonomous prefix from RA (can be used for autoconfiguration) let flags = PrefixFlags::AUTONOMOUS; let attributes = vec![ PrefixAttribute::Address("2001:db8:2::/64".parse()?), ]; ``` -------------------------------- ### Query Namespace by File Descriptor Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Demonstrates creating a vector of NsidAttribute to query for a namespace ID using a file descriptor. ```rust // Query namespace by its file descriptor let attributes = vec![ NsidAttribute::Fd(5), // File descriptor 5 ]; ``` -------------------------------- ### On-Link Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Demonstrates creating attributes for an on-link IPv6 prefix, typically used for devices on the same link, including the address and cache information. ```APIDOC ## On-Link Prefix ### Description Represents an on-link IPv6 prefix from an RA, indicating that devices on this link use this prefix. Includes address and cache information. ### Usage ```rust // On-link prefix from RA (devices on this link use this prefix) let flags = PrefixFlags::ONLINK; // On-link but not autonomous let attributes = vec![ PrefixAttribute::Address("2001:db8:1::/64".parse()?), PrefixAttribute::CacheInfo(PrefixCacheInfo { prefered_lifetime: 604800, valid_lifetime: 2592000, created: 0, updated: 0, }), ]; ``` ``` -------------------------------- ### On-Link Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Demonstrates setting the ONLINK flag for a prefix, indicating that devices on the link use this prefix, often seen in Router Advertisements. ```rust // On-link prefix from RA (devices on this link use this prefix) let flags = PrefixFlags::ONLINK; // On-link but not autonomous let attributes = vec![ PrefixAttribute::Address("2001:db8:1::/64".parse()?), PrefixAttribute::CacheInfo(PrefixCacheInfo { prefered_lifetime: 604800, valid_lifetime: 2592000, created: 0, updated: 0, }), ]; ``` -------------------------------- ### Query Namespace by PID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Illustrates creating a vector of NsidAttribute to query for a namespace ID associated with a specific Process ID. ```rust // Query namespace ID for a process let attributes = vec![ NsidAttribute::Pid(1234), // Query PID 1234 ]; ``` -------------------------------- ### Get Target Namespace ID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Shows how to create a vector of NsidAttribute to query for the target namespace ID. ```rust // Query which namespace ID corresponds to target let attributes = vec![ NsidAttribute::TargetNsid(1), // Query for namespace 1 ]; ``` -------------------------------- ### IPv6 Router Advertisement Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Illustrates the creation of attributes for an IPv6 prefix message, specifically for a Router Advertisement, including the address and cache information. ```APIDOC ## IPv6 Router Advertisement Prefix ### Description Represents an IPv6 prefix from a Router Advertisement, including the address and cache information (lifetimes). ### Usage ```rust // IPv6 prefix from Router Advertisement use std::net::Ipv6Addr; let attributes = vec![ PrefixAttribute::Address("2001:db8::".parse()?), PrefixAttribute::CacheInfo(PrefixCacheInfo { prefered_lifetime: 604800, // 1 week valid_lifetime: 2592000, // 30 days created: 0, updated: 0, }), ]; ``` ``` -------------------------------- ### IPv6 Router Advertisement Prefix Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Illustrates the creation of attributes for an IPv6 prefix message, including the address and cache information, typically used in Router Advertisements. ```rust // IPv6 prefix from Router Advertisement use std::net::Ipv6Addr; let attributes = vec![ PrefixAttribute::Address("2001:db8::".parse()?), PrefixAttribute::CacheInfo(PrefixCacheInfo { prefered_lifetime: 604800, // 1 week valid_lifetime: 2592000, // 30 days created: 0, updated: 0, }), ]; ``` -------------------------------- ### Get Current Namespace ID Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Demonstrates how to get the NSID of the current process by creating an NsidAttribute with the current PID. ```rust // Get the NSID of the current process let attributes = vec![ NsidAttribute::Pid(std::process::id()), ]; ``` -------------------------------- ### Capture Netlink Packets with tcpdump Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/README.md This example demonstrates how to capture Netlink packets using tcpdump for debugging and analysis. The captured data can be converted to Rust byte arrays for testing. ```bash modprobe nlmon ip link add nl0 type nlmon ip link set nl0 up tcpdump -i nl0 -w netlink_capture_file.cap # Then use wireshark to open this `netlink_capture_file.cap` # Find out the packet you are interested, # right click -> "Copy" -> "...as Hex Dump". # You may use https://github.com/cathay4t/hex_to_rust to convert this # hexdump to rust u8 array ``` -------------------------------- ### NAT Action Configuration (SNAT) Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Sets up a Network Address Translation (NAT) action, specifically Source NAT (SNAT). This example replaces the source IP address of outgoing packets. ```rust let nat = TcActionNat { old_addr: IpAddr::V4("192.168.1.0".parse()?), new_addr: IpAddr::V4("10.0.0.1".parse()?), mask: 0xffffff00, // /24 flags: TcNatFlags::SNAT, }; ``` -------------------------------- ### Parse Namespace ID Message Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Demonstrates how to parse raw bytes into an NsidMessage and iterate through its attributes to extract namespace information. ```rust use netlink_packet_route::nsid::{NsidMessage, NsidMessageBuffer}; use netlink_packet_core::Parseable; let buffer = NsidMessageBuffer::new(&raw_bytes); let msg = NsidMessage::parse(&buffer)?; println!("Family: {:?}", msg.header.family); for attr in &msg.attributes { match attr { NsidAttribute::Nsid(id) => { println!("Namespace ID: {}", id); } NsidAttribute::Pid(pid) => { println!("Process ID: {}", pid); } NsidAttribute::Fd(fd) => { println!("File descriptor: {}", fd); } NsidAttribute::TargetNsid(id) => { println!("Target namespace ID: {}", id); } _ => {} } } ``` -------------------------------- ### Handle Message Type with Buffer Validation Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Provides an example of handling different message types by first creating a buffer and then attempting to parse it, returning an error for unknown types. ```rust const RTM_NEWLINK: u16 = 16; fn handle_message(msg_type: u16, data: &[u8]) -> Result<(), DecodeError> { match msg_type { RTM_NEWLINK => { let buffer = LinkMessageBuffer::new(data); let msg = LinkMessage::parse(&buffer)?; process_link(msg); Ok(()) } _ => Err(DecodeError::from("Unknown message type")) } } ``` -------------------------------- ### Parsing a TC Message Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Demonstrates how to parse a raw TC message buffer into a TcMessage object and extract information like interface index, handles, and attributes. ```rust use netlink_packet_route::tc::{TcMessage, TcMessageBuffer}; use netlink_packet_core::Parseable; let buffer = TcMessageBuffer::new(&raw_bytes); let msg = TcMessage::parse(&buffer)?; println!("Interface: {}", msg.header.ifindex); println!("Parent handle: {:x}:{:x}", msg.header.parent.major, msg.header.parent.minor); println!("Object handle: {:x}:{:x}", msg.header.handle.major, msg.header.handle.minor); for attr in &msg.attributes { match attr { TcAttribute::Kind(name) => println!("Qdisc type: {}", name), TcAttribute::Stats(stats) => println!("Stats: {:?}", stats), _ => {} } } ``` -------------------------------- ### Create a Netlink Message Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/README.md Construct a new netlink message by defining its header and attributes. This is the starting point for creating outgoing netlink messages. ```rust let msg = LinkMessage { header: LinkHeader { /* ... */ }, attributes: vec![ LinkAttribute::IfName("eth0".to_string()), LinkAttribute::Mtu(1500), ], }; ``` -------------------------------- ### Lenient Attribute Parsing Example Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/configuration.md Demonstrates lenient attribute parsing where the iteration continues even if a single attribute fails to parse. Invalid attributes are skipped, and valid ones are processed. ```rust // Parse continues even with unknown attribute types for nla_buf in buf.attributes() { match nla_buf { Ok(nla) => { /* process valid attribute */ } Err(_) => { /* skip invalid, continue parsing */ } } } ``` -------------------------------- ### Buffer Too Short Validation Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Provides a code example for checking if a buffer meets the minimum required size before attempting to parse a netlink message, preventing 'buffer too short' errors. ```rust // Verify buffer has minimum required size const MIN_HEADER_SIZE: usize = 16; // For LinkMessageBuffer if raw_bytes.len() < MIN_HEADER_SIZE { eprintln!("Buffer too short"); return Err(...); } ``` -------------------------------- ### Creating a Prefix Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Shows how to construct a PrefixHeader with specific IPv6 details, including kind and flags. ```rust use netlink_packet_route::prefix::{PrefixHeader, PrefixKind, PrefixFlags}; use netlink_packet_route::AddressFamily; let header = PrefixHeader { family: AddressFamily::Inet6, prefix_len: 64, kind: PrefixKind::Unicast, flags: PrefixFlags::ONLINK | PrefixFlags::AUTONOMOUS, ifindex: 2, // eth0 }; ``` -------------------------------- ### RulePortRange Structure Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Specifies a range of ports (start and end, inclusive) for port-based routing rules. ```rust pub struct RulePortRange { /// Start port (inclusive) pub start: u16, /// End port (inclusive) pub end: u16, } ``` -------------------------------- ### Creating a Prefix Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Shows how to construct a `PrefixHeader` manually, specifying the address family, prefix length, kind, flags, and interface index. ```APIDOC ## Creating a Prefix Header ### Description Constructs a `PrefixHeader` manually, specifying the address family, prefix length, kind, flags, and interface index. ### Usage ```rust use netlink_packet_route::prefix::{PrefixHeader, PrefixKind, PrefixFlags}; use netlink_packet_route::AddressFamily; let header = PrefixHeader { family: AddressFamily::Inet6, prefix_len: 64, kind: PrefixKind::Unicast, flags: PrefixFlags::ONLINK | PrefixFlags::AUTONOMOUS, ifindex: 2, // eth0 }; ``` ``` -------------------------------- ### Getting the Message Type Code Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/index.md Explains how to retrieve the RTM_* constant code associated with a `RouteNetlinkMessage` using the `message_type()` method. ```APIDOC ## Getting the Message Type Code ### Description Use the `message_type()` method on a `RouteNetlinkMessage` to obtain its corresponding RTM_* constant, which is useful for identifying the message's intent (e.g., RTM_NEWLINK, RTM_DELROUTE). ### Usage ```rust use netlink_packet_route::RouteNetlinkMessage; // Assume 'message' is a variable of type RouteNetlinkMessage let message: RouteNetlinkMessage = /* ... received or constructed message ... */; // Get the RTM code (returns a u16) let rtm_code = message.message_type(); println!("The RTM code for this message is: {}", rtm_code); // Example: Checking if it's a NewLink message based on the code const RTM_NEWLINK: u16 = 16; // Example constant value if rtm_code == RTM_NEWLINK { println!("This message is an RTM_NEWLINK type."); } ``` ``` -------------------------------- ### RuleUidRange Structure Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Defines a range of user IDs (start and end, inclusive) for matching rules based on the source user. ```rust pub struct RuleUidRange { /// Start UID (inclusive) pub start: u32, /// End UID (inclusive) pub end: u32, } ``` -------------------------------- ### Create a Firewall Mark-Based Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Constructs a routing rule that matches packets based on a firewall mark and mask, directing them to a specific table. Includes priority setting. ```rust // Rule: if fw mark is 0x200, use table 200 let attributes = vec![ RuleAttribute::FwMark(0x200), RuleAttribute::FwMask(0xFFFF), RuleAttribute::Priority(1000), ]; ``` -------------------------------- ### Getting Message Type Code Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/index.md Demonstrates retrieving the RTM_* constant code for a given Netlink message using the message_type() method. ```rust let rtm_code = message.message_type(); // Returns u16 like RTM_NEWLINK (16) ``` -------------------------------- ### Using Message Type Predicates Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/index.md Illustrates how to use type-checking methods like is_new_link() and is_new_address() on RouteNetlinkMessage. ```rust match message { RouteNetlinkMessage::NewLink(_) if message.is_new_link() => { /* ... */ } RouteNetlinkMessage::NewAddress(_) if message.is_new_address() => { /* ... */ } _ => {} } ``` -------------------------------- ### Using Type Predicates for Safer Matching Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Demonstrates using type predicate methods (e.g., `is_new_address()`) for safer and more readable handling of different netlink message types compared to exhaustive pattern matching. ```rust // Safer than exhaustive pattern matching match message { m if m.is_new_address() => { /* handle */ } m if m.is_new_route() => { /* handle */ } _ => { /* handle other types */ } } ``` -------------------------------- ### Create an Address Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/address.md Constructs an AddressHeader with specified family, prefix length, flags, scope, and index. Imports AddressHeader, AddressScope, and AddressHeaderFlags. ```rust use netlink_packet_route::address::{AddressHeader, AddressScope, AddressHeaderFlags}; use netlink_packet_route::AddressFamily; let header = AddressHeader { family: AddressFamily::Inet, prefix_len: 24, flags: AddressHeaderFlags::PERMANENT, scope: AddressScope::Universe, index: 2, // eth0 }; ``` -------------------------------- ### Check for New Namespace ID Message Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/nsid.md Provides an example of using a message type predicate to identify if a received netlink message is a NewNsId message. ```rust use netlink_packet_route::RouteNetlinkMessage; if let RouteNetlinkMessage::NewNsId(msg) = &message { println!("New namespace ID"); } ``` -------------------------------- ### Create a User-Based Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Constructs a routing rule that matches packets based on a source User ID (UID) range, directing them to a specific table. Priority is also set. ```rust // Rule: if source UID is in range 1000-1999, use table 100 let attributes = vec![ RuleAttribute::UidRange(RuleUidRange { start: 1000, end: 1999, }), RuleAttribute::Priority(1000), ]; ``` -------------------------------- ### Stats64 Struct Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/link.md Provides modern 64-bit interface statistics. Use this struct for current systems to get comprehensive statistics without overflow concerns. ```rust pub struct Stats64 { pub rx_packets: u64, pub tx_packets: u64, pub rx_bytes: u64, pub tx_bytes: u64, pub rx_errors: u64, pub tx_errors: u64, pub rx_dropped: u64, pub tx_dropped: u64, pub multicast: u64, pub collisions: u64, pub rx_length_errors: u64, pub rx_over_errors: u64, pub rx_crc_errors: u64, pub rx_frame_errors: u64, pub rx_fifo_errors: u64, pub rx_missed_errors: u64, pub tx_aborted_errors: u64, pub tx_carrier_errors: u64, pub tx_fifo_errors: u64, pub tx_heartbeat_errors: u64, pub tx_window_errors: u64, } ``` -------------------------------- ### Configure IPv6 NDP Table Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/neighbour-table.md Sets up the header and attributes for an IPv6 NDP neighbour table, specifying the table name and garbage collection thresholds. Requires `netlink_packet_route::{AddressFamily, neighbour_table::*}`. ```rust use netlink_packet_route::{AddressFamily, neighbour_table::*}; let header = NeighbourTableHeader { family: AddressFamily::Inet6, // IPv6 NDP table }; let attributes = vec![ NeighbourTableAttribute::Name("ndisc_cache".to_string()), NeighbourTableAttribute::Config(NeighbourTableConfig { family: AddressFamily::Inet6, filled: 0, gc_thresh1: 128, gc_thresh2: 512, gc_thresh3: 1024, }), ]; ``` -------------------------------- ### FQ_Codel Queue Discipline Configuration Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Configures a Fair Queue with Controlled Delay (FQ_Codel) queue discipline. Use this to set parameters like limit, target, and interval for packet scheduling. ```rust let header = TcHeader { ifindex: 2, parent: TcHandle { major: 0x1, minor: 0 }, // Root qdisc handle: TcHandle { major: 0x1, minor: 0 }, info: 0, }; let options = vec![ TcOption::FqCodel(TcQdiscFqCodelOption::Limit(1000)), TcOption::FqCodel(TcQdiscFqCodelOption::Target(5000)), // 5ms TcOption::FqCodel(TcQdiscFqCodelOption::Interval(100000)), // 100ms ]; ``` -------------------------------- ### Common Pattern: Dynamic/DHCP Address Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/address.md Demonstrates the AddressHeader configuration for a dynamic or DHCP-assigned IPv4 address, highlighting the AddressHeaderFlags::DYNAMIC flag. ```rust AddressHeader { family: AddressFamily::Inet, prefix_len: 24, flags: AddressHeaderFlags::DYNAMIC, // vs PERMANENT scope: AddressScope::Universe, index: 2, } ``` -------------------------------- ### Common Pattern: IPv4 Address on Interface Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/address.md Illustrates the structure of an AddressHeader for a typical IPv4 address configuration on interface 2 (eth0). ```rust // Header specifying IPv4 on interface 2 (eth0) AddressHeader { family: AddressFamily::Inet, prefix_len: 24, flags: AddressHeaderFlags::PERMANENT, scope: AddressScope::Universe, index: 2, } ``` -------------------------------- ### Create a Source-Based Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Defines a routing rule based on the source IP address and priority. Packets from the specified source prefix will use the designated table. ```rust // Rule: if source is from 192.168.100.0/24, use table 200 let header = RuleHeader { family: AddressFamily::Inet, destination_prefix_len: 0, source_prefix_len: 24, tos: 0, table: 200, action: RuleAction::Table, flags: RuleFlags::empty(), }; let attributes = vec![ RuleAttribute::Source(IpAddr::V4("192.168.100.0".parse()?)), RuleAttribute::Priority(1000), // Lower number = higher priority ]; ``` -------------------------------- ### Create an Interface-Based Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Defines a routing rule that matches packets arriving on a specific input interface and assigns them to a table. Priority is also set. ```rust // Rule: if input interface is eth1, use table 100 RuleAttribute::IifName("eth1".to_string()), RuleAttribute::Priority(500), ``` -------------------------------- ### Create an Inverted Match Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Constructs a routing rule with the `INVERT` flag, meaning the rule applies when the specified condition is NOT met. This example matches if the input interface is NOT eth0. ```rust // Rule: if NOT from eth0, use table 100 let header = RuleHeader { family: AddressFamily::Inet, destination_prefix_len: 0, source_prefix_len: 0, tos: 0, table: 100, action: RuleAction::Table, flags: RuleFlags::INVERT, // Invert match logic }; let attributes = vec![ RuleAttribute::IifName("eth0".to_string()), ]; ``` -------------------------------- ### LinkVfInfo Struct Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/link.md Provides information about a virtual function (VF) for SR-IOV capable devices. ```APIDOC ## LinkVfInfo Struct ### Description Virtual function information for SR-IOV capable devices. ### Fields - **vf_index** (u32): The index of the virtual function. - **attributes** (Vec): A vector of attributes associated with the virtual function. ``` -------------------------------- ### RuleUidRange Structure Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/types.md Defines a range of user IDs (UIDs) for policy routing or firewall rules. It specifies a start and end UID. Use this to apply rules based on the originating user process. ```rust pub struct RuleUidRange { pub start: u32, pub end: u32, } ``` -------------------------------- ### Safe Parsing vs. Panicking Parsing Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Illustrates the difference between safe parsing that returns a Result and unsafe parsing that panics on invalid data. ```rust // ✓ Always safe - returns error instead of panicking let msg = LinkMessage::parse(&buffer)?; ``` ```rust // ✗ Avoid - panics on invalid data let msg = LinkMessage::parse(&buffer).unwrap(); ``` -------------------------------- ### Mirror Action Configuration Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Configures a mirror action to duplicate incoming packets and send them to a specified interface. Use this for network monitoring or analysis. ```rust let mirror = TcActionMirror { ifindex: 3 }; let attributes = vec![ TcAttribute::Kind("mirror".to_string()), ]; ``` -------------------------------- ### TcQdiscFqCodel Structure Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Defines the Fair Queue with Controlled Delay (FqCodel) queue discipline, a modern and recommended qdisc. It includes parameters for packet limits, flow tracking, delay targets, and ECN marking. ```rust pub struct TcQdiscFqCodel { pub limit: u32, // Max packets in queue pub flows: u32, // Number of flows to track pub target: u32, // Target queue delay (microseconds) pub interval: u32, // Interval for dropping (microseconds) pub ecn: u8, // Enable ECN marking pub quantum: u32, // Quantum (bytes per flow) pub ce_threshold: u32, // CE marking threshold pub drop_batch_size: u16, // Packets to drop per batch } ``` -------------------------------- ### Cargo.toml Dependencies Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/configuration.md Lists the core dependencies for the netlink-packet-route crate, including versions for bitflags, libc, log, and netlink-packet-core. ```toml [dependencies] bitflags = "2" libc = "0.2.66" log = { version = "0.4.20", features = ["std"] } netlink-packet-core = { version = "0.8.0" } ``` -------------------------------- ### Parsing a Prefix Message Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Demonstrates how to parse raw bytes into a `PrefixMessage` object, extracting details like family, prefix length, interface, and attributes such as the IPv6 address and cache information. ```APIDOC ## Parsing a Prefix Message ### Description Parses raw bytes into a `PrefixMessage` object, extracting details like family, prefix length, interface, and attributes such as the IPv6 address and cache information. ### Usage ```rust use netlink_packet_route::prefix::{PrefixMessage, PrefixMessageBuffer}; use netlink_packet_core::Parseable; let buffer = PrefixMessageBuffer::new(&raw_bytes); let msg = PrefixMessage::parse(&buffer)?; println!("Family: {:?}", msg.header.family); println!("Prefix length: {}", msg.header.prefix_len); println!("Interface: {}", msg.header.ifindex); for attr in &msg.attributes { match attr { PrefixAttribute::Address(addr) => { println!("Prefix: {}/{}", addr, msg.header.prefix_len); } PrefixAttribute::CacheInfo(cache) => { println!("Preferred lifetime: {} seconds", cache.prefered_lifetime); println!("Valid lifetime: {} seconds", cache.valid_lifetime); } _ => {} } } ``` ``` -------------------------------- ### Create a Route Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/route.md Constructs a RouteHeader for a unicast route with static protocol and universe scope. This serves as a base for defining route entries. ```rust use netlink_packet_route::route::{ RouteHeader, RouteType, RouteScope, RouteProtocol, RouteFlags }; use netlink_packet_route::AddressFamily; let header = RouteHeader { address_family: AddressFamily::Inet, destination_prefix_len: 24, source_prefix_len: 0, tos: 0, kind: RouteType::Unicast, scope: RouteScope::Universe, protocol: RouteProtocol::Static, flags: RouteFlags::empty(), }; ``` -------------------------------- ### Create an IPv6 Neighbor (NDP) Entry Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/neighbour.md Constructs a NeighbourHeader and attributes for an IPv6 neighbour using Neighbour Discovery Protocol (NDP). Requires `netlink_packet_route::neighbour::{NeighbourHeader, NeighbourAddress}` and related types. ```rust use netlink_packet_route::neighbour::{NeighbourHeader, NeighbourAddress}; let header = NeighbourHeader { family: AddressFamily::Inet6, // IPv6 ifindex: 2, state: NeighbourState::REACHABLE, flags: NeighbourFlags::empty(), kind: NeighbourKind::Unspec, }; let attributes = vec![ NeighbourAttribute::Destination( NeighbourAddress::Ipv6("fe80::1".parse()?) ), NeighbourAttribute::LinkLayerAddress( vec![0x00, 0x11, 0x22, 0x33, 0x44, 0x55] ), ]; ``` -------------------------------- ### LinkVfInfo Struct Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/link.md Holds information for a virtual function (VF) on SR-IOV capable devices. Use this to manage VF configurations. ```rust pub struct LinkVfInfo { pub vf_index: u32, pub attributes: Vec, } ``` -------------------------------- ### Create a Port-Based Routing Rule Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Defines a routing rule that matches packets based on a source port range, assigning them to a specified table. Priority is also configured. ```rust // Rule: if source port is in range 5000-6000, use table 100 let attributes = vec![ RuleAttribute::SourcePortRange(RulePortRange { start: 5000, end: 6000, }), RuleAttribute::Priority(1000), ]; ``` -------------------------------- ### Create a Rule Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/rule.md Constructs a RuleHeader with specified family, destination prefix length, table, action, and flags. Useful for defining routing rule policies. ```rust use netlink_packet_route::rule::{RuleHeader, RuleAction, RuleFlags}; use netlink_packet_route::AddressFamily; let header = RuleHeader { family: AddressFamily::Inet, destination_prefix_len: 24, source_prefix_len: 0, tos: 0, table: 100, // Use routing table 100 action: RuleAction::Table, flags: RuleFlags::empty(), }; ``` -------------------------------- ### TcQdiscFqCodel Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/tc.md Defines the Fair Queue with Controlled Delay (FQ-CoDel) queueing discipline, a modern and recommended qdisc for managing network queues. ```APIDOC ## TcQdiscFqCodel ### Description Represents the Fair Queue with Controlled Delay (FQ-CoDel) queueing discipline. This is a modern and recommended algorithm for managing network queues to reduce latency and packet loss. ### Struct Definition ```rust pub struct TcQdiscFqCodel { pub limit: u32, // Max packets in queue pub flows: u32, // Number of flows to track pub target: u32, // Target queue delay (microseconds) pub interval: u32, // Interval for dropping (microseconds) pub ecn: u8, // Enable ECN marking pub quantum: u32, // Quantum (bytes per flow) pub ce_threshold: u32, // CE marking threshold pub drop_batch_size: u16, // Packets to drop per batch } ``` ### Options ```rust pub enum TcQdiscFqCodelOption { Limit(u32), Flows(u32), Target(u32), Interval(u32), Ecn(u8), Quantum(u32), CeThreshold(u32), DropBatchSize(u16), } ``` ``` -------------------------------- ### Configure IPv4 ARP Table Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/neighbour-table.md Sets up the header and attributes for an IPv4 ARP neighbour table, specifying the table name and garbage collection thresholds. Requires `netlink_packet_route::{AddressFamily, neighbour_table::*}`. ```rust use netlink_packet_route::{AddressFamily, neighbour_table::*}; let header = NeighbourTableHeader { family: AddressFamily::Inet, // IPv4 ARP table }; let attributes = vec![ NeighbourTableAttribute::Name("arp_cache".to_string()), NeighbourTableAttribute::Config(NeighbourTableConfig { family: AddressFamily::Inet, filled: 0, gc_thresh1: 128, // Start GC at 128 entries gc_thresh2: 512, // Soft limit at 512 entries gc_thresh3: 1024, // Hard limit at 1024 entries }), ]; ``` -------------------------------- ### Create an IPv6 Default Route Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/route.md Defines a RouteHeader for an IPv6 default route (::/0). The destination_prefix_len is set to 0 to match all IPv6 addresses. ```rust // Default route: ::/0 let header = RouteHeader { address_family: AddressFamily::Inet6, destination_prefix_len: 0, // Matches all IPv6 addresses source_prefix_len: 0, tos: 0, kind: RouteType::Unicast, scope: RouteScope::Universe, protocol: RouteProtocol::Static, flags: RouteFlags::empty(), }; ``` -------------------------------- ### Create a Multipath Route Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/route.md Defines a RouteAttribute of type NextHops, specifying multiple gateways for load balancing. Each next-hop includes a gateway address, interface, and weight. ```rust // Route with multiple next-hops for load balancing RouteAttribute::NextHops(vec![ RouteNextHop { gateway: RouteAddress::Ipv4("192.168.1.1".parse()?), interface: 2, weight: 1, flags: RouteNextHopFlags::empty(), attributes: vec![], }, RouteNextHop { gateway: RouteAddress::Ipv4("192.168.1.2".parse()?), interface: 2, weight: 1, flags: RouteNextHopFlags::empty(), attributes: vec![], }, ]) ``` -------------------------------- ### Common Pattern: IPv6 Link-Local Address Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/address.md Shows the typical AddressHeader configuration for an IPv6 link-local address (fe80::/10) on interface 2. ```rust // Typical link-local address (fe80::/10) AddressHeader { family: AddressFamily::Inet6, prefix_len: 64, flags: AddressHeaderFlags::PERMANENT, scope: AddressScope::Link, // Link-local scope index: 2, } ``` -------------------------------- ### Create Link Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/configuration.md Constructs a LinkHeader with specified interface family, index, link layer type, flags, and change mask. ```rust let header = LinkHeader { interface_family: AddressFamily::Unspec, index: 2, link_layer_type: LinkLayerType::Ether, flags: LinkFlags::UP | LinkFlags::RUNNING, change_mask: LinkFlags::UP, }; ``` -------------------------------- ### Link Info Data Options Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/configuration.md Shows the various link-type-specific configuration data structures available for different network link types, such as bridges, bonds, and tunnels. ```rust pub enum InfoData { Bridge(InfoBridge), // Bridge settings Bond(InfoBond), // Bonding settings Vlan(InfoVlan), // VLAN settings Vxlan(InfoVxlan), // VXLAN tunnel settings Geneve(InfoGeneve), // Geneve tunnel settings Gre(InfoGre), // GRE tunnel settings // ... 30+ link types } ``` -------------------------------- ### Handle New Neighbour Message Type Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/neighbour.md Demonstrates how to pattern match on a generic `RouteNetlinkMessage` to specifically identify and process a `NewNeighbour` message. Requires `netlink_packet_route::RouteNetlinkMessage`. ```rust use netlink_packet_route::RouteNetlinkMessage; if let RouteNetlinkMessage::NewNeighbour(msg) = &message { println!("New neighbor: {:?}", msg.header.state); } ``` -------------------------------- ### PrefixMessageBuffer Usage Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/prefix.md Demonstrates how to use PrefixMessageBuffer to parse raw bytes into a PrefixMessage and iterate over its attributes. ```rust use netlink_packet_route::prefix::{PrefixMessage, PrefixMessageBuffer}; use netlink_packet_core::Parseable; let buffer = PrefixMessageBuffer::new(&raw_bytes); let msg = PrefixMessage::parse(&buffer)?; println!("Family: {:?}", msg.header.family); println!("Prefix length: {}", msg.header.prefix_len); println!("Interface: {}", msg.header.ifindex); for attr in &msg.attributes { match attr { PrefixAttribute::Address(addr) => { println!("Prefix: {}/{}", addr, msg.header.prefix_len); } PrefixAttribute::CacheInfo(cache) => { println!("Preferred lifetime: {} seconds", cache.prefered_lifetime); println!("Valid lifetime: {} seconds", cache.valid_lifetime); } _ => {} } } ``` -------------------------------- ### Safely Skip Unknown Attributes Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Demonstrates how to iterate over message attributes and safely skip unknown ones using a match statement with an empty arm. ```rust for attr in &msg.attributes { match attr { LinkAttribute::IfName(n) => use_name(n), LinkAttribute::Mtu(m) => use_mtu(m), LinkAttribute::Other(_) => {}, // Skip safely _ => {} // Also skip other unknown attributes } } ``` -------------------------------- ### Create an IPv4 Default Route Header Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/route.md Defines a RouteHeader for an IPv4 default route (0.0.0.0/0). The destination_prefix_len is set to 0 to match all IPv4 addresses. ```rust // Default route: 0.0.0.0/0 let header = RouteHeader { address_family: AddressFamily::Inet, destination_prefix_len: 0, // Matches all IPv4 addresses source_prefix_len: 0, tos: 0, kind: RouteType::Unicast, scope: RouteScope::Universe, protocol: RouteProtocol::Static, flags: RouteFlags::empty(), }; ``` -------------------------------- ### Stats Struct Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/link.md Contains legacy interface statistics (32-bit) for network interfaces. ```APIDOC ## Stats Struct ### Description Legacy interface statistics (32-bit, pre-64-bit kernel). ### Fields - **rx_packets** (u32): Number of received packets. - **tx_packets** (u32): Number of transmitted packets. - **rx_bytes** (u32): Number of received bytes. - **tx_bytes** (u32): Number of transmitted bytes. - **rx_errors** (u32): Number of received errors. - **tx_errors** (u32): Number of transmitted errors. - **rx_dropped** (u32): Number of received packets dropped. - **tx_dropped** (u32): Number of transmitted packets dropped. - **multicast** (u32): Number of multicast packets. - **collisions** (u32): Number of transmission collisions. - **rx_length_errors** (u32): Number of received packet length errors. - **rx_over_errors** (u32): Number of received packet overruns. - **rx_crc_errors** (u32): Number of received CRC errors. - **rx_frame_errors** (u32): Number of received frame errors. - **rx_fifo_errors** (u32): Number of received FIFO errors. - **rx_missed_errors** (u32): Number of missed received packets. - **tx_aborted_errors** (u32): Number of transmitted aborted errors. - **tx_carrier_errors** (u32): Number of transmitted carrier errors. - **tx_fifo_errors** (u32): Number of transmitted FIFO errors. - **tx_heartbeat_errors** (u32): Number of transmitted heartbeat errors. - **tx_window_errors** (u32): Number of transmitted window errors. ``` -------------------------------- ### Parsing Link Messages Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/errors.md Demonstrates how to parse LinkMessage from raw bytes using a buffer and handle potential DecodeErrors. This pattern is common for all message types. ```rust use netlink_packet_route::link::{LinkMessage, LinkMessageBuffer}; use netlink_packet_core::Parseable; let buffer = LinkMessageBuffer::new(&raw_bytes); match LinkMessage::parse(&buffer) { Ok(msg) => { // Process message println!("Interface: {}", msg.header.index); } Err(e) => { // Handle parse error eprintln!("Failed to parse link message: {}", e); } } ``` -------------------------------- ### CacheInfo Structure Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/address.md Contains address cache information, including valid and preferred lifetimes, and creation/update timestamps. ```rust pub struct CacheInfo { /// Address valid lifetime (seconds, or u32::MAX for permanent) pub valid_lifetime: u32, /// Preferred lifetime (seconds, or u32::MAX for permanent) pub prefered_lifetime: u32, /// Time when address was created (jiffies/clock_ticks) pub created: u32, /// Time of last update (jiffies/clock_ticks) pub updated: u32, } ``` -------------------------------- ### Stats64 Struct Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/api-reference/link.md Contains modern 64-bit interface statistics for network interfaces. ```APIDOC ## Stats64 Struct ### Description Modern 64-bit interface statistics. ### Fields - **rx_packets** (u64): Number of received packets. - **tx_packets** (u64): Number of transmitted packets. - **rx_bytes** (u64): Number of received bytes. - **tx_bytes** (u64): Number of transmitted bytes. - **rx_errors** (u64): Number of received errors. - **tx_errors** (u64): Number of transmitted errors. - **rx_dropped** (u64): Number of received packets dropped. - **tx_dropped** (u64): Number of transmitted packets dropped. - **multicast** (u64): Number of multicast packets. - **collisions** (u64): Number of transmission collisions. - **rx_length_errors** (u64): Number of received packet length errors. - **rx_over_errors** (u64): Number of received packet overruns. - **rx_crc_errors** (u64): Number of received CRC errors. - **rx_frame_errors** (u64): Number of received frame errors. - **rx_fifo_errors** (u64): Number of received FIFO errors. - **rx_missed_errors** (u64): Number of missed received packets. - **tx_aborted_errors** (u64): Number of transmitted aborted errors. - **tx_carrier_errors** (u64): Number of transmitted carrier errors. - **tx_fifo_errors** (u64): Number of transmitted FIFO errors. - **tx_heartbeat_errors** (u64): Number of transmitted heartbeat errors. - **tx_window_errors** (u64): Number of transmitted window errors. ``` -------------------------------- ### Message Type Predicates Source: https://github.com/rust-netlink/netlink-packet-route/blob/main/_autodocs/index.md Illustrates the use of type-checking methods provided by `RouteNetlinkMessage` for easily identifying message types. ```APIDOC ## Message Type Predicates ### Description `RouteNetlinkMessage` provides convenient type-checking methods (predicates) to easily determine the specific type of a received message. ### Usage ```rust use netlink_packet_route::RouteNetlinkMessage; // Assume 'message' is a variable of type RouteNetlinkMessage let message: RouteNetlinkMessage = /* ... received or constructed message ... */; match message { // Using the predicate method for NewLink RouteNetlinkMessage::NewLink(_) if message.is_new_link() => { println!("This is a NewLink message."); // Access link_msg details here if needed } // Using the predicate method for NewAddress RouteNetlinkMessage::NewAddress(_) if message.is_new_address() => { println!("This is a NewAddress message."); // Access address_msg details here if needed } // Using the predicate method for GetRoute RouteNetlinkMessage::GetRoute(_) if message.is_get_route() => { println!("This is a GetRoute message."); // Access route_msg details here if needed } // Fallback for other message types _ => { println!("This is another type of RouteNetlinkMessage."); } } ``` ```