blob: 085e8fab03fdc7b970b57a5dd9f794c1472308e1 [file] [log] [blame]
Otto Sabart1b23f5e2019-01-06 00:28:59 +01001.. SPDX-License-Identifier: GPL-2.0
2
Otto Sabartb83eb682019-01-06 00:29:28 +01003=====================
4Segmentation Offloads
5=====================
Otto Sabart1b23f5e2019-01-06 00:28:59 +01006
Alexander Duyckf7a62722016-04-10 21:45:09 -04007
8Introduction
9============
10
11This document describes a set of techniques in the Linux networking stack
12to take advantage of segmentation offload capabilities of various NICs.
13
14The following technologies are described:
15 * TCP Segmentation Offload - TSO
16 * UDP Fragmentation Offload - UFO
17 * IPIP, SIT, GRE, and UDP Tunnel Offloads
18 * Generic Segmentation Offload - GSO
19 * Generic Receive Offload - GRO
20 * Partial Generic Segmentation Offload - GSO_PARTIAL
Weitao Houba3c4382019-05-20 13:23:17 +080021 * SCTP acceleration with GSO - GSO_BY_FRAGS
Alexander Duyckf7a62722016-04-10 21:45:09 -040022
Otto Sabart1b23f5e2019-01-06 00:28:59 +010023
Alexander Duyckf7a62722016-04-10 21:45:09 -040024TCP Segmentation Offload
25========================
26
27TCP segmentation allows a device to segment a single frame into multiple
28frames with a data payload size specified in skb_shinfo()->gso_size.
Daniel Axtens3d07e072018-03-08 23:34:35 +110029When TCP segmentation requested the bit for either SKB_GSO_TCPV4 or
30SKB_GSO_TCPV6 should be set in skb_shinfo()->gso_type and
Alexander Duyckf7a62722016-04-10 21:45:09 -040031skb_shinfo()->gso_size should be set to a non-zero value.
32
33TCP segmentation is dependent on support for the use of partial checksum
34offload. For this reason TSO is normally disabled if the Tx checksum
35offload for a given device is disabled.
36
37In order to support TCP segmentation offload it is necessary to populate
38the network and transport header offsets of the skbuff so that the device
39drivers will be able determine the offsets of the IP or IPv6 header and the
40TCP header. In addition as CHECKSUM_PARTIAL is required csum_start should
41also 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 the
45GSO type SKB_GSO_TCP_FIXEDID is specified then we will not increment the IP
46ID and all segments will use the same IP ID. If a device has
47NETIF_F_TSO_MANGLEID set then the IP ID can be ignored when performing TSO
48and we will either increment the IP ID for all frames, or leave it at a
49static value based on driver preference.
50
Otto Sabart1b23f5e2019-01-06 00:28:59 +010051
Alexander Duyckf7a62722016-04-10 21:45:09 -040052UDP Fragmentation Offload
53=========================
54
55UDP fragmentation offload allows a device to fragment an oversized UDP
56datagram into multiple IPv4 fragments. Many of the requirements for UDP
57fragmentation offload are the same as TSO. However the IPv4 ID for
58fragments should not increment as a single IPv4 datagram is fragmented.
59
Daniel Axtensa65820e2018-02-14 18:05:31 +110060UFO is deprecated: modern kernels will no longer generate UFO skbs, but can
61still receive them from tuntap and similar devices. Offload of UDP-based
62tunnel protocols is still supported.
63
Otto Sabart1b23f5e2019-01-06 00:28:59 +010064
Alexander Duyckf7a62722016-04-10 21:45:09 -040065IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads
66========================================================
67
68In addition to the offloads described above it is possible for a frame to
69contain additional headers such as an outer tunnel. In order to account
70for such instances an additional set of segmentation offload types were
Nicolas Dichtel11bafd52017-07-07 14:08:25 +020071introduced including SKB_GSO_IPXIP4, SKB_GSO_IPXIP6, SKB_GSO_GRE, and
Alexander Duyckf7a62722016-04-10 21:45:09 -040072SKB_GSO_UDP_TUNNEL. These extra segmentation types are used to identify
73cases where there are more than just 1 set of headers. For example in the
74case of IPIP and SIT we should have the network and transport headers moved
75from the standard list of headers to "inner" header offsets.
76
77Currently only two levels of headers are supported. The convention is to
78refer to the tunnel headers as the outer headers, while the encapsulated
79data is normally referred to as the inner headers. Below is the list of
80calls to access the given headers:
81
Otto Sabart1b23f5e2019-01-06 00:28:59 +010082IPIP/SIT Tunnel::
Alexander Duyckf7a62722016-04-10 21:45:09 -040083
Otto Sabart1b23f5e2019-01-06 00:28:59 +010084 Outer Inner
85 MAC skb_mac_header
86 Network skb_network_header skb_inner_network_header
87 Transport skb_transport_header
88
89UDP/GRE Tunnel::
90
91 Outer Inner
92 MAC skb_mac_header skb_inner_mac_header
93 Network skb_network_header skb_inner_network_header
94 Transport skb_transport_header skb_inner_transport_header
Alexander Duyckf7a62722016-04-10 21:45:09 -040095
96In addition to the above tunnel types there are also SKB_GSO_GRE_CSUM and
97SKB_GSO_UDP_TUNNEL_CSUM. These two additional tunnel types reflect the
98fact that the outer header also requests to have a non-zero checksum
99included in the outer header.
100
Daniel Axtensbc3c2432018-02-14 18:05:32 +1100101Finally there is SKB_GSO_TUNNEL_REMCSUM which indicates that a given tunnel
102header has requested a remote checksum offload. In this case the inner
103headers will be left with a partial checksum and only the outer header
104checksum will be computed.
Alexander Duyckf7a62722016-04-10 21:45:09 -0400105
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100106
Alexander Duyckf7a62722016-04-10 21:45:09 -0400107Generic Segmentation Offload
108============================
109
110Generic segmentation offload is a pure software offload that is meant to
111deal with cases where device drivers cannot perform the offloads described
112above. What occurs in GSO is that a given skbuff will have its data broken
113out over multiple skbuffs that have been resized to match the MSS provided
114via skb_shinfo()->gso_size.
115
116Before enabling any hardware segmentation offload a corresponding software
117offload is required in GSO. Otherwise it becomes possible for a frame to
118be re-routed between devices and end up being unable to be transmitted.
119
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100120
Alexander Duyckf7a62722016-04-10 21:45:09 -0400121Generic Receive Offload
122=======================
123
124Generic receive offload is the complement to GSO. Ideally any frame
125assembled by GRO should be segmented to create an identical sequence of
126frames using GSO, and any sequence of frames segmented by GSO should be
127able to be reassembled back to the original by GRO. The only exception to
128this 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 be
130altered so that it is when a frame assembled via GRO is segmented via GSO.
131
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100132
Alexander Duyckf7a62722016-04-10 21:45:09 -0400133Partial Generic Segmentation Offload
134====================================
135
136Partial generic segmentation offload is a hybrid between TSO and GSO. What
137it effectively does is take advantage of certain traits of TCP and tunnels
138so that instead of having to rewrite the packet headers for each segment
139only the inner-most transport header and possibly the outer-most network
140header need to be updated. This allows devices that do not support tunnel
141offloads or tunnel offloads with checksum to still make use of segmentation.
142
143With the partial offload what occurs is that all headers excluding the
144inner transport header are updated such that they will contain the correct
145values for if the header was simply duplicated. The one exception to this
146is the outer IPv4 ID field. It is up to the device drivers to guarantee
147that the IPv4 ID field is incremented in the case that a given header does
148not have the DF bit set.
Daniel Axtensa6770882018-02-14 18:05:33 +1100149
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100150
Weitao Houba3c4382019-05-20 13:23:17 +0800151SCTP acceleration with GSO
Daniel Axtensa6770882018-02-14 18:05:33 +1100152===========================
153
154SCTP - despite the lack of hardware support - can still take advantage of
155GSO to pass one large packet through the network stack, rather than
156multiple small packets.
157
158This requires a different approach to other offloads, as SCTP packets
159cannot be just segmented to (P)MTU. Rather, the chunks must be contained in
160IP segments, padding respected. So unlike regular GSO, SCTP can't just
161generate a big skb, set gso_size to the fragmentation point and deliver it
162to IP layer.
163
164Instead, the SCTP protocol layer builds an skb with the segments correctly
165padded 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 the
169possibility that gso_size will be GSO_BY_FRAGS and handle that case
Daniel Axtensd02f51c2018-03-03 03:03:46 +0100170appropriately.
171
Daniel Axtens1dd27cd2018-03-09 14:06:09 +1100172There are some helpers to make this easier:
173
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100174- skb_is_gso(skb) && skb_is_gso_sctp(skb) is the best way to see if
175 an skb is an SCTP GSO skb.
Daniel Axtensd02f51c2018-03-03 03:03:46 +0100176
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100177- For size checks, the skb_gso_validate_*_len family of helpers correctly
178 considers GSO_BY_FRAGS.
Daniel Axtensd02f51c2018-03-03 03:03:46 +0100179
Otto Sabart1b23f5e2019-01-06 00:28:59 +0100180- For manipulating packets, skb_increase_gso_size and skb_decrease_gso_size
181 will check for GSO_BY_FRAGS and WARN if asked to manipulate these skbs.
Daniel Axtensa6770882018-02-14 18:05:33 +1100182
183This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits
184set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE.