netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Duyck <aduyck@mirantis.com>
To: netdev@vger.kernel.org, alexander.duyck@gmail.com
Cc: ecree@solarflare.com, tom@herbertland.com, davem@davemloft.net
Subject: [net-next PATCH 06/10] gre: Use GSO flags to determine csum need instead of GRE flags
Date: Fri, 05 Feb 2016 15:28:01 -0800	[thread overview]
Message-ID: <20160205232801.18529.33991.stgit@localhost.localdomain> (raw)
In-Reply-To: <20160205232109.18529.99816.stgit@localhost.localdomain>

This patch updates the gre checksum path to follow something much closer to
the UDP checksum path.  By doing this we can avoid needing to do as much
header inspection and can just make use of the fields we were already
reading in the sk_buff structure.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 net/ipv4/gre_offload.c |   64 +++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 34 deletions(-)

diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index 35a8dd35ed4e..c15441b5ff61 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -18,14 +18,14 @@
 static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
 				       netdev_features_t features)
 {
+	int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
-	int ghl;
 	struct gre_base_hdr *greh;
 	u16 mac_offset = skb->mac_header;
-	int mac_len = skb->mac_len;
 	__be16 protocol = skb->protocol;
-	int tnl_hlen;
-	bool csum;
+	u16 mac_len = skb->mac_len;
+	int gre_offset, outer_hlen;
+	bool need_csum;
 
 	if (unlikely(skb_shinfo(skb)->gso_type &
 				~(SKB_GSO_TCPV4 |
@@ -42,64 +42,60 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
 	if (!skb->encapsulation)
 		goto out;
 
-	if (unlikely(!pskb_may_pull(skb, sizeof(*greh))))
+	if (unlikely(tnl_hlen < sizeof(struct gre_base_hdr)))
 		goto out;
 
-	greh = (struct gre_base_hdr *)skb_transport_header(skb);
-
-	ghl = skb_inner_mac_header(skb) - skb_transport_header(skb);
-	if (unlikely(ghl < sizeof(*greh)))
+	if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
 		goto out;
 
-	csum = !!(greh->flags & GRE_CSUM);
-	if (csum)
-		skb->encap_hdr_csum = 1;
+	greh = (struct gre_base_hdr *)skb_transport_header(skb);
 
 	/* setup inner skb. */
 	skb->protocol = greh->protocol;
 	skb->encapsulation = 0;
-
-	if (unlikely(!pskb_may_pull(skb, ghl)))
-		goto out;
-
-	__skb_pull(skb, ghl);
+	__skb_pull(skb, tnl_hlen);
 	skb_reset_mac_header(skb);
 	skb_set_network_header(skb, skb_inner_network_offset(skb));
 	skb->mac_len = skb_inner_network_offset(skb);
 
+	need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_GRE_CSUM);
+	skb->encap_hdr_csum = need_csum;
+
 	features &= skb->dev->hw_enc_features;
 
 	/* segment inner packet. */
 	segs = skb_mac_gso_segment(skb, features);
 	if (IS_ERR_OR_NULL(segs)) {
-		skb_gso_error_unwind(skb, protocol, ghl, mac_offset, mac_len);
+		skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
+				     mac_len);
 		goto out;
 	}
 
+	outer_hlen = skb_tnl_header_len(skb);
+	gre_offset = outer_hlen - tnl_hlen;
 	skb = segs;
-	tnl_hlen = skb_tnl_header_len(skb);
 	do {
-		__skb_push(skb, ghl);
-		if (csum) {
-			__be32 *pcsum;
-
-			skb_reset_transport_header(skb);
-
-			greh = (struct gre_base_hdr *)
-			    skb_transport_header(skb);
-			pcsum = (__be32 *)(greh + 1);
-			*pcsum = 0;
-			*(__sum16 *)pcsum = gso_make_checksum(skb, 0);
-		}
-		__skb_push(skb, tnl_hlen - ghl);
+		__be32 *pcsum;
 
 		skb_reset_inner_headers(skb);
 		skb->encapsulation = 1;
 
-		skb_reset_mac_header(skb);
-		skb_set_network_header(skb, mac_len);
 		skb->mac_len = mac_len;
 		skb->protocol = protocol;
+
+		__skb_push(skb, outer_hlen);
+		skb_reset_mac_header(skb);
+		skb_set_network_header(skb, mac_len);
+		skb_set_transport_header(skb, gre_offset);
+
+		if (!need_csum)
+			continue;
+
+		greh = (struct gre_base_hdr *)skb_transport_header(skb);
+		pcsum = (__be32 *)(greh + 1);
+
+		*pcsum = 0;
+		*(__sum16 *)pcsum = gso_make_checksum(skb, 0);
 	} while ((skb = skb->next));
 out:
 	return segs;

  parent reply	other threads:[~2016-02-05 23:28 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-05 23:27 [net-next PATCH 00/10] Add GSO support for outer checksum w/ inner checksum offloads Alexander Duyck
2016-02-05 23:27 ` [net-next PATCH 01/10] net: Drop unecessary enc_features variable from tunnel segmentation functions Alexander Duyck
2016-02-06 20:38   ` Tom Herbert
2016-02-05 23:27 ` [net-next PATCH 02/10] net: Move GSO csum into SKB_GSO_CB Alexander Duyck
2016-02-06 20:41   ` Tom Herbert
2016-02-05 23:27 ` [net-next PATCH 03/10] net: Update remote checksum segmentation to support use of GSO checksum Alexander Duyck
2016-02-06 20:44   ` Tom Herbert
2016-02-07 10:13     ` Alexander Duyck
2016-02-05 23:27 ` [net-next PATCH 04/10] net: Store checksum result for offloaded GSO checksums Alexander Duyck
2016-02-05 23:27 ` [net-next PATCH 05/10] net: Move skb_has_shared_frag check out of GRE code and into segmentation Alexander Duyck
2016-02-06 20:45   ` Tom Herbert
2016-02-05 23:28 ` Alexander Duyck [this message]
2016-02-06 20:52   ` [net-next PATCH 06/10] gre: Use GSO flags to determine csum need instead of GRE flags Tom Herbert
2016-02-07 10:06     ` Alexander Duyck
2016-02-05 23:28 ` [net-next PATCH 07/10] gre: Use inner_proto to obtain inner header protocol Alexander Duyck
2016-02-06 20:55   ` Tom Herbert
2016-02-07 10:11     ` Alexander Duyck
2016-02-05 23:28 ` [net-next PATCH 08/10] udp: Clean up the use of flags in UDP segmentation offload Alexander Duyck
2016-02-06 20:57   ` Tom Herbert
2016-02-05 23:28 ` [net-next PATCH 09/10] udp: Use uh->len instead of skb->len to compute checksum in segmentation Alexander Duyck
2016-02-06 20:59   ` Tom Herbert
2016-02-05 23:28 ` [net-next PATCH 10/10] net: Allow tunnels to use inner checksum offloads with outer checksums needed Alexander Duyck
2016-02-06 21:00   ` Tom Herbert
2016-02-11 14:32 ` [net-next PATCH 00/10] Add GSO support for outer checksum w/ inner checksum offloads David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160205232801.18529.33991.stgit@localhost.localdomain \
    --to=aduyck@mirantis.com \
    --cc=alexander.duyck@gmail.com \
    --cc=davem@davemloft.net \
    --cc=ecree@solarflare.com \
    --cc=netdev@vger.kernel.org \
    --cc=tom@herbertland.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).