|
39 | 39 | #include <linux/in6.h>
|
40 | 40 | #include <net/flow.h>
|
41 | 41 |
|
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: |
43 | 87 | *
|
44 | 88 | * CHECKSUM_NONE:
|
45 | 89 | *
|
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. |
47 | 91 | * The packet contains full (though not verified) checksum in packet but
|
48 | 92 | * not in skb->csum. Thus, skb->csum is undefined in this case.
|
49 | 93 | *
|
|
53 | 97 | * (as in CHECKSUM_COMPLETE), but it does parse headers and verify checksums
|
54 | 98 | * for specific protocols. For such packets it will set CHECKSUM_UNNECESSARY
|
55 | 99 | * 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. |
59 | 102 | *
|
60 | 103 | * CHECKSUM_UNNECESSARY is applicable to following protocols:
|
61 | 104 | * TCP: IPv6 and IPv4.
|
|
96 | 139 | * packet that are after the checksum being offloaded are not considered to
|
97 | 140 | * be verified.
|
98 | 141 | *
|
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: |
105 | 144 | *
|
106 | 145 | * CHECKSUM_PARTIAL:
|
107 | 146 | *
|
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() |
109 | 148 | * 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. |
111 | 171 | *
|
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: |
114 | 173 | *
|
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. |
121 | 176 | *
|
122 | 177 | * CHECKSUM_UNNECESSARY:
|
123 | 178 | *
|
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. |
127 | 181 | *
|
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). |
133 | 213 | */
|
134 | 214 |
|
135 | 215 | /* Don't change this without changing skb_csum_unnecessary! */
|
|
0 commit comments