diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 241 |
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 | ||
4449 | static 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 | |||
4571 | add_sack: | ||
4572 | if (tcp_is_sack(tp)) | ||
4573 | tcp_sack_new_ofo_skb(sk, seq, end_seq); | ||
4574 | end: | ||
4575 | if (skb) | ||
4576 | skb_set_owner_r(skb, sk); | ||
4577 | } | ||
4578 | |||
4579 | |||
4447 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | 4580 | static 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 | |||
4657 | add_sack: | ||
4658 | if (tcp_is_sack(tp)) | ||
4659 | tcp_sack_new_ofo_skb(sk, seq, end_seq); | ||
4660 | } | ||
4661 | } | 4696 | } |
4662 | 4697 | ||
4663 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, | 4698 | static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, |