diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 110 |
1 files changed, 71 insertions, 39 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c96a6bb25430..2bdb0da237e6 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -77,7 +77,7 @@ int sysctl_tcp_window_scaling __read_mostly = 1; | |||
77 | int sysctl_tcp_sack __read_mostly = 1; | 77 | int sysctl_tcp_sack __read_mostly = 1; |
78 | int sysctl_tcp_fack __read_mostly = 1; | 78 | int sysctl_tcp_fack __read_mostly = 1; |
79 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; | 79 | int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; |
80 | int sysctl_tcp_ecn __read_mostly; | 80 | int sysctl_tcp_ecn __read_mostly = 2; |
81 | int sysctl_tcp_dsack __read_mostly = 1; | 81 | int sysctl_tcp_dsack __read_mostly = 1; |
82 | int sysctl_tcp_app_win __read_mostly = 31; | 82 | int sysctl_tcp_app_win __read_mostly = 31; |
83 | int sysctl_tcp_adv_win_scale __read_mostly = 2; | 83 | int sysctl_tcp_adv_win_scale __read_mostly = 2; |
@@ -597,16 +597,6 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb) | |||
597 | tcp_grow_window(sk, skb); | 597 | tcp_grow_window(sk, skb); |
598 | } | 598 | } |
599 | 599 | ||
600 | static u32 tcp_rto_min(struct sock *sk) | ||
601 | { | ||
602 | struct dst_entry *dst = __sk_dst_get(sk); | ||
603 | u32 rto_min = TCP_RTO_MIN; | ||
604 | |||
605 | if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) | ||
606 | rto_min = dst_metric_rtt(dst, RTAX_RTO_MIN); | ||
607 | return rto_min; | ||
608 | } | ||
609 | |||
610 | /* Called to compute a smoothed rtt estimate. The data fed to this | 600 | /* Called to compute a smoothed rtt estimate. The data fed to this |
611 | * routine either comes from timestamps, or from segments that were | 601 | * routine either comes from timestamps, or from segments that were |
612 | * known _not_ to have been retransmitted [see Karn/Partridge | 602 | * known _not_ to have been retransmitted [see Karn/Partridge |
@@ -4436,7 +4426,7 @@ drop: | |||
4436 | } | 4426 | } |
4437 | __skb_queue_head(&tp->out_of_order_queue, skb); | 4427 | __skb_queue_head(&tp->out_of_order_queue, skb); |
4438 | } else { | 4428 | } else { |
4439 | struct sk_buff *skb1 = tp->out_of_order_queue.prev; | 4429 | struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue); |
4440 | u32 seq = TCP_SKB_CB(skb)->seq; | 4430 | u32 seq = TCP_SKB_CB(skb)->seq; |
4441 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; | 4431 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; |
4442 | 4432 | ||
@@ -4453,15 +4443,18 @@ drop: | |||
4453 | } | 4443 | } |
4454 | 4444 | ||
4455 | /* Find place to insert this segment. */ | 4445 | /* Find place to insert this segment. */ |
4456 | do { | 4446 | while (1) { |
4457 | if (!after(TCP_SKB_CB(skb1)->seq, seq)) | 4447 | if (!after(TCP_SKB_CB(skb1)->seq, seq)) |
4458 | break; | 4448 | break; |
4459 | } while ((skb1 = skb1->prev) != | 4449 | if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) { |
4460 | (struct sk_buff *)&tp->out_of_order_queue); | 4450 | skb1 = NULL; |
4451 | break; | ||
4452 | } | ||
4453 | skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1); | ||
4454 | } | ||
4461 | 4455 | ||
4462 | /* Do skb overlap to previous one? */ | 4456 | /* Do skb overlap to previous one? */ |
4463 | if (skb1 != (struct sk_buff *)&tp->out_of_order_queue && | 4457 | if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { |
4464 | before(seq, TCP_SKB_CB(skb1)->end_seq)) { | ||
4465 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4458 | if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
4466 | /* All the bits are present. Drop. */ | 4459 | /* All the bits are present. Drop. */ |
4467 | __kfree_skb(skb); | 4460 | __kfree_skb(skb); |
@@ -4473,15 +4466,26 @@ drop: | |||
4473 | tcp_dsack_set(sk, seq, | 4466 | tcp_dsack_set(sk, seq, |
4474 | TCP_SKB_CB(skb1)->end_seq); | 4467 | TCP_SKB_CB(skb1)->end_seq); |
4475 | } else { | 4468 | } else { |
4476 | skb1 = skb1->prev; | 4469 | if (skb_queue_is_first(&tp->out_of_order_queue, |
4470 | skb1)) | ||
4471 | skb1 = NULL; | ||
4472 | else | ||
4473 | skb1 = skb_queue_prev( | ||
4474 | &tp->out_of_order_queue, | ||
4475 | skb1); | ||
4477 | } | 4476 | } |
4478 | } | 4477 | } |
4479 | __skb_queue_after(&tp->out_of_order_queue, skb1, skb); | 4478 | if (!skb1) |
4479 | __skb_queue_head(&tp->out_of_order_queue, skb); | ||
4480 | else | ||
4481 | __skb_queue_after(&tp->out_of_order_queue, skb1, skb); | ||
4480 | 4482 | ||
4481 | /* And clean segments covered by new one as whole. */ | 4483 | /* And clean segments covered by new one as whole. */ |
4482 | while ((skb1 = skb->next) != | 4484 | while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) { |
4483 | (struct sk_buff *)&tp->out_of_order_queue && | 4485 | skb1 = skb_queue_next(&tp->out_of_order_queue, skb); |
4484 | after(end_seq, TCP_SKB_CB(skb1)->seq)) { | 4486 | |
4487 | if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) | ||
4488 | break; | ||
4485 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { | 4489 | if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { |
4486 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, | 4490 | tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, |
4487 | end_seq); | 4491 | end_seq); |
@@ -4502,7 +4506,10 @@ add_sack: | |||
4502 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, | 4506 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, |
4503 | struct sk_buff_head *list) | 4507 | struct sk_buff_head *list) |
4504 | { | 4508 | { |
4505 | struct sk_buff *next = skb->next; | 4509 | struct sk_buff *next = NULL; |
4510 | |||
4511 | if (!skb_queue_is_last(list, skb)) | ||
4512 | next = skb_queue_next(list, skb); | ||
4506 | 4513 | ||
4507 | __skb_unlink(skb, list); | 4514 | __skb_unlink(skb, list); |
4508 | __kfree_skb(skb); | 4515 | __kfree_skb(skb); |
@@ -4513,6 +4520,9 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, | |||
4513 | 4520 | ||
4514 | /* Collapse contiguous sequence of skbs head..tail with | 4521 | /* Collapse contiguous sequence of skbs head..tail with |
4515 | * sequence numbers start..end. | 4522 | * sequence numbers start..end. |
4523 | * | ||
4524 | * If tail is NULL, this means until the end of the list. | ||
4525 | * | ||
4516 | * Segments with FIN/SYN are not collapsed (only because this | 4526 | * Segments with FIN/SYN are not collapsed (only because this |
4517 | * simplifies code) | 4527 | * simplifies code) |
4518 | */ | 4528 | */ |
@@ -4521,15 +4531,23 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4521 | struct sk_buff *head, struct sk_buff *tail, | 4531 | struct sk_buff *head, struct sk_buff *tail, |
4522 | u32 start, u32 end) | 4532 | u32 start, u32 end) |
4523 | { | 4533 | { |
4524 | struct sk_buff *skb; | 4534 | struct sk_buff *skb, *n; |
4535 | bool end_of_skbs; | ||
4525 | 4536 | ||
4526 | /* First, check that queue is collapsible and find | 4537 | /* First, check that queue is collapsible and find |
4527 | * the point where collapsing can be useful. */ | 4538 | * the point where collapsing can be useful. */ |
4528 | for (skb = head; skb != tail;) { | 4539 | skb = head; |
4540 | restart: | ||
4541 | end_of_skbs = true; | ||
4542 | skb_queue_walk_from_safe(list, skb, n) { | ||
4543 | if (skb == tail) | ||
4544 | break; | ||
4529 | /* No new bits? It is possible on ofo queue. */ | 4545 | /* No new bits? It is possible on ofo queue. */ |
4530 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { | 4546 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
4531 | skb = tcp_collapse_one(sk, skb, list); | 4547 | skb = tcp_collapse_one(sk, skb, list); |
4532 | continue; | 4548 | if (!skb) |
4549 | break; | ||
4550 | goto restart; | ||
4533 | } | 4551 | } |
4534 | 4552 | ||
4535 | /* The first skb to collapse is: | 4553 | /* The first skb to collapse is: |
@@ -4539,16 +4557,24 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4539 | */ | 4557 | */ |
4540 | if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && | 4558 | if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && |
4541 | (tcp_win_from_space(skb->truesize) > skb->len || | 4559 | (tcp_win_from_space(skb->truesize) > skb->len || |
4542 | before(TCP_SKB_CB(skb)->seq, start) || | 4560 | before(TCP_SKB_CB(skb)->seq, start))) { |
4543 | (skb->next != tail && | 4561 | end_of_skbs = false; |
4544 | TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq))) | ||
4545 | break; | 4562 | break; |
4563 | } | ||
4564 | |||
4565 | if (!skb_queue_is_last(list, skb)) { | ||
4566 | struct sk_buff *next = skb_queue_next(list, skb); | ||
4567 | if (next != tail && | ||
4568 | TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) { | ||
4569 | end_of_skbs = false; | ||
4570 | break; | ||
4571 | } | ||
4572 | } | ||
4546 | 4573 | ||
4547 | /* Decided to skip this, advance start seq. */ | 4574 | /* Decided to skip this, advance start seq. */ |
4548 | start = TCP_SKB_CB(skb)->end_seq; | 4575 | start = TCP_SKB_CB(skb)->end_seq; |
4549 | skb = skb->next; | ||
4550 | } | 4576 | } |
4551 | if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) | 4577 | if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) |
4552 | return; | 4578 | return; |
4553 | 4579 | ||
4554 | while (before(start, end)) { | 4580 | while (before(start, end)) { |
@@ -4593,7 +4619,8 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, | |||
4593 | } | 4619 | } |
4594 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { | 4620 | if (!before(start, TCP_SKB_CB(skb)->end_seq)) { |
4595 | skb = tcp_collapse_one(sk, skb, list); | 4621 | skb = tcp_collapse_one(sk, skb, list); |
4596 | if (skb == tail || | 4622 | if (!skb || |
4623 | skb == tail || | ||
4597 | tcp_hdr(skb)->syn || | 4624 | tcp_hdr(skb)->syn || |
4598 | tcp_hdr(skb)->fin) | 4625 | tcp_hdr(skb)->fin) |
4599 | return; | 4626 | return; |
@@ -4620,17 +4647,21 @@ static void tcp_collapse_ofo_queue(struct sock *sk) | |||
4620 | head = skb; | 4647 | head = skb; |
4621 | 4648 | ||
4622 | for (;;) { | 4649 | for (;;) { |
4623 | skb = skb->next; | 4650 | struct sk_buff *next = NULL; |
4651 | |||
4652 | if (!skb_queue_is_last(&tp->out_of_order_queue, skb)) | ||
4653 | next = skb_queue_next(&tp->out_of_order_queue, skb); | ||
4654 | skb = next; | ||
4624 | 4655 | ||
4625 | /* Segment is terminated when we see gap or when | 4656 | /* Segment is terminated when we see gap or when |
4626 | * we are at the end of all the queue. */ | 4657 | * we are at the end of all the queue. */ |
4627 | if (skb == (struct sk_buff *)&tp->out_of_order_queue || | 4658 | if (!skb || |
4628 | after(TCP_SKB_CB(skb)->seq, end) || | 4659 | after(TCP_SKB_CB(skb)->seq, end) || |
4629 | before(TCP_SKB_CB(skb)->end_seq, start)) { | 4660 | before(TCP_SKB_CB(skb)->end_seq, start)) { |
4630 | tcp_collapse(sk, &tp->out_of_order_queue, | 4661 | tcp_collapse(sk, &tp->out_of_order_queue, |
4631 | head, skb, start, end); | 4662 | head, skb, start, end); |
4632 | head = skb; | 4663 | head = skb; |
4633 | if (skb == (struct sk_buff *)&tp->out_of_order_queue) | 4664 | if (!skb) |
4634 | break; | 4665 | break; |
4635 | /* Start new segment */ | 4666 | /* Start new segment */ |
4636 | start = TCP_SKB_CB(skb)->seq; | 4667 | start = TCP_SKB_CB(skb)->seq; |
@@ -4691,10 +4722,11 @@ static int tcp_prune_queue(struct sock *sk) | |||
4691 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); | 4722 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); |
4692 | 4723 | ||
4693 | tcp_collapse_ofo_queue(sk); | 4724 | tcp_collapse_ofo_queue(sk); |
4694 | tcp_collapse(sk, &sk->sk_receive_queue, | 4725 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
4695 | sk->sk_receive_queue.next, | 4726 | tcp_collapse(sk, &sk->sk_receive_queue, |
4696 | (struct sk_buff *)&sk->sk_receive_queue, | 4727 | skb_peek(&sk->sk_receive_queue), |
4697 | tp->copied_seq, tp->rcv_nxt); | 4728 | NULL, |
4729 | tp->copied_seq, tp->rcv_nxt); | ||
4698 | sk_mem_reclaim(sk); | 4730 | sk_mem_reclaim(sk); |
4699 | 4731 | ||
4700 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) | 4732 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) |