A packet crosses three links and two switches. Every link checks its CRC and the packet passes every check. Yet it arrives with a corrupted byte. Inside one of the switches, between checking the incoming CRC and generating the outgoing one, a buffer cell flipped a bit. The switch dutifully computed a fresh, valid CRC over the corrupted data. Every link was protected; the path was not.
Is checking every link enough, and if not, what is missing?
The obvious answer is to protect every hop: if every link delivers what it was given, the path delivers what the source sent. But a link check covers only the wire. Every switch, bridge and buffer in between receives the data, checks it, stores it, and regenerates the check for the next link. Any corruption inside that device, after the check and before the regeneration, is sealed in under a new, valid check. Only a check made by the source and verified by the destination covers the whole path.
Link (per-hop) check | End-to-end check | |
|---|---|---|
Computed by | Each link's sender | The original source |
Checked by | Each link's receiver, then regenerated | Only the final destination |
Protects | The wire and its electrical path | Everything between source and destination: wires, switch buffers, bridges |
Recovery | Fast local replay on that link | The destination reports an error; recovery is end to end |
Misses | Corruption inside a device between check and regeneration | Nothing on the path, but it detects late and recovers slowly |
Link checks make the common case cheap: wire errors are the most frequent, and fixing them by local replay on one link is fast and invisible.
End-to-end checks make the path trustworthy: rare internal faults are caught, by the only party that can know what the source meant (the end-to-end argument, lesson 0.7).
Devices protect their insides too: ECC or parity on internal buffers reduces what the end-to-end check must catch.
Protocol | Protection |
|---|---|
PCI Express | A 32-bit LCRC on every TLP, checked and regenerated on each link, with replay; an optional 32-bit ECRC computed by the requester and checked by the completer, unchanged by switches. |
Ethernet with TCP | A CRC-32 per frame on each link (switches check and regenerate), plus a TCP checksum end to end. |
Memory systems | ECC that travels with the data from memory to the consumer, rather than being re-encoded at each hop. |
The opening switch (illustrative) had no protection on one internal buffer and no end-to-end CRC on the path. Its rare buffer flips became silent data corruption at the destination, traced only after weeks of comparing logs. Enabling the end-to-end CRC (and adding parity to the buffer) made each occurrence an immediately reported error.
Only the end-to-end CRC: the incoming check passed before the flip, and the outgoing CRC was computed over the flipped data.
Wire errors are frequent; recovering them end to end is slow. Link checks fix them with fast local replay.
Link checks protect wires and are regenerated at every hop; end-to-end checks protect the whole path.
Corruption inside a switch or bridge passes every link check; only an end-to-end check sees it.
Use both: link checks for fast recovery, end-to-end checks (plus internal ECC) for trust.