📡 netmap-rs

Safe, zero-cost abstractions for Netmap kernel-bypass networking in Rust.

Table of Contents

Introduction

netmap-rs provides safe, zero-cost abstractions for Netmap, a high-performance packet I/O framework. It allows you to directly access packet buffers in memory shared with the kernel, eliminating copies and system call overhead for extremely fast networking.

Features

High Performance

Direct memory access to packet buffers with zero-copy operations for maximum throughput.

Memory Safe

Leverages Rust's ownership model to ensure memory safety without performance penalties.

Async Support

Optional integration with Tokio for asynchronous packet processing.

Cross-Platform

Works on Linux, FreeBSD, and other platforms supported by Netmap.

Getting Started

Prerequisites

You must have the Netmap C library installed. Follow the instructions in the official Netmap repository to build and install it on your system.

Adding to Your Project

Add netmap-rs to your Cargo.toml, enabling the sys feature for core functionality:

[dependencies]
netmap-rs = { version = "0.3", features = ["sys"] }

Basic Usage

Here's a simple example of sending and receiving a packet on an interface:

use netmap_rs::prelude::*;
use std::thread::sleep;
use std::time::Duration;

fn main() -> Result<(), Error> {
    let nm = NetmapBuilder::new("eth0")
        .num_tx_rings(1)
        .num_rx_rings(1)
        .build()?;

    let mut tx_ring = nm.tx_ring(0)?;
    let mut rx_ring = nm.rx_ring(0)?;

    let packet_data = b"hello netmap!";

    tx_ring.send(packet_data)?;
    tx_ring.sync();
    println!("Sent packet: {:?}", packet_data);

    // ... (receive logic) ...

    Ok(())
}

Advanced Usage

Thread-per-Ring

For maximum performance, dedicate a thread to each transmission (TX) and reception (RX) ring. This pattern is ideal for multi-core systems.

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()?;

    // Spawn threads for each ring...
    // See the full example in the repository.
    Ok(())
}

Async Support with Tokio

Enable the tokio-async feature for async/await support:

[dependencies]
netmap-rs = { version = "0.3", features = ["sys", "tokio-async"] }
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?;

    // ... (async receive logic) ...
    Ok(())
}

Troubleshooting

Common issues include "netmap_user.h not found" (install Netmap), permission errors (run with sudo), and "NetmapBuilder not found" (enable the sys feature).

Performance Tips