Re: IPv6-UDP 0x0000 checksum
From: Eric Dumazet <hidden>
Date: 2017-01-26 13:45:01
Also in:
linux-wireless
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
On Thu, 2017-01-26 at 14:27 +0100, Johannes Berg wrote:
Hi, It looks like right now we may have a hardware bug and accept 0x0000 as valid, when the outcome of the calculation is 0xffff. What do you think we should do about this? We could ignore the issue entirely, since 0 wasn't ever supposed to be sent anyway - but then we don't drop frames that we should drop. I didn't manage to find the code in the IPv6/UDP stack that even does that, but I assume it's there somewhere. Alternatively, we could parse the packet to find the checksum inside, and if it's 0 then don't report CHECKSUM_UNNECESSARY, but that seems rather expensive/difficult due to the IPv6 variable header and all that. If we wanted to go this route, are there any helper functions for this? Unfortunately, in the current devices, we neither have a complete indication that the packet was even UDP-IPv6, nor do we have the raw csum or anything like that. I think they're adding that to the next hardware spin, but we probably need to address this issue now. johannes
Hi Johannes
I am afraid information is missing.
Is this a xmit or rcv problem ?
I recently fixed an issue, could this be this ?
commit 4f2e4ad56a65f3b7d64c258e373cb71e8d2499f4
Author: Eric Dumazet [off-list ref]
Date: Sat Oct 29 11:02:36 2016 -0700
net: mangle zero checksum in skb_checksum_help()
Sending zero checksum is ok for TCP, but not for UDP.
UDPv6 receiver should by default drop a frame with a 0 checksum,
and UDPv4 would not verify the checksum and might accept a corrupted
packet.
Simply replace such checksum by 0xffff, regardless of transport.
This error was caught on SIT tunnels, but seems generic.
Signed-off-by: Eric Dumazet [off-list ref]
Cc: Maciej Żenczykowski [off-list ref]
Cc: Willem de Bruijn [off-list ref]
Acked-by: Maciej Żenczykowski [off-list ref]
Signed-off-by: David S. Miller [off-list ref]
diff --git a/net/core/dev.c b/net/core/dev.c
index 820bac239738eb021354ac95ca5bbdff1840cb8e..eaad4c28069ff523ac784bf2dffd0acff82341a0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c@@ -2484,7 +2484,7 @@ int skb_checksum_help(struct sk_buff *skb) goto out; } - *(__sum16 *)(skb->data + offset) = csum_fold(csum); + *(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0; out_set_summed: skb->ip_summed = CHECKSUM_NONE; out: