Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Xin Long and committed by
Jakub Kicinski
62fafcd6 fd3d3755

+12 -1
+12 -1
net/core/dev.c
··· 3621 3621 return !!(features & NETIF_F_SCTP_CRC) ? 0 : 3622 3622 skb_crc32c_csum_help(skb); 3623 3623 3624 - return !!(features & NETIF_F_CSUM_MASK) ? 0 : skb_checksum_help(skb); 3624 + if (features & NETIF_F_HW_CSUM) 3625 + return 0; 3626 + 3627 + if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) { 3628 + switch (skb->csum_offset) { 3629 + case offsetof(struct tcphdr, check): 3630 + case offsetof(struct udphdr, check): 3631 + return 0; 3632 + } 3633 + } 3634 + 3635 + return skb_checksum_help(skb); 3625 3636 } 3626 3637 EXPORT_SYMBOL(skb_csum_hwoffload_help); 3627 3638