Skip to content

feat: jumbo frames, checksum offload, and bindgen compatibility - #32

Merged
gspivey merged 23 commits into
mainfrom
claude/review-roadmap-jumbo-frames-rZQcl
Apr 11, 2026
Merged

gspivey merged 23 commits into
mainfrom
claude/review-roadmap-jumbo-frames-rZQcl

Conversation

@gspivey

@gspivey gspivey commented Apr 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Jumbo frame support: Mempool now allocates 9KB data-room mbufs, port initializes with 9001 MTU, and packet build functions accept payloads up to the full Ethernet frame size (not just 1472B). Routing table MTU override ensures DPDK backends use jumbo-capable paths.
  • TX hardware checksum offload: When the NIC supports it (ENA does), IPv4 and UDP checksums are computed by hardware. The mbuf ol_flags and tx_offload fields are set with proper pseudo-header checksums. Software fallback remains for NICs without offload support.
  • RX checksum validation: New verify_ipv4_checksum() and verify_udp_checksum() functions for software verification of received packets. udp_pseudo_header_checksum() helper for TX offload path.
  • Bindgen compatibility fix: tx_offload field lives inside an anonymous union in rte_mbuf, so direct field access breaks with real DPDK bindgen bindings. Added C shim functions (dpdk_shim_set_mbuf_tx_offload / dpdk_shim_get_mbuf_tx_offload) and corresponding Rust wrappers, plus all RTE_MBUF_F_TX/RX constants that bindgen can't capture from #define macros.
  • Perf test improvements: Added 8500B jumbo frame packet size, multi-flow workflow, and auto-detection of instance bandwidth/MTU.

Files changed

  • dpdk-sys/csrc/dpdk_shim.c — C shim for tx_offload field access
  • dpdk-sys/src/shim.rs — Rust wrappers + mbuf offload constants (real DPDK path)
  • dpdk-sys/src/stubs.rs — Matching stubs (no-DPDK path)
  • dpdk/src/mbuf.rs — set_tx_offload() uses shim, new offload accessors
  • dpdk-udp/src/lib.rs — Checksum functions, TX offload in send path, jumbo payload limits
  • dpdk-udp/src/routing.rs — MTU override for DPDK backends
  • apps/test-client/src/main.rs — Jumbo frame CLI support
  • scripts/ — Integration and perf test updates

Test plan

  • 262 local unit tests pass (cargo build && cargo test)
  • Integration tests pass (run 24254143440 — real DPDK on EC2 c5n.large with ENA)
  • Performance tests pass (run 24254920708 — benchmarks on EC2)
  • Earlier integration run (24253929077) also passed with initial fix

https://claude.ai/code/session_01FDpfLChZCtgFqko3oX96e8

claude added 23 commits March 28, 2026 19:57
- Add 8500 to default TREX packet sizes (64,512,1400,8500)
- Increase echo app recv buffers from 2048 to 10000 bytes for jumbo payloads
- Set MTU 9001 on DUT kernel interfaces for jumbo frame support
- Add --max-pkt-len=9100 --mbuf-size=10240 to testpmd for jumbo frames
- Add --mbuf-factor 8 to TRex startup for large packet memory allocation

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
…ling

- Add mbuf_9k: 4096 to trex_cfg.yaml memory config so TRex can allocate
  mbufs large enough for 8500B packets
- Remove --mbuf-factor 8 (explicit pool config is the proper fix)
- Add try/except per packet size in run_benchmark.py so one size failing
  doesn't crash the entire benchmark — partial results are still written

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
- Set DPDK port MTU to 9001 (AWS VPC max) in both the UdpSocket and
  DpdkBackend paths so the NIC accepts jumbo frames
- Increase mempool data_room_size from 2176 to 9344 bytes (9216 + headroom)
  so mbufs can hold full jumbo frames without truncation
- Use force=True in TRex client.start() to bypass the 16 Gbps line rate
  check — ENA PMD falsely reports 16 Gbps but c5n actually has 25 Gbps

Root cause of 100% drop for rust-dpdk 8500B: the DPDK port's default MTU
was 1500, so the NIC silently dropped all jumbo frames on RX.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
- Change instance type from c5n.2xlarge to c6in.xlarge
- Remove force=True from TRex to see if c6in ENA reports accurate line rate
- c6in.xlarge: 4 vCPUs, 8 GB, 30 Gbps — $0.284/hr vs $0.432/hr

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
- Move try/except to per-rate-step so partial results (e.g. 70K, 140K
  succeed but 350K hits line rate) are still saved to the JSON
- Sort packet sizes numerically in the summary table (64B < 512B < 1400B
  < 8500B) instead of lexicographic string sort

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Stubs define RTE_PKTMBUF_HEADROOM as u16 but bindgen generates a wider
type. The 9216 + HEADROOM expression was u32 on EC2, causing a type
mismatch with with_data_room_size(u16).

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Define JUMBO_DATA_ROOM_SIZE as a u16 constant (9344 = 9216 + 128) with
a const assertion that catches overflow at compile time. Removes the
`as u16` cast that could silently truncate.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
… IMDS

The deploy message, results summary, and report JSON all had hardcoded
"c5n.2xlarge". Now queries the actual instance type from IMDS after SSM
is ready, so it correctly reflects whatever instance type the CDK stack
deploys.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Query the port's reported line rate from TRex and skip rate steps that
would exceed 95% of it. This avoids the "Expected L1 B/W exceeds port
line rate" error without using force=True.

For 8500B packets on ENA (reports 16 Gbps): max ~228K PPS.
Rate steps above that are skipped with a clear message.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
TRex benchmark:
- Use force=True to bypass ENA's false 16 Gbps line rate report
- Cap PPS for jumbo frames (>1500B) to stay under 30 Gbps instance
  bandwidth — standard packets keep all rate steps uncapped
- Configurable via --bandwidth-cap-gbps (default 30)

DPDK jumbo echo fix:
- Auto-detect interface MTU from /sys/class/net/<iface>/mtu during
  routing table initialization. On AWS ENA this reads 9001, so
  send_to() no longer rejects jumbo payloads as "too large"
- Also parse MTU column from /proc/net/route as a first source

Root cause of rust-dpdk 100% drop at 8500B: the routing table defaulted
to MTU 1500, so send_to() rejected the 8458-byte echo payload.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Integration tests:
- Add --payload-size flag to test-client for binary jumbo payloads
- Increase test-client recv buffer from 1024 to 10000 bytes
- Add tier1 test 5 (jumbo_diagnostics): dumps interface MTU, route
  table MTU column, and echo server config to CI logs
- Add tier1 test 6 (jumbo_echo_8000): sends 8000B payload, verifies
  echoed response matches size

Echo server:
- Print MTU and max_udp_payload at startup for diagnostics

Routing:
- Auto-detect interface MTU from /sys/class/net/<iface>/mtu
- Parse MTU column from /proc/net/route

Perf tests:
- Fix instance_type in results (use env var, not unexpanded shell var)
- Cap jumbo PPS to 30 Gbps bandwidth limit, use force=True for TRex

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Root cause: when the DPDK ENI is bound to vfio-pci, it has no kernel
interface, so auto_detect_routing() can't read its MTU from sysfs or
/proc/net/route. The routing table defaults to MTU 1500, causing
send_to() to reject jumbo payloads with "Payload too large: max 1472".

Fix: after auto-detection, if we're on a DPDK backend, override the
routing table MTU to 9001 to match the port's rxmode.mtu configuration.

Confirmed by integration test diagnostics:
- Echo server (receiver): MTU=9001, max_udp_payload=8973 ← correct
- Test client (sender): "Payload too large: max 1472, got 8000" ← bug

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
The three build_udp_* functions had a hardcoded MAX_UDP_PAYLOAD (1472)
check that rejected jumbo payloads even when the routing table allowed
them. Changed to use MAX_FRAME_SIZE - TOTAL_HEADER_LEN (8973 bytes)
as the absolute maximum, matching the jumbo MTU 9001 configuration.

The routing table's max_udp_payload() in send_to_addr() remains the
authoritative per-socket MTU guard; the build functions are now just
a safety net for the absolute frame size limit.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
Enable ENA Express (Scalable Reliable Datagram) on all data plane ENIs
in the perf test CDK stack. This raises the single-flow UDP throughput
limit from 5 Gbps to 25 Gbps on c6in instances.

Previous results showed rust-dpdk and native-dpdk hitting the exact
same ~5.3 Gbps ceiling at 8500B — confirmed as ENA's single-flow cap.

Also add a placeholder workflow for future multi-flow perf tests.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
… it)

The CfnNetworkInterfaceProps type doesn't have enaSrdSpecification yet.
Use addPropertyOverride to set EnaSrdSpecification directly on the
CloudFormation resource. Verified via cdk synth — all 3 data plane ENIs
(TRex TX, TRex RX, DUT) have ENA Express enabled.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
…tion

CloudFormation's AWS::EC2::NetworkInterface doesn't support
EnaSrdSpecification. Instead, enable ENA Express after stack deploy
using `aws ec2 modify-network-interface-attribute --ena-srd-specification`
on all 3 data plane ENIs (TRex TX, TRex RX, DUT).

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
c6in.xlarge had only 6.25 Gbps baseline — sustained 30s tests exhausted
burst credits and settled to baseline. c6in.8xlarge has 50 Gbps sustained
baseline with ENA Express support, enough to show the real jumbo frame
throughput advantage.

Also bump bandwidth cap from 30 to 50 Gbps to match.

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
ENA Express (SRD) requires MTU <= 8900 bytes per AWS documentation
(amzn-ec2-ena-utilities/check-ena-express-settings.sh). Our jumbo MTU
9001 exceeds this limit, which caused 90%+ packet drops on c6in.8xlarge.

Reverting to c6in.xlarge without ENA Express:
- Remove ENA Express post-deploy enablement from run-perf-tests.sh
- Revert instance type from c6in.8xlarge to c6in.xlarge
- Revert bandwidth cap from 50 to 30 Gbps

Proven single-flow results on c6in.xlarge:
- rust-dpdk matches native-dpdk within 1% at all packet sizes
- 8500B jumbo: ~5.3 Gbps (ENA single-flow cap, not our stack)
- 1400B: ~7.8 Gbps at 700K PPS with <0.5% drop

Future work for higher bandwidth:
- Multi-flow tests (separate workflow placeholder created)
- ENA Express with MTU <= 8900 on c6in.8xlarge+

https://claude.ai/code/session_01294ECCWxYiENcnK5HVVyoL
RX path: verify IPv4 header and UDP checksums in software on every
received packet. Corrupted packets are dropped before reaching the
application. Handles UDP checksum-disabled (0) per RFC 768. Validation
runs in both the inline recv path and the pipeline worker loop.

TX path: when the NIC supports hardware checksum offload (e.g., ENA),
the DPDK backend sets mbuf ol_flags (RTE_MBUF_F_TX_IP_CKSUM,
RTE_MBUF_F_TX_UDP_CKSUM) and writes a pseudo-header checksum so the
NIC computes final checksums. Falls back to software checksums on NICs
without offload or non-DPDK backends.

Changes:
- dpdk-sys: add RTE_MBUF_F_TX/RX offload flag constants
- dpdk: add ol_flags/tx_offload accessors on Mbuf wrapper
- dpdk-udp: add verify_ipv4_checksum, verify_udp_checksum,
  udp_pseudo_header_checksum functions; enable checksum offloads in
  port config; apply TX offload in DPDK send path; validate RX
  checksums in process_frame_zerocopy and worker_loop
- 10 new unit tests covering validation, corruption, and offload fields

https://claude.ai/code/session_01FDpfLChZCtgFqko3oX96e8
…-jumbo-frames-rZQcl

# Conflicts:
#	dpdk-udp/src/lib.rs
In real DPDK, tx_offload lives inside an anonymous union in rte_mbuf.
Bindgen represents this as __bindgen_anon_N.tx_offload rather than a
direct field, so (*mbuf).tx_offload fails to compile with real DPDK.

Add dpdk_shim_set/get_mbuf_tx_offload() C wrappers and corresponding
Rust shim/stub functions so the access is portable across both paths.

https://claude.ai/code/session_01FDpfLChZCtgFqko3oX96e8
These are #define macros in rte_mbuf_core.h that bindgen cannot capture.
Without them, the TX offload and RX validation code fails to compile
when building with --features dpdk-sys/bindgen on real DPDK systems.

https://claude.ai/code/session_01FDpfLChZCtgFqko3oX96e8
The test was reading tx_offload via direct field access which fails
with real DPDK bindgen bindings. Use mbuf_get_tx_offload() shim instead.

https://claude.ai/code/session_01FDpfLChZCtgFqko3oX96e8
@github-actions

Copy link
Copy Markdown

[CI] Stage: Deploy

Infrastructure ready.

  • Sender: i-0fffcd3ea345e7686 (DPDK ENI: 10.0.1.203)
  • Receiver: i-03be757c112047c2c (DPDK ENI: 10.0.1.234)
  • Both instances SSM-ready.

@github-actions

Copy link
Copy Markdown

[CI] Stage: Summary

All tests PASSED.

ARP seeding: kernel /proc/net/arp (automatic)

  • tier1-dpdk-echo: 6 tests, 0 failures
  • tier2-kernel-interop: 4 tests, 0 failures
  • tier3-iperf-interop: 1 tests, 0 failures
  • tier3-iperf-interop: 1 tests, 0 failures

@github-actions

Copy link
Copy Markdown

✅ Integration Tests Passed (Run 24271256698)

Branch: 32/merge | Commit: a0764c30

Test Results

  • tier1-dpdk-echo.xml: 6 tests, 0 failures, skipped
  • tier2-kernel-interop.xml: 4 tests, 0 failures, skipped
  • tier3-iperf-sends.xml: 1 tests, 0 failures, skipped
  • tier3-our-app-sends.xml: 1 tests, 0 failures, skipped

Application Logs (last 20 lines)

receiver-echo-server.log

EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.234:9000 (MAC: 02:d2:81:29:0f:e9)
echo listening on 10.0.1.234:9000 (MTU=9001, max_udp_payload=8973)
Shutting down gracefully...

sender-echo-server.log

EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.203:9000 (MAC: 02:d7:6b:cc:32:1f)
echo listening on 10.0.1.203:9000 (MTU=9001, max_udp_payload=8973)
Shutting down gracefully...

sender-test-client.log

EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
TELEMETRY: No legacy callbacks, legacy socket not created
DPDK bind failed (Port init failed: Invalid port ID: 0), falling back to tokio
Backend: tokio
Sending packets...
Sent 12 bytes: 'arp-probe #1'
Received 12 bytes from 10.0.1.234:9000: 'arp-probe #1'
Test complete
[2026-04-11T01:29:07Z] INFO: ARP resolution succeeded (got response from peer)
[2026-04-11T01:29:07Z] INFO: Test: udp_send_receive
[2026-04-11T01:29:08Z] INFO: UDP send/receive succeeded
[2026-04-11T01:29:08Z] INFO: Test: echo_roundtrip
[2026-04-11T01:29:09Z] INFO: Echo roundtrip succeeded: 5/5 responses received
[2026-04-11T01:29:09Z] INFO: Test: payload_integrity
[2026-04-11T01:29:09Z] INFO: Response received, checking payload match...
[2026-04-11T01:29:09Z] INFO: Payload integrity verified (found in response)
[2026-04-11T01:29:09Z] INFO: JUnit XML written to: /tmp/test-results/tier2-kernel-interop.xml
[2026-04-11T01:29:09Z] INFO: Tier 2 sender tests complete. Results: /tmp/test-results/tier2-kernel-interop.xml

receiver-test-client-iperf.log

[2026-04-11T01:36:08Z] INFO: iperf-sends: sent 10 packets, received 10 responses
[2026-04-11T01:36:08Z] INFO: iperf-sends: PASS (sent >= 5 packets)
[2026-04-11T01:36:08Z] INFO: JUnit XML written to: /tmp/test-results/tier3-iperf-sends.xml
[2026-04-11T01:36:08Z] INFO: iperf-sends test complete

sender-test-client-iperf.log

Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #3'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #4'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #4'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #5'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #5'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #6'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #6'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #7'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #7'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #8'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #8'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #9'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #9'
Sent 31 bytes: 'dpdk-to-kernel-test-payload #10'
Received 31 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #10'
Test complete
[2026-04-11T01:35:08Z] INFO: our-app-sends: sent 10 packets, received 10 responses
[2026-04-11T01:35:08Z] INFO: our-app-sends: PASS (sent >= 5 packets)
[2026-04-11T01:35:08Z] INFO: JUnit XML written to: /tmp/test-results/tier3-our-app-sends.xml
[2026-04-11T01:35:08Z] INFO: our-app-sends test complete
Full Application Logs (last 200 lines each)

receiver-echo-server.log

EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.234:9000 (MAC: 02:d2:81:29:0f:e9)
echo listening on 10.0.1.234:9000 (MTU=9001, max_udp_payload=8973)
Shutting down gracefully...

sender-echo-server.log

EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.203:9000 (MAC: 02:d7:6b:cc:32:1f)
echo listening on 10.0.1.203:9000 (MTU=9001, max_udp_payload=8973)
Shutting down gracefully...

sender-test-client.log

[2026-04-11T01:24:29Z] INFO: Test: arp_resolution
UDP Test Client
Target: 10.0.1.234:9000
Bind address: 10.0.1.203:0
Message: 'arp-probe'
Count: 1
EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.203:32768 (MAC: 02:d7:6b:cc:32:1f)
Backend: dpdk
Sending packets...
Sent 12 bytes: 'arp-probe #1'
Received 12 bytes from 10.0.1.234:9000: 'arp-probe #1'
Test complete
[2026-04-11T01:24:29Z] INFO: ARP resolution succeeded (got response from peer)
[2026-04-11T01:24:29Z] INFO: Test: udp_send_receive
[2026-04-11T01:24:31Z] INFO: UDP send/receive succeeded
[2026-04-11T01:24:31Z] INFO: Test: echo_roundtrip
[2026-04-11T01:24:33Z] INFO: Echo roundtrip succeeded: 5/5 responses received
[2026-04-11T01:24:33Z] INFO: Test: payload_integrity
[2026-04-11T01:24:34Z] INFO: Response received, checking payload match...
[2026-04-11T01:24:34Z] INFO: Payload integrity verified (found in response)
[2026-04-11T01:24:34Z] INFO: Test: jumbo_diagnostics
[2026-04-11T01:24:34Z] INFO: === JUMBO FRAME DIAGNOSTICS ===
[2026-04-11T01:24:34Z] INFO: Interface MTU:
  9001
  65536
[2026-04-11T01:24:34Z] INFO:   ens5: MTU=9001
[2026-04-11T01:24:34Z] INFO:   lo: MTU=65536
[2026-04-11T01:24:34Z] INFO: Routing table MTU column:
Iface	Destination	Gateway 	Flags	RefCnt	Use	Metric	Mask		MTU	Window	IRTT                                                       
ens5	00000000	0101000A	0003	0	0	512	00000000	0	0	0                                                                             
ens5	0200000A	0101000A	0007	0	0	512	FFFFFFFF	0	0	0                                                                             
ens5	0001000A	00000000	0001	0	0	512	00FFFFFF	0	0	0                                                                             
ens5	0101000A	00000000	0005	0	0	512	FFFFFFFF	0	0	0                                                                             
[2026-04-11T01:24:34Z] INFO: DPDK port config (from echo server log):
[2026-04-11T01:24:34Z] INFO:   (no MTU info in echo log)
[2026-04-11T01:24:34Z] INFO: === END JUMBO DIAGNOSTICS ===
[2026-04-11T01:24:34Z] INFO: Test: jumbo_echo_8000
[2026-04-11T01:24:35Z] INFO: Jumbo output: UDP Test Client
Target: 10.0.1.234:9000
Bind address: 10.0.1.203:0
Payload size: 8000 bytes
Count: 3
EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.203:32768 (MAC: 02:d7:6b:cc:32:1f)
Backend: dpdk
Sending packets...
Sent 8000 bytes (binary payload)
Received 8000 bytes from 10.0.1.234:9000 (expected 8000, OK)
Sent 8000 bytes (binary payload)
Received 8000 bytes from 10.0.1.234:9000 (expected 8000, OK)
Sent 8000 bytes (binary payload)
Received 8000 bytes from 10.0.1.234:9000 (expected 8000, OK)
Test complete
[2026-04-11T01:24:35Z] INFO: Jumbo frame echo succeeded: 3/3 responses with correct size
[2026-04-11T01:24:35Z] INFO: JUnit XML written to: /tmp/test-results/tier1-dpdk-echo.xml
[2026-04-11T01:24:35Z] INFO: Tier 1 sender tests complete. Results: /tmp/test-results/tier1-dpdk-echo.xml
[2026-04-11T01:29:07Z] INFO: Test: arp_resolution
UDP Test Client
Target: 10.0.1.234:9000
Bind address: 0.0.0.0:0
Message: 'arp-probe'
Count: 1
EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
TELEMETRY: No legacy callbacks, legacy socket not created
DPDK bind failed (Port init failed: Invalid port ID: 0), falling back to tokio
Backend: tokio
Sending packets...
Sent 12 bytes: 'arp-probe #1'
Received 12 bytes from 10.0.1.234:9000: 'arp-probe #1'
Test complete
[2026-04-11T01:29:07Z] INFO: ARP resolution succeeded (got response from peer)
[2026-04-11T01:29:07Z] INFO: Test: udp_send_receive
[2026-04-11T01:29:08Z] INFO: UDP send/receive succeeded
[2026-04-11T01:29:08Z] INFO: Test: echo_roundtrip
[2026-04-11T01:29:09Z] INFO: Echo roundtrip succeeded: 5/5 responses received
[2026-04-11T01:29:09Z] INFO: Test: payload_integrity
[2026-04-11T01:29:09Z] INFO: Response received, checking payload match...
[2026-04-11T01:29:09Z] INFO: Payload integrity verified (found in response)
[2026-04-11T01:29:09Z] INFO: JUnit XML written to: /tmp/test-results/tier2-kernel-interop.xml
[2026-04-11T01:29:09Z] INFO: Tier 2 sender tests complete. Results: /tmp/test-results/tier2-kernel-interop.xml

receiver-test-client-iperf.log

[2026-04-11T01:36:08Z] INFO: iperf-sends: sent 10 packets, received 10 responses
[2026-04-11T01:36:08Z] INFO: iperf-sends: PASS (sent >= 5 packets)
[2026-04-11T01:36:08Z] INFO: JUnit XML written to: /tmp/test-results/tier3-iperf-sends.xml
[2026-04-11T01:36:08Z] INFO: iperf-sends test complete

sender-test-client-iperf.log

[2026-04-11T01:35:05Z] INFO: Pre-flight: checking DPDK state and ARP cache...
[2026-04-11T01:35:05Z] INFO: Local IP: 10.0.1.203, Peer IP: 10.0.1.234, Port: 9000
[2026-04-11T01:35:05Z] INFO: /proc/net/arp contents:
IP address       HW type     Flags       HW address            Mask     Device
10.0.1.234       0x1         0x2         02:d2:81:29:0f:e9     *        ens5
10.0.1.116       0x1         0x2         02:05:6a:9c:91:cd     *        ens5
10.0.1.1         0x1         0x2         02:f0:7f:3f:cb:0b     *        ens5
10.0.1.6         0x1         0x2         02:18:1e:f2:d2:5f     *        ens5
10.0.1.203       0x1         0x2         02:d7:6b:cc:32:1f     *        ens5
[2026-04-11T01:35:05Z] INFO: DPDK runtime state:
No /var/run/dpdk/ directory
[2026-04-11T01:35:05Z] INFO: vfio-pci bindings:
0000:00:06.0
bind
module
new_id
remove_id
uevent
unbind
[2026-04-11T01:35:05Z] INFO: Test binary: /opt/dpdk-stdlib/target/release/test-client
-rwxr-xr-x. 2 root root 1889560 Apr 11 01:22 /opt/dpdk-stdlib/target/release/test-client
[2026-04-11T01:35:05Z] INFO: Launching test-client: /opt/dpdk-stdlib/target/release/test-client --target 10.0.1.234 --port 9000 --bind-ip 10.0.1.203 --count 10 --delay 200
[2026-04-11T01:35:08Z] INFO: Test client output: UDP Test Client
Target: 10.0.1.234:9000
Bind address: 10.0.1.203:0
Message: 'dpdk-to-kernel-test-payload'
Count: 10
EAL: Detected CPU lcores: 2
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: VFIO support initialized
EAL: Using IOMMU type 8 (No-IOMMU)
EAL: Probe PCI driver: net_ena (1d0f:ec20) device: 0000:00:06.0 (socket -1)
TELEMETRY: No legacy callbacks, legacy socket not created
✅ DPDK UDP socket bound to 10.0.1.203:32768 (MAC: 02:d7:6b:cc:32:1f)
Backend: dpdk
Sending packets...
Sent 30 bytes: 'dpdk-to-kernel-test-payload #1'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #1'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #2'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #2'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #3'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #3'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #4'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #4'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #5'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #5'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #6'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #6'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #7'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #7'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #8'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #8'
Sent 30 bytes: 'dpdk-to-kernel-test-payload #9'
Received 30 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #9'
Sent 31 bytes: 'dpdk-to-kernel-test-payload #10'
Received 31 bytes from 10.0.1.234:9000: 'dpdk-to-kernel-test-payload #10'
Test complete
[2026-04-11T01:35:08Z] INFO: our-app-sends: sent 10 packets, received 10 responses
[2026-04-11T01:35:08Z] INFO: our-app-sends: PASS (sent >= 5 packets)
[2026-04-11T01:35:08Z] INFO: JUnit XML written to: /tmp/test-results/tier3-our-app-sends.xml
[2026-04-11T01:35:08Z] INFO: our-app-sends test complete
⚠️ SSM Command Failures (receiver-ssm-failure.log)
=== Polling timeout after 30s ===
Status: InProgress
Instance: i-03be757c112047c2c (receiver)
Command ID: ad6ca06a-4041-4faa-8758-f48ed2ceef57

=== STDOUT ===


=== STDERR ===


=== Polling timeout after 30s ===
Status: InProgress
Instance: i-03be757c112047c2c (receiver)
Command ID: 95302367-4792-4504-bedc-2b9f6e03ed43

=== STDOUT ===


=== STDERR ===


=== Polling timeout after 30s ===
Status: InProgress
Instance: i-03be757c112047c2c (receiver)
Command ID: ececcaad-5229-4db9-954e-68a73943335d

=== STDOUT ===


=== STDERR ===


⚠️ SSM Command Failures (sender-ssm-failure.log)
=== Polling timeout 120s (SSM timeout: 90s, command: cd /opt/dpdk-stdlib && bash scripts/integration-tests/configure-eni.sh --action unbind && bash scripts/integration-tests/configure-eni.sh --action assign-ip --ip 10.0.1.203) ===
Status: InProgress
Instance: i-0fffcd3ea345e7686 (sender)
Command ID: 97cd42b0-4f34-425b-8f48-f8ef2b812e0c

=== STDOUT ===


=== STDERR ===


=== Polling timeout after 30s ===
Status: InProgress
Instance: i-0fffcd3ea345e7686 (sender)
Command ID: 3248b4f6-e180-405f-bdee-37957d574b00

=== STDOUT ===


=== STDERR ===


Network & PCI State

receiver-network-interfaces.log

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:07:18:97:c0:f9 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname eni-0c8976388bd7a289d
    altname device-number-0.0
    inet 10.0.1.47/24 metric 512 brd 10.0.1.255 scope global dynamic ens5
       valid_lft 2441sec preferred_lft 2441sec
    inet6 fe80::7:18ff:fe97:c0f9/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
5: ens6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:d2:81:29:0f:e9 brd ff:ff:ff:ff:ff:ff
    altname enp0s6
    altname eni-0721e877094cecf68
    altname device-number-1.0
    inet 10.0.1.234/24 brd 10.0.1.255 scope global ens6
       valid_lft forever preferred_lft forever
    inet6 fe80::d2:81ff:fe29:fe9/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

sender-network-interfaces.log

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:ad:98:e4:29:15 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname eni-05604f713e022e65c
    altname device-number-0.0
    inet 10.0.1.54/24 metric 512 brd 10.0.1.255 scope global dynamic ens5
       valid_lft 2464sec preferred_lft 2464sec
    inet6 fe80::ad:98ff:fee4:2915/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

receiver-networking-diag-baseline.txt

=== NETWORKING DIAGNOSTICS ===
timestamp: 2026-04-11T01:23:49Z
hostname: ip-10-0-1-47.ec2.internal
kernel: 6.18.16-18.222.amzn2023.x86_64

=== DPDK PORT STATUS ===

Network devices using DPDK-compatible driver
============================================
0000:00:06.0 'Elastic Network Adapter (ENA) ec20' drv=vfio-pci unused=ena

Network devices using kernel driver
===================================
0000:00:05.0 'Elastic Network Adapter (ENA) ec20' if=ens5 drv=ena unused=vfio-pci *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'DMA' devices detected
=========================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

No 'Regex' devices detected
===========================

=== IP ADDRESSES ===
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:07:18:97:c0:f9 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname eni-0c8976388bd7a289d
    altname device-number-0.0
    inet 10.0.1.47/24 metric 512 brd 10.0.1.255 scope global dynamic ens5
       valid_lft 3299sec preferred_lft 3299sec
    inet6 fe80::7:18ff:fe97:c0f9/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

=== ARP TABLE ===
10.0.1.1 dev ens5 lladdr 02:f0:7f:3f:cb:0b REACHABLE 
10.0.1.6 dev ens5 lladdr 02:18:1e:f2:d2:5f REACHABLE 
10.0.1.116 dev ens5 lladdr 02:05:6a:9c:91:cd REACHABLE 

=== ROUTE TABLE ===
default via 10.0.1.1 dev ens5 proto dhcp src 10.0.1.47 metric 512 
10.0.0.2 via 10.0.1.1 dev ens5 proto dhcp src 10.0.1.47 metric 512 
10.0.1.0/24 dev ens5 proto kernel scope link src 10.0.1.47 metric 512 
10.0.1.1 dev ens5 proto dhcp scope link src 10.0.1.47 metric 512 

=== IMDS: ENI INFORMATION ===
ENI MACs found: 02:07:18:97:c0:f9/ 02:d2:81:29:0f:e9/ 

--- ENI: 02:07:18:97:c0:f9/ ---
  device-number: 0
  local-ipv4s: 10.0.1.47
  subnet-id: subnet-01b7df9f614c9e994
  subnet-cidr: 10.0.1.0/24

--- ENI: 02:d2:81:29:0f:e9/ ---
  device-number: 1
  local-ipv4s: 10.0.1.234
  subnet-id: subnet-01b7df9f614c9e994
  subnet-cidr: 10.0.1.0/24


=== GATEWAY ARP TEST ===
Gateway IP: 10.0.1.1
Gateway ARP entry:
10.0.1.1 dev ens5 lladdr 02:f0:7f:3f:cb:0b REACHABLE 

arping result:
ARPING 10.0.1.1 from 10.0.1.47 ens5
Unicast reply from 10.0.1.1 [02:F0:7F:3F:CB:0B]  0.533ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

=== HUGEPAGE STATUS ===
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:     14336 kB
HugePages_Total:    1024
HugePages_Free:     1024
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:         2097152 kB

=== VFIO STATUS ===
total 0
drwxr-xr-x.  2 root root       80 Apr 11 01:23 .
drwxr-xr-x. 14 root root     3100 Apr 11 01:22 ..
crw-------.  1 root root 243,   0 Apr 11 01:23 noiommu-0
crw-rw-rw-.  1 root root  10, 196 Apr 11 01:18 vfio

noiommu mode:
Y

=== DPDK SHARED MEMORY ===
no /var/run/dpdk/ directory (clean state)

=== DPDK-RELATED DMESG (last 30 lines) ===
[    0.052979] printk: legacy console [ttyS0] enabled
[    0.054079] x2apic enabled
[    0.058765] mitigations: Enabled attack vectors: user_kernel, user_user, guest_host, guest_guest, SMT mitigations: auto
[    0.058879] x86/fpu: Enabled xstate features 0x2ff, context size is 2568 bytes, using 'compacted' format.
[    0.068463] audit: type=2000 audit(1775870323.950:1): state=initialized audit_enabled=0 res=1
[    0.070496] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    0.133029] ACPI: Interpreter enabled
[    0.133029] ACPI: Enabled 2 GPEs in block 00 to 0F
[    0.147106] pci 0000:00:05.0: enabling Extended Tags
[    0.223909] SGI XFS with ACLs, security attributes, quota, no debug enabled
[    0.239387] ACPI: \_SB_.LNKD: Enabled at IRQ 11
[    0.245366] IPI shorthand broadcast: enabled
[    2.125973] systemd[1]: Mounting dev-hugepages.mount - Huge Pages File System...
[    2.167107] systemd[1]: Mounted dev-hugepages.mount - Huge Pages File System.
[    2.240618] VFIO - User Level meta-driver version: 0.3
[    2.591621] ena 0000:00:05.0: Elastic Network Adapter (ENA) v2.16.1g
[    2.603519] ena 0000:00:05.0: ENA device version: 0.10
[    2.604232] ena 0000:00:05.0: ENA controller version: 0.0.1 implementation version 1
[    2.715025] ena 0000:00:05.0: ENA Large LLQ is disabled
[    2.728126] ena 0000:00:05.0: Elastic Network Adapter (ENA) found at mem c0500000, mac addr 02:07:18:97:c0:f9
[    2.778350] ena 0000:00:05.0 ens5: renamed from eth0
[  230.870747] pci 0000:00:06.0: enabling Extended Tags
[  230.874782] ena 0000:00:06.0: enabling device (0000 -> 0002)
[  230.883791] ena 0000:00:06.0: ENA device version: 0.10
[  230.884593] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  230.983768] ena 0000:00:06.0: ENA Large LLQ is disabled
[  230.995563] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d2:81:29:0f:e9
[  231.002657] ena 0000:00:06.0 ens6: renamed from eth0
[  292.133667] vfio-pci 0000:00:06.0: Adding to iommu group 0
[  292.135055] vfio-pci 0000:00:06.0: Adding kernel taint for vfio-noiommu group on device

=== DPDK-RELATED PROCESSES ===
no DPDK processes running

=== END DIAGNOSTICS ===

sender-networking-diag-baseline.txt

=== NETWORKING DIAGNOSTICS ===
timestamp: 2026-04-11T01:23:41Z
hostname: ip-10-0-1-54.ec2.internal
kernel: 6.18.16-18.222.amzn2023.x86_64

=== DPDK PORT STATUS ===

Network devices using DPDK-compatible driver
============================================
0000:00:06.0 'Elastic Network Adapter (ENA) ec20' drv=vfio-pci unused=ena

Network devices using kernel driver
===================================
0000:00:05.0 'Elastic Network Adapter (ENA) ec20' if=ens5 drv=ena unused=vfio-pci *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'DMA' devices detected
=========================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

No 'Regex' devices detected
===========================

=== IP ADDRESSES ===
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:ad:98:e4:29:15 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname eni-05604f713e022e65c
    altname device-number-0.0
    inet 10.0.1.54/24 metric 512 brd 10.0.1.255 scope global dynamic ens5
       valid_lft 3308sec preferred_lft 3308sec
    inet6 fe80::ad:98ff:fee4:2915/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

=== ARP TABLE ===
10.0.1.116 dev ens5 lladdr 02:05:6a:9c:91:cd REACHABLE 
10.0.1.1 dev ens5 lladdr 02:f0:7f:3f:cb:0b REACHABLE 

=== ROUTE TABLE ===
default via 10.0.1.1 dev ens5 proto dhcp src 10.0.1.54 metric 512 
10.0.0.2 via 10.0.1.1 dev ens5 proto dhcp src 10.0.1.54 metric 512 
10.0.1.0/24 dev ens5 proto kernel scope link src 10.0.1.54 metric 512 
10.0.1.1 dev ens5 proto dhcp scope link src 10.0.1.54 metric 512 

=== IMDS: ENI INFORMATION ===
ENI MACs found: 02:ad:98:e4:29:15/ 02:d7:6b:cc:32:1f/ 

--- ENI: 02:ad:98:e4:29:15/ ---
  device-number: 0
  local-ipv4s: 10.0.1.54
  subnet-id: subnet-01b7df9f614c9e994
  subnet-cidr: 10.0.1.0/24

--- ENI: 02:d7:6b:cc:32:1f/ ---
  device-number: 1
  local-ipv4s: 10.0.1.203
  subnet-id: subnet-01b7df9f614c9e994
  subnet-cidr: 10.0.1.0/24


=== GATEWAY ARP TEST ===
Gateway IP: 10.0.1.1
Gateway ARP entry:
10.0.1.1 dev ens5 lladdr 02:f0:7f:3f:cb:0b REACHABLE 

arping result:
ARPING 10.0.1.1 from 10.0.1.54 ens5
Unicast reply from 10.0.1.1 [02:F0:7F:3F:CB:0B]  0.537ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

=== HUGEPAGE STATUS ===
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:     14336 kB
HugePages_Total:    1024
HugePages_Free:     1024
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:         2097152 kB

=== VFIO STATUS ===
total 0
drwxr-xr-x.  2 root root       80 Apr 11 01:23 .
drwxr-xr-x. 14 root root     3100 Apr 11 01:22 ..
crw-------.  1 root root 243,   0 Apr 11 01:23 noiommu-0
crw-rw-rw-.  1 root root  10, 196 Apr 11 01:18 vfio

noiommu mode:
Y

=== DPDK SHARED MEMORY ===
no /var/run/dpdk/ directory (clean state)

=== DPDK-RELATED DMESG (last 30 lines) ===
[    0.053285] printk: legacy console [ttyS0] enabled
[    0.054397] x2apic enabled
[    0.059261] mitigations: Enabled attack vectors: user_kernel, user_user, guest_host, guest_guest, SMT mitigations: auto
[    0.059385] x86/fpu: Enabled xstate features 0x2ff, context size is 2568 bytes, using 'compacted' format.
[    0.068817] audit: type=2000 audit(1775870323.680:1): state=initialized audit_enabled=0 res=1
[    0.070841] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    0.132332] ACPI: Interpreter enabled
[    0.132332] ACPI: Enabled 2 GPEs in block 00 to 0F
[    0.147007] pci 0000:00:05.0: enabling Extended Tags
[    0.223291] SGI XFS with ACLs, security attributes, quota, no debug enabled
[    0.247308] ACPI: \_SB_.LNKD: Enabled at IRQ 11
[    0.255417] IPI shorthand broadcast: enabled
[    3.248037] systemd[1]: Mounting dev-hugepages.mount - Huge Pages File System...
[    3.282706] systemd[1]: Mounted dev-hugepages.mount - Huge Pages File System.
[    3.381403] VFIO - User Level meta-driver version: 0.3
[    3.733246] ena 0000:00:05.0: Elastic Network Adapter (ENA) v2.16.1g
[    3.757882] ena 0000:00:05.0: ENA device version: 0.10
[    3.758643] ena 0000:00:05.0: ENA controller version: 0.0.1 implementation version 1
[    3.855050] ena 0000:00:05.0: ENA Large LLQ is disabled
[    3.867212] ena 0000:00:05.0: Elastic Network Adapter (ENA) found at mem c0500000, mac addr 02:ad:98:e4:29:15
[    3.883366] ena 0000:00:05.0 ens5: renamed from eth0
[  250.938352] pci 0000:00:06.0: enabling Extended Tags
[  250.942503] ena 0000:00:06.0: enabling device (0000 -> 0002)
[  250.955387] ena 0000:00:06.0: ENA device version: 0.10
[  250.956166] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  251.055737] ena 0000:00:06.0: ENA Large LLQ is disabled
[  251.067928] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d7:6b:cc:32:1f
[  251.075231] ena 0000:00:06.0 ens6: renamed from eth0
[  285.539961] vfio-pci 0000:00:06.0: Adding to iommu group 0
[  285.541433] vfio-pci 0000:00:06.0: Adding kernel taint for vfio-noiommu group on device

=== DPDK-RELATED PROCESSES ===
no DPDK processes running

=== END DIAGNOSTICS ===
⚠️ Crash Diagnostics

receiver-dmesg-crashes.log

[    0.067839] pid_max: default: 32768 minimum: 301
[    0.151006] iommu: Default domain type: Translated
[    0.151032] NetLabel:  unlabeled traffic allowed by default
[    0.187787] PCI: CLS 0 bytes, default 64
[    0.263302] nvme nvme0: 2/0/0 default/read/poll queues
[    0.412243] systemd[1]: systemd 252.23-11.amzn2023 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP -GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB -ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[    0.412367] systemd[1]: No hostname configured, using default hostname.
[    0.476433] systemd[1]: Queued start job for default target initrd.target.
[    1.564635] systemd[1]: systemd 252.23-11.amzn2023 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP -GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB -ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[  329.666371] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:4201)
[  607.734770] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:4682)

sender-dmesg-crashes.log

[    0.068166] pid_max: default: 32768 minimum: 301
[    0.151057] iommu: Default domain type: Translated
[    0.151085] NetLabel:  unlabeled traffic allowed by default
[    0.190642] PCI: CLS 0 bytes, default 64
[    0.268098] nvme nvme0: 2/0/0 default/read/poll queues
[    0.402673] systemd[1]: systemd 252.23-11.amzn2023 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP -GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB -ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[    0.402798] systemd[1]: No hostname configured, using default hostname.
[    0.469415] systemd[1]: Queued start job for default target initrd.target.
[    2.762518] systemd[1]: systemd 252.23-11.amzn2023 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP -GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB -ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[ 1027.131282] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:5473)
Kernel Console (dmesg)

receiver-console-output.log (PCI/driver events only)

[  230.884593] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  230.983768] ena 0000:00:06.0: ENA Large LLQ is disabled
[  230.995563] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d2:81:29:0f:e9
[  231.002657] ena 0000:00:06.0 ens6: renamed from eth0
[  292.133667] vfio-pci 0000:00:06.0: Adding to iommu group 0
[  292.135055] vfio-pci 0000:00:06.0: Adding kernel taint for vfio-noiommu group on device
[  329.449965] vfio-pci 0000:00:06.0: resetting
[  329.664765] vfio-pci 0000:00:06.0: reset done
[  329.666371] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:4201)
[  329.667924] vfio-pci 0000:00:06.0: resetting
[  329.884609] vfio-pci 0000:00:06.0: reset done
[  410.956848] vfio-pci 0000:00:06.0: Removing from iommu group 0
[  411.969761] ena 0000:00:06.0: ENA device version: 0.10
[  411.970541] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  412.071744] ena 0000:00:06.0: ENA Large LLQ is disabled
[  412.084388] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d2:81:29:0f:e9
[  412.097003] ena 0000:00:06.0 ens6: renamed from eth0 (while UP)
[  431.716198] vfio-pci 0000:00:06.0: Adding to iommu group 0
[  431.717615] vfio-pci 0000:00:06.0: Adding kernel taint for vfio-noiommu group on device
[  607.521550] vfio-pci 0000:00:06.0: resetting
[  607.733150] vfio-pci 0000:00:06.0: reset done
[  607.734770] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:4682)
[  607.736282] vfio-pci 0000:00:06.0: resetting
[  607.952991] vfio-pci 0000:00:06.0: reset done
[  683.214802] vfio-pci 0000:00:06.0: Removing from iommu group 0
[  684.227865] ena 0000:00:06.0: ENA device version: 0.10
[  684.228639] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  684.329848] ena 0000:00:06.0: ENA Large LLQ is disabled
[  684.342475] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d2:81:29:0f:e9
[  684.353400] ena 0000:00:06.0 ens6: renamed from eth0 (while UP)

sender-console-output.log (PCI/driver events only)

[  348.370983] vfio-pci 0000:00:06.0: resetting
[  348.587605] vfio-pci 0000:00:06.0: reset done
[  349.757643] vfio-pci 0000:00:06.0: resetting
[  349.987670] vfio-pci 0000:00:06.0: reset done
[  349.989277] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (tokio-rt-worker:4271)
[  349.990933] vfio-pci 0000:00:06.0: resetting
[  350.207631] vfio-pci 0000:00:06.0: reset done
[  350.551537] vfio-pci 0000:00:06.0: resetting
[  350.767669] vfio-pci 0000:00:06.0: reset done
[  350.769287] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (tokio-rt-worker:4376)
[  350.770995] vfio-pci 0000:00:06.0: resetting
[  350.997621] vfio-pci 0000:00:06.0: reset done
[  401.237324] vfio-pci 0000:00:06.0: Removing from iommu group 0
[  402.246177] ena 0000:00:06.0: ENA device version: 0.10
[  402.246954] ena 0000:00:06.0: ENA controller version: 0.0.1 implementation version 1
[  402.346155] ena 0000:00:06.0: ENA Large LLQ is disabled
[  402.358268] ena 0000:00:06.0: Elastic Network Adapter (ENA) found at mem c0508000, mac addr 02:d7:6b:cc:32:1f
[  402.366454] ena 0000:00:06.0 ens6: renamed from eth0
[  704.557868] vfio-pci 0000:00:06.0: Adding to iommu group 0
[  704.559158] vfio-pci 0000:00:06.0: Adding kernel taint for vfio-noiommu group on device
[  981.998970] vfio-pci 0000:00:06.0: resetting
[  982.219506] vfio-pci 0000:00:06.0: reset done
[  982.221108] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (tokio-rt-worker:5383)
[  982.222864] vfio-pci 0000:00:06.0: resetting
[  982.439376] vfio-pci 0000:00:06.0: reset done
[ 1026.913301] vfio-pci 0000:00:06.0: resetting
[ 1027.129651] vfio-pci 0000:00:06.0: reset done
[ 1027.131282] vfio-pci 0000:00:06.0: vfio-noiommu device opened by user (echo:5473)
[ 1027.132835] vfio-pci 0000:00:06.0: resetting
[ 1027.349506] vfio-pci 0000:00:06.0: reset done

@gspivey
gspivey merged commit 9a42e41 into main Apr 11, 2026
8 checks passed
@gspivey
gspivey deleted the claude/review-roadmap-jumbo-frames-rZQcl branch April 11, 2026 01:49
gspivey pushed a commit that referenced this pull request Apr 12, 2026
…test

Add full 802.1Q VLAN support to the socket layer:

- VlanConfig type with VLAN ID (0-4094), PCP priority (0-7), DEI
- build_udp_frame_into_vlan() for VLAN-tagged frame construction
- parse_udp_packet/parse_udp_packet_ref transparently handle VLAN tags
- verify_ipv4_checksum/verify_udp_checksum work on VLAN-tagged frames
- process_frame_zerocopy dispatches ARP/ICMP/UDP correctly for tagged frames
- ARP and ICMP parsers handle VLAN-tagged frames via detect_vlan() helper
- Per-socket VLAN config via set_vlan()/vlan() and NetworkConfig::with_vlan()
- UdpSocketBuilder applies VLAN config from NetworkConfig
- 16 new unit tests covering build/parse/checksum/roundtrip/config

Also adds Tier 4 jumbo frame echo integration test that exercises the jumbo
frame feature (PR #32) with 1400/4000/8000-byte payloads on EC2.

https://claude.ai/code/session_01Tumf1bXMixEaMKzgLvcBbD
@gspivey gspivey mentioned this pull request Apr 12, 2026
2 of 4 tasks
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 pushed a commit that referenced this pull request Jun 6, 2026
- Append performance test results from GH Actions run 27059998412
- No regressions: rust-dpdk 697K RX at 700K PPS (0.4% drop),
  native-dpdk 699K RX (0.13% drop) — consistent with Run #32
- Mark roadmap item #6 (dpdk-stdlib-quic TX queue) complete with PR #70
gspivey pushed a commit that referenced this pull request Jun 18, 2026
gspivey pushed a commit that referenced this pull request Jun 19, 2026
- Append Run #50 to docs/perf-test-log.md (GH Actions run 27851557307)
- No performance regression vs Run #49
- Mark ROADMAP item #32 as complete (PR #96)
gspivey added a commit that referenced this pull request Jun 20, 2026
## ROADMAP Item #32

Implements the TRex TCP performance profile and benchmark runner (tasks
14.1–14.4 from `.kiro/specs/tcp-support/tasks.md`).

### Changes

1. **`scripts/perf-tests/trex/tcp_echo_profile.py`** — TRex ASTF
(Advanced Stateful) TCP echo profile. Generates TCP connections: client
sends payload, server echoes, teardown. Configurable payload size via
tunables.

2. **`scripts/perf-tests/trex/run_tcp_benchmark.py`** — TCP benchmark
runner covering four payload sizes (64/512/1400/65536 B). Collects:
   - P50/P90/P99 latency percentiles
   - CPS (connections per second)
   - Throughput (Mbps)
   - Retransmits, timeouts, connection drops
- Structured JSON output: `test_name, backend, metric_name,
metric_value, unit`

3. **`apps/plain-tcp-echo`** — Minimal kernel TCP echo server using
`std::net::TcpListener/TcpStream`. DUT baseline config
(`plain-rust-tcp`) for comparison against DPDK TCP paths.

4. **`scripts/perf-tests/tcp-dut-configs.md`** — Documents all TCP DUT
configurations (plain-rust-tcp, rust-dpdk-tcp, tokio-dpdk-tcp) and
benchmark parameters.

### Testing

- `cargo check --workspace` — passes
- `cargo test -p plain-tcp-echo` — passes (binary crate, no unit tests)
- `cargo test -p dpdk-stdlib-tcp` — all existing TCP tests pass (no
regressions)

### Tradeoffs

- TCP requires TRex ASTF mode (stateful) unlike UDP which uses STL
(stateless). The profile and runner are separate from the UDP
infrastructure because TRex exposes different APIs/metrics for ASTF.
- The `plain-tcp-echo` uses thread-per-connection with 64KB read buffer
— matching typical kernel server patterns for a fair baseline
comparison.

---------

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