summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2021-01-28 12:18:31 +0300
committerJakub Kicinski <kuba@kernel.org>2021-01-30 07:39:14 +0300
commit62fafcd63139920eb25b3fbf154177ce3e6f3232 (patch)
treea1ef2f7a6aae6fac67c9c8a1f83045bdd9b76dd1 /net/core
parentfd3d37551cec11fc69f8909d2a591754b2752db9 (diff)
downloadlinux-62fafcd63139920eb25b3fbf154177ce3e6f3232.tar.xz
net: support ip generic csum processing in skb_csum_hwoffload_help
NETIF_F_IP|IPV6_CSUM feature flag indicates UDP and TCP csum offload while NETIF_F_HW_CSUM feature flag indicates ip generic csum offload for HW, which includes not only for TCP/UDP csum, but also for other protocols' csum like GRE's. However, in skb_csum_hwoffload_help() it only checks features against NETIF_F_CSUM_MASK(NETIF_F_HW|IP|IPV6_CSUM). So if it's a non TCP/UDP packet and the features doesn't support NETIF_F_HW_CSUM, but supports NETIF_F_IP|IPV6_CSUM only, it would still return 0 and leave the HW to do csum. This patch is to support ip generic csum processing by checking NETIF_F_HW_CSUM for all protocols, and check (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) only for TCP and UDP. Note that we're using skb->csum_offset to check if it's a TCP/UDP proctol, this might be fragile. However, as Alex said, for now we only have a few L4 protocols that are requesting Tx csum offload, we'd better fix this until a new protocol comes with a same csum offset. v1->v2: - not extend skb->csum_not_inet, but use skb->csum_offset to tell if it's an UDP/TCP csum packet. v2->v3: - add a note in the changelog, as Willem suggested. Suggested-by: Alexander Duyck <alexander.duyck@gmail.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 6df3f1bcdc68..aae116d059da 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3621,7 +3621,18 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
return !!(features & NETIF_F_SCTP_CRC) ? 0 :
skb_crc32c_csum_help(skb);
- return !!(features & NETIF_F_CSUM_MASK) ? 0 : skb_checksum_help(skb);
+ if (features & NETIF_F_HW_CSUM)
+ return 0;
+
+ if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
+ switch (skb->csum_offset) {
+ case offsetof(struct tcphdr, check):
+ case offsetof(struct udphdr, check):
+ return 0;
+ }
+ }
+
+ return skb_checksum_help(skb);
}
EXPORT_SYMBOL(skb_csum_hwoffload_help);