Skip to content

Commit

Permalink
Calculate checksum only for valid IP length
Browse files Browse the repository at this point in the history
__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
  • Loading branch information
anandhk-juniper committed Jan 23, 2017
1 parent ddd0c0a commit 9ea1059
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions linux/vrouter_mod.c
Expand Up @@ -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;
}

Expand All @@ -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);
}

/*
Expand Down

0 comments on commit 9ea1059

Please sign in to comment.