From 9ea10592817a9a81b33ee719c7e10728078c22e5 Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Mon, 23 Jan 2017 13:53:53 +0530 Subject: [PATCH] Calculate checksum only for valid IP length __skb_checksum_complete calculates checksum for the whole packet, including the ethernet padding if any. This will result in wrong checksum verification at the receiving end and thus a wrong packet drop. Use __skb_checksum_complete_head instead and pass the length calculated from IP header as the size over which checksum has to be calculated. Change-Id: Ic9b44a336f314bae369900e383ff5f3003f6c114 Closes-Bug: #1658576 --- linux/vrouter_mod.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/linux/vrouter_mod.c b/linux/vrouter_mod.c index 6a730a1d3..62c1bfa57 100644 --- a/linux/vrouter_mod.c +++ b/linux/vrouter_mod.c @@ -915,10 +915,13 @@ lh_csum_verify_fast(struct vr_ip *iph, struct tcphdr *tcph, static int lh_csum_verify(struct sk_buff *skb, struct vr_ip *iph) { + uint32_t size; + + size = ntohs(iph->ip_len) - (iph->ip_hl * 4); skb->csum = csum_tcpudp_nofold(iph->ip_saddr, iph->ip_daddr, - ntohs(iph->ip_len) - (iph->ip_hl * 4), - IPPROTO_TCP, 0); - if (__skb_checksum_complete(skb)) { + size, + iph->ip_proto, 0); + if (__skb_checksum_complete_head(skb, size)) { return -1; } @@ -945,21 +948,19 @@ lh_handle_checksum_complete_skb(struct sk_buff *skb) static int lh_csum_verify_udp(struct sk_buff *skb, struct vr_ip *iph) { + uint32_t size; + + size = ntohs(iph->ip_len) - (iph->ip_hl * 4); + if (skb->ip_summed == CHECKSUM_COMPLETE) { if (!csum_tcpudp_magic(iph->ip_saddr, iph->ip_daddr, - skb->len, IPPROTO_UDP, skb->csum)) { + size, IPPROTO_UDP, skb->csum)) { skb->ip_summed = CHECKSUM_UNNECESSARY; return 0; } } - skb->csum = csum_tcpudp_nofold(iph->ip_saddr, iph->ip_daddr, - skb->len, IPPROTO_UDP, 0); - if (__skb_checksum_complete(skb)) { - return -1; - } - - return 0; + return lh_csum_verify(skb, iph); } /*