brintos

brintos / linux-shallow public Read only

0
0
Text · 7.7 KiB · 085e8fa Raw
185 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3=====================4Segmentation Offloads5=====================6 7 8Introduction9============10 11This document describes a set of techniques in the Linux networking stack12to take advantage of segmentation offload capabilities of various NICs.13 14The following technologies are described:15 * TCP Segmentation Offload - TSO16 * UDP Fragmentation Offload - UFO17 * IPIP, SIT, GRE, and UDP Tunnel Offloads18 * Generic Segmentation Offload - GSO19 * Generic Receive Offload - GRO20 * Partial Generic Segmentation Offload - GSO_PARTIAL21 * SCTP acceleration with GSO - GSO_BY_FRAGS22 23 24TCP Segmentation Offload25========================26 27TCP segmentation allows a device to segment a single frame into multiple28frames with a data payload size specified in skb_shinfo()->gso_size.29When TCP segmentation requested the bit for either SKB_GSO_TCPV4 or30SKB_GSO_TCPV6 should be set in skb_shinfo()->gso_type and31skb_shinfo()->gso_size should be set to a non-zero value.32 33TCP segmentation is dependent on support for the use of partial checksum34offload.  For this reason TSO is normally disabled if the Tx checksum35offload for a given device is disabled.36 37In order to support TCP segmentation offload it is necessary to populate38the network and transport header offsets of the skbuff so that the device39drivers will be able determine the offsets of the IP or IPv6 header and the40TCP header.  In addition as CHECKSUM_PARTIAL is required csum_start should41also point to the TCP header of the packet.42 43For IPv4 segmentation we support one of two types in terms of the IP ID.44The default behavior is to increment the IP ID with every segment.  If the45GSO type SKB_GSO_TCP_FIXEDID is specified then we will not increment the IP46ID and all segments will use the same IP ID.  If a device has47NETIF_F_TSO_MANGLEID set then the IP ID can be ignored when performing TSO48and we will either increment the IP ID for all frames, or leave it at a49static value based on driver preference.50 51 52UDP Fragmentation Offload53=========================54 55UDP fragmentation offload allows a device to fragment an oversized UDP56datagram into multiple IPv4 fragments.  Many of the requirements for UDP57fragmentation offload are the same as TSO.  However the IPv4 ID for58fragments should not increment as a single IPv4 datagram is fragmented.59 60UFO is deprecated: modern kernels will no longer generate UFO skbs, but can61still receive them from tuntap and similar devices. Offload of UDP-based62tunnel protocols is still supported.63 64 65IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads66========================================================67 68In addition to the offloads described above it is possible for a frame to69contain additional headers such as an outer tunnel.  In order to account70for such instances an additional set of segmentation offload types were71introduced including SKB_GSO_IPXIP4, SKB_GSO_IPXIP6, SKB_GSO_GRE, and72SKB_GSO_UDP_TUNNEL.  These extra segmentation types are used to identify73cases where there are more than just 1 set of headers.  For example in the74case of IPIP and SIT we should have the network and transport headers moved75from the standard list of headers to "inner" header offsets.76 77Currently only two levels of headers are supported.  The convention is to78refer to the tunnel headers as the outer headers, while the encapsulated79data is normally referred to as the inner headers.  Below is the list of80calls to access the given headers:81 82IPIP/SIT Tunnel::83 84             Outer                  Inner85  MAC        skb_mac_header86  Network    skb_network_header     skb_inner_network_header87  Transport  skb_transport_header88 89UDP/GRE Tunnel::90 91             Outer                  Inner92  MAC        skb_mac_header         skb_inner_mac_header93  Network    skb_network_header     skb_inner_network_header94  Transport  skb_transport_header   skb_inner_transport_header95 96In addition to the above tunnel types there are also SKB_GSO_GRE_CSUM and97SKB_GSO_UDP_TUNNEL_CSUM.  These two additional tunnel types reflect the98fact that the outer header also requests to have a non-zero checksum99included in the outer header.100 101Finally there is SKB_GSO_TUNNEL_REMCSUM which indicates that a given tunnel102header has requested a remote checksum offload.  In this case the inner103headers will be left with a partial checksum and only the outer header104checksum will be computed.105 106 107Generic Segmentation Offload108============================109 110Generic segmentation offload is a pure software offload that is meant to111deal with cases where device drivers cannot perform the offloads described112above.  What occurs in GSO is that a given skbuff will have its data broken113out over multiple skbuffs that have been resized to match the MSS provided114via skb_shinfo()->gso_size.115 116Before enabling any hardware segmentation offload a corresponding software117offload is required in GSO.  Otherwise it becomes possible for a frame to118be re-routed between devices and end up being unable to be transmitted.119 120 121Generic Receive Offload122=======================123 124Generic receive offload is the complement to GSO.  Ideally any frame125assembled by GRO should be segmented to create an identical sequence of126frames using GSO, and any sequence of frames segmented by GSO should be127able to be reassembled back to the original by GRO.  The only exception to128this is IPv4 ID in the case that the DF bit is set for a given IP header.129If the value of the IPv4 ID is not sequentially incrementing it will be130altered so that it is when a frame assembled via GRO is segmented via GSO.131 132 133Partial Generic Segmentation Offload134====================================135 136Partial generic segmentation offload is a hybrid between TSO and GSO.  What137it effectively does is take advantage of certain traits of TCP and tunnels138so that instead of having to rewrite the packet headers for each segment139only the inner-most transport header and possibly the outer-most network140header need to be updated.  This allows devices that do not support tunnel141offloads or tunnel offloads with checksum to still make use of segmentation.142 143With the partial offload what occurs is that all headers excluding the144inner transport header are updated such that they will contain the correct145values for if the header was simply duplicated.  The one exception to this146is the outer IPv4 ID field.  It is up to the device drivers to guarantee147that the IPv4 ID field is incremented in the case that a given header does148not have the DF bit set.149 150 151SCTP acceleration with GSO152===========================153 154SCTP - despite the lack of hardware support - can still take advantage of155GSO to pass one large packet through the network stack, rather than156multiple small packets.157 158This requires a different approach to other offloads, as SCTP packets159cannot be just segmented to (P)MTU. Rather, the chunks must be contained in160IP segments, padding respected. So unlike regular GSO, SCTP can't just161generate a big skb, set gso_size to the fragmentation point and deliver it162to IP layer.163 164Instead, the SCTP protocol layer builds an skb with the segments correctly165padded and stored as chained skbs, and skb_segment() splits based on those.166To signal this, gso_size is set to the special value GSO_BY_FRAGS.167 168Therefore, any code in the core networking stack must be aware of the169possibility that gso_size will be GSO_BY_FRAGS and handle that case170appropriately.171 172There are some helpers to make this easier:173 174- skb_is_gso(skb) && skb_is_gso_sctp(skb) is the best way to see if175  an skb is an SCTP GSO skb.176 177- For size checks, the skb_gso_validate_*_len family of helpers correctly178  considers GSO_BY_FRAGS.179 180- For manipulating packets, skb_increase_gso_size and skb_decrease_gso_size181  will check for GSO_BY_FRAGS and WARN if asked to manipulate these skbs.182 183This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits184set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE.185