xfrm: Fix GSO for IPsec with GRE tunnel.

We reset the encapsulation field of the skb too early
in xfrm_output. As a result, the GRE GSO handler does
not segment the packets. This leads to a performance
drop down. We fix this by resetting the encapsulation
field right before we do the transformation, when
the inner headers become invalid.

Fixes: f1bd7d659e ("xfrm: Add encapsulation header offsets while SKB is not encrypted")
Reported-by: Vicente De Luca <vdeluca@zendesk.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
Steffen Klassert 2017-10-30 10:04:04 +01:00
parent 2b06cdf3e6
commit 73b9fc49b4

View file

@ -105,6 +105,9 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
if (xfrm_offload(skb)) { if (xfrm_offload(skb)) {
x->type_offload->encap(x, skb); x->type_offload->encap(x, skb);
} else { } else {
/* Inner headers are invalid now. */
skb->encapsulation = 0;
err = x->type->output(x, skb); err = x->type->output(x, skb);
if (err == -EINPROGRESS) if (err == -EINPROGRESS)
goto out; goto out;
@ -208,7 +211,6 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
int err; int err;
secpath_reset(skb); secpath_reset(skb);
skb->encapsulation = 0;
if (xfrm_dev_offload_ok(skb, x)) { if (xfrm_dev_offload_ok(skb, x)) {
struct sec_path *sp; struct sec_path *sp;