summaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
authorAlexey Kodanev <alexey.kodanev@oracle.com>2018-02-15 12:18:43 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-16 15:57:42 -0500
commit15f35d49c93f4fa9875235e7bf3e3783d2dd7a1b (patch)
tree2d100c2307313118f62ae83634a3f23046fa1a90 /net/ipv4/udp.c
parentda27988766e338e4a4fe198170497c0920395d4c (diff)
udplite: fix partial checksum initialization
Since UDP-Lite is always using checksum, the following path is triggered when calculating pseudo header for it: udp4_csum_init() or udp6_csum_init() skb_checksum_init_zero_check() __skb_checksum_validate_complete() The problem can appear if skb->len is less than CHECKSUM_BREAK. In this particular case __skb_checksum_validate_complete() also invokes __skb_checksum_complete(skb). If UDP-Lite is using partial checksum that covers only part of a packet, the function will return bad checksum and the packet will be dropped. It can be fixed if we skip skb_checksum_init_zero_check() and only set the required pseudo header checksum for UDP-Lite with partial checksum before udp4_csum_init()/udp6_csum_init() functions return. Fixes: ed70fcfcee95 ("net: Call skb_checksum_init in IPv4") Fixes: e4f45b7f40bd ("net: Call skb_checksum_init in IPv6") Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index bfaefe560b5c..e5ef7c38c934 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2024,6 +2024,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
2024 err = udplite_checksum_init(skb, uh); 2024 err = udplite_checksum_init(skb, uh);
2025 if (err) 2025 if (err)
2026 return err; 2026 return err;
2027
2028 if (UDP_SKB_CB(skb)->partial_cov) {
2029 skb->csum = inet_compute_pseudo(skb, proto);
2030 return 0;
2031 }
2027 } 2032 }
2028 2033
2029 /* Note, we are only interested in != 0 or == 0, thus the 2034 /* Note, we are only interested in != 0 or == 0, thus the