diff options
author | Xin Long <lucien.xin@gmail.com> | 2020-04-19 16:11:02 +0800 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2020-04-21 07:18:14 +0200 |
commit | 6f297068a0696eafecef13852408b05a81edb560 (patch) | |
tree | e064d6bf8d8fd540ee8630478d1e1403313b3a9e /net | |
parent | 25a44ae93d1a490f36d88a180f11aa2650bef074 (diff) | |
download | linux-6f297068a0696eafecef13852408b05a81edb560.tar.gz linux-6f297068a0696eafecef13852408b05a81edb560.tar.bz2 linux-6f297068a0696eafecef13852408b05a81edb560.zip |
esp4: support ipv6 nexthdrs process for beet gso segment
For beet mode, when it's ipv6 inner address with nexthdrs set,
the packet format might be:
----------------------------------------------------
| outer | | dest | | | ESP | ESP |
| IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
----------------------------------------------------
Before doing gso segment in xfrm4_beet_gso_segment(), the same
thing is needed as it does in xfrm6_beet_gso_segment() in last
patch 'esp6: support ipv6 nexthdrs process for beet gso segment'.
v1->v2:
- remove skb_transport_offset(), as it will always return 0
in xfrm6_beet_gso_segment(), thank Sabrina's check.
Fixes: 384a46ea7bdc ("esp4: add gso_segment for esp4 beet mode")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/esp4_offload.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 231edcb84c08..9b1d451edae0 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -137,7 +137,7 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x, struct xfrm_offload *xo = xfrm_offload(skb); struct sk_buff *segs = ERR_PTR(-EINVAL); const struct net_offload *ops; - int proto = xo->proto; + u8 proto = xo->proto; skb->transport_header += x->props.header_len; @@ -146,10 +146,15 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x, skb->transport_header += ph->hdrlen * 8; proto = ph->nexthdr; - } else if (x->sel.family != AF_INET6) { + } else if (x->sel.family == AF_INET6) { + __be16 frag; + + skb->transport_header += + ipv6_skip_exthdr(skb, 0, &proto, &frag); + if (proto == IPPROTO_TCP) + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; + } else { skb->transport_header -= IPV4_BEET_PHMAXLEN; - } else if (proto == IPPROTO_TCP) { - skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; } __skb_pull(skb, skb_transport_offset(skb)); |