aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c241
1 files changed, 138 insertions, 103 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b5e315f13641..e886e2f7fa8d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -61,6 +61,8 @@
61 * Pasi Sarolahti: F-RTO for dealing with spurious RTOs 61 * Pasi Sarolahti: F-RTO for dealing with spurious RTOs
62 */ 62 */
63 63
64#define pr_fmt(fmt) "TCP: " fmt
65
64#include <linux/mm.h> 66#include <linux/mm.h>
65#include <linux/slab.h> 67#include <linux/slab.h>
66#include <linux/module.h> 68#include <linux/module.h>
@@ -3867,9 +3869,9 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o
3867 opt_rx->wscale_ok = 1; 3869 opt_rx->wscale_ok = 1;
3868 if (snd_wscale > 14) { 3870 if (snd_wscale > 14) {
3869 if (net_ratelimit()) 3871 if (net_ratelimit())
3870 printk(KERN_INFO "tcp_parse_options: Illegal window " 3872 pr_info("%s: Illegal window scaling value %d >14 received\n",
3871 "scaling value %d >14 received.\n", 3873 __func__,
3872 snd_wscale); 3874 snd_wscale);
3873 snd_wscale = 14; 3875 snd_wscale = 14;
3874 } 3876 }
3875 opt_rx->snd_wscale = snd_wscale; 3877 opt_rx->snd_wscale = snd_wscale;
@@ -4191,7 +4193,7 @@ static void tcp_fin(struct sock *sk)
4191 /* Only TCP_LISTEN and TCP_CLOSE are left, in these 4193 /* Only TCP_LISTEN and TCP_CLOSE are left, in these
4192 * cases we should never reach this piece of code. 4194 * cases we should never reach this piece of code.
4193 */ 4195 */
4194 printk(KERN_ERR "%s: Impossible, sk->sk_state=%d\n", 4196 pr_err("%s: Impossible, sk->sk_state=%d\n",
4195 __func__, sk->sk_state); 4197 __func__, sk->sk_state);
4196 break; 4198 break;
4197 } 4199 }
@@ -4444,6 +4446,137 @@ static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
4444 return 0; 4446 return 0;
4445} 4447}
4446 4448
4449static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
4450{
4451 struct tcp_sock *tp = tcp_sk(sk);
4452 struct sk_buff *skb1;
4453 u32 seq, end_seq;
4454
4455 TCP_ECN_check_ce(tp, skb);
4456
4457 if (tcp_try_rmem_schedule(sk, skb->truesize)) {
4458 /* TODO: should increment a counter */
4459 __kfree_skb(skb);
4460 return;
4461 }
4462
4463 /* Disable header prediction. */
4464 tp->pred_flags = 0;
4465 inet_csk_schedule_ack(sk);
4466
4467 SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
4468 tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
4469
4470 skb1 = skb_peek_tail(&tp->out_of_order_queue);
4471 if (!skb1) {
4472 /* Initial out of order segment, build 1 SACK. */
4473 if (tcp_is_sack(tp)) {
4474 tp->rx_opt.num_sacks = 1;
4475 tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
4476 tp->selective_acks[0].end_seq =
4477 TCP_SKB_CB(skb)->end_seq;
4478 }
4479 __skb_queue_head(&tp->out_of_order_queue, skb);
4480 goto end;
4481 }
4482
4483 seq = TCP_SKB_CB(skb)->seq;
4484 end_seq = TCP_SKB_CB(skb)->end_seq;
4485
4486 if (seq == TCP_SKB_CB(skb1)->end_seq) {
4487 /* Packets in ofo can stay in queue a long time.
4488 * Better try to coalesce them right now
4489 * to avoid future tcp_collapse_ofo_queue(),
4490 * probably the most expensive function in tcp stack.
4491 */
4492 if (skb->len <= skb_tailroom(skb1) && !tcp_hdr(skb)->fin) {
4493 NET_INC_STATS_BH(sock_net(sk),
4494 LINUX_MIB_TCPRCVCOALESCE);
4495 BUG_ON(skb_copy_bits(skb, 0,
4496 skb_put(skb1, skb->len),
4497 skb->len));
4498 TCP_SKB_CB(skb1)->end_seq = end_seq;
4499 TCP_SKB_CB(skb1)->ack_seq = TCP_SKB_CB(skb)->ack_seq;
4500 __kfree_skb(skb);
4501 skb = NULL;
4502 } else {
4503 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4504 }
4505
4506 if (!tp->rx_opt.num_sacks ||
4507 tp->selective_acks[0].end_seq != seq)
4508 goto add_sack;
4509
4510 /* Common case: data arrive in order after hole. */
4511 tp->selective_acks[0].end_seq = end_seq;
4512 goto end;
4513 }
4514
4515 /* Find place to insert this segment. */
4516 while (1) {
4517 if (!after(TCP_SKB_CB(skb1)->seq, seq))
4518 break;
4519 if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
4520 skb1 = NULL;
4521 break;
4522 }
4523 skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
4524 }
4525
4526 /* Do skb overlap to previous one? */
4527 if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
4528 if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4529 /* All the bits are present. Drop. */
4530 __kfree_skb(skb);
4531 skb = NULL;
4532 tcp_dsack_set(sk, seq, end_seq);
4533 goto add_sack;
4534 }
4535 if (after(seq, TCP_SKB_CB(skb1)->seq)) {
4536 /* Partial overlap. */
4537 tcp_dsack_set(sk, seq,
4538 TCP_SKB_CB(skb1)->end_seq);
4539 } else {
4540 if (skb_queue_is_first(&tp->out_of_order_queue,
4541 skb1))
4542 skb1 = NULL;
4543 else
4544 skb1 = skb_queue_prev(
4545 &tp->out_of_order_queue,
4546 skb1);
4547 }
4548 }
4549 if (!skb1)
4550 __skb_queue_head(&tp->out_of_order_queue, skb);
4551 else
4552 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4553
4554 /* And clean segments covered by new one as whole. */
4555 while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
4556 skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
4557
4558 if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
4559 break;
4560 if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4561 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
4562 end_seq);
4563 break;
4564 }
4565 __skb_unlink(skb1, &tp->out_of_order_queue);
4566 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
4567 TCP_SKB_CB(skb1)->end_seq);
4568 __kfree_skb(skb1);
4569 }
4570
4571add_sack:
4572 if (tcp_is_sack(tp))
4573 tcp_sack_new_ofo_skb(sk, seq, end_seq);
4574end:
4575 if (skb)
4576 skb_set_owner_r(skb, sk);
4577}
4578
4579
4447static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) 4580static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
4448{ 4581{
4449 const struct tcphdr *th = tcp_hdr(skb); 4582 const struct tcphdr *th = tcp_hdr(skb);
@@ -4559,105 +4692,7 @@ drop:
4559 goto queue_and_out; 4692 goto queue_and_out;
4560 } 4693 }
4561 4694
4562 TCP_ECN_check_ce(tp, skb); 4695 tcp_data_queue_ofo(sk, skb);
4563
4564 if (tcp_try_rmem_schedule(sk, skb->truesize))
4565 goto drop;
4566
4567 /* Disable header prediction. */
4568 tp->pred_flags = 0;
4569 inet_csk_schedule_ack(sk);
4570
4571 SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
4572 tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
4573
4574 skb_set_owner_r(skb, sk);
4575
4576 if (!skb_peek(&tp->out_of_order_queue)) {
4577 /* Initial out of order segment, build 1 SACK. */
4578 if (tcp_is_sack(tp)) {
4579 tp->rx_opt.num_sacks = 1;
4580 tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
4581 tp->selective_acks[0].end_seq =
4582 TCP_SKB_CB(skb)->end_seq;
4583 }
4584 __skb_queue_head(&tp->out_of_order_queue, skb);
4585 } else {
4586 struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue);
4587 u32 seq = TCP_SKB_CB(skb)->seq;
4588 u32 end_seq = TCP_SKB_CB(skb)->end_seq;
4589
4590 if (seq == TCP_SKB_CB(skb1)->end_seq) {
4591 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4592
4593 if (!tp->rx_opt.num_sacks ||
4594 tp->selective_acks[0].end_seq != seq)
4595 goto add_sack;
4596
4597 /* Common case: data arrive in order after hole. */
4598 tp->selective_acks[0].end_seq = end_seq;
4599 return;
4600 }
4601
4602 /* Find place to insert this segment. */
4603 while (1) {
4604 if (!after(TCP_SKB_CB(skb1)->seq, seq))
4605 break;
4606 if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
4607 skb1 = NULL;
4608 break;
4609 }
4610 skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
4611 }
4612
4613 /* Do skb overlap to previous one? */
4614 if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
4615 if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4616 /* All the bits are present. Drop. */
4617 __kfree_skb(skb);
4618 tcp_dsack_set(sk, seq, end_seq);
4619 goto add_sack;
4620 }
4621 if (after(seq, TCP_SKB_CB(skb1)->seq)) {
4622 /* Partial overlap. */
4623 tcp_dsack_set(sk, seq,
4624 TCP_SKB_CB(skb1)->end_seq);
4625 } else {
4626 if (skb_queue_is_first(&tp->out_of_order_queue,
4627 skb1))
4628 skb1 = NULL;
4629 else
4630 skb1 = skb_queue_prev(
4631 &tp->out_of_order_queue,
4632 skb1);
4633 }
4634 }
4635 if (!skb1)
4636 __skb_queue_head(&tp->out_of_order_queue, skb);
4637 else
4638 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4639
4640 /* And clean segments covered by new one as whole. */
4641 while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
4642 skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
4643
4644 if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
4645 break;
4646 if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
4647 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
4648 end_seq);
4649 break;
4650 }
4651 __skb_unlink(skb1, &tp->out_of_order_queue);
4652 tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
4653 TCP_SKB_CB(skb1)->end_seq);
4654 __kfree_skb(skb1);
4655 }
4656
4657add_sack:
4658 if (tcp_is_sack(tp))
4659 tcp_sack_new_ofo_skb(sk, seq, end_seq);
4660 }
4661} 4696}
4662 4697
4663static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, 4698static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,