On Sat, Feb 6, 2016 at 2:52 PM, Tom Herbert <t...@herbertland.com> wrote: > On Fri, Feb 5, 2016 at 3:28 PM, Alexander Duyck <adu...@mirantis.com> wrote: >> 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 <adu...@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); > > Should we do a WARN_ON(need_csum && !(greh->flags & GRE_CSUM)) just to > be conservative? >
We could but what would be the point? If there is an issue like that present in the kernel we should probably fix it in build_header in ip_gre.c instead of trying to push validation for the case into the GSO code. - Alex