On 2014-01-15, Stuart Henderson <s...@spacehopper.org> wrote: > On 2014-01-14, Richard Procter <richard.n.proc...@gmail.com> wrote: >> >> I've a question about the new checksum changes. [...] >> My understanding is that checksums are now always recalculated when >> a header is altered, never updated. >> >> Is that right and if so has this affected NAT reliability? >> >> Recalculation here would compromise reliable end-to-end transport >> as the payload checksum no longer covers the entire network path, >> and so break a basic transport layer design principle. > > That is exactly what slides 30-33 talk about. PF now checks > the incoming packets before it rewrites the checksum, so it can > reject them if they are broken.
Right -- so NAT now replaces the existing transport checksum with one newly computed from the payload [0]. This fundamentally weakens its usefulness, though: a correct checksum now implies only that the payload likely matches what the last NAT router happened to have in its memory, whereas the receiver wants to know whether what it got is what was originally transmitted. In the worst case of NAT on every intermediate node the transport checksum is effectively reduced to an adjunct of the link layer checksum. This means transport layer payload integrity is no longer reliant on the quality of the checksum algorithm alone but now depends too on the reliability of the path the packet took through the network. I think it's great to see someone working hard to simplify crucial code but in light of the above I believe pf should always update the checksum, as it did in versions prior to 5.4, as the alternative fundamentally undermines TCP by making the undetected error rate of its streams unknown and unbounded. One might argue networks these days are reliable; I think it better to avoid the need to make the argument. In any case the work I've found on that question is not reassuring [1]. best, Richard. [0] pf.c 1.863 On initial rule match: pf_test_rule() 3445: pf_translate() 3707: pf_change_ap() 1677: PF_ACPY [= pf_addrcpy()] 3461: pf_cksum() 6775: pd->hdr.tcp->th_sum = 0; m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT (if orig checksum good) On subsequent state matching: pf_test_state() ~4445: pf_change_ap() etc 4471: pf_cksum() etc [1] "Probably the strongest message of this study is that the networking hardware is often trashing the packets which are entrusted to it" http://conferences.sigcomm.org/sigcomm/2000/conf/paper/sigcomm2000-9-1.pdf Jonathan Stone and Craig Partridge. 2000. When the CRC and TCP checksum disagree. In Proceedings of the conference on Applications, Technologies, Architectures, and Protocols for Computer Communication (SIGCOMM '00). ACM, New York, NY, USA, 309-319. DOI=10.1145/347059.347561 http://doi.acm.org/10.1145/347059.347561