| Crates.io | netmap-rs |
| lib.rs | netmap-rs |
| version | 0.3.0 |
| created_at | 2025-06-25 21:50:59.651311+00 |
| updated_at | 2025-11-08 09:18:29.044261+00 |
| description | Safe, zero-cost abstractions for Netmap kernel-bypass networking |
| homepage | |
| repository | https://github.com/Kyle6012/netmap-rs |
| max_upload_size | |
| id | 1726484 |
| size | 211,421 |
netmap-rs provides safe, zero-cost abstractions for Netmap kernel-bypass networking in Rust. It aims to offer high-performance packet I/O by leveraging Netmap's efficient memory-mapped ring buffers.
netmap C structures.sys for core Netmap functionality, tokio-async for Tokio integration).IMPORTANT: This crate requires the Netmap C library to be installed on your system. Without it, the sys feature will not work.
Install build dependencies:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install build-essential git linux-headers-$(uname -r)
# CentOS/RHEL
sudo yum install gcc git kernel-devel-$(uname -r)
Download and build netmap:
git clone https://github.com/luigirizzo/netmap.git
cd netmap/LINUX
./configure
make
sudo make install
Load the kernel module:
sudo insmod netmap.ko
# Verify it's loaded
ls /dev/netmap
Netmap is included by default in FreeBSD 11+. No additional installation is required.
If you installed netmap in a non-standard location, set the NETMAP_LOCATION environment variable:
export NETMAP_LOCATION=/opt/netmap
# Then build your project
To use netmap-rs in your project, add it to your Cargo.toml.
Crucially, for most use cases, you will need to enable the sys feature. This feature compiles and links against the necessary netmap C libraries and enables the core structures like NetmapBuilder, Netmap, TxRing, and RxRing.
[dependencies]
netmap-rs = { version = "0.3", features = ["sys"] }
If you intend to use netmap-rs with Tokio for asynchronous operations, you should also enable the tokio-async feature:
[dependencies]
netmap-rs = { version = "0.3", features = ["sys", "tokio-async"] }
Here's a basic example of how to open a Netmap interface, send, and receive a packet. This example assumes you have a loopback interface or a setup where packets sent on an interface can be received on it.
use netmap_rs::prelude::*;
use std::thread::sleep;
use std::time::Duration;
fn main() -> Result<(), Error> {
// Ensure you have enabled the "sys" feature for netmap-rs in your Cargo.toml
// e.g., netmap-rs = { version = "...", features = ["sys"] }
// Attempt to open a netmap interface.
// Replace "eth0" with your desired interface.
// NetmapBuilder will prefix with "netmap:" if needed.
// Use "eth0^" to access host stack rings.
let nm = NetmapBuilder::new("eth0") // Or "netmap:eth0"
.num_tx_rings(1) // Configure one transmission ring
.num_rx_rings(1) // Configure one reception ring
.build()?;
// Get handles to the first transmission and reception rings.
let mut tx_ring = nm.tx_ring(0)?;
let mut rx_ring = nm.rx_ring(0)?;
// Prepare a packet to send.
let packet_data = b"hello netmap!";
// Send the packet.
// The `send` method queues the packet.
tx_ring.send(packet_data)?;
// `sync` ensures that queued packets are made available to the hardware.
tx_ring.sync();
println!("Sent packet: {:?}", packet_data);
// Attempt to receive the packet.
let mut received = false;
for _ in 0..5 { // Try a few times with a delay
// `sync` on the rx_ring tells the kernel we are done with previously received packets
// and updates the ring's state to see new packets.
rx_ring.sync();
while let Some(frame) = rx_ring.recv() {
println!("Received packet: {:?}", frame.payload());
assert_eq!(frame.payload(), packet_data);
received = true;
break;
}
if received {
break;
}
sleep(Duration::from_millis(100)); // Wait a bit for the packet to arrive
}
if !received {
eprintln!("Failed to receive the packet back.");
// Depending on the setup (e.g. loopback interface), this might indicate an issue.
}
Ok(())
}
This means the Netmap C library is not installed or not found. Make sure to:
NETMAP_LOCATION if installed in a non-standard pathnm_open"This indicates the Netmap library is not being linked properly. Ensure:
sys feature is enabled in Cargo.tomlIf you get errors like "NetmapBuilder not found", make sure you have enabled the sys feature:
[dependencies]
netmap-rs = { version = "0.3", features = ["sys"] }
Common causes:
Permission issues: You need root/sudo access to use netmap
sudo ./your_program
Interface doesn't exist: Check available interfaces with:
ip link show
Netmap kernel module not loaded:
sudo insmod netmap.ko
Driver not supported: Not all network drivers support netmap. Check supported drivers:
cd netmap/LINUX
./configure --show-drivers
This is normal behavior when the ring buffer is full or empty. Implement proper retry logic in your application.
For maximum performance, dedicate threads to individual rings:
use netmap_rs::prelude::*;
use std::thread;
fn main() -> Result<(), Error> {
let nm = NetmapBuilder::new("eth0")
.num_tx_rings(4)
.num_rx_rings(4)
.build()?;
let mut handles = vec![];
// Spawn RX threads
for i in 0..nm.num_rx_rings() {
let rx_ring = nm.rx_ring(i)?;
let handle = thread::spawn(move || {
// Process packets on this ring
// ...
});
handles.push(handle);
}
// Spawn TX threads
for i in 0..nm.num_tx_rings() {
let tx_ring = nm.tx_ring(i)?;
let handle = thread::spawn(move || {
// Send packets on this ring
// ...
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
Ok(())
}
Enable the tokio-async feature for async/await support:
use netmap_rs::tokio_async::*;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let nm = TokioNetmap::new("eth0").await?;
let mut rx_ring = nm.async_rx_ring(0).await?;
loop {
if let Some(frame) = rx_ring.recv().await? {
println!("Received: {:?}", frame.payload());
}
sleep(Duration::from_millis(10)).await;
}
}
The examples/ directory contains several complete examples:
ping_pong.rs - Basic send/receive examplesliding_window_arq.rs - Reliable delivery with ARQfec.rs - Forward Error Correctionthread_per_ring.rs - Thread-per-ring patternRun examples with:
cargo run --example ping_pong --features sys
core_affinity for consistent performanceThis project is licensed under either of:
at your option.
Meshack Bahati Ouma - CS major (Maseno University (Kenya))
Email: bahatikylemeshack@gmail.com
Contributions are welcome! Please feel free to submit a Pull Request.