diff --git a/README.md b/README.md index 6bbfbcc..d797e5e 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,222 @@ -# DPDK-STDLIB +# dpdk-stdlib-rust -A Rust library providing safe, high-level abstractions for DPDK (Data Plane Development Kit) with focus on UDP networking. +Drop-in DPDK-accelerated replacements for `std::net::UdpSocket` and `tokio::net::UdpSocket`. Bypass the Linux kernel network stack for high-throughput packet processing, with automatic fallback when DPDK is unavailable. + +## Why + +Traditional Linux networking routes every packet through the kernel: syscalls, context switches, interrupts, and the full TCP/IP stack. For high-packet-rate workloads (DNS servers, load balancers, packet processors), this overhead becomes the bottleneck. + +DPDK (Data Plane Development Kit) bypasses the kernel entirely using userspace drivers and polling. This eliminates syscalls and context switches, achieving: + +- **10-100x higher packet rates** — millions of packets/sec per core +- **Microsecond-level latency** instead of milliseconds +- **Zero kernel overhead** for packet I/O + +**But DPDK's C API is complex and unsafe.** This project wraps DPDK in safe Rust with a familiar `std::net` API, so you get kernel bypass without rewriting your application. ## Features -- **Safe DPDK Wrapper**: Memory-safe Rust bindings for DPDK -- **UDP Protocol Layer**: High-level UDP socket abstraction -- **Synthetic Mode**: Test without real DPDK installation -- **Cross-Platform**: macOS (synthetic) and Linux (real DPDK) -- **Echo Server**: Example UDP echo application +- **100% API-compatible** with `std::net::UdpSocket` and `tokio::net::UdpSocket` +- **Multiple backends**: DPDK (kernel bypass), AF_PACKET (raw sockets), AF_PACKET+MMAP (zero-copy) +- **Automatic fallback**: Works without DPDK installed (development, testing, CI) +- **Hardware offload**: IPv4/UDP checksum offloading on supported NICs +- **Protocol support**: ARP resolution, ICMP echo reply +- **Async runtime**: Full Tokio integration with poll-based API ## Quick Start -### Synthetic Mode (Development) -```bash -# Works on any platform without DPDK -cargo run -p echo +### As a Library + +Replace your socket imports: + +```rust +// Before +use std::net::UdpSocket; + +// After +use dpdk_tokio::compat::net::UdpSocket; + +// Code stays identical +let socket = UdpSocket::bind("0.0.0.0:9000")?; +socket.send_to(b"hello", "192.168.1.100:9000")?; ``` -### Real DPDK Mode (Linux) -```bash -# Install DPDK first -sudo ./scripts/install_dpdk_amazon_linux.sh +For async: + +```rust +// Before +use tokio::net::UdpSocket; + +// After +use dpdk_tokio::compat::tokio::UdpSocket; -# Build with DPDK support -cargo run -p echo --features dpdk-support -- --dpdk --dpdk-args="-l 0-1 -n 4" +// Code stays identical +let socket = UdpSocket::bind("0.0.0.0:9000").await?; +socket.send_to(b"hello", "192.168.1.100:9000").await?; ``` -### Test Client +Backend selection is automatic: DPDK if available, otherwise AF_PACKET raw sockets. + +### Running Examples + ```bash -cargo run -p test-client -- --target 10.0.0.2 --port 9000 --message "hello world" +# Run async echo server (works anywhere, no DPDK required) +cargo run -p tokio-echo + +# Test it +cargo run -p test-client -- --target 127.0.0.1 --port 9000 ``` -## Architecture +## Backend Selection -``` -┌─────────────────┐ -│ Applications │ (echo, test-client) -├─────────────────┤ -│ dpdk-udp │ (UDP protocol layer) -├─────────────────┤ -│ dpdk │ (Safe wrapper) -├─────────────────┤ -│ dpdk-sys │ (Raw FFI bindings) -└─────────────────┘ -``` +Three backends available (automatic selection by default): -## Installation +| Backend | Requires | Performance | Use Case | +|---------|----------|-------------|----------| +| **DPDK** | DPDK installed, dedicated NIC | Highest (kernel bypass) | Production packet processing | +| **AF_PACKET+MMAP** | Linux raw sockets | High (zero-copy ring buffers) | Development, containers | +| **AF_PACKET** | Linux raw sockets | Medium (syscalls but no kernel stack) | Fallback, testing | -### Amazon Linux 3 -```bash -./scripts/install_dpdk_amazon_linux.sh +Configure explicitly: + +```rust +use dpdk_tokio::{SocketConfig, BackendType}; + +let config = SocketConfig { + backend: BackendType::Dpdk, + ..Default::default() +}; +let socket = AsyncUdpSocket::bind_with_config("0.0.0.0:9000", config).await?; ``` -### macOS (Synthetic Only) +## Development + +### Build and Test + ```bash -# No DPDK installation needed +# Build everything (works without DPDK - uses stubs) cargo build -``` -## AWS Deployment +# Run 133+ unit tests (no DPDK required) +cargo test -Deploy test infrastructure to EC2: -```bash -cd deploy/cdk -npm install -cdk deploy --profile your-aws-profile +# Run specific crate tests +cargo test -p dpdk-udp ``` -This creates: -- 2x c6gn.large instances (sender/receiver) -- Dual ENIs (management + DPDK) -- SSM access (no SSH keys needed) +### Local Development Setup -## Usage Examples +No DPDK installation needed. The stub system provides mock implementations so all tests pass on macOS, Linux, or CI without dedicated hardware. -### Echo Server -```bash -# Synthetic mode (default) -cargo run -p echo +### Integration Testing -# DPDK mode with custom IP/port -cargo run -p echo --features dpdk-support -- \ - --dpdk --dpdk-args="-l 0-1 -n 4" \ - --ip 192.168.1.100 --port 8080 -``` +For changes touching networking or backends: -### Test Client ```bash -# Send single packet -cargo run -p test-client -- --target 192.168.1.100 --port 8080 - -# Send multiple packets with delay -cargo run -p test-client -- \ - --target 192.168.1.100 \ - --count 10 \ - --delay 500 \ - --message "test packet" +# Validate locally + trigger EC2 integration tests +./scripts/ci-validate.sh ``` -## Development +This runs: +1. `cargo build && cargo test` locally +2. Pushes your branch +3. Triggers GitHub Actions workflow on real EC2 DPDK hardware +4. Waits for results (exits non-zero on failure) + +**Do not create a PR until this passes.** + +### Contributing + +1. Create a feature branch: `git checkout -b feature/my-change` +2. Make changes with tests +3. Run `./scripts/ci-validate.sh` to validate +4. Push and create PR + +See `CLAUDE.md` for agent instructions and `API_COMPATIBILITY.md` for API tracking. + +## Architecture -### Project Structure ``` -dpdk-stdlib/ -├── dpdk-sys/ # Raw DPDK FFI bindings -├── dpdk/ # Safe Rust wrapper -├── dpdk-udp/ # UDP protocol implementation -├── apps/ -│ ├── echo/ # UDP echo server -│ └── test-client/ # UDP test client -├── scripts/ # Installation scripts -├── deploy/cdk/ # AWS CDK deployment -└── docs/ # Documentation +┌──────────────────────────────────────────────────────────────────┐ +│ Applications (echo, tokio-echo, test-client) │ +├──────────────────────────────────────────────────────────────────┤ +│ dpdk-tokio Async runtime, compat layer (std/tokio drop-ins) │ +├──────────────────────────────────────────────────────────────────┤ +│ dpdk-udp UdpSocket API, ARP, ICMP, packet parsing │ +│ ┌──────────────┬────────────────┬────────────────┐ │ +│ │ DpdkBackend │ RawSocket │ RawSocket+MMAP │ │ +├───────────────┴──────────────┴────────────────┴────────────────┤ +│ dpdk Safe wrapper (Port, Mbuf, Mempool, Queue) │ +├──────────────────────────────────────────────────────────────────┤ +│ dpdk-sys Raw FFI bindings + stubs (no DPDK required) │ +└──────────────────────────────────────────────────────────────────┘ + │ + ┌───────┴────────┐ + │ DPDK Library │ (optional, kernel bypass) + └────────────────┘ ``` -### Building +- **dpdk-sys**: Raw FFI bindings with stub fallback (works without DPDK) +- **dpdk**: Safe Rust wrapper (Port, Mbuf, Mempool, Queue) +- **dpdk-udp**: Protocol layer with backend abstraction (sockets, ARP, ICMP) + - **DpdkBackend**: Userspace DPDK with kernel bypass + - **RawSocketBackend**: Linux AF_PACKET raw sockets + - **MmapBackend**: AF_PACKET + PACKET_MMAP ring buffers (zero-copy) +- **dpdk-tokio**: Async support and drop-in compat layer for std/tokio + +## Status + +- ✅ **Phase 1-5 complete** (see `API_COMPATIBILITY.md`) +- ✅ **std::net::UdpSocket**: 19/19 methods implemented +- ✅ **tokio::net::UdpSocket**: All async methods + poll API +- ✅ **ARP resolution** and **ICMP echo reply** support +- ✅ **Hardware checksum offload** (IPv4, UDP, TCP) +- ✅ **Backend abstraction** (DPDK, AF_PACKET, MMAP) +- ✅ **Integration tests** on AWS EC2 (c6gn.large with ENA) + +## DPDK Installation (Optional) + +Development and testing work without DPDK. For production kernel bypass: + +### Amazon Linux 2023 + ```bash -# Check all crates -cargo check +sudo ./scripts/install_dpdk_amazon_linux.sh +``` -# Build with DPDK support -cargo build --features dpdk-support +This installs DPDK 23.11 and configures hugepages. -# Run tests -cargo test +### Verify DPDK + +```bash +# Should show "real" not "stub" +cargo run -p echo -- --dpdk ``` ### Platform Support -| Platform | Synthetic Mode | Real DPDK | Notes | -|----------|---------------|-----------|-------| -| macOS | ✅ | ❌ | DPDK 23.11+ lacks macOS support | -| Linux | ✅ | ✅ | Full DPDK functionality | -| Windows | ❌ | ❌ | Not implemented | +| Platform | Stub Mode | Real DPDK | Notes | +|----------|-----------|-----------|-------| +| macOS | ✅ | ❌ | DPDK 23.11+ lacks macOS support | +| Linux | ✅ | ✅ | Full DPDK functionality | +| Windows | ❌ | ❌ | Not implemented | + +## AWS Deployment + +Deploy test infrastructure to EC2: + +```bash +cd deploy/cdk +npm install +cdk deploy --profile your-aws-profile +``` -## Contributing +This creates: +- 2x c6gn.large instances (sender/receiver) +- Dual ENIs (management + DPDK) +- SSM access (no SSH keys needed) -1. Fork the repository -2. Create a feature branch -3. Make changes with tests -4. Submit a pull request +See `deploy/README.md` for details. ## License