On Tue, Jan 2, 2018 at 12:23 PM, Willem de Bruijn <willemdebruijn.ker...@gmail.com> wrote: >> Actually, changes just to inet_gso_segment and ipv6_gso_segment >> will suffice: >> >> bool udpfrag = false, fixedid = false, gso_partial, encap; >> struct sk_buff *segs = ERR_PTR(-EINVAL); >> + unsigned int offset = 0, gso_type; >> const struct net_offload *ops; >> - unsigned int offset = 0; >> struct iphdr *iph; >> int proto, tot_len; >> int nhoff; >> @@ -1258,6 +1258,22 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, >> >> skb_reset_transport_header(skb); >> >> + gso_type = skb_shinfo(skb)->gso_type; >> + if (gso_type & SKB_GSO_DODGY) { >> + switch (gso_type & (SKB_GSO_TCPV4 | SKB_GSO_UDP)) { >> + case SKB_GSO_TCPV4: >> + if (proto != IPPROTO_TCP) >> + goto out; >> + break; >> + case SKB_GSO_UDP: >> + if (proto != IPPROTO_UDP) >> + goto out; >> + break; >> + default: >> + goto out; >> + } >> + } >> >> and analogous for IPv6. For a real patch I would deduplicate this >> logic between them and move it to a separate helper function >> (in a header file, then). > > This approach would also need an skb->protocol check either in > virtio_net_hdr_to_skb or skb_mac_gso_segment.
It turns out that all paths already call skb_probe_transport_header, which also does flow dissection, so has the necessary preconditions for dissection checked: skb->protocol and network header have been initialized. I posted http://patchwork.ozlabs.org/patch/861874/ which adds gso type and protocol tests based on that flow dissector pass. Flow dissection was short circuited when csum offload already set the transport header, so this does add a flow dissector call to gso packets in practice, even if the datapath is not new.