net: core: handle encapsulation offloads when computing segment lengths
authorFlorian Westphal <fw@strlen.de>
Mon, 20 Oct 2014 11:49:18 +0000 (13:49 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Oct 2014 16:38:13 +0000 (12:38 -0400)
if ->encapsulation is set we have to use inner_tcp_hdrlen and add the
size of the inner network headers too.

This is 'mostly harmless'; tbf might send skb that is slightly over
quota or drop skb even if it would have fit.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/skbuff.c

index 61059a05ec95f1fdc420e7bbb250d1a8b22c87b0..c16615bfb61edd2a1dae9ef7935a3153d78dc4df 100644 (file)
@@ -4070,15 +4070,22 @@ EXPORT_SYMBOL_GPL(skb_scrub_packet);
 unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
 {
        const struct skb_shared_info *shinfo = skb_shinfo(skb);
+       unsigned int thlen = 0;
 
-       if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
-               return tcp_hdrlen(skb) + shinfo->gso_size;
+       if (skb->encapsulation) {
+               thlen = skb_inner_transport_header(skb) -
+                       skb_transport_header(skb);
 
+               if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+                       thlen += inner_tcp_hdrlen(skb);
+       } else if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
+               thlen = tcp_hdrlen(skb);
+       }
        /* UFO sets gso_size to the size of the fragmentation
         * payload, i.e. the size of the L4 (UDP) header is already
         * accounted for.
         */
-       return shinfo->gso_size;
+       return thlen + shinfo->gso_size;
 }
 EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);