checksum-offloads.rst 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. .. SPDX-License-Identifier: GPL-2.0
  2. =================
  3. Checksum Offloads
  4. =================
  5. Introduction
  6. ============
  7. This document describes a set of techniques in the Linux networking stack to
  8. take advantage of checksum offload capabilities of various NICs.
  9. The following technologies are described:
  10. * TX Checksum Offload
  11. * LCO: Local Checksum Offload
  12. * RCO: Remote Checksum Offload
  13. Things that should be documented here but aren't yet:
  14. * RX Checksum Offload
  15. * CHECKSUM_UNNECESSARY conversion
  16. TX Checksum Offload
  17. ===================
  18. The interface for offloading a transmit checksum to a device is explained in
  19. detail in comments near the top of include/linux/skbuff.h.
  20. In brief, it allows to request the device fill in a single ones-complement
  21. checksum defined by the sk_buff fields skb->csum_start and skb->csum_offset.
  22. The device should compute the 16-bit ones-complement checksum (i.e. the
  23. 'IP-style' checksum) from csum_start to the end of the packet, and fill in the
  24. result at (csum_start + csum_offset).
  25. Because csum_offset cannot be negative, this ensures that the previous value of
  26. the checksum field is included in the checksum computation, thus it can be used
  27. to supply any needed corrections to the checksum (such as the sum of the
  28. pseudo-header for UDP or TCP).
  29. This interface only allows a single checksum to be offloaded. Where
  30. encapsulation is used, the packet may have multiple checksum fields in
  31. different header layers, and the rest will have to be handled by another
  32. mechanism such as LCO or RCO.
  33. CRC32c can also be offloaded using this interface, by means of filling
  34. skb->csum_start and skb->csum_offset as described above, and setting
  35. skb->csum_not_inet: see skbuff.h comment (section 'D') for more details.
  36. No offloading of the IP header checksum is performed; it is always done in
  37. software. This is OK because when we build the IP header, we obviously have it
  38. in cache, so summing it isn't expensive. It's also rather short.
  39. The requirements for GSO are more complicated, because when segmenting an
  40. encapsulated packet both the inner and outer checksums may need to be edited or
  41. recomputed for each resulting segment. See the skbuff.h comment (section 'E')
  42. for more details.
  43. A driver declares its offload capabilities in netdev->hw_features; see
  44. Documentation/networking/netdev-features.rst for more. Note that a device
  45. which only advertises NETIF_F_IP[V6]_CSUM must still obey the csum_start and
  46. csum_offset given in the SKB; if it tries to deduce these itself in hardware
  47. (as some NICs do) the driver should check that the values in the SKB match
  48. those which the hardware will deduce, and if not, fall back to checksumming in
  49. software instead (with skb_csum_hwoffload_help() or one of the
  50. skb_checksum_help() / skb_crc32c_csum_help functions, as mentioned in
  51. include/linux/skbuff.h).
  52. The stack should, for the most part, assume that checksum offload is supported
  53. by the underlying device. The only place that should check is
  54. validate_xmit_skb(), and the functions it calls directly or indirectly. That
  55. function compares the offload features requested by the SKB (which may include
  56. other offloads besides TX Checksum Offload) and, if they are not supported or
  57. enabled on the device (determined by netdev->features), performs the
  58. corresponding offload in software. In the case of TX Checksum Offload, that
  59. means calling skb_csum_hwoffload_help(skb, features).
  60. LCO: Local Checksum Offload
  61. ===========================
  62. LCO is a technique for efficiently computing the outer checksum of an
  63. encapsulated datagram when the inner checksum is due to be offloaded.
  64. The ones-complement sum of a correctly checksummed TCP or UDP packet is equal
  65. to the complement of the sum of the pseudo header, because everything else gets
  66. 'cancelled out' by the checksum field. This is because the sum was
  67. complemented before being written to the checksum field.
  68. More generally, this holds in any case where the 'IP-style' ones complement
  69. checksum is used, and thus any checksum that TX Checksum Offload supports.
  70. That is, if we have set up TX Checksum Offload with a start/offset pair, we
  71. know that after the device has filled in that checksum, the ones complement sum
  72. from csum_start to the end of the packet will be equal to the complement of
  73. whatever value we put in the checksum field beforehand. This allows us to
  74. compute the outer checksum without looking at the payload: we simply stop
  75. summing when we get to csum_start, then add the complement of the 16-bit word
  76. at (csum_start + csum_offset).
  77. Then, when the true inner checksum is filled in (either by hardware or by
  78. skb_checksum_help()), the outer checksum will become correct by virtue of the
  79. arithmetic.
  80. LCO is performed by the stack when constructing an outer UDP header for an
  81. encapsulation such as VXLAN or GENEVE, in udp_set_csum(). Similarly for the
  82. IPv6 equivalents, in udp6_set_csum().
  83. It is also performed when constructing an IPv4 GRE header, in
  84. net/ipv4/ip_gre.c:build_header(). It is *not* currently performed when
  85. constructing an IPv6 GRE header; the GRE checksum is computed over the whole
  86. packet in net/ipv6/ip6_gre.c:ip6gre_xmit2(), but it should be possible to use
  87. LCO here as IPv6 GRE still uses an IP-style checksum.
  88. All of the LCO implementations use a helper function lco_csum(), in
  89. include/linux/skbuff.h.
  90. LCO can safely be used for nested encapsulations; in this case, the outer
  91. encapsulation layer will sum over both its own header and the 'middle' header.
  92. This does mean that the 'middle' header will get summed multiple times, but
  93. there doesn't seem to be a way to avoid that without incurring bigger costs
  94. (e.g. in SKB bloat).
  95. RCO: Remote Checksum Offload
  96. ============================
  97. RCO is a technique for eliding the inner checksum of an encapsulated datagram,
  98. allowing the outer checksum to be offloaded. It does, however, involve a
  99. change to the encapsulation protocols, which the receiver must also support.
  100. For this reason, it is disabled by default.
  101. RCO is detailed in the following Internet-Drafts:
  102. * https://tools.ietf.org/html/draft-herbert-remotecsumoffload-00
  103. * https://tools.ietf.org/html/draft-herbert-vxlan-rco-00
  104. In Linux, RCO is implemented individually in each encapsulation protocol, and
  105. most tunnel types have flags controlling its use. For instance, VXLAN has the
  106. flag VXLAN_F_REMCSUM_TX (per struct vxlan_rdst) to indicate that RCO should be
  107. used when transmitting to a given remote destination.