Skip to content

Commit 7a6ae71

Browse files
tomratbertdavem330
authored andcommitted
net: Elaborate on checksum offload interface description
Add specifics and details the description of the interface between the stack and drivers for doing checksum offload. This description is meant to be as specific and complete as possible. Signed-off-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6ae23ad commit 7a6ae71

File tree

1 file changed

+109
-29
lines changed

1 file changed

+109
-29
lines changed

include/linux/skbuff.h

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,55 @@
3939
#include <linux/in6.h>
4040
#include <net/flow.h>
4141

42-
/* A. Checksumming of received packets by device.
42+
/* The interface for checksum offload between the stack and networking drivers
43+
* is as follows...
44+
*
45+
* A. IP checksum related features
46+
*
47+
* Drivers advertise checksum offload capabilities in the features of a device.
48+
* From the stack's point of view these are capabilities offered by the driver,
49+
* a driver typically only advertises features that it is capable of offloading
50+
* to its device.
51+
*
52+
* The checksum related features are:
53+
*
54+
* NETIF_F_HW_CSUM - The driver (or its device) is able to compute one
55+
* IP (one's complement) checksum for any combination
56+
* of protocols or protocol layering. The checksum is
57+
* computed and set in a packet per the CHECKSUM_PARTIAL
58+
* interface (see below).
59+
*
60+
* NETIF_F_IP_CSUM - Driver (device) is only able to checksum plain
61+
* TCP or UDP packets over IPv4. These are specifically
62+
* unencapsulated packets of the form IPv4|TCP or
63+
* IPv4|UDP where the Protocol field in the IPv4 header
64+
* is TCP or UDP. The IPv4 header may contain IP options
65+
* This feature cannot be set in features for a device
66+
* with NETIF_F_HW_CSUM also set. This feature is being
67+
* DEPRECATED (see below).
68+
*
69+
* NETIF_F_IPV6_CSUM - Driver (device) is only able to checksum plain
70+
* TCP or UDP packets over IPv6. These are specifically
71+
* unencapsulated packets of the form IPv6|TCP or
72+
* IPv4|UDP where the Next Header field in the IPv6
73+
* header is either TCP or UDP. IPv6 extension headers
74+
* are not supported with this feature. This feature
75+
* cannot be set in features for a device with
76+
* NETIF_F_HW_CSUM also set. This feature is being
77+
* DEPRECATED (see below).
78+
*
79+
* NETIF_F_RXCSUM - Driver (device) performs receive checksum offload.
80+
* This flag is used only used to disable the RX checksum
81+
* feature for a device. The stack will accept receive
82+
* checksum indication in packets received on a device
83+
* regardless of whether NETIF_F_RXCSUM is set.
84+
*
85+
* B. Checksumming of received packets by device. Indication of checksum
86+
* verification is in set skb->ip_summed. Possible values are:
4387
*
4488
* CHECKSUM_NONE:
4589
*
46-
* Device failed to checksum this packet e.g. due to lack of capabilities.
90+
* Device did not checksum this packet e.g. due to lack of capabilities.
4791
* The packet contains full (though not verified) checksum in packet but
4892
* not in skb->csum. Thus, skb->csum is undefined in this case.
4993
*
@@ -53,9 +97,8 @@
5397
* (as in CHECKSUM_COMPLETE), but it does parse headers and verify checksums
5498
* for specific protocols. For such packets it will set CHECKSUM_UNNECESSARY
5599
* if their checksums are okay. skb->csum is still undefined in this case
56-
* though. It is a bad option, but, unfortunately, nowadays most vendors do
57-
* this. Apparently with the secret goal to sell you new devices, when you
58-
* will add new protocol to your host, f.e. IPv6 8)
100+
* though. A driver or device must never modify the checksum field in the
101+
* packet even if checksum is verified.
59102
*
60103
* CHECKSUM_UNNECESSARY is applicable to following protocols:
61104
* TCP: IPv6 and IPv4.
@@ -96,40 +139,77 @@
96139
* packet that are after the checksum being offloaded are not considered to
97140
* be verified.
98141
*
99-
* B. Checksumming on output.
100-
*
101-
* CHECKSUM_NONE:
102-
*
103-
* The skb was already checksummed by the protocol, or a checksum is not
104-
* required.
142+
* C. Checksumming on transmit for non-GSO. The stack requests checksum offload
143+
* in the skb->ip_summed for a packet. Values are:
105144
*
106145
* CHECKSUM_PARTIAL:
107146
*
108-
* The device is required to checksum the packet as seen by hard_start_xmit()
147+
* The driver is required to checksum the packet as seen by hard_start_xmit()
109148
* from skb->csum_start up to the end, and to record/write the checksum at
110-
* offset skb->csum_start + skb->csum_offset.
149+
* offset skb->csum_start + skb->csum_offset. A driver may verify that the
150+
* csum_start and csum_offset values are valid values given the length and
151+
* offset of the packet, however they should not attempt to validate that the
152+
* checksum refers to a legitimate transport layer checksum-- it is the
153+
* purview of the stack to validate that csum_start and csum_offset are set
154+
* correctly.
155+
*
156+
* When the stack requests checksum offload for a packet, the driver MUST
157+
* ensure that the checksum is set correctly. A driver can either offload the
158+
* checksum calculation to the device, or call skb_checksum_help (in the case
159+
* that the device does not support offload for a particular checksum).
160+
*
161+
* NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are being deprecated in favor of
162+
* NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to indicate
163+
* checksum offload capability. If a device has limited checksum capabilities
164+
* (for instance can only perform NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM as
165+
* described above) a helper function can be called to resolve
166+
* CHECKSUM_PARTIAL. The helper functions are skb_csum_off_chk*. The helper
167+
* function takes a spec argument that describes the protocol layer that is
168+
* supported for checksum offload and can be called for each packet. If a
169+
* packet does not match the specification for offload, skb_checksum_help
170+
* is called to resolve the checksum.
111171
*
112-
* The device must show its capabilities in dev->features, set up at device
113-
* setup time, e.g. netdev_features.h:
172+
* CHECKSUM_NONE:
114173
*
115-
* NETIF_F_HW_CSUM - It's a clever device, it's able to checksum everything.
116-
* NETIF_F_IP_CSUM - Device is dumb, it's able to checksum only TCP/UDP over
117-
* IPv4. Sigh. Vendors like this way for an unknown reason.
118-
* Though, see comment above about CHECKSUM_UNNECESSARY. 8)
119-
* NETIF_F_IPV6_CSUM - About as dumb as the last one but does IPv6 instead.
120-
* NETIF_F_... - Well, you get the picture.
174+
* The skb was already checksummed by the protocol, or a checksum is not
175+
* required.
121176
*
122177
* CHECKSUM_UNNECESSARY:
123178
*
124-
* Normally, the device will do per protocol specific checksumming. Protocol
125-
* implementations that do not want the NIC to perform the checksum
126-
* calculation should use this flag in their outgoing skbs.
179+
* This has the same meaning on as CHECKSUM_NONE for checksum offload on
180+
* output.
127181
*
128-
* NETIF_F_FCOE_CRC - This indicates that the device can do FCoE FC CRC
129-
* offload. Correspondingly, the FCoE protocol driver
130-
* stack should use CHECKSUM_UNNECESSARY.
131-
*
132-
* Any questions? No questions, good. --ANK
182+
* CHECKSUM_COMPLETE:
183+
* Not used in checksum output. If a driver observes a packet with this value
184+
* set in skbuff, if should treat as CHECKSUM_NONE being set.
185+
*
186+
* D. Non-IP checksum (CRC) offloads
187+
*
188+
* NETIF_F_SCTP_CRC - This feature indicates that a device is capable of
189+
* offloading the SCTP CRC in a packet. To perform this offload the stack
190+
* will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
191+
* accordingly. Note the there is no indication in the skbuff that the
192+
* CHECKSUM_PARTIAL refers to an SCTP checksum, a driver that supports
193+
* both IP checksum offload and SCTP CRC offload must verify which offload
194+
* is configured for a packet presumably by inspecting packet headers.
195+
*
196+
* NETIF_F_FCOE_CRC - This feature indicates that a device is capable of
197+
* offloading the FCOE CRC in a packet. To perform this offload the stack
198+
* will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
199+
* accordingly. Note the there is no indication in the skbuff that the
200+
* CHECKSUM_PARTIAL refers to an FCOE checksum, a driver that supports
201+
* both IP checksum offload and FCOE CRC offload must verify which offload
202+
* is configured for a packet presumably by inspecting packet headers.
203+
*
204+
* E. Checksumming on output with GSO.
205+
*
206+
* In the case of a GSO packet (skb_is_gso(skb) is true), checksum offload
207+
* is implied by the SKB_GSO_* flags in gso_type. Most obviously, if the
208+
* gso_type is SKB_GSO_TCPV4 or SKB_GSO_TCPV6, TCP checksum offload as
209+
* part of the GSO operation is implied. If a checksum is being offloaded
210+
* with GSO then ip_summed is CHECKSUM_PARTIAL, csum_start and csum_offset
211+
* are set to refer to the outermost checksum being offload (two offloaded
212+
* checksums are possible with UDP encapsulation).
133213
*/
134214

135215
/* Don't change this without changing skb_csum_unnecessary! */

0 commit comments

Comments
 (0)