Skip to content

feat: implement Phase 5 - raw socket backend with PacketBackend trait - #5

Merged
gspivey merged 2 commits into
mainfrom
claude/complete-phase-5-api-9PmZN
Feb 7, 2026
Merged

gspivey merged 2 commits into
mainfrom
claude/complete-phase-5-api-9PmZN

Conversation

@gspivey

@gspivey gspivey commented Feb 6, 2026

Copy link
Copy Markdown
Owner

Add AF_PACKET raw socket backend as a non-DPDK fallback, with an abstract
PacketBackend trait enabling runtime backend selection.

New modules:

  • backend.rs: PacketBackend trait + BackendConfig/BackendType for
    runtime backend selection (DPDK, AF_PACKET, AF_PACKET+MMAP, Auto)
  • backend_dpdk.rs: DPDK implementation of PacketBackend wrapping
    Port + Mempool for high-performance packet I/O
  • backend_raw.rs: Linux AF_PACKET raw socket backend with support
    for both basic send/recv and PACKET_MMAP zero-copy modes
  • ring_buffer.rs: PACKET_MMAP TX/RX ring buffer implementation with
    tpacket_v2 headers for zero-copy packet I/O

Key changes to lib.rs:

  • Added build_udp_frame() for backend-agnostic frame construction
    (builds complete Ethernet frame as Vec vs mbuf-specific build_udp_packet)
  • Added SocketBackend enum dispatching between DPDK and generic backends
  • Refactored UdpSocket send/recv to use backend abstraction, reusing
    existing ARP/ICMP handlers and packet parsing code unchanged
  • Added UdpSocket::bind_with_backend() for custom backend selection
  • Added create_backend() factory for runtime backend initialization
  • All 74 dpdk-udp tests pass, all 133 workspace tests pass

https://claude.ai/code/session_013wpw76iG9rx8PxU9omE8LY

Add AF_PACKET raw socket backend as a non-DPDK fallback, with an abstract
PacketBackend trait enabling runtime backend selection.

New modules:
- backend.rs: PacketBackend trait + BackendConfig/BackendType for
  runtime backend selection (DPDK, AF_PACKET, AF_PACKET+MMAP, Auto)
- backend_dpdk.rs: DPDK implementation of PacketBackend wrapping
  Port + Mempool for high-performance packet I/O
- backend_raw.rs: Linux AF_PACKET raw socket backend with support
  for both basic send/recv and PACKET_MMAP zero-copy modes
- ring_buffer.rs: PACKET_MMAP TX/RX ring buffer implementation with
  tpacket_v2 headers for zero-copy packet I/O

Key changes to lib.rs:
- Added build_udp_frame() for backend-agnostic frame construction
  (builds complete Ethernet frame as Vec<u8> vs mbuf-specific build_udp_packet)
- Added SocketBackend enum dispatching between DPDK and generic backends
- Refactored UdpSocket send/recv to use backend abstraction, reusing
  existing ARP/ICMP handlers and packet parsing code unchanged
- Added UdpSocket::bind_with_backend() for custom backend selection
- Added create_backend() factory for runtime backend initialization
- All 74 dpdk-udp tests pass, all 133 workspace tests pass

https://claude.ai/code/session_013wpw76iG9rx8PxU9omE8LY
Comprehensive guide for AI agents covering architecture, crate layout,
design decisions, steering rules, and quick reference for key files.
CLAUDE.md symlinked to AGENTS.md for Claude Code compatibility.

https://claude.ai/code/session_013wpw76iG9rx8PxU9omE8LY
@gspivey
gspivey merged commit 682c52f into main Feb 7, 2026
1 check passed
@gspivey
gspivey deleted the claude/complete-phase-5-api-9PmZN branch February 19, 2026 00:52
gspivey pushed a commit that referenced this pull request Mar 25, 2026
Remove misleading claim that abstraction layer "masked" kernel
performance — a fallback to kernel sockets adds overhead, it
can't make things faster. Acknowledge Run #5 kernel numbers
(78% drop) are an outlier vs historical ~50-58% baseline.
Revert README to ~2x DPDK advantage claim.

https://claude.ai/code/session_013kEK2d9wyTRWwmoAB4VBco
gspivey pushed a commit that referenced this pull request Mar 25, 2026
Run #5 (23548559577) had anomalous kernel numbers (78% drop at 64B/700K)
due to a bad EC2 instance. Run #6 (23567309410) shows normal kernel
performance (51% drop) consistent with Run #4. Updated both
perf-test-log.md and README performance tables with the correct data.

DPDK advantage is consistently ~2x at saturation, not the 3-4x that the
outlier suggested.

https://claude.ai/code/session_013kEK2d9wyTRWwmoAB4VBco
@gspivey gspivey mentioned this pull request Jun 6, 2026
gspivey pushed a commit that referenced this pull request Jun 6, 2026
- Append perf-test-log.md Run #32: no regression from RX queue impl
- Update ROADMAP.md: mark item 5 (dpdk-stdlib-quic: RX queue) complete
  with PR #69
gspivey added a commit that referenced this pull request Jun 6, 2026
## Roadmap Item

Implements roadmap item #5: `dpdk-stdlib-quic: RX queue`

## Changes

- **`DpdkRxQueue`** implementing `s2n_quic_core::io::rx::Queue` trait
(`for_each`, `is_empty`)
- **`parse_to_rx_datagram(frame, local_addr)`** — reuses
`parse_udp_packet_ref` from `dpdk-udp`, extracts TOS byte for ECN
codepoint, constructs `Header { path: DpdkPathHandle, ecn }`, returns
payload as `Vec<u8>`
- Public re-exports of `DpdkRxQueue` and `parse_to_rx_datagram` from the
crate root

## Tests Added

- `valid_parse_produces_correct_datagram` — verifies payload, ECN,
remote/local addresses
- `wrong_dst_port_returns_none` — frames not destined for bound port are
dropped
- `non_ipv4_frame_returns_none` — non-IPv4 EtherType frames discarded
- `truncated_frame_returns_none` — malformed/short frames discarded
- `for_each_drains_all_datagrams` — Queue trait drains and resets
correctly
- `ecn_all_codepoints_extracted` — all 4 ECN codepoints (NotEct, Ect1,
Ect0, Ce) parsed

## Tradeoffs

- Payload is copied to `Vec<u8>` (accepted v1 cost per design doc —
zero-copy RX is a future optimization)
- Port filtering uses the port from `local_addr` parameter (matches the
event loop pattern where bound port is known)

---------

Co-authored-by: Agent Router <agent@agent-router.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants