netmap-rs
Safe, idiomatic, and zero-cost abstractions for the Netmap kernel-bypass networking framework.
Netmap allows for extremely fast packet I/O by bypassing the kernel's network stack, enabling direct communication between applications and network hardware. netmap-rs
provides a Rust interface to these capabilities, prioritizing safety and ease of use without sacrificing performance.
This crate builds upon the raw FFI bindings provided by netmap-min-sys
(when the sys
feature is enabled).
Features
- Zero-Copy Packet I/O: Directly access packet buffers in memory-mapped regions for maximum throughput and minimum latency.
- Safe Abstractions: Wraps unsafe C FFI calls in safe Rust APIs.
- High-Level Interface: Provides
Netmap
,TxRing
,RxRing
, andFrame
types for easy management of netmap resources. - Builder Pattern: Fluent
NetmapBuilder
for configuring netmap interfaces. - Batch Operations: Efficiently send and receive packets in batches.
- Fallback Mode: Includes a software-based fallback implementation for platforms or environments where native Netmap is unavailable, allowing for broader compatibility and easier development.
- Thread-per-Ring Design: Facilitates architectures where each network ring is managed by a dedicated thread, often pinned to a specific core for performance.
Prerequisites
- For Native Netmap (Linux/FreeBSD):
- Netmap kernel module installed and loaded.
- Netmap header files available.
- See the official netmap documentation for installation instructions.
- Rust: Version 1.60 or later.
Usage
Add netmap-rs
to your Cargo.toml
:
[]
= "0.1" # Replace with the latest version from crates.io
By default, netmap-rs
tries to use the native Netmap system interface via the sys
feature. If Netmap is not available or you are on an unsupported platform, it can operate in a fallback mode.
Basic Example
This example demonstrates how to open a netmap interface, send a packet, and receive it back (e.g., on a loopback interface or if another host sends it back).
use *;
use sleep;
use Duration;
For more advanced examples, please see the files in the examples
directory of the crate. These include:
ping_pong.rs
: A simple ping-pong example.fec.rs
: Demonstrates Forward Error Correction.sliding_window_arq.rs
: Implements a basic Automatic Repeat Request (ARQ) for reliable delivery.thread_per_ring.rs
: Shows a single thread managing a ring pair (can be adapted for fallback mode).multi_thread_rings.rs
: A more comprehensive example demonstrating how to use multiple TX/RX rings with dedicated threads pinned to CPU cores for each ring pair, suitable for high-performance packet forwarding or processing.host_receive.rs
: Shows how to receive packets from the host operating system's network stack for a given interface (e.g., by opening "netmap:eth0^").host_transmit.rs
: Shows how to transmit packets into the host operating system's network stack for a given interface.pipe_threads.rs
: Demonstrates intra-process (thread-to-thread) communication using a Netmap pipe.pipe_sender_process.rs
&pipe_receiver_process.rs
: Example pair for inter-process communication using Netmap pipes.poll_basic.rs
: Shows basic usage ofpoll()
with Netmap file descriptors for non-blocking I/O readiness notification.tokio_pipe_async.rs
: (Requirestokio-async
feature) Demonstrates asynchronous packet send/receive over a Netmap pipe using Tokio and theAsyncNetmap*Ring
wrappers.
Interacting with the Host Stack
Netmap allows applications to interact directly with the host operating system's network stack, effectively creating a high-speed path to inject packets into the kernel or receive packets from it, bypassing normal socket APIs for the data path. netmap-rs
supports this by recognizing the ^
suffix on interface names.
When you create a NetmapBuilder
with an interface name like "netmap:eth0^"
or "em1^"
, netmap-rs
configures the underlying Netmap request to access the host stack rings associated with eth0
(or em1
).
use *;
#
The Netmap::is_host_if()
method can be used to check if a Netmap
instance is configured for host stack rings. The examples/host_receive.rs
and examples/host_transmit.rs
files provide practical demonstrations. Accessing host stack rings typically requires appropriate system permissions (e.g., root).
Using Netmap Pipes for IPC
Netmap pipes provide a mechanism for zero-copy inter-process communication (IPC) or intra-process (thread-to-thread) communication. A pipe is identified by a unique name, and each endpoint of the pipe typically gets one transmission (TX) ring and one reception (RX) ring.
To use a Netmap pipe with netmap-rs
:
- Choose a unique name for your pipe, e.g., "my_pipe_1".
- Use
NetmapBuilder::new("pipe{my_pipe_1}")
(or"netmap:pipe{my_pipe_1}"
) to create builders for each endpoint. - Call
.build()
on each builder to getNetmap
instances. The first successful open creates the pipe and becomes its master; subsequent opens of the same pipe name attach as slaves/peers. - Use the TX ring of one endpoint to send data and the RX ring of the other endpoint to receive it. Communication is bidirectional.
use *;
#
Refer to examples/pipe_threads.rs
for a thread-to-thread example and examples/pipe_sender_process.rs
/ examples/pipe_receiver_process.rs
for inter-process examples.
Polling and Asynchronous Operations
Basic Polling
Netmap file descriptors can be used with polling mechanisms like poll()
, select()
, epoll
, or kqueue
to wait for I/O readiness without busy-looping. The Netmap
struct implements AsRawFd
to provide the necessary file descriptor.
POLLIN
typically indicates that an RX ring has packets available (after anrx_ring.sync()
) or a TX ring has space.POLLOUT
typically indicates that a TX ring has space available for sending. Theexamples/poll_basic.rs
demonstrates using thepolling
crate for this purpose. Remember that Netmap'spoll
is generally level-triggered, andsync()
calls on rings are crucial after readiness events.
Tokio Asynchronous Support (Optional Feature)
netmap-rs
provides support for asynchronous operations using Tokio via the tokio-async
feature flag. To enable it, add to your Cargo.toml
:
= { = "0.1", = ["tokio-async", "sys"] }
This feature provides the following types in the netmap_rs::tokio_async
module (also re-exported at netmap_rs::*
when the feature is enabled):
TokioNetmap
: Wraps aNetmap
instance to integrate with Tokio's event loop.AsyncNetmapRxRing
: Implementstokio::io::AsyncRead
for a Netmap RX ring.AsyncNetmapTxRing
: Implementstokio::io::AsyncWrite
for a Netmap TX ring.
#
# async
The examples/tokio_pipe_async.rs
example shows these types in action.
Important Note on Async Wrappers: The current AsyncRead
and AsyncWrite
implementations have placeholders for the crucial ioctl
calls (NIOCRXSYNC
, NIOCTXSYNC
) needed for proper Netmap ring synchronization with the kernel. These ioctl
s MUST be correctly implemented within the async wrappers for them to function reliably. Refer to the docstrings in src/tokio_async.rs
for more details.
Platform Support
Platform | Native Netmap Status | Fallback Mode | Notes |
---|---|---|---|
Linux | ✅ Supported | ✅ Available | Requires Netmap kernel module and headers. |
FreeBSD | ✅ Supported | ✅ Available | Netmap originated on FreeBSD. |
macOS | ⚠️ Experimental | ✅ Available | Native support might be limited or require specific configurations. |
Windows | ❌ Not Supported | ✅ Available | Operates only in fallback mode. |
Other Unix-like | ❔ Untested | ✅ Available | May work with native Netmap if supported; fallback mode is available. |
Error Handling
The library uses the netmap_rs::Error
enum to report errors. This includes I/O errors, configuration issues, and problems during packet operations.
Fallback Mode
If the sys
feature is not enabled or if netmap-rs
cannot initialize a native Netmap interface at runtime, it can operate in a fallback mode. This mode simulates Netmap's ring buffer behavior in software, using standard socket APIs (or in-memory queues for loopback-like examples). While performance will be significantly lower than native Netmap, it allows for development and testing on systems without Netmap or for applications where extreme performance is not the primary concern.
Author
- Meshack Bahati (Kenya)
License
- Apache License, Version 2.0, (LICENSE-APACHE).
- MIT license (LICENSE-MIT).
For more details on the API, please refer to the API documentation on docs.rs.