Files
Johnathan Corgan 56d39f223b Add ECN congestion signaling and transport congestion detection
Implement hop-by-hop ECN congestion signaling through the FMP layer,
transport-level congestion detection via kernel drop counters, and
chaos harness integration for end-to-end validation.

FMP/session ECN plumbing:

- Thread ce_flag parsed at link layer through dispatch_link_message,
  handle_session_datagram, handle_session_payload, and
  handle_encrypted_session_msg to session delivery
- Replace hardcoded false in session-layer record_recv() with actual
  ce_flag, activating ecn_ce_count tracking in session MMP

ECN congestion detection and CE relay:

- Add EcnConfig (node.ecn.*) with configurable loss_threshold (5%)
  and etx_threshold (3.0) for transit congestion detection
- Add send_encrypted_link_message_with_ce() that ORs FLAG_CE into FMP
  header flags; original method delegates with ce_flag=false
- Compute outgoing_ce = incoming_ce || local congestion on next-hop
  link, enabling hop-by-hop CE relay through transit nodes

IPv6 ECN-CE marking:

- Mark ECN-CE (0b11) in IPv6 Traffic Class on received DataPackets
  before TUN delivery when FMP CE flag is set
- Only marks ECN-capable packets (ECT(0)/ECT(1)); Not-ECT packets
  unchanged per RFC 3168

Transport congestion abstraction and UDP kernel drop detection:

- Add TransportCongestion struct to transport layer for transport-
  agnostic local congestion indicators
- Replace tokio::UdpSocket with AsyncFd<socket2::Socket> using
  libc::recvmsg() with ancillary data parsing
- Enable SO_RXQ_OVFL for kernel receive buffer drop counter on every
  packet, wiring up previously-stubbed UdpStats.kernel_drops
- Add TransportDropState for per-transport delta tracking with 1s
  tick sampling via sample_transport_congestion()
- Extend detect_congestion() with transport kernel drop check
  alongside MMP loss metrics

Congestion monitoring and control:

- Add CongestionStats (ce_forwarded, ce_received, congestion_detected,
  kernel_drop_events) to NodeStats with snapshot serialization
- Wire counters into forwarding path, session handler, and transport
  drop sampling with rate-limited warn logging (5s interval)
- Expose congestion data in show_routing control query and
  ecn_ce_count in show_mmp peer entries
- Add congestion counters to fipstop routing tab in two-column layout

Chaos harness integration:

- Add query_routing(), query_transports(), snapshot_all_congestion()
  to chaos control module
- Add congestion/kernel-drop log analysis in logs module
- Add congestion-stress scenario: 10-node tree, 1 Mbps bandwidth,
  5-10% netem loss, heavy iperf3 traffic
- Add IngressConfig for tc ingress policing with per-peer policer
  filters simulating upstream bandwidth bottlenecks
- Add iperf3 JSON result capture to traffic manager for throughput
  measurement across scenarios
- Add ECN A/B test scenarios (ecn-ab-on/off.yaml) with ingress
  policing and comparison script
- Enable TCP ECN negotiation (tcp_ecn=1 sysctl) in container
  entrypoint for end-to-end CE propagation

Tests:

- 10 ECN unit/integration tests: mark_ipv6_ecn_ce variants, CE relay
  chain (3-node propagation), EcnConfig serde roundtrip
- 3 transport drop congestion detection unit tests

Documentation:

- Update fips-mesh-layer.md: replace outdated CE Echo stub with full
  ECN Congestion Signaling section covering detection logic, CE relay,
  IPv6 marking, session tracking, and monitoring counters
- Update fips-configuration.md: add node.ecn.* parameter table and
  ecn block in complete reference YAML
- Update fips-transport-layer.md: add Congestion Reporting section
  with TransportCongestion struct, congestion() trait method, and
  per-transport status; document AsyncFd/recvmsg/SO_RXQ_OVFL in UDP
- Update chaos README: add congestion/ECN scenario docs, ingress
  traffic control, and iperf3 JSON capture sections
- Update README.md: add ECN to features list and "What works today";
  update transport and tooling entries
2026-03-05 17:05:57 +00:00

101 lines
2.6 KiB
YAML

# ECN A/B Test: ECN ENABLED
#
# Identical to ecn-ab-off.yaml except ecn.enabled = true.
# Run both scenarios and compare iperf3 throughput results.
#
# Design rationale:
# - Ingress policing at 1000 kbps: unlike HTB (which paces smoothly),
# the ingress policer *drops* excess inbound packets at the kernel
# level. This creates real packet loss visible to the FIPS UDP
# socket, triggering detect_congestion() via transport_drops.
# - 10 Mbps egress bandwidth: lets traffic flow freely outbound so
# that the ingress policer is the bottleneck. Multiple flows
# competing through bottleneck nodes generate excess traffic that
# the policer drops.
# - 10ms link delay: creates realistic RTT and causes TCP to batch
# packets into bursts, making ingress drops more likely.
# - 8KB recv_buf_size: small buffer amplifies the effect of bursty
# arrivals — dropped packets at ingress + buffer overflow trigger
# detect_congestion() via both MMP loss and transport_drops paths.
# - tcp_ecn=1 in entrypoint.sh: TCP negotiates ECN so CE marks
# reach TCP congestion control, enabling proactive backoff.
# - 4 concurrent sessions with 4 parallel streams: moderate load
# that creates real contention without overwhelming everything.
#
# With ECN enabled, transit nodes detect congestion early and set CE
# flags, causing TCP to reduce its window proactively. Without ECN,
# TCP only learns about congestion from packet drops (timeouts/triple
# dup-ack), which is slower and causes more throughput loss.
#
# n01 (root)
# / \
# n02 n03
# / \ \
# n04 n05 n06
scenario:
name: "ecn-ab-on"
seed: 42
duration_secs: 120
topology:
algorithm: explicit
num_nodes: 6
params:
adjacency:
- [n01, n02]
- [n01, n03]
- [n02, n04]
- [n02, n05]
- [n03, n06]
subnet: "172.20.0.0/24"
ip_start: 10
bandwidth:
enabled: true
tiers_mbps: [10]
ingress:
enabled: true
tiers_kbps: [1000]
burst_bytes: 16000
netem:
enabled: true
default_policy:
delay_ms: [10, 10]
jitter_ms: [0, 0]
loss_pct: [0, 0]
mutation:
interval_secs: {min: 9999, max: 9999}
fraction: 0.0
policies:
baseline:
delay_ms: [10, 10]
loss_pct: [0, 0]
link_flaps:
enabled: false
traffic:
enabled: true
max_concurrent: 4
interval_secs: {min: 3, max: 5}
duration_secs: {min: 20, max: 30}
parallel_streams: 4
node_churn:
enabled: false
logging:
rust_log: "info"
output_dir: "./sim-results/ecn-ab-on"
fips_overrides:
node:
ecn:
enabled: true
transports:
udp:
recv_buf_size: 8192