Message ID | 7607f06c9a9f39d8a4581dd76e6e6e5314ad2968.1586509651.git.lucien.xin@gmail.com |
---|---|
State | Awaiting Upstream |
Delegated to: | David Miller |
Headers | show |
Series | [ipsec] esp6: support ipv6 nexthdrs process for beet gso segment | expand |
2020-04-10, 17:07:31 +0800, Xin Long wrote: > For beet mode, when it's ipv6 inner address with nexthdrs set, > the packet format might be: > > ---------------------------------------------------- > | outer | | dest | | | ESP | ESP | > | IP6 hdr| ESP | opts.| TCP | Data | Trailer | ICV | > ---------------------------------------------------- > > Before doing gso segment in xfrm6_beet_gso_segment(), it should > skip all nexthdrs and get the real transport proto, and set > transport_header properly. > > This patch is to fix it by simply calling ipv6_skip_exthdr() > in xfrm6_beet_gso_segment(). > > Fixes: 7f9e40eb18a9 ("esp6: add gso_segment for esp6 beet mode") > Signed-off-by: Xin Long <lucien.xin@gmail.com> > --- > net/ipv6/esp6_offload.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c > index b828508..021f58c 100644 > --- a/net/ipv6/esp6_offload.c > +++ b/net/ipv6/esp6_offload.c > @@ -173,7 +173,7 @@ static struct sk_buff *xfrm6_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; > > @@ -184,7 +184,13 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x, > proto = ph->nexthdr; > } > > - if (x->sel.family != AF_INET6) { > + if (x->sel.family == AF_INET6) { > + int offset = skb_transport_offset(skb); > + __be16 frag; > + > + offset = ipv6_skip_exthdr(skb, offset, &proto, &frag); > + skb->transport_header += offset; This seems a bit wrong: we start with offset = transport_offset, then ipv6_skip_exthdr adds the size of the extension headers to it. In a simple case where there's no extension header, ipv6_skip_exthdr returns offset. Now we add offset to skb->transport_header, so transport_header is increased, but it shouldn't have changed. What am I missing? Thanks.
On Wed, Apr 15, 2020 at 5:56 PM Sabrina Dubroca <sd@queasysnail.net> wrote: > > 2020-04-10, 17:07:31 +0800, Xin Long wrote: > > For beet mode, when it's ipv6 inner address with nexthdrs set, > > the packet format might be: > > > > ---------------------------------------------------- > > | outer | | dest | | | ESP | ESP | > > | IP6 hdr| ESP | opts.| TCP | Data | Trailer | ICV | > > ---------------------------------------------------- > > > > Before doing gso segment in xfrm6_beet_gso_segment(), it should > > skip all nexthdrs and get the real transport proto, and set > > transport_header properly. > > > > This patch is to fix it by simply calling ipv6_skip_exthdr() > > in xfrm6_beet_gso_segment(). > > > > Fixes: 7f9e40eb18a9 ("esp6: add gso_segment for esp6 beet mode") > > Signed-off-by: Xin Long <lucien.xin@gmail.com> > > --- > > net/ipv6/esp6_offload.c | 10 ++++++++-- > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c > > index b828508..021f58c 100644 > > --- a/net/ipv6/esp6_offload.c > > +++ b/net/ipv6/esp6_offload.c > > @@ -173,7 +173,7 @@ static struct sk_buff *xfrm6_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; > > > > @@ -184,7 +184,13 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x, > > proto = ph->nexthdr; > > } > > > > - if (x->sel.family != AF_INET6) { > > + if (x->sel.family == AF_INET6) { > > + int offset = skb_transport_offset(skb); > > + __be16 frag; > > + > > + offset = ipv6_skip_exthdr(skb, offset, &proto, &frag); > > + skb->transport_header += offset; > > This seems a bit wrong: we start with offset = transport_offset, then > ipv6_skip_exthdr adds the size of the extension headers to it. > > In a simple case where there's no extension header, ipv6_skip_exthdr > returns offset. Now we add offset to skb->transport_header, so > transport_header is increased, but it shouldn't have changed. > > What am I missing? You're right, actually skb_transport_offset(skb) is always 0 in there. I will post v2 with: skb->transport_header += ipv6_skip_exthdr(skb, 0, &proto, &frag); Thanks for reviewing. > > Thanks. > > -- > Sabrina >
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index b828508..021f58c 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -173,7 +173,7 @@ static struct sk_buff *xfrm6_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; @@ -184,7 +184,13 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x, proto = ph->nexthdr; } - if (x->sel.family != AF_INET6) { + if (x->sel.family == AF_INET6) { + int offset = skb_transport_offset(skb); + __be16 frag; + + offset = ipv6_skip_exthdr(skb, offset, &proto, &frag); + skb->transport_header += offset; + } else { skb->transport_header -= (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
For beet mode, when it's ipv6 inner address with nexthdrs set, the packet format might be: ---------------------------------------------------- | outer | | dest | | | ESP | ESP | | IP6 hdr| ESP | opts.| TCP | Data | Trailer | ICV | ---------------------------------------------------- Before doing gso segment in xfrm6_beet_gso_segment(), it should skip all nexthdrs and get the real transport proto, and set transport_header properly. This patch is to fix it by simply calling ipv6_skip_exthdr() in xfrm6_beet_gso_segment(). Fixes: 7f9e40eb18a9 ("esp6: add gso_segment for esp6 beet mode") Signed-off-by: Xin Long <lucien.xin@gmail.com> --- net/ipv6/esp6_offload.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)