aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 48ada1b2d2c4..0cd71b84e483 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2389,7 +2389,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2389 unsigned int seq; 2389 unsigned int seq;
2390 __be32 delta; 2390 __be32 delta;
2391 unsigned int oldlen; 2391 unsigned int oldlen;
2392 unsigned int len; 2392 unsigned int mss;
2393 2393
2394 if (!pskb_may_pull(skb, sizeof(*th))) 2394 if (!pskb_may_pull(skb, sizeof(*th)))
2395 goto out; 2395 goto out;
@@ -2405,10 +2405,13 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2405 oldlen = (u16)~skb->len; 2405 oldlen = (u16)~skb->len;
2406 __skb_pull(skb, thlen); 2406 __skb_pull(skb, thlen);
2407 2407
2408 mss = skb_shinfo(skb)->gso_size;
2409 if (unlikely(skb->len <= mss))
2410 goto out;
2411
2408 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { 2412 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
2409 /* Packet is from an untrusted source, reset gso_segs. */ 2413 /* Packet is from an untrusted source, reset gso_segs. */
2410 int type = skb_shinfo(skb)->gso_type; 2414 int type = skb_shinfo(skb)->gso_type;
2411 int mss;
2412 2415
2413 if (unlikely(type & 2416 if (unlikely(type &
2414 ~(SKB_GSO_TCPV4 | 2417 ~(SKB_GSO_TCPV4 |
@@ -2419,7 +2422,6 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2419 !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))) 2422 !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
2420 goto out; 2423 goto out;
2421 2424
2422 mss = skb_shinfo(skb)->gso_size;
2423 skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss); 2425 skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
2424 2426
2425 segs = NULL; 2427 segs = NULL;
@@ -2430,8 +2432,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2430 if (IS_ERR(segs)) 2432 if (IS_ERR(segs))
2431 goto out; 2433 goto out;
2432 2434
2433 len = skb_shinfo(skb)->gso_size; 2435 delta = htonl(oldlen + (thlen + mss));
2434 delta = htonl(oldlen + (thlen + len));
2435 2436
2436 skb = segs; 2437 skb = segs;
2437 th = tcp_hdr(skb); 2438 th = tcp_hdr(skb);
@@ -2447,7 +2448,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2447 csum_fold(csum_partial(skb_transport_header(skb), 2448 csum_fold(csum_partial(skb_transport_header(skb),
2448 thlen, skb->csum)); 2449 thlen, skb->csum));
2449 2450
2450 seq += len; 2451 seq += mss;
2451 skb = skb->next; 2452 skb = skb->next;
2452 th = tcp_hdr(skb); 2453 th = tcp_hdr(skb);
2453 2454