Skip to content

Commit 15f35d4

Browse files
akodanevdavem330
authored andcommitted
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: ed70fcf ("net: Call skb_checksum_init in IPv4") Fixes: e4f45b7 ("net: Call skb_checksum_init in IPv6") Signed-off-by: Alexey Kodanev <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da27988 commit 15f35d4

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

include/net/udplite.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
6464
UDP_SKB_CB(skb)->cscov = cscov;
6565
if (skb->ip_summed == CHECKSUM_COMPLETE)
6666
skb->ip_summed = CHECKSUM_NONE;
67+
skb->csum_valid = 0;
6768
}
6869

6970
return 0;

net/ipv4/udp.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
20242024
err = udplite_checksum_init(skb, uh);
20252025
if (err)
20262026
return err;
2027+
2028+
if (UDP_SKB_CB(skb)->partial_cov) {
2029+
skb->csum = inet_compute_pseudo(skb, proto);
2030+
return 0;
2031+
}
20272032
}
20282033

20292034
/* Note, we are only interested in != 0 or == 0, thus the

net/ipv6/ip6_checksum.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
7373
err = udplite_checksum_init(skb, uh);
7474
if (err)
7575
return err;
76+
77+
if (UDP_SKB_CB(skb)->partial_cov) {
78+
skb->csum = ip6_compute_pseudo(skb, proto);
79+
return 0;
80+
}
7681
}
7782

7883
/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)

0 commit comments

Comments
 (0)