diff mbox series

[net,3/4] udp: fix outer header csum for SKB_GSO_FRAGLIST over UDP tunnel

Message ID 82e982530f74f7b736071f041918c22919b734d8.1620223174.git.pabeni@redhat.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series udp: more FRAGLIST fixes | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net
netdev/subject_prefix success Link
netdev/cc_maintainers warning 2 maintainers not CCed: yoshfuji@linux-ipv6.org dsahern@kernel.org
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 7 this patch: 7
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 7 this patch: 7
netdev/header_inline success Link

Commit Message

Paolo Abeni May 5, 2021, 3:35 p.m. UTC
In the following scenario:

    GRO -> SKB_GSO_FRAGLIST aggregation -> forward ->
      xmit over UDP tunnel

SKB_GSO_FRAGLIST packet traverse an UDP tunnel in the xmit path.
The tunnel code sets up the outer header csum via udp_set_csum()
and the latter assumes that each GSO packet is CHECKSUM_PARTIAL.

Since the introduction of SKB_GSO_FRAGLIST and veth GRO, the above
assumption is not true anymore as SKB_GSO_FRAGLIST are
CHECKSUM_UNNECESSARY, and the csum for the outer header will be
left uninitialized.

All the above will cause wrong outer UDP header checksum when the
mentioned packet will be xmitted on some real NIC.

This change addresses the issue explicitly checking for both gso and
CHECKSUM_PARTIAL in udp_set_csum(), so that the mentioned packet will
be processed correctly.

Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 net/ipv4/udp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 15f5504adf5b..055fceb18bea 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -857,7 +857,7 @@  void udp_set_csum(bool nocheck, struct sk_buff *skb,
 
 	if (nocheck) {
 		uh->check = 0;
-	} else if (skb_is_gso(skb)) {
+	} else if (skb_is_gso(skb) && skb->ip_summed == CHECKSUM_PARTIAL) {
 		uh->check = ~udp_v4_check(len, saddr, daddr, 0);
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		uh->check = 0;