From patchwork Tue Nov 25 19:21:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 414834 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6D84E14019C for ; Wed, 26 Nov 2014 06:22:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751485AbaKYTV5 (ORCPT ); Tue, 25 Nov 2014 14:21:57 -0500 Received: from mail-ie0-f180.google.com ([209.85.223.180]:53279 "EHLO mail-ie0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751160AbaKYTV4 (ORCPT ); Tue, 25 Nov 2014 14:21:56 -0500 Received: by mail-ie0-f180.google.com with SMTP id rp18so1161589iec.25 for ; Tue, 25 Nov 2014 11:21:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=Okn5GRxoVrGD6p4DoofB7wY2cEkQ5lEnF3xi2SX+pPs=; b=aP2u8UQBUhIMGojCibo+sA3Y1e98Y4ssUvpRYAM8P7xUzG7sH7cbK52vENENeAkmS0 Ud6pZb8oY47UD1sJF04+hipWoqhWFh2PLm67EdslAK25MtYa8hAtJ45KhwgFNDa94yjB PlSQ72s/9kJ1B7M8Aj8TRxIAV+jXj6pUOxAorNshMqsgH8m2GwaTYM+5Q+U8UO4HVKV2 eOOa9lzEnGmWVFDQfG95enLjfU4ijB07YEmOzuUa18RtiXd1c4p/4Q+j1tfmO/Erd6TC L+8bGp/bbCBdsIqSTKnN7LpIldQLFZVYAFbe8gDsWhQP9BVN9WJyfkZlP/cX2ouUprLP Wi1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Okn5GRxoVrGD6p4DoofB7wY2cEkQ5lEnF3xi2SX+pPs=; b=akpQksREinSz5maExrS5PvjdDYb802MUo2e/pPpIQa2q2tl2RLP653ZyGacIoEVeCX YFPe6cn8L3g9tFRv+2v2Y8W4wJE1bGbaTNG8gAOF7QQi6bSazBXYmVYC+cwPL/y8BI+D gHAVVNETGacdwUYnzxC8UQyYtj6gkPJkuFDdMq/e2KbHj22wt4cCMqJYOUovoB5rPkrl La5l6kLVz4GwhiPa2VrQVGbmMnt2+85+cs5Cm9J112TSbvzPjJATJwSStqko4jdv8vzk Ojs/251KSewE1jPoj6ltRxdBJFs2AAleBSfNMPcPEGxBbLd9Z9aAkVLPWXdOcvV9g8LO Gg3A== X-Gm-Message-State: ALoCoQmqNUWNmQS6g6qMgT4VtIvbTKsxRk5Kk3aonA53AcibwpoduDivb2F83rwQLLB+Nw2/tOmi X-Received: by 10.43.79.7 with SMTP id zo7mr30577142icb.5.1416943315481; Tue, 25 Nov 2014 11:21:55 -0800 (PST) Received: from tomh.mtv.corp.google.com ([172.18.117.126]) by mx.google.com with ESMTPSA id r12sm980058ioe.43.2014.11.25.11.21.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Nov 2014 11:21:55 -0800 (PST) From: Tom Herbert To: davem@davemloft.net, netdev@vger.kernel.org Subject: [PATCH net-next 2/2] gue: Call remcsum_adjust Date: Tue, 25 Nov 2014 11:21:20 -0800 Message-Id: <1416943280-28473-3-git-send-email-therbert@google.com> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1416943280-28473-1-git-send-email-therbert@google.com> References: <1416943280-28473-1-git-send-email-therbert@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Change remote checksum offload to call remcsum_adjust. This also eliminates the optimization to skip an IP header as part of the adjustment (really does not seem to be much of a win). Signed-off-by: Tom Herbert --- net/ipv4/fou.c | 84 ++++++++++++---------------------------------------------- 1 file changed, 17 insertions(+), 67 deletions(-) diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index 3dfe982..b986298 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -64,15 +64,13 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb) } static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, - void *data, int hdrlen, u8 ipproto) + void *data, size_t hdrlen, u8 ipproto) { __be16 *pd = data; - u16 start = ntohs(pd[0]); - u16 offset = ntohs(pd[1]); - u16 poffset = 0; - u16 plen; - __wsum csum, delta; - __sum16 *psum; + size_t start = ntohs(pd[0]); + size_t offset = ntohs(pd[1]); + size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); + __wsum delta; if (skb->remcsum_offload) { /* Already processed in GRO path */ @@ -80,35 +78,15 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, return guehdr; } - if (start > skb->len - hdrlen || - offset > skb->len - hdrlen - sizeof(u16)) - return NULL; - - if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) - __skb_checksum_complete(skb); - - plen = hdrlen + offset + sizeof(u16); if (!pskb_may_pull(skb, plen)) return NULL; guehdr = (struct guehdr *)&udp_hdr(skb)[1]; - if (ipproto == IPPROTO_IP && sizeof(struct iphdr) < plen) { - struct iphdr *ip = (struct iphdr *)(skb->data + hdrlen); - - /* If next header happens to be IP we can skip that for the - * checksum calculation since the IP header checksum is zero - * if correct. - */ - poffset = ip->ihl * 4; - } - - csum = csum_sub(skb->csum, skb_checksum(skb, poffset + hdrlen, - start - poffset - hdrlen, 0)); + if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) + __skb_checksum_complete(skb); - /* Set derived checksum in packet */ - psum = (__sum16 *)(skb->data + hdrlen + offset); - delta = csum_sub(csum_fold(csum), *psum); - *psum = csum_fold(csum); + delta = remcsum_adjust((void *)guehdr + hdrlen, + skb->csum, start, offset); /* Adjust skb->csum since we changed the packet */ skb->csum = csum_add(skb->csum, delta); @@ -158,9 +136,6 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len); - /* Pull UDP header now, skb->data points to guehdr */ - __skb_pull(skb, sizeof(struct udphdr)); - /* Pull csum through the guehdr now . This can be used if * there is a remote checksum offload. */ @@ -188,7 +163,7 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) if (unlikely(guehdr->control)) return gue_control_message(skb, guehdr); - __skb_pull(skb, hdrlen); + __skb_pull(skb, sizeof(struct udphdr) + hdrlen); skb_reset_transport_header(skb); return -guehdr->proto_ctype; @@ -248,24 +223,17 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, size_t hdrlen, u8 ipproto) { __be16 *pd = data; - u16 start = ntohs(pd[0]); - u16 offset = ntohs(pd[1]); - u16 poffset = 0; - u16 plen; - void *ptr; - __wsum csum, delta; - __sum16 *psum; + size_t start = ntohs(pd[0]); + size_t offset = ntohs(pd[1]); + size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); + __wsum delta; if (skb->remcsum_offload) return guehdr; - if (start > skb_gro_len(skb) - hdrlen || - offset > skb_gro_len(skb) - hdrlen - sizeof(u16) || - !NAPI_GRO_CB(skb)->csum_valid || skb->remcsum_offload) + if (!NAPI_GRO_CB(skb)->csum_valid) return NULL; - plen = hdrlen + offset + sizeof(u16); - /* Pull checksum that will be written */ if (skb_gro_header_hard(skb, off + plen)) { guehdr = skb_gro_header_slow(skb, off + plen, off); @@ -273,26 +241,8 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, return NULL; } - ptr = (void *)guehdr + hdrlen; - - if (ipproto == IPPROTO_IP && - (hdrlen + sizeof(struct iphdr) < plen)) { - struct iphdr *ip = (struct iphdr *)(ptr + hdrlen); - - /* If next header happens to be IP we can skip - * that for the checksum calculation since the - * IP header checksum is zero if correct. - */ - poffset = ip->ihl * 4; - } - - csum = csum_sub(NAPI_GRO_CB(skb)->csum, - csum_partial(ptr + poffset, start - poffset, 0)); - - /* Set derived checksum in packet */ - psum = (__sum16 *)(ptr + offset); - delta = csum_sub(csum_fold(csum), *psum); - *psum = csum_fold(csum); + delta = remcsum_adjust((void *)guehdr + hdrlen, + NAPI_GRO_CB(skb)->csum, start, offset); /* Adjust skb->csum since we changed the packet */ skb->csum = csum_add(skb->csum, delta);