|
@@ -2389,7 +2389,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
|
|
|
unsigned int seq;
|
|
|
__be32 delta;
|
|
|
unsigned int oldlen;
|
|
|
- unsigned int len;
|
|
|
+ unsigned int mss;
|
|
|
|
|
|
if (!pskb_may_pull(skb, sizeof(*th)))
|
|
|
goto out;
|
|
@@ -2405,10 +2405,13 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
|
|
|
oldlen = (u16)~skb->len;
|
|
|
__skb_pull(skb, thlen);
|
|
|
|
|
|
+ mss = skb_shinfo(skb)->gso_size;
|
|
|
+ if (unlikely(skb->len <= mss))
|
|
|
+ goto out;
|
|
|
+
|
|
|
if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
|
|
|
/* Packet is from an untrusted source, reset gso_segs. */
|
|
|
int type = skb_shinfo(skb)->gso_type;
|
|
|
- int mss;
|
|
|
|
|
|
if (unlikely(type &
|
|
|
~(SKB_GSO_TCPV4 |
|
|
@@ -2419,7 +2422,6 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
|
|
|
!(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
|
|
|
goto out;
|
|
|
|
|
|
- mss = skb_shinfo(skb)->gso_size;
|
|
|
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
|
|
|
|
|
|
segs = NULL;
|
|
@@ -2430,8 +2432,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
|
|
|
if (IS_ERR(segs))
|
|
|
goto out;
|
|
|
|
|
|
- len = skb_shinfo(skb)->gso_size;
|
|
|
- delta = htonl(oldlen + (thlen + len));
|
|
|
+ delta = htonl(oldlen + (thlen + mss));
|
|
|
|
|
|
skb = segs;
|
|
|
th = tcp_hdr(skb);
|
|
@@ -2447,7 +2448,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
|
|
|
csum_fold(csum_partial(skb_transport_header(skb),
|
|
|
thlen, skb->csum));
|
|
|
|
|
|
- seq += len;
|
|
|
+ seq += mss;
|
|
|
skb = skb->next;
|
|
|
th = tcp_hdr(skb);
|
|
|
|