diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 13 |
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 | ||