|
@@ -3151,10 +3151,21 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
|
|
|
hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
|
|
|
|
|
|
/* + transport layer */
|
|
|
- if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
|
|
|
- hdr_len += tcp_hdrlen(skb);
|
|
|
- else
|
|
|
- hdr_len += sizeof(struct udphdr);
|
|
|
+ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
|
|
|
+ const struct tcphdr *th;
|
|
|
+ struct tcphdr _tcphdr;
|
|
|
+
|
|
|
+ th = skb_header_pointer(skb, skb_transport_offset(skb),
|
|
|
+ sizeof(_tcphdr), &_tcphdr);
|
|
|
+ if (likely(th))
|
|
|
+ hdr_len += __tcp_hdrlen(th);
|
|
|
+ } else {
|
|
|
+ struct udphdr _udphdr;
|
|
|
+
|
|
|
+ if (skb_header_pointer(skb, skb_transport_offset(skb),
|
|
|
+ sizeof(_udphdr), &_udphdr))
|
|
|
+ hdr_len += sizeof(struct udphdr);
|
|
|
+ }
|
|
|
|
|
|
if (shinfo->gso_type & SKB_GSO_DODGY)
|
|
|
gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
|