|
|
@@ -109,6 +109,7 @@
|
|
|
* may perform further validation in this case.
|
|
|
* GRE: only if the checksum is present in the header.
|
|
|
* SCTP: indicates the CRC in SCTP header has been validated.
|
|
|
+ * FCOE: indicates the CRC in FC frame has been validated.
|
|
|
*
|
|
|
* skb->csum_level indicates the number of consecutive checksums found in
|
|
|
* the packet minus one that have been verified as CHECKSUM_UNNECESSARY.
|
|
|
@@ -126,8 +127,10 @@
|
|
|
* packet as seen by netif_rx() and fills out in skb->csum. Meaning, the
|
|
|
* hardware doesn't need to parse L3/L4 headers to implement this.
|
|
|
*
|
|
|
- * Note: Even if device supports only some protocols, but is able to produce
|
|
|
- * skb->csum, it MUST use CHECKSUM_COMPLETE, not CHECKSUM_UNNECESSARY.
|
|
|
+ * Notes:
|
|
|
+ * - Even if device supports only some protocols, but is able to produce
|
|
|
+ * skb->csum, it MUST use CHECKSUM_COMPLETE, not CHECKSUM_UNNECESSARY.
|
|
|
+ * - CHECKSUM_COMPLETE is not applicable to SCTP and FCoE protocols.
|
|
|
*
|
|
|
* CHECKSUM_PARTIAL:
|
|
|
*
|
|
|
@@ -162,14 +165,11 @@
|
|
|
*
|
|
|
* NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are being deprecated in favor of
|
|
|
* NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to indicate
|
|
|
- * checksum offload capability. If a device has limited checksum capabilities
|
|
|
- * (for instance can only perform NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM as
|
|
|
- * described above) a helper function can be called to resolve
|
|
|
- * CHECKSUM_PARTIAL. The helper functions are skb_csum_off_chk*. The helper
|
|
|
- * function takes a spec argument that describes the protocol layer that is
|
|
|
- * supported for checksum offload and can be called for each packet. If a
|
|
|
- * packet does not match the specification for offload, skb_checksum_help
|
|
|
- * is called to resolve the checksum.
|
|
|
+ * checksum offload capability.
|
|
|
+ * skb_csum_hwoffload_help() can be called to resolve CHECKSUM_PARTIAL based
|
|
|
+ * on network device checksumming capabilities: if a packet does not match
|
|
|
+ * them, skb_checksum_help or skb_crc32c_help (depending on the value of
|
|
|
+ * csum_not_inet, see item D.) is called to resolve the checksum.
|
|
|
*
|
|
|
* CHECKSUM_NONE:
|
|
|
*
|
|
|
@@ -189,11 +189,13 @@
|
|
|
*
|
|
|
* NETIF_F_SCTP_CRC - This feature indicates that a device is capable of
|
|
|
* offloading the SCTP CRC in a packet. To perform this offload the stack
|
|
|
- * will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
|
|
|
- * accordingly. Note the there is no indication in the skbuff that the
|
|
|
- * CHECKSUM_PARTIAL refers to an SCTP checksum, a driver that supports
|
|
|
- * both IP checksum offload and SCTP CRC offload must verify which offload
|
|
|
- * is configured for a packet presumably by inspecting packet headers.
|
|
|
+ * will set set csum_start and csum_offset accordingly, set ip_summed to
|
|
|
+ * CHECKSUM_PARTIAL and set csum_not_inet to 1, to provide an indication in
|
|
|
+ * the skbuff that the CHECKSUM_PARTIAL refers to CRC32c.
|
|
|
+ * A driver that supports both IP checksum offload and SCTP CRC32c offload
|
|
|
+ * must verify which offload is configured for a packet by testing the
|
|
|
+ * value of skb->csum_not_inet; skb_crc32c_csum_help is provided to resolve
|
|
|
+ * CHECKSUM_PARTIAL on skbs where csum_not_inet is set to 1.
|
|
|
*
|
|
|
* NETIF_F_FCOE_CRC - This feature indicates that a device is capable of
|
|
|
* offloading the FCOE CRC in a packet. To perform this offload the stack
|
|
|
@@ -556,6 +558,7 @@ typedef unsigned char *sk_buff_data_t;
|
|
|
* @wifi_acked_valid: wifi_acked was set
|
|
|
* @wifi_acked: whether frame was acked on wifi or not
|
|
|
* @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS
|
|
|
+ * @csum_not_inet: use CRC32c to resolve CHECKSUM_PARTIAL
|
|
|
* @dst_pending_confirm: need to confirm neighbour
|
|
|
* @napi_id: id of the NAPI struct this skb came from
|
|
|
* @secmark: security marking
|
|
|
@@ -684,7 +687,7 @@ struct sk_buff {
|
|
|
__u8 csum_valid:1;
|
|
|
__u8 csum_complete_sw:1;
|
|
|
__u8 csum_level:2;
|
|
|
- __u8 csum_bad:1;
|
|
|
+ __u8 csum_not_inet:1;
|
|
|
|
|
|
__u8 dst_pending_confirm:1;
|
|
|
#ifdef CONFIG_IPV6_NDISC_NODETYPE
|
|
|
@@ -3076,6 +3079,8 @@ struct skb_checksum_ops {
|
|
|
__wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len);
|
|
|
};
|
|
|
|
|
|
+extern const struct skb_checksum_ops *crc32c_csum_stub __read_mostly;
|
|
|
+
|
|
|
__wsum __skb_checksum(const struct sk_buff *skb, int offset, int len,
|
|
|
__wsum csum, const struct skb_checksum_ops *ops);
|
|
|
__wsum skb_checksum(const struct sk_buff *skb, int offset, int len,
|
|
|
@@ -3333,21 +3338,6 @@ static inline void __skb_incr_checksum_unnecessary(struct sk_buff *skb)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static inline void __skb_mark_checksum_bad(struct sk_buff *skb)
|
|
|
-{
|
|
|
- /* Mark current checksum as bad (typically called from GRO
|
|
|
- * path). In the case that ip_summed is CHECKSUM_NONE
|
|
|
- * this must be the first checksum encountered in the packet.
|
|
|
- * When ip_summed is CHECKSUM_UNNECESSARY, this is the first
|
|
|
- * checksum after the last one validated. For UDP, a zero
|
|
|
- * checksum can not be marked as bad.
|
|
|
- */
|
|
|
-
|
|
|
- if (skb->ip_summed == CHECKSUM_NONE ||
|
|
|
- skb->ip_summed == CHECKSUM_UNNECESSARY)
|
|
|
- skb->csum_bad = 1;
|
|
|
-}
|
|
|
-
|
|
|
/* Check if we need to perform checksum complete validation.
|
|
|
*
|
|
|
* Returns true if checksum complete is needed, false otherwise
|
|
|
@@ -3401,9 +3391,6 @@ static inline __sum16 __skb_checksum_validate_complete(struct sk_buff *skb,
|
|
|
skb->csum_valid = 1;
|
|
|
return 0;
|
|
|
}
|
|
|
- } else if (skb->csum_bad) {
|
|
|
- /* ip_summed == CHECKSUM_NONE in this case */
|
|
|
- return (__force __sum16)1;
|
|
|
}
|
|
|
|
|
|
skb->csum = psum;
|
|
|
@@ -3463,8 +3450,7 @@ static inline __wsum null_compute_pseudo(struct sk_buff *skb, int proto)
|
|
|
|
|
|
static inline bool __skb_checksum_convert_check(struct sk_buff *skb)
|
|
|
{
|
|
|
- return (skb->ip_summed == CHECKSUM_NONE &&
|
|
|
- skb->csum_valid && !skb->csum_bad);
|
|
|
+ return (skb->ip_summed == CHECKSUM_NONE && skb->csum_valid);
|
|
|
}
|
|
|
|
|
|
static inline void __skb_checksum_convert(struct sk_buff *skb,
|