Octet

How does ECN work in IP and TCP, and why is it not used everywhere?

Show the answer

Say this first

Explicit Congestion Notification (RFC 3168) lets a router with active queue management mark a packet as congestion experienced instead of dropping it. ECN uses the two low bits of the old IP ToS byte. The receiver echoes the mark with the ECE flag; the sender reduces cwnd as if a loss had happened, without any retransmission, and confirms with CWR. It needs support at both ends and marking routers. Linux by default only accepts ECN when the peer asks for it and does not request it itself, and old middleboxes that mishandled the bits slowed deployment.

Go deeper

IP codepoints (2 bits after the 6-bit DSCP)

BitsNameMeaning
00Not-ECTSender does not support ECN
10ECT(0)ECN-capable transport
01ECT(1)ECN-capable transport, used by L4S
11CECongestion experienced, set by a router

TCP negotiation

  • SYN with ECE and CWR set: "I support ECN".
  • SYN-ACK with ECE set: "So do I".
  • Data packets then carry ECT. A router marks CE; the receiver sets ECE on its ACKs until the sender replies with CWR.

Where it matters

  • Data centers: DCTCP and RoCEv2 congestion control rely on ECN marking at low queue thresholds.
  • L4S (RFC 9330 to 9332) uses ECT(1) for very low queueing delay.
  • Linux: net.ipv4.tcp_ecn=2 by default (accept, do not initiate); 1 requests ECN on outgoing connections.

Network gotcha

QoS policies that rewrite the whole ToS byte instead of only DSCP wipe ECN bits. Remarking DSCP should leave the two ECN bits alone.

Traps

  • Saying ECN uses DSCP bits. It uses the two bits after DSCP in the same byte.