netmap_rs/lib.rs
1//! Safe, zero-cost abstractions for Netmap kernel-bypass networking.
2//!
3//! # Features
4//! - Zero-copy packet I/O
5//! - Thread-per-ring with core pinning
6//! - Batch Operations for high throughput
7//! - Cross-platform support (with fallback implementation)
8//!
9//! # Usage
10//!
11//! Add `netmap-rs` to your `Cargo.toml`:
12//! ```toml
13//! [dependencies]
14//! netmap-rs = { version = "0.3", features = ["sys"] }
15//! ```
16//!
17//! Basic example:
18//! ```no_run
19//! use netmap_rs::prelude::*;
20//! use std::thread::sleep;
21//! use std::time::Duration;
22//!
23//! fn main() -> Result<(), Error> {
24//! // Attempt to open a netmap interface.
25//! // Replace "netmap:eth0" with your desired interface.
26//! // The `.build()?` method finalizes the configuration and opens the interface.
27//! let nm = NetmapBuilder::new("netmap:eth0")
28//! .num_tx_rings(1) // Configure one transmission ring
29//! .num_rx_rings(1) // Configure one reception ring
30//! .build()?;
31//!
32//! // Get handles to the first transmission and reception rings.
33//! let mut tx_ring = nm.tx_ring(0)?;
34//! let mut rx_ring = nm.rx_ring(0)?;
35//!
36//! // Prepare a packet to send.
37//! let packet_data = b"hello netmap!";
38//!
39//! // Send the packet.
40//! // The `send` method might not transmit immediately; it queues the packet.
41//! tx_ring.send(packet_data)?;
42//! // `sync` ensures that queued packets are made available to the hardware.
43//! tx_ring.sync();
44//! println!("Sent packet: {:?}", packet_data);
45//!
46//! // Attempt to receive the packet.
47//! let mut received = false;
48//! for _ in 0..5 { // Try a few times with a delay
49//! // `sync` on the rx_ring tells the kernel we are done with previously received packets
50//! // and updates the ring's state to see new packets.
51//! rx_ring.sync();
52//! while let Some(frame) = rx_ring.recv() {
53//! println!("Received packet: {:?}", frame.payload());
54//! assert_eq!(frame.payload(), packet_data);
55//! received = true;
56//! break;
57//! }
58//! if received {
59//! break;
60//! }
61//! sleep(Duration::from_millis(100)); // Wait a bit for the packet to arrive
62//! }
63//!
64//! if !received {
65//! eprintln!("Failed to receive the packet back.");
66//! // Depending on the setup (e.g. loopback interface), this might indicate an issue.
67//! }
68//!
69//! Ok(())
70//! }
71//! ```
72//! For more advanced examples, such as Forward Error Correction (FEC),
73//! reliable delivery with ARQ, or dedicating threads per ring, please see the
74//! files in the `examples` directory of the crate.
75
76#![cfg_attr(docsrs, feature(doc_cfg))]
77#![warn(missing_docs)]
78// #![warn(rustdoc::missing_crate_level_docs)] // Already covered by the extensive example above
79
80#[cfg(feature = "sys")]
81extern crate bitflags;
82#[allow(unused_imports)] // Clippy seems to have a false positive with specific feature flags
83#[macro_use]
84extern crate thiserror;
85
86/// Error types for the netmap library.
87pub mod error;
88/// Fallback implementations for non-Netmap platforms.
89pub mod fallback;
90/// Frame structures for representing network packets.
91pub mod frame;
92/// Netmap interface and builder types.
93pub mod netmap;
94/// Netmap ring manipulation.
95pub mod ring;
96
97#[cfg(feature = "sys")]
98pub use netmap_min_sys as ffi;
99
100// Tokio async support (optional feature)
101#[cfg(feature = "tokio-async")]
102#[cfg_attr(docsrs, doc(cfg(feature = "tokio-async")))]
103pub mod tokio_async;
104// Re-export async types at the crate root when feature is enabled.
105#[cfg(feature = "tokio-async")]
106#[cfg_attr(docsrs, doc(cfg(feature = "tokio-async")))]
107pub use tokio_async::{AsyncNetmapRxRing, AsyncNetmapTxRing, TokioNetmap};
108
109pub use crate::{error::Error, frame::Frame};
110
111/// The `prelude` module re-exports commonly used types from this crate
112/// for easier access.
113///
114/// It is recommended to import all items from the prelude:
115/// ```
116/// use netmap_rs::prelude::*;
117/// ```
118pub mod prelude {
119 pub use crate::error::Error;
120 pub use crate::frame::Frame;
121
122 #[cfg(feature = "sys")]
123 pub use crate::{
124 netmap::{Netmap, NetmapBuilder},
125 ring::{Ring, RxRing, TxRing},
126 };
127}
128
129// Re-export sys-specific types only when sys feature is enabled
130#[cfg(feature = "sys")]
131pub use crate::{
132 netmap::{Netmap, NetmapBuilder},
133 ring::{Ring, RxRing, TxRing},
134};
135
136#[cfg(test)]
137mod tests {
138 use crate::prelude::*;
139
140 #[test]
141 fn it_works() {
142 let frame = Frame::new(b"smoke");
143 assert_eq!(frame.len(), 5);
144 assert!(!Error::WouldBlock.to_string().is_empty());
145 }
146}