From 6f2edd76d32348cf02a9f1c4b4bc0927532358f2 Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Wed, 3 Jun 2015 16:41:39 +0530 Subject: [PATCH] Pull a transport header only if one is present When packets arrive from a vm/fabric, we try to pull all data till the first 8 bytes of a transport header into the first buffer so that linear access to data is possible (keys to flow is what we look for in the transport header). We do this operation without checking whether the packet is a fragment or not and such an unconditional attempt at pull can result in pull failures for fragments whose data length is less that 8. Hence, pull only for packets that have a valid transport header and that has a trapsort protocol we recognize. Change-Id: Iaf8ec480bef045c774630a7c0cc9afbc867a6062 Closes-BUG: #1460218 --- linux/vr_host_interface.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/linux/vr_host_interface.c b/linux/vr_host_interface.c index 37b0795ea..3a023f1da 100644 --- a/linux/vr_host_interface.c +++ b/linux/vr_host_interface.c @@ -1010,6 +1010,7 @@ static int linux_pull_outer_headers(struct sk_buff *skb) { struct vlan_hdr *vhdr; + bool thdr = false, pull = false; uint16_t proto, offset, ip_proto = 0; struct iphdr *iph = NULL; struct ipv6hdr *ip6h = NULL; @@ -1038,8 +1039,9 @@ linux_pull_outer_headers(struct sk_buff *skb) if (!pskb_may_pull(skb, offset)) goto pull_fail; iph = ip_hdr(skb); - if (linux_ip_proto_pull(iph) && - vr_ip_transport_header_valid((struct vr_ip *)iph)) { + thdr = vr_ip_transport_header_valid((struct vr_ip *)iph); + pull = linux_ip_proto_pull(iph); + if (pull && thdr) { ip_proto = iph->protocol; } } else if (proto == htons(ETH_P_IPV6)) { @@ -1050,8 +1052,9 @@ linux_pull_outer_headers(struct sk_buff *skb) goto pull_fail; ip6h = ipv6_hdr(skb); - - if (linux_ipv6_proto_pull(ip6h)) { + thdr = true; + pull = linux_ipv6_proto_pull(ip6h); + if (pull) { ip_proto = ip6h->nexthdr; } } else if (proto == htons(ETH_P_ARP)) { @@ -1060,7 +1063,7 @@ linux_pull_outer_headers(struct sk_buff *skb) goto pull_fail; } - if (iph || ip6h) { + if (thdr && pull && (iph || ip6h)) { /* * this covers both regular port number offsets that come in * the first 4 bytes and the icmp header